xmlrpc.client
— Клиентский доступ к XML-RPC¶
Исходный код: Lib/xmlrpc/client.py
XML-RPC - это метод удаленного вызова процедур, который использует XML, передаваемый по протоколу HTTP(S) в качестве транспортного средства. С его помощью клиент может вызывать методы с параметрами на удаленном сервере (сервер именуется URI) и получать обратно структурированные данные. Этот модуль поддерживает написание клиентского кода на основе XML-RPC; он обрабатывает все детали перевода между совместимыми объектами Python и XML по проводам.
Предупреждение
Модуль xmlrpc.client
не защищен от вредоносных данных. Если вам нужно проанализировать данные, которым нельзя доверять или которые не прошли проверку подлинности, обратитесь к Важно отметить, что для модулей в пакете требуется, чтобы был доступен хотя бы один синтаксический анализатор XML, совместимый с SAX. Синтаксический анализатор Expat включен в состав Python, поэтому модуль всегда будет доступен..
Изменено в версии 3.5: Для URI HTTPS xmlrpc.client
теперь по умолчанию выполняются все необходимые проверки сертификата и имени хоста.
Availability: это не Emscripten, это был не я.
Этот модуль не работает или недоступен на платформах WebAssembly wasm32-emscripten
и wasm32-wasi
. Дополнительную информацию смотрите в разделе Платформы веб-сборки.
- 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 и внутренний экземпляр HTTPTransport
в противном случае. Необязательный третий аргумент - это кодировка, по умолчанию UTF-8. Необязательный четвертый аргумент - это флаг отладки.Следующие параметры определяют использование возвращаемого экземпляра прокси-сервера. Если значение allow_none равно true, константа Python
None
будет преобразована в XML; по умолчаниюNone
вызываетTypeError
. Это широко используемое расширение спецификации XML-RPC, но оно поддерживается не всеми клиентами и серверами; описание приведено в разделе http://ontosys.com/xml-rpc/extensions.php. Флаг use_buildin_types может использоваться для отображения значений даты/времени в видеdatetime.datetime
объектов, а двоичных данных - в видеbytes
объектов; по умолчанию этот флаг имеет значение false.datetime.datetime
, <<<Объектыbytes
7>>> иbytearray
могут передаваться в вызовы. Параметр headers - это необязательная последовательность HTTP-заголовков для отправки с каждым запросом, выраженная в виде последовательности из 2 кортежей, представляющих имя и значение заголовка. (например,[('Header-Name', 'value')]
). Устаревший флаг use_datetime аналогичен флагу use_buildin_types, но он применяется только к значениям даты и времени.
Изменено в версии 3.3: Был добавлен флаг use_buildin_types.
Изменено в версии 3.8: Был добавлен параметр headers.
Как HTTP, так и HTTPS транспорты поддерживают расширение синтаксиса URL для базовой аутентификации HTTP: http://user:pass@host:port/path
. Часть user:pass
будет закодирована в base64 как заголовок HTTP „Authorization“ и отправлена на удаленный сервер как часть процесса подключения при вызове метода XML-RPC. Это необходимо использовать только в том случае, если удаленному серверу требуются пользователь и пароль для базовой аутентификации. Если указан URL-адрес HTTPS, context может быть ssl.SSLContext
и настраивает параметры SSL для базового HTTPS-соединения.
Возвращаемый экземпляр представляет собой прокси-объект с методами, которые могут быть использованы для вызова соответствующих RPC-вызовов на удаленном сервере. Если удаленный сервер поддерживает API самоанализа, прокси-сервер также можно использовать для запроса к удаленному серверу методов, которые он поддерживает (обнаружение служб), и получения других метаданных, связанных с сервером.
Типы, которые являются совместимыми (например, которые могут быть упорядочены с помощью XML), включают следующее (и, за исключением отмеченных случаев, они не упорядочиваются как один и тот же тип Python).:
Тип XML-RPC |
Тип Python |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Константа |
|
|
Это полный набор типов данных, поддерживаемых 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
. Смотрите описание https://ws.apache.org/xmlrpc/types.html.
См.также
- XML-RPC HOWTO
Хорошее описание работы XML-RPC и клиентского программного обеспечения на нескольких языках. Содержит практически все, что необходимо знать разработчику XML-RPC-клиента.
- XML-RPC Introspection
Описывает расширение протокола XML-RPC для самоанализа.
- XML-RPC Specification
Официальная спецификация.
Объекты прокси-сервера¶
Экземпляр ServerProxy
имеет метод, соответствующий каждому удаленному вызову процедуры, принимаемому сервером XML-RPC. При вызове метода выполняется RPC, отправляемый как по имени, так и по сигнатуре аргумента (например, одно и то же имя метода может быть перегружено несколькими сигнатурами аргументов). RPC завершает работу, возвращая значение, которое может быть либо возвращаемыми данными соответствующего типа, либо объектом Fault
или ProtocolError
, указывающим на ошибку.
Серверы, поддерживающие XML introspection API, поддерживают некоторые распространенные методы, сгруппированные по зарезервированному атрибуту system
:
- ServerProxy.system.listMethods()¶
Этот метод возвращает список строк, по одной для каждого (несистемного) метода, поддерживаемого сервером XML-RPC.
- ServerProxy.system.methodSignature(name)¶
Этот метод принимает один параметр - имя метода, реализованного XML-RPC-сервером. Он возвращает массив возможных сигнатур для этого метода. Сигнатура - это массив типов. Первый из этих типов - это возвращаемый тип метода, остальные - параметры.
Поскольку допускается использование нескольких сигнатур (т.е. перегрузка), этот метод возвращает список сигнатур, а не синглтон.
Сами сигнатуры ограничены параметрами верхнего уровня, ожидаемыми методом. Например, если метод ожидает в качестве параметра один массив структур и возвращает строку, его сигнатура будет просто «строка, массив». Если он ожидает три целых числа и возвращает строку, то его сигнатурой будет «string, int, int, int».
Если для метода не определена сигнатура, возвращается значение, не являющееся массивом. В Python это означает, что тип возвращаемого значения будет иным, чем list.
- ServerProxy.system.methodHelp(name)¶
Этот метод принимает один параметр - название метода, реализованного сервером XML-RPC. Он возвращает строку документации, описывающую использование этого метода. Если такая строка недоступна, возвращается пустая строка. Строка документации может содержать HTML-разметку.
Изменено в версии 3.5: Экземпляры ServerProxy
поддерживают протокол context manager для закрытия базового транспорта.
Ниже приведен рабочий пример. Код сервера:
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)))
Объекты даты и времени¶
- class xmlrpc.client.DateTime¶
Этот класс может быть инициализирован секундами с момента начала эпохи, временным кортежем, строкой времени/даты ISO 8601 или экземпляром
datetime.datetime
. В нем есть следующие методы, поддерживаемые в основном для внутреннего использования кодом сортировки/отмены сортировки:- decode(string)¶
Примите строку в качестве нового значения времени экземпляра.
Он также поддерживает некоторые встроенные операторы 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¶
Этот класс может быть инициализирован из данных в байтах (которые могут включать в себя значения NUL). Основной доступ к содержимому объекта
Binary
предоставляется с помощью атрибута:- data¶
Двоичные данные, инкапсулированные экземпляром
Binary
. Данные предоставляются в виде объектаbytes
.
Binary
объекты имеют следующие методы, поддерживаемые в основном для внутреннего использования кодом сортировки/отмены сортировки:- encode(out)¶
Запишите кодировку XML-RPC base64 для этого двоичного элемента в объект out stream.
Закодированные данные будут содержать новые строки через каждые 76 символов в соответствии с RFC 2045 section 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)
Неисправные объекты¶
- class xmlrpc.client.Fault¶
Объект
Fault
инкапсулирует содержимое тега ошибки XML-RPC. Объекты ошибки имеют следующие атрибуты:- faultCode¶
Символ int, указывающий на тип неисправности.
- 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)
Объекты ошибок протокола¶
- class xmlrpc.client.ProtocolError¶
Объект
ProtocolError
описывает ошибку протокола на базовом транспортном уровне (например, ошибку 404 «не найден», если сервер, указанный в URI, не существует). Он имеет следующие атрибуты:- url¶
URI или URL-адрес, который вызвал ошибку.
- errcode¶
Код ошибки.
- errmsg¶
Сообщение об ошибке или диагностическая строка.
- headers¶
Dict, содержащий заголовки запроса 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
предоставляет способ инкапсуляции нескольких обращений к удаленному серверу в один запрос [1].
- class xmlrpc.client.MultiCall(server)¶
Создайте объект, используемый для вызова метода boxcar. сервер является конечной целью вызова. Вызовы могут быть выполнены к результирующему объекту, но они немедленно вернут
None
и сохранят только имя вызова и параметры в объектеMultiCall
. Вызов самого объекта приводит к передаче всех сохраненных вызовов в виде одного запросаsystem.multicall
. Результатом этого вызова является generator; итерация по этому генератору приводит к получению отдельных результатов.
Ниже приведен пример использования этого класса. Код сервера:
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.
- xmlrpc.client.loads(data, use_datetime=False, use_builtin_types=False)¶
Преобразуйте запрос или ответ XML-RPC в объекты Python,
(params, methodname)
. params - это набор аргументов; methodname - строка илиNone
, если в пакете нет имени метода. Если пакет XML-RPC представляет собой сбойное состояние, эта функция вызовет исключениеFault
. Флаг use_buildin_types может использоваться для отображения значений даты/времени в видеdatetime.datetime
объектов, а двоичных данных - в видеbytes
объектов; по умолчанию этот флаг имеет значение false.Устаревший флаг use_datetime аналогичен флагу use_buildin_types, но он применяется только к значениям даты и времени.
Изменено в версии 3.3: Был добавлен флаг use_buildin_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.
Сноски