Документация Python неофициальный перевод

xmlrpc.client.md

427 строк · 31.6 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.15/library/xmlrpc.client.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `xmlrpc.client` – доступ к XML-RPC клиенту89**Исходный код:** [Lib/xmlrpc/client.py](https://python-all.ru/src/3.15/Lib/xmlrpc/client.py)1011---1213XML-RPC – это метод удалённого вызова процедур (Remote Procedure Call), использующий XML, передаваемый через HTTP(S) в качестве транспорта. С его помощью клиент может вызывать методы с параметрами на удалённом сервере (сервер задаётся URI) и получать структурированные данные. Этот модуль предназначен для написания кода XML-RPC клиента; он берёт на себя все детали преобразования между совместимыми объектами Python и XML, передаваемыми по сети.1415> **Предупреждение**16>17> Модуль `xmlrpc.client` не защищён от вредоносных данных. Если требуется разбирать непроверенные или неаутентифицированные данные, обратитесь к разделу [Безопасность XML](https://python-all.ru/3.15/library/xml.html#xml-security).1819Изменено в версии 3.5: Для HTTPS URI `xmlrpc.client` теперь по умолчанию выполняет все необходимые проверки сертификата и имени хоста.2021[Доступность](https://python-all.ru/3.15/library/intro.html#availability): не WASI.2223Этот модуль не работает или недоступен на WebAssembly. Подробнее см. [платформы WebAssembly](https://python-all.ru/3.15/library/intro.html#wasm-availability).2425#### `class xmlrpc.client.ServerProxy(uri, transport=None, encoding=None, verbose=False, allow_none=False, use_datetime=False, use_builtin_types=False, *, headers=(), context=None)`2627Экземпляр `ServerProxy` – это объект, управляющий связью с удалённым XML-RPC сервером. Обязательный первый аргумент – URI (Uniform Resource Indicator), обычно это URL сервера. Второй необязательный аргумент – экземпляр транспортной фабрики; по умолчанию для URL https: используется внутренний экземпляр `SafeTransport`, а в остальных случаях – внутренний экземпляр HTTP `Transport`. Третий необязательный аргумент – кодировка, по умолчанию UTF-8. Четвёртый необязательный аргумент – флаг отладки.2829Следующие параметры управляют использованием возвращаемого экземпляра прокси. Если *allow\_none* равен true, константа Python `None` будет преобразована в XML; по умолчанию `None` вызывает исключение [`TypeError`](https://python-all.ru/3.15/library/exceptions.html#TypeError). Это часто используемое расширение спецификации XML-RPC, но оно поддерживается не всеми клиентами и серверами; описание см. на [http://ontosys.com/xml-rpc/extensions.php](https://python-all.ru/3.15/library/xmlrpc.client.html). Флаг *use\_builtin\_types* можно использовать, чтобы значения даты/времени представлялись как объекты [`datetime.datetime`](https://python-all.ru/3.15/library/datetime.html#datetime.datetime), а двоичные данные – как объекты [`bytes`](https://python-all.ru/3.15/library/stdtypes.html#bytes); по умолчанию этот флаг равен false. Объекты `datetime.datetime`, `bytes` и [`bytearray`](https://python-all.ru/3.15/library/stdtypes.html#bytearray) могут передаваться в вызовы. Параметр *headers* – это необязательная последовательность HTTP-заголовков для отправки с каждым запросом, задаваемая как последовательность кортежей из двух элементов, представляющих имя и значение заголовка (например, `[('Header-Name', 'value')]`). Если указан HTTPS URL, *context* может быть [`ssl.SSLContext`](https://python-all.ru/3.15/library/ssl.html#ssl.SSLContext) и настраивает параметры SSL базового HTTPS-соединения. Устаревший флаг *use\_datetime* аналогичен *use\_builtin\_types*, но применяется только к значениям даты/времени.3031Изменено в версии 3.3: Добавлен флаг *use\_builtin\_types*.3233Изменено в версии 3.8: Добавлен параметр *headers*.3435Как HTTP, так и HTTPS транспорт поддерживают расширение синтаксиса URL для базовой аутентификации HTTP: `http://user:pass@host:port/path`. Часть `user:pass` будет закодирована в base64 в виде HTTP-заголовка «Authorization» и отправлена на удалённый сервер в процессе установки соединения при вызове XML-RPC метода. Использовать это нужно только в том случае, если удалённый сервер требует базовую аутентификацию с именем пользователя и паролем.3637Возвращаемый экземпляр – это прокси-объект с методами, которые можно использовать для вызова соответствующих RPC-вызовов на удалённом сервере. Если удалённый сервер поддерживает API интроспекции, прокси также можно использовать для запроса методов, которые он поддерживает (обнаружение служб), и получения других метаданных, связанных с сервером.3839Типы, которые являются совместимыми (т.е. могут быть преобразованы в XML), включают следующие (и, если не указано иное, они десериализуются как те же типы Python):4041| Тип XML-RPC | Тип Python |42| --- | --- |43| `boolean` | [`bool`](https://python-all.ru/3.15/library/functions.html#bool) |44| `int`, `i1`, `i2`, `i4`, `i8` or `biginteger` | [`int`](https://python-all.ru/3.15/library/functions.html#int) в диапазоне от -2147483648 до 2147483647. Значения получают тег `<int>`. |45| `double` или `float` | [`float`](https://python-all.ru/3.15/library/functions.html#float). Значения получают тег `<double>`. |46| `string` | [`str`](https://python-all.ru/3.15/library/stdtypes.html#str) |47| `array` | [`list`](https://python-all.ru/3.15/library/stdtypes.html#list) или [`tuple`](https://python-all.ru/3.15/library/stdtypes.html#tuple), содержащие совместимые элементы. Массивы возвращаются как `lists`. |48| `struct` | [`dict`](https://python-all.ru/3.15/library/stdtypes.html#dict). Ключи должны быть строками, значения могут быть любого совместимого типа. Можно передавать объекты пользовательских классов; передаётся только их атрибут [`__dict__`](https://python-all.ru/3.15/reference/datamodel.html#object.__dict__). |49| `dateTime.iso8601` | [`DateTime`](https://python-all.ru/3.15/library/xmlrpc.client.html#xmlrpc.client.DateTime) или [`datetime.datetime`](https://python-all.ru/3.15/library/datetime.html#datetime.datetime). Возвращаемый тип зависит от значений флагов *use\_builtin\_types* и *use\_datetime*. |50| `base64` | [`Binary`](https://python-all.ru/3.15/library/xmlrpc.client.html#xmlrpc.client.Binary), [`bytes`](https://python-all.ru/3.15/library/stdtypes.html#bytes) или [`bytearray`](https://python-all.ru/3.15/library/stdtypes.html#bytearray). Возвращаемый тип зависит от значения флага *use\_builtin\_types*. |51| `nil` | Константа `None`. Передача разрешена только если *allow\_none* равен true. |52| `bigdecimal` | [`decimal.Decimal`](https://python-all.ru/3.15/library/decimal.html#decimal.Decimal). Только возвращаемый тип. |5354Это полный набор типов данных, поддерживаемых XML-RPC. Вызовы методов также могут возбуждать специальный экземпляр [`Fault`](https://python-all.ru/3.15/library/xmlrpc.client.html#xmlrpc.client.Fault) для сообщения об ошибках XML-RPC сервера, или [`ProtocolError`](https://python-all.ru/3.15/library/xmlrpc.client.html#xmlrpc.client.ProtocolError) для сообщения об ошибке в транспортном слое HTTP/HTTPS. И `Fault`, и `ProtocolError` наследуются от базового класса `Error`. Обратите внимание, что модуль xmlrpc.client в настоящее время не выполняет маршалинг экземпляров подклассов встроенных типов.5556При передаче строк символы, специальные для XML, такие как `<`, `>` и `&`, автоматически экранируются. Однако вызывающая сторона должна гарантировать, что строка не содержит символов, запрещённых в XML, например управляющих символов с ASCII-кодами от 0 до 31 (за исключением табуляции, новой строки и возврата каретки); несоблюдение этого требования приведёт к тому, что XML-RPC запрос не будет корректным XML. Если необходимо передать произвольные байты через XML-RPC, используйте классы [`bytes`](https://python-all.ru/3.15/library/stdtypes.html#bytes) или [`bytearray`](https://python-all.ru/3.15/library/stdtypes.html#bytearray), или класс-обёртку [`Binary`](https://python-all.ru/3.15/library/xmlrpc.client.html#xmlrpc.client.Binary), описанный ниже.5758`Server` сохранён как псевдоним для `ServerProxy` для обратной совместимости. В новом коде следует использовать `ServerProxy`.5960Изменено в версии 3.5: Добавлен аргумент *context*.6162Изменено в версии 3.6: Добавлена поддержка тегов типов с префиксами (например, `ex:nil`). Добавлена поддержка десериализации дополнительных типов, используемых реализацией Apache XML-RPC для чисел: `i1`, `i2`, `i8`, `biginteger`, `float` и `bigdecimal`. Описание см. на [https://ws.apache.org/xmlrpc/types.html](https://python-all.ru/3.15/library/xmlrpc.client.html).6364> **См. также**65>66> **[Руководство по XML-RPC](https://python-all.ru/3.15/library/xmlrpc.client.html)**67>68> Хорошее описание работы XML-RPC и клиентского ПО на нескольких языках. Содержит практически всё, что нужно знать разработчику XML-RPC клиента.69>70> **[Интроспекция XML-RPC](https://python-all.ru/3.15/library/xmlrpc.client.html)**71>72> Описывает расширение протокола XML-RPC для интроспекции.73>74> **[Спецификация XML-RPC](https://python-all.ru/3.15/library/xmlrpc.client.html)**75>76> Официальная спецификация.7778## Объекты ServerProxy7980Экземпляр [`ServerProxy`](https://python-all.ru/3.15/library/xmlrpc.client.html#xmlrpc.client.ServerProxy) имеет метод для каждого удаленного вызова процедуры, принимаемого XML-RPC сервером. Вызов метода выполняет RPC, диспетчеризуемый как по имени, так и по сигнатуре аргументов (например, одно и то же имя метода может быть перегружено несколькими сигнатурами аргументов). RPC завершается либо возвратом данных в соответствующем типе, либо возбуждением исключения [`Fault`](https://python-all.ru/3.15/library/xmlrpc.client.html#xmlrpc.client.Fault) или [`ProtocolError`](https://python-all.ru/3.15/library/xmlrpc.client.html#xmlrpc.client.ProtocolError), указывающего на ошибку.8182Серверы, поддерживающие API интроспекции XML, предоставляют несколько общих методов, сгруппированных в зарезервированном атрибуте `system`:8384#### `ServerProxy.system.listMethods()`8586Этот метод возвращает список строк, по одной для каждого (не системного) метода, поддерживаемого XML-RPC сервером.8788#### `ServerProxy.system.methodSignature(name)`8990Этот метод принимает один параметр – имя метода, реализованного XML-RPC сервером. Он возвращает массив возможных сигнатур для этого метода. Сигнатура – это массив типов. Первый из этих типов – возвращаемый тип метода, остальные – параметры.9192Поскольку допускается несколько сигнатур (т.е. перегрузка), этот метод возвращает список сигнатур, а не один элемент.9394Сигнатуры ограничены параметрами верхнего уровня, ожидаемыми методом. Например, если метод ожидает один массив структур в качестве параметра и возвращает строку, его сигнатура – просто «string, array». Если он ожидает три целых числа и возвращает строку, его сигнатура – «string, int, int, int».9596Если для метода не определена сигнатура, возвращается не-массив. В Python это означает, что тип возвращаемого значения будет чем-то отличным от list.9798#### `ServerProxy.system.methodHelp(name)`99100Этот метод принимает один параметр – имя метода, реализованного XML-RPC сервером. Он возвращает строку документации, описывающую использование этого метода. Если такая строка отсутствует, возвращается пустая строка. Строка документации может содержать HTML-разметку.101102Изменено в версии 3.5: Экземпляры [`ServerProxy`](https://python-all.ru/3.15/library/xmlrpc.client.html#xmlrpc.client.ServerProxy) поддерживают протокол [менеджера контекста](https://python-all.ru/3.15/glossary.html#term-context-manager) для закрытия нижележащего транспорта.103104Далее следует работающий пример. Код сервера:105106```python107from xmlrpc.server import SimpleXMLRPCServer108109def is_even(n):110    return n % 2 == 0111112server = SimpleXMLRPCServer(("localhost", 8000))113print("Listening on port 8000...")114server.register_function(is_even, "is_even")115server.serve_forever()116```117118Клиентский код для указанного сервера:119120```python121import xmlrpc.client122123with xmlrpc.client.ServerProxy("http://localhost:8000/") as proxy:124    print("3 is even: %s" % str(proxy.is_even(3)))125    print("100 is even: %s" % str(proxy.is_even(100)))126```127128## Объекты даты и времени129130#### `class xmlrpc.client.DateTime`131132Этот класс можно инициализировать секундами с начала эпохи, временным кортежем, строкой даты/времени в формате ISO 8601 или экземпляром [`datetime.datetime`](https://python-all.ru/3.15/library/datetime.html#datetime.datetime). Он имеет следующие методы, поддерживаемые в основном для внутреннего использования кодом маршалинга/демаршалинга:133134#### `decode(string)`135136Принимает строку в качестве нового значения времени экземпляра.137138#### `encode(out)`139140Записывает XML-RPC кодировку этого элемента `DateTime` в потоковый объект *out* .141142Он также поддерживает некоторые встроенные операторы Python через методы [`rich comparison`](https://python-all.ru/3.15/reference/datamodel.html#object.__lt__) и [`__repr__()`](https://python-all.ru/3.15/reference/datamodel.html#object.__repr__).143144Далее следует работающий пример. Код сервера:145146```python147import datetime as dt148from xmlrpc.server import SimpleXMLRPCServer149import xmlrpc.client150151def today():152    today = dt.datetime.today()153    return xmlrpc.client.DateTime(today)154155server = SimpleXMLRPCServer(("localhost", 8000))156print("Listening on port 8000...")157server.register_function(today, "today")158server.serve_forever()159```160161Клиентский код для указанного сервера:162163```python164import xmlrpc.client165import datetime as dt166167proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")168169today = proxy.today()170# преобразовать строку в формате ISO 8601 в объект datetime171converted = dt.datetime.strptime(today.value, "%Y%m%dT%H:%M:%S")172print(f"Today: {converted.strftime('%d.%m.%Y, %H:%M')}")173```174175## Двоичные объекты176177#### `class xmlrpc.client.Binary`178179Этот класс можно инициализировать данными bytes (которые могут содержать NUL-символы). Основной доступ к содержимому объекта `Binary` предоставляется через атрибут:180181#### `data`182183Двоичные данные, инкапсулированные экземпляром `Binary`. Данные предоставляются как объект [`bytes`](https://python-all.ru/3.15/library/stdtypes.html#bytes).184185Объекты `Binary` имеют следующие методы, предназначенные в основном для внутреннего использования кодом маршалинга/демаршалинга:186187#### `decode(bytes)`188189Принимает объект base64 [`bytes`](https://python-all.ru/3.15/library/stdtypes.html#bytes) и декодирует его как новые данные экземпляра.190191#### `encode(out)`192193Записывает XML-RPC base64-кодировку этого двоичного объекта в потоковый объект *out*.194195Закодированные данные будут содержать переводы строки каждые 76 символов в соответствии с [**RFC 2045, раздел 6.8**](https://python-all.ru/3.15/library/xmlrpc.client.html), что было фактическим стандартом спецификации base64 на момент написания спецификации XML-RPC.196197Он также поддерживает некоторые встроенные операторы Python через методы [`__eq__()`](https://python-all.ru/3.15/reference/datamodel.html#object.__eq__) и [`__ne__()`](https://python-all.ru/3.15/reference/datamodel.html#object.__ne__).198199Пример использования двоичных объектов. Мы собираемся передать изображение через XMLRPC:200201```python202from xmlrpc.server import SimpleXMLRPCServer203import xmlrpc.client204205def python_logo():206    with open("python_logo.jpg", "rb") as handle:207        return xmlrpc.client.Binary(handle.read())208209server = SimpleXMLRPCServer(("localhost", 8000))210print("Listening on port 8000...")211server.register_function(python_logo, 'python_logo')212213server.serve_forever()214```215216Клиент получает изображение и сохраняет его в файл:217218```python219import xmlrpc.client220221proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")222with open("fetched_python_logo.jpg", "wb") as handle:223    handle.write(proxy.python_logo().data)224```225226## Объекты Fault227228#### `class xmlrpc.client.Fault`229230Объект `Fault` инкапсулирует содержимое тега ошибки (fault tag) XML-RPC. Объекты Fault имеют следующие атрибуты:231232#### `faultCode`233234Целое число (int), указывающее тип ошибки.235236#### `faultString`237238Строка, содержащая диагностическое сообщение, связанное с ошибкой.239240В следующем примере мы намеренно вызовем [`Fault`](https://python-all.ru/3.15/library/xmlrpc.client.html#xmlrpc.client.Fault), возвращая объект сложного типа. Код сервера:241242```python243from xmlrpc.server import SimpleXMLRPCServer244245# Произойдёт ошибка маршалинга, потому что возвращается246# комплексное число247def add(x, y):248    return x+y+0j249250server = SimpleXMLRPCServer(("localhost", 8000))251print("Listening on port 8000...")252server.register_function(add, 'add')253254server.serve_forever()255```256257Клиентский код для указанного сервера:258259```python260import xmlrpc.client261262proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")263try:264    proxy.add(2, 5)265except xmlrpc.client.Fault as err:266    print("A fault occurred")267    print("Fault code: %d" % err.faultCode)268    print("Fault string: %s" % err.faultString)269```270271## Объекты ProtocolError272273#### `class xmlrpc.client.ProtocolError`274275Объект `ProtocolError` описывает протокольную ошибку на уровне нижележащего транспорта (например, ошибку 404 «не найдено», если сервер по указанному URI не существует). Он имеет следующие атрибуты:276277#### `url`278279URI или URL, вызвавший ошибку.280281#### `errcode`282283Код ошибки.284285#### `errmsg`286287Сообщение об ошибке или диагностическая строка.288289#### `headers`290291Словарь (dict), содержащий заголовки HTTP/HTTPS-запроса, вызвавшего ошибку.292293В следующем примере мы намеренно вызовем [`ProtocolError`](https://python-all.ru/3.15/library/xmlrpc.client.html#xmlrpc.client.ProtocolError), предоставив неверный URI:294295```python296import xmlrpc.client297298# Создание ServerProxy с URI, который не отвечает на XMLRPC-запросы299proxy = xmlrpc.client.ServerProxy("http://google.com/")300301try:302    proxy.some_method()303except xmlrpc.client.ProtocolError as err:304    print("A protocol error occurred")305    print("URL: %s" % err.url)306    print("HTTP/HTTPS headers: %s" % err.headers)307    print("Error code: %d" % err.errcode)308    print("Error message: %s" % err.errmsg)309```310311## Объекты MultiCall312313Объект [`MultiCall`](https://python-all.ru/3.15/library/xmlrpc.client.html#xmlrpc.client.MultiCall) позволяет инкапсулировать несколько вызовов к удалённому серверу в один запрос [\[1\]](https://python-all.ru/3.15/library/xmlrpc.client.html#id6).314315#### `class xmlrpc.client.MultiCall(server)`316317Создаёт объект, используемый для пакетирования вызовов методов (boxcar). *server* – это конечная цель вызова. Вызовы могут быть направлены результирующему объекту, но они немедленно вернут `None` и только сохранят имя метода и аргументы в объекте `MultiCall`. Вызов самого объекта приводит к тому, что все сохранённые вызовы передаются как один запрос `system.multicall`. Результатом этого вызова является [генератор](https://python-all.ru/3.15/glossary.html#term-generator); итерация по этому генератору даёт отдельные результаты.318319Далее приведён пример использования этого класса. Серверный код:320321```python322from xmlrpc.server import SimpleXMLRPCServer323324def add(x, y):325    return x + y326327def subtract(x, y):328    return x - y329330def multiply(x, y):331    return x * y332333def divide(x, y):334    return x // y335336# Простой сервер с простыми арифметическими функциями337server = SimpleXMLRPCServer(("localhost", 8000))338print("Listening on port 8000...")339server.register_multicall_functions()340server.register_function(add, 'add')341server.register_function(subtract, 'subtract')342server.register_function(multiply, 'multiply')343server.register_function(divide, 'divide')344server.serve_forever()345```346347Клиентский код для указанного сервера:348349```python350import xmlrpc.client351352proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")353multicall = xmlrpc.client.MultiCall(proxy)354multicall.add(7, 3)355multicall.subtract(7, 3)356multicall.multiply(7, 3)357multicall.divide(7, 3)358result = multicall()359360print("7+3=%d, 7-3=%d, 7*3=%d, 7//3=%d" % tuple(result))361```362363## Вспомогательные функции364365#### `xmlrpc.client.dumps(params, methodname=None, methodresponse=None, encoding=None, allow_none=False)`366367Преобразует *params* в XML-RPC запрос или в ответ, если *methodresponse* равно true. *params* может быть либо кортежем аргументов, либо экземпляром класса исключения [`Fault`](https://python-all.ru/3.15/library/xmlrpc.client.html#xmlrpc.client.Fault). Если *methodresponse* равно true, может быть возвращено только одно значение, то есть *params* должна иметь длину 1. *encoding*, если указан, определяет кодировку для генерируемого XML; по умолчанию UTF-8. Значение [`None`](https://python-all.ru/3.15/library/constants.html#None) в Python не может использоваться в стандартном XML-RPC; чтобы разрешить его использование через расширение, укажите истинное значение для *allow\_none*.368369#### `xmlrpc.client.loads(data, use_datetime=False, use_builtin_types=False)`370371Преобразует XML-RPC запрос или ответ в объекты Python, `(params, methodname)`. *params* – кортеж аргументов; *methodname* – строка или `None`, если имя метода отсутствует в пакете. Если XML-RPC пакет представляет собой условие ошибки, эта функция возбуждает исключение [`Fault`](https://python-all.ru/3.15/library/xmlrpc.client.html#xmlrpc.client.Fault). Флаг *use\_builtin\_types* можно использовать, чтобы значения даты/времени представлялись как объекты [`datetime.datetime`](https://python-all.ru/3.15/library/datetime.html#datetime.datetime), а бинарные данные – как объекты [`bytes`](https://python-all.ru/3.15/library/stdtypes.html#bytes); по умолчанию этот флаг выключен.372373Устаревший флаг *use\_datetime* похож на *use\_builtin\_types*, но применяется только к значениям даты/времени.374375Изменено в версии 3.3: Добавлен флаг *use\_builtin\_types*.376377## Пример клиентского использования378379```python380# простая тестовая программа (из спецификации XML-RPC)381from xmlrpc.client import ServerProxy, Error382383# server = ServerProxy("http://localhost:8000") # локальный сервер384with ServerProxy("http://betty.userland.com") as proxy:385386    print(proxy)387388    try:389        print(proxy.examples.getStateName(41))390    except Error as v:391        print("ERROR", v)392```393394Для доступа к XML-RPC серверу через HTTP-прокси необходимо определить собственный транспорт. В следующем примере показано, как это сделать:395396```python397import http.client398import xmlrpc.client399400class ProxiedTransport(xmlrpc.client.Transport):401402    def set_proxy(self, host, port=None, headers=None):403        self.proxy = host, port404        self.proxy_headers = headers405406    def make_connection(self, host):407        connection = http.client.HTTPConnection(*self.proxy)408        connection.set_tunnel(host, headers=self.proxy_headers)409        self._connection = host, connection410        return connection411412transport = ProxiedTransport()413transport.set_proxy('proxy-server', 8080)414server = xmlrpc.client.ServerProxy('http://betty.userland.com', transport=transport)415print(server.examples.getStateName(41))416```417418## Пример клиентского и серверного использования419420См. [пример SimpleXMLRPCServer](https://python-all.ru/3.15/library/xmlrpc.server.html#simplexmlrpcserver-example).421422Сноски423424\[[1](https://python-all.ru/3.15/library/xmlrpc.client.html#id5)\]425426Этот подход был впервые представлен в [обсуждении на xmlrpc.com](https://python-all.ru/3.15/library/xmlrpc.client.html).427