"xmlrpc.server" --- Servidores XML-RPC básicos
**********************************************

**Código-fonte:** Lib/xmlrpc/server.py

======================================================================

O módulo "xmlrpc.server" fornece um framework básico de servidor para
servidores XML-RPC escritos em Python. Os servidores podem ser
independentes, usando "SimpleXMLRPCServer", ou incorporados em um
ambiente CGI, usando "CGIXMLRPCRequestHandler".

Aviso:

  O módulo "xmlrpc.server" não é seguro contra dados criados com
  códigos maliciosos. Se você precisar analisar dados não confiáveis
  ou não autenticados, consulte Vulnerabilidades em XML.

Disponibilidade

Este módulo não funciona ou não está disponível em WebAssembly. Veja
Plataformas WebAssembly para mais informações.

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

   Cria uma nova instância do servidor. Esta classe fornece métodos
   para registro de funções que podem ser chamadas pelo protocolo XML-
   RPC. O parâmetro *requestHandler* deve ser uma fábrica para
   instâncias do tratador de solicitações; o padrão é
   "SimpleXMLRPCRequestHandler". Os parâmetros *addr* e
   *requestHandler* são passados ​​para o construtor
   "socketserver.TCPServer". Se *logRequests* for true (o padrão), as
   solicitações serão registradas; definir esse parâmetro como false
   desativará os registros. Os parâmetros *allow_none* e *encoding*
   são transmitidos para "xmlrpc.client" e controlam as respostas XML-
   RPC que serão retornadas do servidor. O parâmetro
   *bind_and_activate* controla se "server_bind()" e
   "server_activate()" são chamados imediatamente pelo construtor; o
   padrão é true. A configuração como false permite que o código
   manipule a variável de classe *allow_reuse_address* antes que o
   endereço seja vinculado. O parâmetro *use_builtin_types* é passado
   para a função "loads()" e controla quais tipos são processados
   ​​quando valores de data/hora ou dados binários são recebidos; o
   padrão é false.

   Alterado na versão 3.3: O sinalizador *use_builtin_types* foi
   adicionado.

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

   Cria uma nova instância para manipular solicitações XML-RPC em um
   ambiente CGI. Os parâmetros *allow_none* e *encoding* são
   transmitidos para "xmlrpc.client" e controlam as respostas XML-RPC
   que serão retornadas do servidor. O parâmetro *use_builtin_types* é
   passado para a função "loads()" e controla quais tipos são
   processados quando valores de data/hora ou dados binários são
   recebidos; o padrão é false.

   Alterado na versão 3.3: O sinalizador *use_builtin_types* foi
   adicionado.

class xmlrpc.server.SimpleXMLRPCRequestHandler

   Cria uma nova instância do manipulador de solicitações. Este
   manipulador de solicitação possui suporte a solicitações "POST" e
   modifica o registro para que o parâmetro *logRequests* para o
   construtor de "SimpleXMLRPCServer" seja respeitado.


Objetos de SimpleXMLRPCServer
=============================

A classe "SimpleXMLRPCServer" é baseada em "socketserver.TCPServer" e
fornece um meio de criar servidores XML-RPC simples e independentes.

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

   Registra uma função que possa responder às solicitações XML-RPC. Se
   *name* for fornecido, será o nome do método associado a *function*,
   caso contrário, "function.__name__" será usado. *name* é uma string
   e pode conter caracteres ilegais para identificadores Python,
   incluindo o caractere de ponto.

   Este método também pode ser usado como um decorador. Quando usado
   como decorador, *name* só pode ser fornecido como argumento nomeado
   para registrar *function* em *name*. Se nenhum *name* for
   fornecido, "function.__name__" será usado.

   Alterado na versão 3.7: "register_function()" pode ser usado como
   um decorador.

