Spec-Zone.ru › Python 3.8

xmlrpc.client — Доступ к клиенту XML-RPC

Исходный код: Lib/xmlrpc/client.py

XML-RPC — это метод удалённого вызова процедур, использующий XML, передаваемый через HTTP(S) в качестве транспорта. С его помощью клиент может вызывать методы с параметрами на удалённом сервере (сервер указывается URI) и получать обратно структурированные данные. Этот модуль поддерживает написание кода клиента XML-RPC; он обрабатывает все детали преобразования между совместимыми объектами Python и XML в сети.

Предупреждение

Модуль xmlrpc.client не защищён от вредоносно сконструированных данных. Если вам необходимо разобрать недоверенные или неавторизованные данные, см. Уязвимости XML.

Изменено в версии 3.5: Для HTTPS-URI, xmlrpc.client теперь по умолчанию выполняет все необходимые проверки сертификата и имени хоста.

class xmlrpc.client.ServerProxy(uri, transport=None, encoding=None, verbose=False, allow_none=False, use_datetime=False, use_builtin_types=False, *, headers=(), context=None)

Экземпляр ServerProxy — это объект, управляющий взаимодействием с удалённым сервером XML-RPC. Обязательным первым аргументом является URI (указатель ресурса), который обычно является URL-адресом сервера. Необязательный второй аргумент — экземпляр фабрики транспорта; по умолчанию — внутренний экземпляр SafeTransport для HTTPS-URL и внутренний HTTP Transport экземпляр в противном случае. Необязательный третий аргумент — кодировка, по умолчанию UTF-8. Необязательный четвёртый аргумент — флаг отладки.

Следующие параметры управляют использованием возвращённого экземпляра прокси. Если allow_none имеет значение True, константа Python None будет преобразована в XML; по умолчанию None вызывает исключение TypeError. Это общепринятое расширение спецификации XML-RPC, но не поддерживается всеми клиентами и серверами; см. http://ontosys.com/xml-rpc/extensions.php для описания. Флаг use_builtin_types можно использовать для того, чтобы значения даты/времени представлялись как объекты datetime.datetime, а двоичные данные — как объекты bytes; по умолчанию этот флаг имеет значение False. datetime.datetime, bytes и bytearray объекты могут быть переданы в вызовы. Параметр headers — это необязательная последовательность HTTP-заголовков, которые должны отправляться с каждым запросом, представленная как последовательность пар 2-х элементов, представляющих имя и значение заголовка. (например, [(‘Header-Name’, ‘value’)]). Устаревший флаг use_datetime похож на use_builtin_types, но он применяется только к значениям даты/времени.

Изменено в версии 3.3: Добавлен флаг use_builtin_types.

Изменено в версии 3.8: Добавлен параметр headers.

И HTTP, и HTTPS-транспорты поддерживают расширение синтаксиса URL для HTTP Basic Authentication: http://user:pass@host:port/path. Часть user:pass будет закодирована в base64 как HTTP-заголовок «Authorization» и отправлена на удалённый сервер в рамках процесса подключения при вызове метода XML-RPC. Вам необходимо использовать это только если удалённый сервер требует пользователя и пароль для Basic Authentication. Если предоставлен HTTPS-URL, параметр context может быть ssl.SSLContext и настраивает настройки SSL для подлежащего HTTPS-соединения.

Возвращённый экземпляр — это прокси-объект с методами, которые могут использоваться для вызова соответствующих вызовов RPC на удалённом сервере. Если удалённый сервер поддерживает API интроспекции, прокси также можно использовать для запроса информации о поддерживаемых им методах (обнаружение сервиса) и получения другой метаданных, связанных с сервером.

Совместимые типы (т. е. те, которые могут быть обработаны через XML), включают следующие (и за исключением отмеченного, они возвращаются как тот же тип Python):

Тип XML-RPC

Тип Python

boolean

bool

int, i1, i2, i4, i8 или biginteger

int в диапазоне от -2147483648 до 2147483647. Значения получают тег <int>.

double или float

float. Значения получают тег <double>.

string

str

array

list или tuple содержащие совместимые элементы. Массивы возвращаются как lists.

struct

dict. Ключи должны быть строками, значения могут быть любого совместимого типа. Объекты пользовательских классов могут быть переданы; передаётся только атрибут __dict__.

dateTime.iso8601

DateTime или datetime.datetime. Тип возвращаемого значения зависит от значений флагов use_builtin_types и use_datetime.

base64

Binary, bytes или bytearray. Возвращаемый тип зависит от значения флага use_builtin_types.

nil

Константа None. Передача разрешена только если allow_none равно True.

bigdecimal

decimal.Decimal. Возвращаемый тип только.

