# `xmlrpc.server` — Basic XML-RPC servers

Вихідний код: Lib/xmlrpc/server.py

Модуль `xmlrpc.server` надає базову серверну структуру для серверів XML-RPC, написаних на Python. Сервери можуть бути автономними, використовуючи `SimpleXMLRPCServer`, або вбудованими в середовище CGI, використовуючи `CGIXMLRPCRequestHandler`.

Попередження

Модуль `xmlrpc.server` не захищений від зловмисно створених даних. Якщо вам потрібно проаналізувати ненадійні або неавтентифіковані дані, перегляньте Уразливості XML.

class `xmlrpc.server.``SimpleXMLRPCServer`(addr, requestHandler=SimpleXMLRPCRequestHandler, logRequests=True, allow_none=False, encoding=None, bind_and_activate=True, use_builtin_types=False)

  Створіть новий екземпляр сервера. Цей клас надає методи для реєстрації функцій, які можуть бути викликані протоколом XML-RPC. Параметр requestHandler має бути фабрикою для екземплярів обробника запитів; за замовчуванням `SimpleXMLRPCRequestHandler`. Параметри addr і requestHandler передаються до конструктора `socketserver.TCPServer`. Якщо logRequests має значення true (за замовчуванням), запити реєструватимуться; встановлення цього параметра на false вимкне журналювання. Параметри allow_none і encoding передаються до `xmlrpc.client` і контролюють відповіді XML-RPC, які повертаються з сервера. Параметр bind_and_activate контролює, чи `server_bind()` і `server_activate()` негайно викликаються конструктором; за замовчуванням значення true. Встановлення значення false дозволяє коду маніпулювати змінною класу allow_reuse_address до того, як адресу буде зв’язано. Параметр use_builtin_types передається до функції `loads()` і контролює, які типи обробляються під час отримання значень дати/часу або двійкових даних; за замовчуванням значення false.

  Змінено в версії 3.3: Додано прапорець use_builtin_types.

class `xmlrpc.server.``CGIXMLRPCRequestHandler`(allow_none=False, encoding=None, use_builtin_types=False)

  Створіть новий екземпляр для обробки запитів XML-RPC у середовищі CGI. Параметри allow_none і encoding передаються до `xmlrpc.client` і контролюють відповіді XML-RPC, які повертаються з сервера. Параметр use_builtin_types передається до функції `loads()` і контролює, які типи обробляються під час отримання значень дати/часу або двійкових даних; за замовчуванням значення false.

  Змінено в версії 3.3: Додано прапорець use_builtin_types.

class `xmlrpc.server.``SimpleXMLRPCRequestHandler`

  Створіть новий екземпляр обробника запитів. Цей обробник запитів підтримує запити `POST` і змінює журналювання таким чином, щоб параметр logRequests для параметра конструктора `SimpleXMLRPCServer` враховувався.

## Об’єкти SimpleXMLRPCServer

Клас `SimpleXMLRPCServer` заснований на `socketserver.TCPServer` і надає засоби для створення простих автономних серверів XML-RPC.

`SimpleXMLRPCServer.``register_function`(function=None, name=None)

  Register a function that can respond to XML-RPC requests. If name is given, it will be the method name associated with function, otherwise `function.__name__` will be used. name is a string, and may contain characters not legal in Python identifiers, including the period character.

  This method can also be used as a decorator. When used as a decorator, name can only be given as a keyword argument to register function under name. If no name is given, `function.__name__` will be used.

  Змінено в версії 3.7: `register_function()` можна використовувати як декоратор.

