"xmlrpc.server" — Serveurs XML-RPC de base
******************************************

**Code source :** Lib/xmlrpc/server.py

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

Le module "xmlrpc.server" fournit un cadriciel basique pour les
serveurs XML-RPC écrits en Python. Les serveurs peuvent être soit
autonomes, en utilisant "SimpleXMLRPCServer", soit intégrés dans un
environnement CGI, en utilisant "CGIXMLRPCRequestHandler".

Avertissement:

  Le module "xmlrpc.server" n'est pas sécurisé contre les données
  construites de façon malveillante. Si vous avez besoin d'analyser
  des données non sécurisées ou non authentifiées, voir XML security.

Disponibilité: not WASI.

Ce module ne fonctionne pas ou n'est pas disponible sur WebAssembly.
Voir Plateformes WebAssembly pour plus d'informations.

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

   Crée une nouvelle instance de serveur. Cette classe fournit des
   méthodes d'enregistrement des fonctions pouvant être appelées par
   le protocole XML-RPC. Le paramètre *requestHandler* doit être une
   fabrique pour les instances de gestionnaire de requêtes ; sa valeur
   par défaut est "SimpleXMLRPCRequestHandler". Les paramètres *addr*
   et *requestHandler* sont passés au constructeur
   "socketserver.TCPServer". Si *logRequests* est vrai (valeur par
   défaut), les requêtes sont enregistrées ; définir ce paramètre sur
   faux désactive la journalisation. Les paramètres *allow_none* et
   *encoding* sont transmis à "xmlrpc.client" et contrôlent les
   réponses XML-RPC qui sont renvoyées par le serveur. Le paramètre
   *bind_and_activate* contrôle si "server_bind()" et
   "server_activate()" sont appelés immédiatement par le constructeur
   ; la valeur par défaut est vraie. Le définir sur faux permet au
   code de manipuler la variable de classe *allow_reuse_address* avant
   que l'adresse ne soit liée. Le paramètre *use_builtin_types* est
   transmis à la fonction "loads()" et contrôle quels types sont
   traités lorsque des valeurs temporelles ou des données binaires
   sont reçues ; la valeur par défaut est faux.

   Modifié dans la version 3.3: l'indicateur *use_builtin_types* a été
   ajouté.

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

   Crée une nouvelle instance pour gérer les requêtes XML-RPC dans un
   environnement CGI. Les paramètres *allow_none* et *encoding* sont
   transmis à "xmlrpc.client" et contrôlent les réponses XML-RPC qui
   sont renvoyées par le serveur. Le paramètre *use_builtin_types* est
   transmis à la fonction "loads()" et contrôle quels types sont
   traités lorsque des valeurs temporelles ou des données binaires
   sont reçues ; la valeur par défaut est faux.

   Modifié dans la version 3.3: l'indicateur *use_builtin_types* a été
   ajouté.

class xmlrpc.server.SimpleXMLRPCRequestHandler

   Crée une nouvelle instance de gestionnaire de requêtes. Ce
   gestionnaire de requêtes prend en charge les requêtes "POST" et
   modifie la journalisation afin que le paramètre *logRequests* du
   paramètre du constructeur "SimpleXMLRPCServer" soit honoré.


Objets *SimpleXMLRPCServer*
===========================

La classe "SimpleXMLRPCServer" dérive de "socketserver.TCPServer" et
fournit un moyen de créer des serveurs XML-RPC simples et autonomes.

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

   Enregistre une fonction pouvant répondre aux requêtes XML-RPC. Si
   *name* est donné, c'est le nom de la méthode associée à *function*,
   sinon "function.__name__" est utilisé. *name* est une chaîne et
   peut contenir des caractères non légaux dans les identifiants
   Python, y compris le point.

   Cette méthode peut également être utilisée en tant que décorateur.
   Lorsqu'elle est utilisée comme décorateur, *name* ne peut être
   donné que comme argument nommé pour enregistrer *function* sous le
   nom *name*. Si *name* n'est pas donné, "function.__name__" est
   utilisé.

   Modifié dans la version 3.7: "register_function()" peut être
   utilisée comme décorateur.