SimpleXMLRPCServer.register_instance(instance, allow_dotted_names=False)

   Registra um objeto que é usado para expor nomes de métodos que não
   foram registrados usando "register_function()". Se *instance*
   contiver um método "_dispatch()", ele será chamado com o nome do
   método solicitado e os parâmetros da solicitação. Sua API é "def
   _dispatch(self, method, params)" (observe que *params* não
   representa uma lista de argumentos variáveis). Se ele chama uma
   função subjacente para executar sua tarefa, essa função é chamada
   como "func(*params)", expandindo a lista de parâmetros. O valor de
   retorno de "_dispatch()" é retornado ao cliente como resultado. Se
   *instance* não possui o método "_dispatch()", é procurado por um
   atributo correspondente ao nome do método solicitado.

   Se o argumento opcional *allow_dotted_names* for true e a instância
   não tiver o método "_dispatch()", e se o nome do método solicitado
   contiver pontos, cada componente do nome do método será pesquisado
   individualmente, com o efeito de que um simples pesquisa
   hierárquica é realizada. O valor encontrado nessa pesquisa é
   chamado com os parâmetros da solicitação e o valor retornado é
   passado de volta ao cliente.

   Aviso:

     A ativação da opção *allow_dotted_names* permite que os invasores
     acessem as variáveis globais do seu módulo e podem permitir que
     os invasores executem códigos arbitrários em sua máquina. Use
     esta opção apenas em uma rede fechada e segura.

SimpleXMLRPCServer.register_introspection_functions()

   Registra as funções de introspecção XML-RPC "system.listMethods",
   "system.methodHelp" e "system.methodSignature".

SimpleXMLRPCServer.register_multicall_functions()

   Registra a função de multichamada XML-RPC system.multicall.

SimpleXMLRPCRequestHandler.rpc_paths

   Um valor de atributo que deve ser uma tupla listando partes do
   caminho válidas da URL para receber solicitações XML-RPC.
   Solicitações postadas em outros caminhos resultarão em um erro HTTP
   404 "página inexistente". Se esta tupla estiver vazia, todos os
   caminhos serão considerados válidos. O valor padrão é "('/',
   '/RPC2')".


Exemplo de SimpleXMLRPCServer
-----------------------------

Código do servidor:

   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()

O código do cliente a seguir chamará os métodos disponibilizados pelo
servidor anterior:

   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()" também pode ser usado como um decorador. O
exemplo anterior do servidor pode registrar funções com um decorador:

   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()

O exemplo a seguir, incluído no módulo "Lib/xmlrpc/server.py", mostra
um servidor que permite nomes com pontos e registra uma função de
várias chamadas.

Aviso:

  A ativação da opção *allow_dotted_names* permite que os invasores
  acessem as variáveis globais do seu módulo e podem permitir que os
  invasores executem códigos arbitrários em sua máquina. Use este
  exemplo apenas em uma rede fechada e segura.

   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)

Esta demonstração ExampleService pode ser chamada na linha de comando:

   python -m xmlrpc.server

O cliente que interage com o servidor acima está incluído em
"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)

Este cliente que interage com o servidor XMLRPC de demonstração pode
ser chamado como:

   python -m xmlrpc.client


CGIXMLRPCRequestHandler
=======================

A classe "CGIXMLRPCRequestHandler" pode ser usada para manipular
solicitações XML-RPC enviadas para scripts CGI Python.

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

   Registra uma função que possa responder às solicitações XML-RPC. Se
   *name* for fornecido, será o nome do método associado a *function*,
   caso contrário, "function.__name__" será usado. *name* é uma string
   e pode conter caracteres ilegais para identificadores Python,
   incluindo o caractere de ponto.

   Este método também pode ser usado como um decorador. Quando usado
   como decorador, *name* só pode ser fornecido como argumento nomeado
   para registrar *function* em *name*. Se nenhum *name* for
   fornecido, "function.__name__" será usado.

   Alterado na versão 3.7: "register_function()" pode ser usado como
   um decorador.

CGIXMLRPCRequestHandler.register_instance(instance)

   Registra um objeto que é usado para expor nomes de métodos que não
   foram registrados usando "register_function()". Se a instância
   contiver um método "_dispatch()", ela será chamada com o nome do
   método solicitado e os parâmetros da solicitação; o valor retornado
   é retornado ao cliente como resultado. Se a instância não tiver um
   método "_dispatch()", será procurado um atributo correspondente ao
   nome do método solicitado; se o nome do método solicitado contiver
   pontos, cada componente do nome do método será pesquisado
   individualmente, com o efeito de que uma pesquisa hierárquica
   simples é executada. O valor encontrado nessa pesquisa é chamado
   com os parâmetros da solicitação e o valor retornado é passado de
   volta ao cliente.