`SimpleXMLRPCServer.``register_instance`(instance, allow_dotted_names=False)

  Зареєструйте об’єкт, який використовується для надання імен методів, які не були зареєстровані за допомогою `register_function()`. Якщо екземпляр містить метод `_dispatch()`, він викликається із запитаною назвою методу та параметрами із запиту. Його API — `def _dispatch(self, method, params)` (зверніть увагу, що params не представляє список змінних аргументів). Якщо вона викликає базову функцію для виконання свого завдання, ця функція викликається як `func(*params)`, розширюючи список параметрів. Повернене значення від `_dispatch()` повертається клієнту як результат. Якщо екземпляр не має методу `_dispatch()`, він шукається за атрибутом, який відповідає назві запитаного методу.

  Якщо необов’язковий аргумент allow_dotted_names має значення true і екземпляр не має методу `_dispatch()`, тоді, якщо запитане ім’я методу містить крапки, кожен компонент імені методу шукається окремо, з ефектом простого виконується ієрархічний пошук. Значення, знайдене в результаті цього пошуку, потім викликається з параметрами із запиту, а повернуте значення передається назад клієнту.

  Попередження

  Увімкнення опції allow_dotted_names дозволяє зловмисникам отримати доступ до глобальних змінних вашого модуля та може дозволити зловмисникам виконувати довільний код на вашій машині. Використовуйте цей параметр лише в безпечній закритій мережі.

`SimpleXMLRPCServer.``register_introspection_functions`()

  Реєструє функції інтроспекції XML-RPC `system.listMethods`, `system.methodHelp` і `system.methodSignature`.

`SimpleXMLRPCServer.``register_multicall_functions`()

  Реєструє функцію багаторазового виклику XML-RPC system.multicall.

`SimpleXMLRPCRequestHandler.``rpc_paths`

  Значення атрибута, яке має бути кортежем із переліком дійсних частин шляху URL-адреси для отримання запитів XML-RPC. Запити, опубліковані на інших шляхах, призведуть до помилки HTTP 404 «немає такої сторінки». Якщо цей кортеж порожній, усі шляхи вважатимуться дійсними. Значення за замовчуванням – `('/', '/RPC2')`.

### Приклад SimpleXMLRPCServer

Код сервера

    from xmlrpc.server import SimpleXMLRPCServer
    from xmlrpc.server import SimpleXMLRPCRequestHandler

    # Restrict to a particular path.
    class RequestHandler(SimpleXMLRPCRequestHandler):
        rpc_paths = ('/RPC2',)

    # Create server
    with SimpleXMLRPCServer(('localhost', 8000),
                            requestHandler=RequestHandler) as server:
        server.register_introspection_functions()

        # Register pow() function; this will use the value of
        # pow.__name__ as the name, which is just 'pow'.
        server.register_function(pow)

        # Register a function under a different name
        def adder_function(x, y):
            return x + y
        server.register_function(adder_function, 'add')

        # Register an instance; all the methods of the instance are
        # published as XML-RPC methods (in this case, just 'mul').
        class MyFuncs:
            def mul(self, x, y):
                return x * y

        server.register_instance(MyFuncs())

        # Run the server's main loop
        server.serve_forever()

Наступний код клієнта викличе методи, доступні попереднім сервером:

    import xmlrpc.client

    s = xmlrpc.client.ServerProxy('http://localhost:8000')
    print(s.pow(2,3))  # Returns 2**3 = 8
    print(s.add(2,3))  # Returns 5
    print(s.mul(5,2))  # Returns 5*2 = 10

    # Print list of available methods
    print(s.system.listMethods())

`register_function()` також можна використовувати як декоратор. Попередній приклад сервера може реєструвати функції у спосіб декоратора:

    from xmlrpc.server import SimpleXMLRPCServer
    from xmlrpc.server import SimpleXMLRPCRequestHandler

    class RequestHandler(SimpleXMLRPCRequestHandler):
        rpc_paths = ('/RPC2',)

    with SimpleXMLRPCServer(('localhost', 8000),
                            requestHandler=RequestHandler) as server:
        server.register_introspection_functions()

        # Register pow() function; this will use the value of
        # pow.__name__ as the name, which is just 'pow'.
        server.register_function(pow)

        # Register a function under a different name, using
        # register_function as a decorator. *name* can only be given
        # as a keyword argument.
        @server.register_function(name='add')
        def adder_function(x, y):
            return x + y

        # Register a function under function.__name__.
        @server.register_function
        def mul(x, y):
            return x * y

        server.serve_forever()