Это полный набор типов данных, поддерживаемых XML-RPC. Вызовы методов также могут вызвать специальный экземпляр Fault, используемый для сигнализации об ошибках сервера XML-RPC, или ProtocolError, используемый для сигнализации об ошибке в транспортном уровне HTTP/HTTPS. Оба Fault и ProtocolError наследуются от базового класса Error. Обратите внимание, что модуль клиента xmlrpc в настоящее время не сериализует экземпляры подклассов встроенных типов.

При передаче строк символы, являющиеся специальными для XML, такие как <, >, и & будут автоматически экранированы. Однако, ответственность за обеспечение отсутствия в строке символов, запрещённых в XML, например, управляющих символов с ASCII-кодами от 0 до 31 (за исключением, конечно, табуляции, новой строки и возврата каретки), возлагается на вызывающий код; невыполнение этого требования приведёт к запросу XML-RPC, который не является правильно сформированным XML. Если вам нужно передать произвольные байты через XML-RPC, используйте классы bytes или bytearray, или обёртку класса Binary, описанную ниже.

Server сохраняется как псевдоним для ServerProxy для обратной совместимости. Новый код должен использовать ServerProxy.

Изменено в версии 3.5: Добавлен аргумент context.

Изменено в версии 3.6: Добавлена поддержка тегов типов с префиксами (например, ex:nil). Добавлена поддержка распаковки дополнительных типов, используемых реализацией Apache XML-RPC для числовых значений: i1, i2, i8, biginteger, float и bigdecimal. См. http://ws.apache.org/xmlrpc/types.html для описания.

См. также

XML-RPC HOWTO

Хорошее описание работы XML-RPC и клиентского программного обеспечения на нескольких языках. Содержит практически всё необходимое для разработчика XML-RPC клиента.

XML-RPC Introspection

Описание расширения протокола XML-RPC для интроспекции.

Спецификация XML-RPC

Официальная спецификация.

Неофициальные исправления XML-RPC

«Неофициальные исправления» Фредрика Лундха, предназначенные для уточнения определённых деталей в спецификации XML-RPC, а также указания «рекомендованной практики» при разработке собственных реализаций XML-RPC.

Объекты ServerProxy

У экземпляра ServerProxy есть метод, соответствующий каждому удалённому вызову процедуры, принимаемому сервером XML-RPC. Вызов метода выполняет RPC, определяемый по имени и подписи аргументов (например, одно и то же имя метода может быть перегружено несколькими подписями аргументов). RPC завершается возвращением значения, которое может быть либо возвращаемыми данными в соответствующем типе, либо объектом Fault или ProtocolError, указывающим на ошибку.

Серверы, поддерживающие API XML-интроспекции, поддерживают некоторые общие методы, сгруппированные под зарезервированным атрибутом system:

ServerProxy.system.listMethods()

Этот метод возвращает список строк, по одной на каждый (не системный) метод, поддерживаемый сервером XML-RPC.

ServerProxy.system.methodSignature(name)

Этот метод принимает один параметр — имя метода, реализованного сервером XML-RPC. Он возвращает массив возможных подписей для этого метода. Подпись — это массив типов. Первый из этих типов — тип возвращаемого значения метода, остальные — параметры.

Поскольку разрешено множество подписей (т.е. перегрузка), этот метод возвращает список подписей, а не одиночную запись.

Сами подписи ограничены верхним уровнем параметров, ожидаемых методом. Например, если метод ожидает один массив структур в качестве параметра и возвращает строку, его подпись — просто «строка, массив». Если он ожидает три целых числа и возвращает строку, его подпись — «строка, целое число, целое число, целое число».

Если для метода не определена подпись, возвращается значение, не являющееся массивом. В Python это означает, что тип возвращаемого значения будет чем-то отличным от списка.

ServerProxy.system.methodHelp(name)

Этот метод принимает один параметр — имя метода, реализованного сервером XML-RPC. Он возвращает строку документации, описывающую использование этого метода. Если такая строка недоступна, возвращается пустая строка. Строка документации может содержать HTML-разметку.

Изменено в версии 3.5: Экземпляры ServerProxy поддерживают протокол менеджера контекста для закрытия базового транспорта.

Далее следует рабочий пример. Серверный код:

from xmlrpc.server import SimpleXMLRPCServer

def is_even(n):
    return n % 2 == 0

server = SimpleXMLRPCServer(("localhost", 8000))
print("Listening on port 8000...")
server.register_function(is_even, "is_even")
server.serve_forever()

Клиентский код для предыдущего сервера:

import xmlrpc.client

with xmlrpc.client.ServerProxy("http://localhost:8000/") as proxy:
    print("3 is even: %s" % str(proxy.is_even(3)))
    print("100 is even: %s" % str(proxy.is_even(100)))

