xmlrpc.client — доступ к клиенту XML-RPC
Исходный код: Lib/xmlrpc/client.py
XML-RPC — это метод удалённого вызова процедур, использующий XML, передаваемый по HTTP(S), в качестве транспорта. С его помощью клиент может вызывать методы удалённого сервера с параметрами (сервер задаётся URI) и получать структурированные данные. Этот модуль поддерживает написание кода XML-RPC-клиента; он обрабатывает все детали преобразования совместимых объектов Python в XML и обратно при передаче по сети.
Предупреждение
Модуль xmlrpc.client не защищён от данных, сформированных злоумышленником. Если вам нужно анализировать недоверенные или неаутентифицированные данные, см. раздел Безопасность XML.
Изменено в версии 3.5: Для URI HTTPS xmlrpc.client теперь по умолчанию выполняет все необходимые проверки сертификата и имени хоста.
Доступность: недоступен в WASI.
Этот модуль не работает или недоступен в WebAssembly. Дополнительные сведения см. в разделе Платформы WebAssembly.
-
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 сервера. Второй необязательный аргумент — экземпляр фабрики транспорта; по умолчанию для URL https: используется внутренний экземплярSafeTransport, а в остальных случаях — внутренний экземпляр HTTPTransport. Третий необязательный аргумент — кодировка, по умолчанию 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')]). Если указан URL HTTPS, параметр context может быть объектомssl.SSLContextи настраивает параметры SSL для базового HTTPS-соединения. Устаревший флаг use_datetime похож на use_builtin_types, но применяется только к значениям даты и времени.Изменено в версии 3.3: Добавлен флаг use_builtin_types.
Изменено в версии 3.8: Добавлен параметр headers.
Оба транспорта, HTTP и HTTPS, поддерживают расширение синтаксиса URL для базовой аутентификации HTTP:
http://user:pass@host:port/path. Частьuser:passкодируется в base64 как HTTP-заголовок «Authorization» и отправляется удалённому серверу в процессе установления соединения при вызове метода XML-RPC. Использовать это нужно только в том случае, если удалённый сервер требует имя пользователя и пароль для базовой аутентификации.Возвращённый экземпляр — это объект-прокси с методами, которые можно использовать для вызова соответствующих процедур RPC на удалённом сервере. Если удалённый сервер поддерживает API интроспекции, прокси также можно использовать для запроса списка поддерживаемых сервером методов (обнаружение служб) и получения других метаданных сервера.
К совместимым типам (то есть типам, которые можно маршалировать через XML) относятся следующие типы (если не указано иное, они демаршалируются в тот же тип Python):
Тип XML-RPC
Тип Python
booleanint,i1,i2,i4,i8илиbigintegerintв диапазоне от -2147483648 до 2147483647. Значениям назначается тег<int>.doubleилиfloatfloat. Значениям назначается тег<double>.stringarraylistилиtuple, содержащие совместимые элементы. Массивы возвращаются какlists.structdict. Ключи должны быть строками, значения могут иметь любой совместимый тип. Можно передавать объекты пользовательских классов; передаётся только их атрибут__dict__.dateTime.iso8601DateTimeилиdatetime.datetime. Возвращаемый тип зависит от значений флагов use_builtin_types и use_datetime.base64Binary,bytesилиbytearray. Возвращаемый тип зависит от значения флага use_builtin_types.nilКонстанта
None. Передача допускается только при значении true у allow_none.bigdecimaldecimal.Decimal. Только возвращаемый тип.Это полный набор типов данных, поддерживаемых XML-RPC. При вызове методов также может быть возбуждено специальное исключение-экземпляр
Fault, используемое для передачи ошибок сервера XML-RPC, илиProtocolError, используемое для передачи ошибок транспортного уровня HTTP/HTTPS. ИFault, иProtocolErrorявляются подклассами базового классаError. Обратите внимание, что в настоящее время модуль клиента XML-RPC не маршалирует экземпляры подклассов встроенных типов.При передаче строк специальные для 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. Описание см. на странице https://ws.apache.org/xmlrpc/types.html.
См. также
- Руководство по XML-RPC
-
Хорошее описание работы 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. Он возвращает массив возможных сигнатур этого метода. Сигнатура представляет собой массив типов. Первый из этих типов — тип возвращаемого значения метода, остальные — типы параметров.
Поскольку допускается несколько сигнатур (то есть перегрузка), этот метод возвращает список сигнатур, а не одну сигнатуру.
Сами сигнатуры ограничены параметрами верхнего уровня, ожидаемыми методом. Например, если метод ожидает один массив структур в качестве параметра и возвращает строку, его сигнатура — просто «string, array». Если он ожидает три целых числа и возвращает строку, его сигнатура — «string, int, int, int».
Если для метода не определена сигнатура, возвращается значение, не являющееся массивом. В Python это означает, что тип возвращаемого значения будет отличаться от list.
-
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 as dt
from xmlrpc.server import SimpleXMLRPCServer
import xmlrpc.client
def today():
today = dt.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 as dt
proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")
today = proxy.today()
# convert the ISO 8601 string to a datetime object
converted = dt.datetime.strptime(today.value, "%Y%m%dT%H:%M:%S")
print(f"Today: {converted.strftime('%d.%m.%Y, %H:%M')}")
Двоичные объекты
-
class xmlrpc.client.Binary -
Этот класс можно инициализировать байтовыми данными (которые могут содержать нулевые байты). Основной доступ к содержимому объекта
Binaryпредоставляется через атрибут:-
data -
Двоичные данные, инкапсулированные экземпляром
Binary. Данные представлены объектомbytes.
Объекты
Binaryимеют следующие методы, предназначенные главным образом для внутреннего использования кодом маршалирования/демаршалирования:-
decode(bytes) -
Принимает объект
bytesв формате base64 и декодирует его как новые данные экземпляра.
-
encode(out) -
Записывает base64-представление этого двоичного элемента в формате XML-RPC в потоковый объект out.
В соответствии с разделом 6.8 RFC 2045 в закодированных данных каждые 76 символов будет добавлен перевод строки. На момент написания спецификации XML-RPC этот документ был фактическим стандартом для спецификации base64.
Он также поддерживает некоторые встроенные операторы Python с помощью методов
__eq__()и__ne__(). -
Пример использования двоичных объектов. Передадим изображение по XML-RPC:
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инкапсулирует содержимое тега 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. Значение PythonNoneнельзя использовать в стандартном XML-RPC; чтобы разрешить его использование с помощью расширения, задайте для allow_none значение true.
-
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.
Сноски
© 2001 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.14/library/xmlrpc.client.html