xmlrpc.client
— XML-RPC client access¶
Вихідний код: Lib/xmlrpc/client.py
XML-RPC — це метод віддаленого виклику процедури, який використовує XML, що передається через HTTP(S) як транспорт. З його допомогою клієнт може викликати методи з параметрами на віддаленому сервері (сервер має назву URI) і отримати назад структуровані дані. Цей модуль підтримує написання клієнтського коду XML-RPC; він обробляє всі деталі перекладу між відповідними об’єктами Python і XML на дроті.
Попередження
Модуль xmlrpc.client
не захищений від зловмисно створених даних. Якщо вам потрібно проаналізувати ненадійні або неавтентифіковані дані, перегляньте Уразливості XML.
Змінено в версії 3.5: Для HTTPS URI xmlrpc.client
тепер виконує всі необхідні перевірки сертифікатів і імен хостів за умовчанням.
Availability: not WASI.
This module does not work or is not available on WebAssembly. See WebAssembly platforms for more information.
- 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. Необов’язковий четвертий аргумент - це позначка налагодження.The following parameters govern the use of the returned proxy instance. If allow_none is true, the Python constant
None
will be translated into XML; the default behaviour is forNone
to raise aTypeError
. This is a commonly used extension to the XML-RPC specification, but isn’t supported by all clients and servers; see http://ontosys.com/xml-rpc/extensions.php for a description. The use_builtin_types flag can be used to cause date/time values to be presented asdatetime.datetime
objects and binary data to be presented asbytes
objects; this flag is false by default.datetime.datetime
,bytes
andbytearray
objects may be passed to calls. The headers parameter is an optional sequence of HTTP headers to send with each request, expressed as a sequence of 2-tuples representing the header name and value. (e.g.[('Header-Name', 'value')]
). If an HTTPS URL is provided, context may bessl.SSLContext
and configures the SSL settings of the underlying HTTPS connection. The obsolete use_datetime flag is similar to use_builtin_types but it applies only to date/time values.Змінено в версії 3.3: Додано прапорець use_builtin_types.
Змінено в версії 3.8: Додано параметр headers.
Both the HTTP and HTTPS transports support the URL syntax extension for HTTP Basic Authentication:
http://user:pass@host:port/path
. Theuser:pass
portion will be base64-encoded as an HTTP „Authorization“ header, and sent to the remote server as part of the connection process when invoking an XML-RPC method. You only need to use this if the remote server requires a Basic Authentication user and password.Повернений екземпляр — це проксі-об’єкт із методами, які можна використовувати для виклику відповідних викликів RPC на віддаленому сервері. Якщо віддалений сервер підтримує API інтроспекції, проксі також можна використовувати для запиту віддаленого сервера щодо методів, які він підтримує (виявлення служби), і отримання інших пов’язаних із сервером метаданих.
Типи, які є сумісними (наприклад, які можна маршалізувати через XML), включають наступне (і, якщо не зазначено, вони не маршалізуються як той самий тип Python):
Тип XML-RPC
Тип Python
логічний
int
,i1
,i2
,i4
,i8
абоbiginteger
int
в діапазоні від -2147483648 до 2147483647. Значення отримують тег<int>
.double
абоfloat
float
. Значення отримують тег<double>
.рядок
array
list
абоtuple
, що містять відповідні елементи. Масиви повертаються якlists
.структура
dict
. Ключі мають бути рядками, значення можуть мати будь-який відповідний тип. Можна передати об’єкти визначених користувачем класів; передається лише їхній атрибут__dict__
.dateTime.iso8601
DateTime
абоdatetime.datetime
. Повернений тип залежить від значень прапорців use_builtin_types і use_datetime.base64
Binary
,bytes
абоbytearray
. Повернений тип залежить від значення прапорця use_builtin_types.нуль
Константа
None
. Передача дозволена, лише якщо allow_none має значення true.великий десятковий
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: Додано аргумент контекст.
Змінено в версії 3.6: Added support of type tags with prefixes (e.g.
ex:nil
). Added support of unmarshalling additional types used by Apache XML-RPC implementation for numerics:i1
,i2
,i8
,biginteger
,float
andbigdecimal
. See https://ws.apache.org/xmlrpc/types.html for a description.
Дивись також
- XML-RPC HOWTO
Гарний опис роботи XML-RPC і клієнтського програмного забезпечення кількома мовами. Містить практично все, що потрібно знати розробнику клієнта XML-RPC.
- XML-RPC Introspection
Описує розширення протоколу 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. Він повертає масив можливих підписів для цього методу. Підпис — це масив типів. Перший із цих типів є типом повернення методу, решта є параметрами.
Оскільки дозволено кілька підписів (тобто перевантаження), цей метод повертає список підписів, а не одиночний.
Самі підписи обмежені параметрами верхнього рівня, очікуваними методом. Наприклад, якщо метод очікує один масив структур як параметр і повертає рядок, його підпис буде просто «рядок, масив». Якщо він очікує три цілі числа та повертає рядок, його підписом є «рядок, int, int, int».
Якщо для методу не визначено підпису, повертається немасивне значення. У Python це означає, що типом поверненого значення буде щось інше, ніж список.
- 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)))
Об’єкти DateTime¶
- class xmlrpc.client.DateTime¶
Цей клас може бути ініціалізований секундами з епохи, кортежем часу, рядком часу/дати ISO 8601 або екземпляром
datetime.datetime
. Він має такі методи, які підтримуються головним чином для внутрішнього використання кодом маршалінгу/демаршалінгу:- decode(string)¶
Прийняти рядок як нове значення часу екземпляра.
It also supports certain of Python’s built-in operators through
rich comparison
and__repr__()
methods.
Нижче наведено робочий приклад. Код сервера:
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
забезпечується атрибутом:Binary
об’єкти мають такі методи, які підтримуються переважно для внутрішнього використання кодом маршалінгу/демаршалінгу:- encode(out)¶
Запишіть кодування XML-RPC base 64 цього бінарного елемента в об’єкт потоку out.
Закодовані дані матимуть символи нового рядка через кожні 76 символів відповідно до RFC 2045, розділ 6.8, який був де-факто стандартною специфікацією base64 на момент написання специфікації XML-RPC.
It also supports certain of Python’s built-in operators through
__eq__()
and__ne__()
methods.
Приклад використання бінарних об’єктів. Ми збираємося передати зображення через 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)
Об’єкти ProtocolError¶
- 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¶
Об’єкт 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_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.
Виноски