Содержание страницы
xmlrpc.client – доступ к XML-RPC клиенту¶xmlrpc.client – XML-RPC client access
Исходный код: Lib/xmlrpc/client.py
XML-RPC – это метод удалённого вызова процедур (Remote Procedure Call), использующий XML, передаваемый через HTTP(S) в качестве транспорта. С его помощью клиент может вызывать методы с параметрами на удалённом сервере (сервер задаётся URI) и получать структурированные данные. Этот модуль предназначен для написания кода XML-RPC клиента; он берёт на себя все детали преобразования между совместимыми объектами Python и XML, передаваемыми по сети.
Предупреждение
Модуль xmlrpc.client не защищён от вредоносных данных. Если требуется разбирать непроверенные или неаутентифицированные данные, обратитесь к разделу Безопасность XML.
Изменено в версии 3.5: Для HTTPS URI 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 (Uniform Resource Indicator), обычно это 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-заголовков для отправки с каждым запросом, задаваемая как последовательность кортежей из двух элементов, представляющих имя и значение заголовка (например,[('Header-Name', 'value')]). Если указан HTTPS URL, 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,i8orbigintegerintв диапазоне от -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. Передача разрешена только если allow_none равен true.bigdecimaldecimal.Decimal. Только возвращаемый тип.Это полный набор типов данных, поддерживаемых XML-RPC. Вызовы методов также могут возбуждать специальный экземпляр
Faultдля сообщения об ошибках XML-RPC сервера, илиProtocolErrorдля сообщения об ошибке в транспортном слое HTTP/HTTPS. ИFault, иProtocolErrorнаследуются от базового классаError. Обратите внимание, что модуль xmlrpc.client в настоящее время не выполняет маршалинг экземпляров подклассов встроенных типов.При передаче строк символы, специальные для 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 Objects
Экземпляр 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 Objects
- 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()
# преобразовать строку в формате ISO 8601 в объект datetime
converted = dt.datetime.strptime(today.value, "%Y%m%dT%H:%M:%S")
print(f"Today: {converted.strftime('%d.%m.%Y, %H:%M')}")
Двоичные объекты¶Binary Objects
- class xmlrpc.client.Binary¶
Этот класс можно инициализировать данными bytes (которые могут содержать NUL-символы). Основной доступ к содержимому объекта
Binaryпредоставляется через атрибут:- data¶
Двоичные данные, инкапсулированные экземпляром
Binary. Данные предоставляются как объектbytes.
Объекты
Binaryимеют следующие методы, предназначенные в основном для внутреннего использования кодом маршалинга/демаршалинга:- encode(out)¶
Записывает XML-RPC base64-кодировку этого двоичного объекта в потоковый объект 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¶Fault Objects
- class xmlrpc.client.Fault¶
Объект
Faultинкапсулирует содержимое тега ошибки (fault tag) XML-RPC. Объекты Fault имеют следующие атрибуты:- faultCode¶
Целое число (int), указывающее тип ошибки.
- faultString¶
Строка, содержащая диагностическое сообщение, связанное с ошибкой.
В следующем примере мы намеренно вызовем Fault, возвращая
объект сложного типа. Код сервера:
from xmlrpc.server import SimpleXMLRPCServer
# Произойдёт ошибка маршалинга, потому что возвращается
# комплексное число
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¶ProtocolError Objects
- class xmlrpc.client.ProtocolError¶
Объект
ProtocolErrorописывает протокольную ошибку на уровне нижележащего транспорта (например, ошибку 404 «не найдено», если сервер по указанному URI не существует). Он имеет следующие атрибуты:- url¶
URI или URL, вызвавший ошибку.
- errcode¶
Код ошибки.
- errmsg¶
Сообщение об ошибке или диагностическая строка.
- headers¶
Словарь (dict), содержащий заголовки HTTP/HTTPS-запроса, вызвавшего ошибку.
В следующем примере мы намеренно вызовем ProtocolError,
предоставив неверный URI:
import xmlrpc.client
# Создание ServerProxy с URI, который не отвечает на XMLRPC-запросы
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 Objects
Объект MultiCall позволяет инкапсулировать несколько вызовов к
удалённому серверу в один запрос [1].
- class xmlrpc.client.MultiCall(server)¶
Создаёт объект, используемый для пакетирования вызовов методов (boxcar). 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
# Простой сервер с простыми арифметическими функциями
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))
Вспомогательные функции¶Convenience Functions
- 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. ЗначениеNoneв Python не может использоваться в стандартном XML-RPC; чтобы разрешить его использование через расширение, укажите истинное значение для 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; по умолчанию этот флаг выключен.Устаревший флаг use_datetime похож на use_builtin_types, но применяется только к значениям даты/времени.
Изменено в версии 3.3: Добавлен флаг use_builtin_types.
Пример клиентского использования¶Example of Client Usage
# простая тестовая программа (из спецификации XML-RPC)
from xmlrpc.client import ServerProxy, Error
# server = ServerProxy("http://localhost:8000") # локальный сервер
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))
Пример клиентского и серверного использования¶Example of Client and Server Usage
См. пример SimpleXMLRPCServer.
Сноски
Эта страница – перевод. Оригинал на английском – docs.python.org. Нашли неточность? Сообщите нам.