SimpleXMLRPCServer.register_instance(instance, allow_dotted_names=False)

   Enregistre un objet utilisé pour exposer des noms de méthodes qui
   n'ont pas été enregistrés à l'aide de "register_function()". Si
   *instance* contient une méthode "_dispatch()", elle est appelée
   avec le nom de la méthode demandée et les paramètres de la requête.
   Son prototype est "def _dispatch(self, method, params)" (notez que
   *params* ne représente pas une liste d'arguments variables). Si
   elle appelle une fonction sous-jacente pour effectuer sa tâche,
   cette fonction est appelée avec "func(*params)", dépaquetant ainsi
   la liste des paramètres. La valeur de retour de "_dispatch()" est
   renvoyée au client comme résultat. Si *instance* n'a pas de méthode
   "_dispatch()", un attribut correspondant au nom de la méthode
   demandée est recherché.

   Si l'argument facultatif *allow_dotted_names* est vrai et que
   l'instance n'a pas de méthode "_dispatch()", alors si le nom de
   méthode demandé contient des points, chaque composant du nom de
   méthode est recherché individuellement, avec pour effet qu'une
   simple recherche hiérarchique est effectuée. La valeur trouvée lors
   de cette recherche est ensuite appelée avec les paramètres de la
   requête et la valeur de retour est renvoyée au client.

   Avertissement:

     l'activation de l'option *allow_dotted_names* permet aux clients
     malveillants d'accéder aux variables globales de votre module et
     peut permettre aux clients malveillants d'exécuter du code
     arbitraire sur votre machine. Utilisez cette option uniquement
     sur un réseau sécurisé et fermé.

SimpleXMLRPCServer.register_introspection_functions()

   Enregistre les fonctions d'introspection XML-RPC
   "system.listMethods", "system.methodHelp" et
   "system.methodSignature".

SimpleXMLRPCServer.register_multicall_functions()

   Enregistre la fonction multi-appels XML-RPC "system.multicall".

SimpleXMLRPCRequestHandler.rpc_paths

   La valeur de cet attribut doit être un *n*-uplet contenant les
   parties de chemin d'URL valides pour recevoir les requêtes XML-RPC.
   Les requêtes effectuées sur d’autres chemins entraînent une erreur
   HTTP 404 « *No such page* ». Si ce *n*-uplet est vide, tous les
   chemins sont considérés comme valides. La valeur par défaut est
   "('/', '/RPC2')".


Exemple *SimpleXMLRPCServer*
----------------------------

Code du serveur :

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

Le code client suivant appelle les méthodes mises à disposition par le
serveur précédent :

   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()" peut également être utilisée comme décorateur,
voici l'équivalent du serveur précédent :

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

L'exemple suivant inclus dans le module "Lib/xmlrpc/server.py" montre
un serveur autorisant les noms pointés et enregistrant une fonction
*multicall*.

Avertissement:

  l'activation de l'option *allow_dotted_names* permet aux clients
  malveillants d'accéder aux variables globales de votre module et
  peut permettre aux clients malveillants d'exécuter du code
  arbitraire sur votre machine. N'utilisez cet exemple que dans un
  réseau sécurisé et fermé.

   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)

Cette démonstration d'*ExempleService* peut être invoquée à partir de
la ligne de commande suivante :

   python -m xmlrpc.server

Le client qui interagit avec le serveur ci-dessus est inclus dans
"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)

Ce client qui interagit avec le serveur de démonstration XMLRPC peut
être appelé comme ci :

   python -m xmlrpc.client


*CGIXMLRPCRequestHandler*
=========================

La classe "CGIXMLRPCRequestHandler" peut être utilisée pour gérer les
requêtes XML-RPC envoyées aux scripts Python CGI.

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

   Enregistre une fonction pouvant répondre aux requêtes XML-RPC. Si
   *name* est donné, c'est le nom de la méthode associée à *function*,
   sinon "function.__name__" est utilisé. *name* est une chaîne et
   peut contenir des caractères non légaux dans les identifiants
   Python, y compris le point.

   Cette méthode peut également être utilisée en tant que décorateur.
   Lorsqu'elle est utilisée comme décorateur, *name* ne peut être
   donné que comme argument nommé pour enregistrer *function* sous le
   nom *name*. Si *name* n'est pas donné, "function.__name__" est
   utilisé.

   Modifié dans la version 3.7: "register_function()" peut être
   utilisée comme décorateur.

CGIXMLRPCRequestHandler.register_instance(instance)

   Enregistre un objet utilisé pour exposer des noms de méthodes qui
   n'ont pas été enregistrées à l'aide de "register_function()". Si
   l'instance contient une méthode "_dispatch()", elle est appelée
   avec le nom de la méthode demandée et les paramètres de la requête
   ; la valeur de retour est renvoyée au client comme résultat. Si
   l'instance n'a pas de méthode "_dispatch()", elle recherche un
   attribut correspondant au nom de la méthode demandée ; si le nom de
   méthode demandée contient des points, chaque composant du nom de
   méthode est recherché individuellement, avec pour effet qu'une
   simple recherche hiérarchique est effectuée. La valeur trouvée lors
   de cette recherche est ensuite appelée avec les paramètres de la
   requête et la valeur de retour est renvoyée au client.