У наступному прикладі, включеному в модуль `Lib/xmlrpc/server.py`, показано сервер, який дозволяє використовувати імена з крапками та реєструє функцію багаторазового виклику.

Попередження

Увімкнення опції allow_dotted_names дозволяє зловмисникам отримати доступ до глобальних змінних вашого модуля та може дозволити зловмисникам виконувати довільний код на вашій машині. Використовуйте цей приклад лише в безпечній закритій мережі.

    import datetime

    class ExampleService:
        def getData(self):
            return '42'

        class currentTime:
            @staticmethod
            def getCurrentTime():
                return datetime.datetime.now()

    with SimpleXMLRPCServer(("localhost", 8000)) as server:
        server.register_function(pow)
        server.register_function(lambda x,y: x+y, 'add')
        server.register_instance(ExampleService(), allow_dotted_names=True)
        server.register_multicall_functions()
        print('Serving XML-RPC on localhost port 8000')
        try:
            server.serve_forever()
        except KeyboardInterrupt:
            print("\nKeyboard interrupt received, exiting.")
            sys.exit(0)

Цю демо-версію ExampleService можна викликати з командного рядка:

    python -m xmlrpc.server

The client that interacts with the above server is included in `Lib/xmlrpc/client.py`:

    server = ServerProxy("http://localhost:8000")

    try:
        print(server.currentTime.getCurrentTime())
    except Error as v:
        print("ERROR", v)

    multi = MultiCall(server)
    multi.getData()
    multi.pow(2,9)
    multi.add(1,2)
    try:
        for response in multi():
            print(response)
    except Error as v:
        print("ERROR", v)

Цей клієнт, який взаємодіє з демонстраційним сервером XMLRPC, можна викликати як:

    python -m xmlrpc.client

## CGIXMLRPCRequestHandler

Клас `CGIXMLRPCRequestHandler` можна використовувати для обробки запитів XML-RPC, надісланих до сценаріїв Python CGI.

`CGIXMLRPCRequestHandler.``register_function`(function=None, name=None)

  Register a function that can respond to XML-RPC requests. If name is given, it will be the method name associated with function, otherwise `function.__name__` will be used. name is a string, and may contain characters not legal in Python identifiers, including the period character.

  This method can also be used as a decorator. When used as a decorator, name can only be given as a keyword argument to register function under name. If no name is given, `function.__name__` will be used.

  Змінено в версії 3.7: `register_function()` можна використовувати як декоратор.

`CGIXMLRPCRequestHandler.``register_instance`(instance)

  Зареєструйте об’єкт, який використовується для надання імен методів, які не були зареєстровані за допомогою `register_function()`. Якщо екземпляр містить метод `_dispatch()`, він викликається із запитаною назвою методу та параметрами із запиту; повертається значення повертається клієнту як результат. Якщо екземпляр не має методу `_dispatch()`, він шукається за атрибутом, який відповідає назві запитуваного методу; якщо запитане ім’я методу містить крапки, кожен компонент імені методу шукається окремо, в результаті чого виконується простий ієрархічний пошук. Значення, знайдене в результаті цього пошуку, потім викликається з параметрами із запиту, а повернуте значення передається назад клієнту.

`CGIXMLRPCRequestHandler.``register_introspection_functions`()

  Зареєструйте функції інтроспекції XML-RPC `system.listMethods`, `system.methodHelp` і `system.methodSignature`.

`CGIXMLRPCRequestHandler.``register_multicall_functions`()

  Зареєструйте функцію багаторазового виклику XML-RPC `system.multicall`.

