Spec-Zone.ru › Python 3.14

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

Доступность: недоступен в 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 (унифицированный идентификатор ресурса), обычно URL сервера. Второй необязательный аргумент — экземпляр фабрики транспорта; по умолчанию для URL https: используется внутренний экземпляр SafeTransport, а в остальных случаях — внутренний экземпляр 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-заголовков, отправляемых с каждым запросом; она задаётся последовательностью 2-кортежей, содержащих имя и значение заголовка (например, [('Header-Name', 'value')]). Если указан URL HTTPS, параметр 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

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. Передача допускается только при значении true у allow_none.

bigdecimal

decimal.Decimal. Только возвращаемый тип.

Это полный набор типов данных, поддерживаемых XML-RPC. При вызове методов также может быть возбуждено специальное исключение-экземпляр Fault, используемое для передачи ошибок сервера XML-RPC, или ProtocolError, используемое для передачи ошибок транспортного уровня HTTP/HTTPS. И Fault, и ProtocolError являются подклассами базового класса Error. Обратите внимание, что в настоящее время модуль клиента XML-RPC не маршалирует экземпляры подклассов встроенных типов.

При передаче строк специальные для 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 имеет метод для каждого удалённого вызова процедуры, принимаемого сервером 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

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()
# convert the ISO 8601 string to a datetime object
converted = dt.datetime.strptime(today.value, "%Y%m%dT%H:%M:%S")
print(f"Today: {converted.strftime('%d.%m.%Y, %H:%M')}")

Двоичные объекты

class xmlrpc.client.Binary

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

data

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

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

decode(bytes)

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

encode(out)

Записывает base64-представление этого двоичного элемента в формате XML-RPC в потоковый объект out.

В соответствии с разделом 6.8 RFC 2045 в закодированных данных каждые 76 символов будет добавлен перевод строки. На момент написания спецификации XML-RPC этот документ был фактическим стандартом для спецификации base64.

Он также поддерживает некоторые встроенные операторы Python с помощью методов __eq__() и __ne__().

Пример использования двоичных объектов. Передадим изображение по XML-RPC:

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

class xmlrpc.client.Fault

Объект Fault инкапсулирует содержимое тега fault в XML-RPC. У объектов Fault есть следующие атрибуты:

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)

Объекты ProtocolError

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 значение true.

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.

Сноски

[1]

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

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

Spec-Zone.ru

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