Spec-Zone.ru › Python 3.12

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 теперь по умолчанию выполняет все необходимые проверки сертификата и имени хоста.

Доступность: не Emscripten, не WASI.

Этот модуль не работает и недоступен на платформах WebAssembly wasm32-emscripten и wasm32-wasi. См. Платформы 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 сервера. Необязательным вторым аргументом является экземпляр фабрики транспорта; по умолчанию это внутренний экземпляр SafeTransport для HTTPS-URL и внутренний HTTP-экземпляр Transport в противном случае. Необязательным третьим аргументом является кодировка, по умолчанию 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')]). Устаревший флаг use_datetime аналогичен флагу use_builtin_types, но применяется только к значениям даты/времени.

Изменено в версии 3.3: Добавлен флаг use_builtin_types.

Изменено в версии 3.8: Добавлен параметр headers.

Как транспорт HTTP, так и HTTPS поддерживают расширение синтаксиса URL для аутентификации HTTP Basic: http://user:pass@host:port/path. Часть user:pass будет закодирована в base64 в качестве заголовка HTTP ‘Authorization’ и отправлена на удаленный сервер в рамках процесса подключения при вызове метода XML-RPC. Вам нужно использовать это только если удаленный сервер требует пользователя и пароль для аутентификации Basic. Если предоставлен 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-клиента в настоящее время не сериализует экземпляры подклассов встроенных типов.

При передаче строк символы, являющиеся специальными для XML, такие как <, >, и &, будут автоматически экранироваться. Однако ответственность за обеспечение того, чтобы строка не содержала недопустимых в XML символов, таких как управляющие символы с кодами ASCII от 0 до 31 (за исключением, конечно, табуляции, новой строки и возврата каретки), лежит на вызывающей стороне; отсутствие таких проверок приведёт к некорректному 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

Официальная спецификация.

Объекты ServerProxy

Экземпляр ServerProxy имеет метод, соответствующий каждому удалённому вызову процедуры, принимаемому сервером XML-RPC. Вызов метода выполняет RPC, определяемый по имени и подписи аргумента (например, одно и то же имя метода может быть перегружено несколькими подписями аргументов). RPC завершается возвращением значения, которое может быть возвращаемыми данными совместимого типа или объектом Fault или ProtocolError, указывающим на ошибку.

Серверы, поддерживающие API XML-интроспекции, поддерживают некоторые общие методы, сгруппированные под зарезервированным атрибутом system:

ServerProxy.system.listMethods()

Этот метод возвращает список строк, по одной для каждого (не системного) метода, поддерживаемого сервером XML-RPC.

ServerProxy.system.methodSignature(name)

Этот метод принимает один параметр — имя метода, реализованного на сервере XML-RPC. Он возвращает массив возможных подписей для этого метода. Подпись — это массив типов. Первый из этих типов — тип возвращаемого значения метода, остальные — параметры.

Поскольку допускается несколько подписей (то есть перегрузка), этот метод возвращает список подписей, а не одиночное значение.

Сами подписи ограничены параметрами верхнего уровня, ожидаемыми методом. Например, если метод ожидает один массив структур в качестве параметра и возвращает строку, его подпись просто “строка, массив”. Если он ожидает три целых числа и возвращает строку, его подпись — “строка, целое число, целое число, целое число”.

Если для метода не определена ни одна подпись, возвращается значение, отличное от массива. В 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)

Принимает строку в качестве нового значения времени экземпляра.

encode(out)

Записывает XML-RPC кодирование этого объекта DateTime в объект потока out.

Он также поддерживает некоторые встроенные операторы 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

Этот класс можно инициализировать из данных типа bytes (которые могут включать нули). Основной доступ к содержимому объекта Binary предоставляется атрибутом:

data

Бинарные данные, содержащиеся в экземпляре Binary. Данные предоставляются как объект bytes.

Объекты Binary имеют следующие методы, в основном используемые для внутренней работы кода сериализации/десериализации:

decode(bytes)

Принимает объект base64 bytes и декодирует его как новые данные экземпляра.

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)

Объекты ошибок

class xmlrpc.client.Fault

Объект Fault содержит содержимое тега XML-RPC ошибки. Объекты ошибок имеют следующие атрибуты:

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)

Объекты ошибок протокола

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. Значение Python None не может быть использовано в стандартном 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 был добавлен.

Пример использования клиента

# 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.

Примечания

[1]

Этот подход был впервые представлен в обсуждении на xmlrpc.com.

© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/xmlrpc.client.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API