Объекты DateTime

class xmlrpc.client.DateTime

Этот класс можно инициализировать с помощью секунд с момента эпохи, кортежа времени, строки времени/даты в формате ISO 8601 или экземпляра datetime.datetime. У него есть следующие методы, в основном поддерживаемые для внутреннего использования кодом маршализации/демаршализации:

decode(string)

Принимает строку в качестве нового значения времени экземпляра.

encode(out)

Записывает XML-RPC кодировку этого объекта DateTime в объект потока out.

Он также поддерживает некоторые встроенные операторы Python через методы rich comparison и __repr__().

Далее следует рабочий пример. Серверный код:

import datetime
from xmlrpc.server import SimpleXMLRPCServer
import xmlrpc.client

def today():
    today = datetime.datetime.today()
    return xmlrpc.client.DateTime(today)

server = SimpleXMLRPCServer(("localhost", 8000))
print("Listening on port 8000...")
server.register_function(today, "today")
server.serve_forever()

Клиентский код для предыдущего сервера:

import xmlrpc.client
import datetime

proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")

today = proxy.today()
# convert the ISO8601 string to a datetime object
converted = datetime.datetime.strptime(today.value, "%Y%m%dT%H:%M:%S")
print("Today: %s" % converted.strftime("%d.%m.%Y, %H:%M"))

Двоичные объекты

class xmlrpc.client.Binary

Этот класс можно инициализировать данными типа байты (которые могут включать нули). Основной доступ к содержимому объекта Binary предоставляется атрибутом:

data

Двоичные данные, заключённые в экземпляре Binary. Данные предоставляются как объект bytes.

Объекты Binary имеют следующие методы, поддерживаемые в основном для внутреннего использования кодом маршализации/демаршализации:

decode(bytes)

Принимает объект base64 байтов bytes и декодирует его как новые данные экземпляра.

encode(out)

Записывает кодировку base 64 этого двоичного элемента XML-RPC в объект потока out.

Закодированные данные будут иметь новые строки через каждые 76 символов в соответствии с RFC 2045 раздел 6.8, которая была фактическим стандартом base64 при написании спецификации XML-RPC.

Он также поддерживает некоторые встроенные операторы Python через методы __eq__() и __ne__().

Пример использования двоичных объектов. Мы собираемся передавать изображение через XMLRPC:

from xmlrpc.server import SimpleXMLRPCServer
import xmlrpc.client

def python_logo():
    with open("python_logo.jpg", "rb") as handle:
        return xmlrpc.client.Binary(handle.read())

server = SimpleXMLRPCServer(("localhost", 8000))
print("Listening on port 8000...")
server.register_function(python_logo, 'python_logo')

server.serve_forever()

Клиент получает изображение и сохраняет его в файл:

import xmlrpc.client

proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")
with open("fetched_python_logo.jpg", "wb") as handle:
    handle.write(proxy.python_logo().data)

Объекты Fault

class xmlrpc.client.Fault

Объект Fault инкапсулирует содержимое тега ошибки XML-RPC. Объекты Fault имеют следующие атрибуты:

faultCode

Строка, указывающая тип ошибки.

faultString

Строка, содержащая диагностическое сообщение, связанное с ошибкой.

В следующем примере мы намеренно вызываем Fault, возвращая сложный объект типа. Серверный код:

from xmlrpc.server import SimpleXMLRPCServer

# A marshalling error is going to occur because we're returning a
# complex number
def add(x, y):
    return x+y+0j

server = SimpleXMLRPCServer(("localhost", 8000))
print("Listening on port 8000...")
server.register_function(add, 'add')

server.serve_forever()

Клиентский код для предыдущего сервера:

import xmlrpc.client

proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")
try:
    proxy.add(2, 5)
except xmlrpc.client.Fault as err:
    print("A fault occurred")
    print("Fault code: %d" % err.faultCode)
    print("Fault string: %s" % err.faultString)

Объекты ProtocolError

class xmlrpc.client.ProtocolError

Объект ProtocolError описывает ошибку протокола в базовом транспортном слое (например, ошибку 404 «не найдено», если сервер, указанный в URI, не существует). У него есть следующие атрибуты:

url

URI или URL, вызвавший ошибку.

errcode

Код ошибки.

errmsg

Сообщение об ошибке или диагностическая строка.

headers

Словарь, содержащий заголовки HTTP/HTTPS запроса, вызвавшего ошибку.

В следующем примере мы намеренно вызываем ProtocolError, предоставив некорректный URI:

import xmlrpc.client

