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
выполняет все необходимые проверки сертификатов
и имен хостов по умолчанию.
-
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-адресом сервера. Дополнительным вторым аргументом является сущность транспортной фабрики; по умолчанию это - внутренняяSafeTransport
сущность для https: URL и внутренний 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“)]). Устаревший флаг 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. Это необходимо
использовать только в том случае, если удаленному серверу требуются пользователь
и пароль для обычной аутентификации. Если указан URL-адрес HTTPS, 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 в настоящее время не marshal
сущности подклассы встроенных типов.
При передаче строки автоматически удаляются специальные символы XML, такие
как <
, >
и &
. Тем не менее, вызывающий
должен убедиться, что строка не содержать символов, запрещенных в XML, таких
как управляющие символы с значения ASCII от 0 до 31 (за исключением, конечно,
табуляции, новой строки и каретки возвращает); если этого не сделать, запрос
XML-RPC не будет правильно сформирован. Если требуется передать произвольные
байты через 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
- Описывает расширение протокола XML-RPC для внутреннего анализа.
- Спецификация XML-RPC
- Официальная спецификация.
- Неофициальные ошибки XML-RPC
- Фредрика Лундха (Fredrik Lundh’s) «Неофициальные ошибки, призванные прояснить некоторые детали в спецификации 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, int, int, int».
Если для метода не определен сигнатура, значение возвращенный, не являющийся массивом. В 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)¶ Принять строку в качестве нового временного значения сущности.
Он также поддерживает некоторые из Python’а встроенных операторов с помощью методов богатого сравнения и
__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()
# преобразовать ISO8601 строку в объект datetime
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
обеспечивается атрибут:Объекты
Binary
имеют следующие методы, поддерживаемые в основном для внутреннего использования маршаллинг/размаршаллинг код:-
encode
(out)¶ Записать 64 кодировка базы XML-RPC этого двоичного элемента в объект потока out.
Данные кодированный будут иметь новые строки каждые 76 символов согласно RFC 2045 секция 6.8, что было фактической стандартной спецификацией base64 при написании спецификации XML-RPC.
Он также поддерживает некоторые из Python’s встроенных операторов с помощью методов
__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
¶ Строка, указывающее тип отказа.
-
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¶
-
class
xmlrpc.client.
ProtocolError
¶ Объект
ProtocolError
описывает ошибку протокола на базовом транспортном уровне (например, ошибку 404 „not found“, если сервер с именем URI не существует). Имеет следующие атрибуты:-
url
¶ URI или URL-адрес, вызвавший ошибку.
-
errcode
¶ Код ошибки.
-
errmsg
¶ Сообщение об ошибке или диагностический строка.
-
headers
¶ Словарь, содержащий заголовки запроса 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
обеспечивает способ инкапсуляции нескольких вызовов на
удаленный сервер в единый запрос [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))
Удобные функции¶
-
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’sNone
значение не может быть используемый в стандартном 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
объектов; по умолчанию этот флаг имеет значение false.Устаревший флаг use_datetime аналогичен use_builtin_types, но применяется только к значения даты/времени.
Изменено в версии 3.3: Добавлен флаг use_builtin_types.
Пример использования клиента¶
# простая тестовая программа (из спецификации 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))
Пример использования клиента и сервера¶
Смотрите Пример SimpleXMLRPCServer.
Сноски
[1] | Этот подход был впервые представлен в обсуждении xmlrpc.com. |