CGIXMLRPCRequestHandler.register_introspection_functions()

   Registra as funções de introspecção XML-RPC "system.listMethods",
   "system.methodHelp" e "system.methodSignature".

CGIXMLRPCRequestHandler.register_multicall_functions()

   Registra a função de multichamada XML-RPC "system.multicall".

CGIXMLRPCRequestHandler.handle_request(request_text=None)

   Manipula uma solicitação XML-RPC. Se *request_text* for fornecido,
   devem ser os dados POST fornecidos pelo servidor HTTP, caso
   contrário, o conteúdo do stdin será usado.

Exemplo:

   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()


Documentando servidor XMLRPC
============================

Essas classes estendem as classes acima para servir a documentação
HTML em resposta a solicitações HTTP GET. Os servidores podem ser
independentes, usando "DocXMLRPCServer" ou incorporados em um ambiente
CGI, usando "DocCGIXMLRPCRequestHandler".

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

   Cria uma nova instância do servidor. Todos os parâmetros têm o
   mesmo significado que para "SimpleXMLRPCServer"; *requestHandler*
   assume como padrão "DocXMLRPCRequestHandler".

   Alterado na versão 3.3: O sinalizador *use_builtin_types* foi
   adicionado.

class xmlrpc.server.DocCGIXMLRPCRequestHandler

   Cria uma nova instância para manipular solicitações XML-RPC em um
   ambiente CGI.

class xmlrpc.server.DocXMLRPCRequestHandler

   Cria uma nova instância do manipulador de solicitações. Este
   manipulador de solicitações possui suporte a solicitações POST de
   XML-RPC, documenta solicitações GET e modifica o registro para que
   o parâmetro *logRequests* no parâmetro "DocXMLRPCServer" seja
   respeitado.


Objetos de DocXMLRPCServer
==========================

A classe "DocXMLRPCServer" é derivada de "SimpleXMLRPCServer" e
fornece um meio de criar servidores XML-RPC autodocumentados e
independentes. Solicitações HTTP POST são tratadas como chamadas de
método XML-RPC. As solicitações HTTP GET são tratadas gerando
documentação HTML no estilo pydoc. Isso permite que um servidor
forneça sua própria documentação baseada na Web.

DocXMLRPCServer.set_server_title(server_title)

   Define o título usado na documentação HTML gerada. Este título será
   usado dentro do elemento "title" do HTML.

DocXMLRPCServer.set_server_name(server_name)

   Define o nome usado na documentação HTML gerada. Este nome
   aparecerá na parte superior da documentação gerada dentro de um
   elemento "h1".

DocXMLRPCServer.set_server_documentation(server_documentation)

   Define a descrição usada na documentação HTML gerada. Esta
   descrição aparecerá na documentação como um parágrafo, abaixo do
   nome do servidor.


DocCGIXMLRPCRequestHandler
==========================

A classe "DocCGIXMLRPCRequestHandler" é derivada de
"CGIXMLRPCRequestHandler" e fornece um meio de criar scripts CGI XML-
RPC autodocumentados. Solicitações HTTP POST são tratadas como
chamadas de método XML-RPC. As solicitações HTTP GET são tratadas
gerando documentação HTML no estilo pydoc. Isso permite que um
servidor forneça sua própria documentação baseada na web.

DocCGIXMLRPCRequestHandler.set_server_title(server_title)

   Define o título usado na documentação HTML gerada. Este título será
   usado dentro do elemento "title" do HTML.

DocCGIXMLRPCRequestHandler.set_server_name(server_name)

   Define o nome usado na documentação HTML gerada. Este nome
   aparecerá na parte superior da documentação gerada dentro de um
   elemento "h1".

DocCGIXMLRPCRequestHandler.set_server_documentation(server_documentation)

   Define a descrição usada na documentação HTML gerada. Esta
   descrição aparecerá na documentação como um parágrafo, abaixo do
   nome do servidor.