CGIXMLRPCRequestHandler.register_introspection_functions()

   Enregistre les fonctions d'introspection XML-RPC
   "system.listMethods", "system.methodHelp" et
   "system.methodSignature".

CGIXMLRPCRequestHandler.register_multicall_functions()

   Enregistre la fonction multi-appels XML-RPC "system.multicall".

CGIXMLRPCRequestHandler.handle_request(request_text=None)

   Gère une requête XML-RPC. Si *request_text* est donné, il doit
   s'agir des données POST fournies par le serveur HTTP, sinon le
   contenu de *stdin* est utilisé.

Exemple :

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


Documentation du serveur XMLRPC
===============================

Ces classes étendent les classes ci-dessus pour servir la
documentation HTML en réponse aux requêtes HTTP GET. Les serveurs
peuvent être soit autonomes, en utilisant "DocXMLRPCServer", soit
intégrés dans un environnement CGI, en utilisant
"DocCGIXMLRPCRequestHandler".

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

   Crée une nouvelle instance de serveur. Tous les paramètres ont la
   même signification que pour "SimpleXMLRPCServer" ; *requestHandler*
   est par défaut "DocXMLRPCRequestHandler".

   Modifié dans la version 3.3: l'indicateur *use_builtin_types* a été
   ajouté.

class xmlrpc.server.DocCGIXMLRPCRequestHandler

   Crée une nouvelle instance pour gérer les requêtes XML-RPC dans un
   environnement CGI.

class xmlrpc.server.DocXMLRPCRequestHandler

   Crée une nouvelle instance de gestionnaire de requêtes. Ce
   gestionnaire de requêtes prend en charge les requêtes XML-RPC POST,
   les requêtes GET de documentation et modifie la journalisation afin
   que le paramètre *logRequests* du paramètre de constructeur
   "DocXMLRPCServer" soit honoré.


Objets *DocXMLRPCServer*
========================

La classe "DocXMLRPCServer" dérive de "SimpleXMLRPCServer" et fournit
un moyen de créer des serveurs XML-RPC autonomes et auto-documentés.
Les requêtes HTTP POST sont traitées comme des appels de méthode XML-
RPC. Les requêtes HTTP GET sont gérées en générant une documentation
HTML de style *pydoc*. Cela permet à un serveur de fournir sa propre
documentation Web.

DocXMLRPCServer.set_server_title(server_title)

   Définit le titre utilisé dans la documentation HTML générée. Ce
   titre est utilisé à l'intérieur de l'élément HTML "title".

DocXMLRPCServer.set_server_name(server_name)

   Définit le nom utilisé dans la documentation HTML générée. Ce nom
   apparaît en haut de la documentation générée à l'intérieur d'un
   élément "h1".

DocXMLRPCServer.set_server_documentation(server_documentation)

   Définit la description utilisée dans la documentation HTML générée.
   Cette description apparaît sous forme de paragraphe, sous le nom du
   serveur, dans la documentation.


*DocCGIXMLRPCRequestHandler*
============================

La classe "DocCGIXMLRPCRequestHandler" dérive de
"CGIXMLRPCRequestHandler" et fournit un moyen de créer des scripts CGI
XML-RPC auto-documentés. Les requêtes HTTP POST sont traitées comme
des appels de méthode XML-RPC. Les requêtes HTTP GET sont gérées en
générant une documentation HTML de style *pydoc*. Cela permet à un
serveur de fournir sa propre documentation Web.

DocCGIXMLRPCRequestHandler.set_server_title(server_title)

   Définit le titre utilisé dans la documentation HTML générée. Ce
   titre est utilisé à l'intérieur de l'élément HTML "title".

DocCGIXMLRPCRequestHandler.set_server_name(server_name)

   Définit le nom utilisé dans la documentation HTML générée. Ce nom
   apparaît en haut de la documentation générée à l'intérieur d'un
   élément "h1".

DocCGIXMLRPCRequestHandler.set_server_documentation(server_documentation)

   Définit la description utilisée dans la documentation HTML générée.
   Cette description apparaît sous forme de paragraphe, sous le nom du
   serveur, dans la documentation.