# create a ServerProxy with a URI that doesn't respond to XMLRPC requests
proxy = xmlrpc.client.ServerProxy("http://google.com/")

try:
    proxy.some_method()
except xmlrpc.client.ProtocolError as err:
    print("A protocol error occurred")
    print("URL: %s" % err.url)
    print("HTTP/HTTPS headers: %s" % err.headers)
    print("Error code: %d" % err.errcode)
    print("Error message: %s" % err.errmsg)

Объекты MultiCall

Объект MultiCall предоставляет способ объединения нескольких вызовов удаленному серверу в один запрос 1.

class xmlrpc.client.MultiCall(server)

Создает объект, используемый для группировки вызовов методов. server — конечный получатель вызова. Вызовы могут быть сделаны к объекту результата, но они сразу же вернут None, и только запомнят имя вызова и параметры в объекте MultiCall. Вызов самого объекта приводит к передаче всех сохраненных вызовов как одного system.multicall запроса. Результатом этого вызова является генератор; перебор этого генератора возвращает отдельные результаты.

Пример использования этого класса представлен ниже. Серверный код:

from xmlrpc.server import SimpleXMLRPCServer

def add(x, y):
    return x + y

def subtract(x, y):
    return x - y

def multiply(x, y):
    return x * y

def divide(x, y):
    return x // y

# A simple server with simple arithmetic functions
server = SimpleXMLRPCServer(("localhost", 8000))
print("Listening on port 8000...")
server.register_multicall_functions()
server.register_function(add, 'add')
server.register_function(subtract, 'subtract')
server.register_function(multiply, 'multiply')
server.register_function(divide, 'divide')
server.serve_forever()

Клиентский код для предыдущего сервера:

import xmlrpc.client

proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")
multicall = xmlrpc.client.MultiCall(proxy)
multicall.add(7, 3)
multicall.subtract(7, 3)
multicall.multiply(7, 3)
multicall.divide(7, 3)
result = multicall()

print("7+3=%d, 7-3=%d, 7*3=%d, 7//3=%d" % tuple(result))

Вспомогательные функции

xmlrpc.client.dumps(params, methodname=None, methodresponse=None, encoding=None, allow_none=False)

Преобразует params в запрос XML-RPC. Или в ответ, если methodresponse равно true. params может быть кортежем аргументов или экземпляром исключения Fault. Если methodresponse равно true, может быть возвращено только одно значение, что означает, что params должен иметь длину 1. encoding, если предоставлен, — это кодировка, используемая в сгенерированном XML; по умолчанию используется UTF-8. Значение Python None не может использоваться в стандартном XML-RPC; для возможности его использования с помощью расширения, укажите true для allow_none.

xmlrpc.client.loads(data, use_datetime=False, use_builtin_types=False)

Преобразует запрос или ответ XML-RPC в объекты Python, а также (params, methodname). params — это кортеж аргументов; methodname — строка или None если имя метода отсутствует в пакете. Если пакет XML-RPC представляет ошибку, эта функция поднимет исключение Fault. Флаг use_builtin_types может быть использован для того, чтобы значения даты/времени представлялись как объекты datetime.datetime, а двоичные данные — как объекты bytes; этот флаг по умолчанию равен false.

Устаревший флаг use_datetime похож на use_builtin_types, но он применяется только к значениям даты/времени.

Изменено в версии 3.3: Флаг use_builtin_types был добавлен.

Пример использования клиента

# simple test program (from the XML-RPC specification)
from xmlrpc.client import ServerProxy, Error

# server = ServerProxy("http://localhost:8000") # local server
with ServerProxy("http://betty.userland.com") as proxy:

    print(proxy)

    try:
        print(proxy.examples.getStateName(41))
    except Error as v:
        print("ERROR", v)

Для доступа к серверу XML-RPC через прокси-сервер HTTP необходимо определить пользовательский транспорт. Следующий пример показывает, как это сделать:

import http.client
import xmlrpc.client

class ProxiedTransport(xmlrpc.client.Transport):

    def set_proxy(self, host, port=None, headers=None):
        self.proxy = host, port
        self.proxy_headers = headers

    def make_connection(self, host):
        connection = http.client.HTTPConnection(*self.proxy)
        connection.set_tunnel(host, headers=self.proxy_headers)
        self._connection = host, connection
        return connection

transport = ProxiedTransport()
transport.set_proxy('proxy-server', 8080)
server = xmlrpc.client.ServerProxy('http://betty.userland.com', transport=transport)
print(server.examples.getStateName(41))

Пример использования клиента и сервера

См. Пример SimpleXMLRPCServer.

Примечания

1

Этот подход был впервые представлен в обсуждении на xmlrpc.com.

© 2001–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.8/library/xmlrpc.client.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API