`CGIXMLRPCRequestHandler.``handle_request`(request_text=None)

  Обробляти запит XML-RPC. Якщо задано request_text, це мають бути дані POST, надані HTTP-сервером, інакше буде використано вміст stdin.

Приклад:

    class MyFuncs:
        def mul(self, x, y):
            return x * y

    handler = CGIXMLRPCRequestHandler()
    handler.register_function(pow)
    handler.register_function(lambda x,y: x+y, 'add')
    handler.register_introspection_functions()
    handler.register_instance(MyFuncs())
    handler.handle_request()

## Документування сервера XMLRPC

Ці класи розширюють наведені вище класи для обслуговування документації HTML у відповідь на запити HTTP GET. Сервери можуть бути автономними, використовуючи `DocXMLRPCServer`, або вбудованими в середовище CGI, використовуючи `DocCGIXMLRPCRequestHandler`.

class `xmlrpc.server.``DocXMLRPCServer`(addr, requestHandler=DocXMLRPCRequestHandler, logRequests=True, allow_none=False, encoding=None, bind_and_activate=True, use_builtin_types=True)

  Створіть новий екземпляр сервера. Усі параметри мають те саме значення, що й для `SimpleXMLRPCServer`; requestHandler за умовчанням має значення `DocXMLRPCRequestHandler`.

  Змінено в версії 3.3: Додано прапорець use_builtin_types.

class `xmlrpc.server.``DocCGIXMLRPCRequestHandler`

  Створіть новий екземпляр для обробки запитів XML-RPC у середовищі CGI.

class `xmlrpc.server.``DocXMLRPCRequestHandler`

  Створіть новий екземпляр обробника запитів. Цей обробник запитів підтримує запити POST XML-RPC, запити GET документації та змінює журналювання таким чином, щоб параметр logRequests для параметра конструктора `DocXMLRPCServer` враховувався.

## Об’єкти DocXMLRPCServer

Клас `DocXMLRPCServer` походить від `SimpleXMLRPCServer` і забезпечує засоби для створення самодокументованих автономних серверів XML-RPC. Запити HTTP POST обробляються як виклики методів XML-RPC. Запити HTTP GET обробляються шляхом створення документації HTML у стилі pydoc. Це дозволяє серверу надавати власну веб-документацію.

`DocXMLRPCServer.``set_server_title`(server_title)

  Встановіть заголовок, який використовується у створеній документації HTML. Цей заголовок використовуватиметься всередині елемента HTML «title».

`DocXMLRPCServer.``set_server_name`(server_name)

  Встановіть назву, яка використовується у створеній документації HTML. Це ім’я з’явиться у верхній частині створеної документації всередині елемента «h1».

`DocXMLRPCServer.``set_server_documentation`(server_documentation)

  Встановіть опис, який використовується у створеній документації HTML. Цей опис відображатиметься як абзац під назвою сервера в документації.

## DocCGIXMLRPCRequestHandler

Клас `DocCGIXMLRPCRequestHandler` походить від `CGIXMLRPCRequestHandler` і надає засоби для створення самодокументованих сценаріїв XML-RPC CGI. Запити HTTP POST обробляються як виклики методів XML-RPC. Запити HTTP GET обробляються шляхом створення документації HTML у стилі pydoc. Це дозволяє серверу надавати власну веб-документацію.

`DocCGIXMLRPCRequestHandler.``set_server_title`(server_title)

  Встановіть заголовок, який використовується у створеній документації HTML. Цей заголовок використовуватиметься всередині елемента HTML «title».

`DocCGIXMLRPCRequestHandler.``set_server_name`(server_name)

  Встановіть назву, яка використовується у створеній документації HTML. Це ім’я з’явиться у верхній частині створеної документації всередині елемента «h1».

`DocCGIXMLRPCRequestHandler.``set_server_documentation`(server_documentation)

  Встановіть опис, який використовується у створеній документації HTML. Цей опис відображатиметься як абзац під назвою сервера в документації.