Differences between revisions 1 and 5 (spanning 4 versions)
Revision 1 as of 2004-04-28 05:58:27
Size: 2643
Editor: dsl254-010-130
Comment: commited from SeaPIG with permission of author
Revision 5 as of 2005-04-14 21:28:05
Size: 5918
Editor: LionKimbro
Comment: frame for shell script
Deletions are marked like this. Additions are marked like this.
Line 50: Line 50:
 * http://www.xml-rpc.com/
 * [http://www.python.org/doc/current/lib/module-xmlrpclib.html xmlrpclib documentation]
 * XmlRpc -- general information on XML-RPC
 * BaseHttpServer -- class that DocXmlRpcServer inherits from
Line 54: Line 54:
 * Also read the comments in both SimpleXMLRPCServer.py, and DocXMLRPCServer.py - they contain many examples of how to use the modules.
 * [http://sourceforge.net/projects/py-xmlrpc/ Fast C implementation of xmlrpc for python] (only for python version up to 2.2)
 * [http://xmlrpc-c.sourceforge.net/xmlrpc-howto/xmlrpc-howto.html Detailed XML-RPC how-to with examples in many languages ]
 * {{{SimpleXMLRPCServer.py}}}, and {{{DocXMLRPCServer.py}}} - comments includ many examples of use
 * [http://sourceforge.net/projects/py-xmlrpc/ Fast C implementation of XML-RPC for python] (only for python version up to 2.2) [http://www.xmlrpc.com/discuss/msgReader$1573 (more notes on it- apparently 20-100x faster!)]

= Discussion =

I'd like a Python script where:

 * You stick the script in a directory and run it to start a DocXmlRpcServer.
   * command line options (OptParse) for host, port,...
 * Scans all modules in the directory for "XMLRPC_namespace='eggs'"
 * Publishes the functions in the modules that name their XML-RPC namespace.
 * Functions that start with an underscore, don't get published.

This way, you can just write:

{{{
#!python
XMLRPC_namespace = "eggs"

def spam():
    return ["eggs", "and", "spam"]
}}}

..., and, given the script, you have everything you need to make your service callable remotely.

I'll probably end up making this myself, and posting it here. It's not terribly complicated.
The only part I don't know well is the ModulesAsPlugins part-- automatically detecting modules, loading them, and looping through them.

-- LionKimbro [[DateTime(2005-04-14T20:45:05Z)]]

Here's the frame. If someone knows how to fill in the guts, I'd be much obliged.

{{{
#!python
"""Serve specially marked modules by XML-RPC.

  -Hhostname host name, default ""
  -Pportnum port number, default 8000

This script starts an XML-RPC server, and publishes auto-detected
modules from the working directory.

Functions within Modules that define the name "XMLRPC_namespace" are
published. Function names that begin with an underscore (ex: _eggs) are
not published. Functions are published within the XML-RPC namespace
designated by the XMLRPC_namespace value, or the base namespace if the
value is None.
"""

import time

import optparse
import DocXMLRPCServer


def find_modules():
    """Find modules that define XMLRPC_namespace.

    Modules are searched for in the current working directory.

    Modules can define the XMLRPC_namespace to be None, in which case,
    it's functions are placed in the XML-RPC server's base namespace.
    """
    return [] # How do I do this?


def functions_in_module(module):
    """Find all functions in a module."""
    return [] # How do I do this?


if __name__ == "__main__":
    parser = optparse.OptionParser("usage: %prog [options]\n" + __doc__)
    parser.add_option("-H", "--host", dest="hostname",
                      default="127.0.0.1", type="string",
                      help="specify hostname to run on")
    parser.add_option("-p", "--port", dest="portnum", default=8000,
                      type="int", help="port number to run on")

    (options, args) = parser.parse_args()
    if len(args) != 0:
        parser.error("incorrect number of arguments")

    ServerClass = DocXMLRPCServer.DocXMLRPCServer
    server = ServerClass((options.hostname, options.portnum),
                         logRequests=0)

    for module in find_modules():
        for func in functions_in_module(module):
            full_name = func.__name__
            if module.XMLRPC_namespace is not None:
                full_name = full_name + ".%s" % module.XMLRPC_namespace
            server.register_function(func, full_name)

    server.set_server_title("xrserver")
    server.register_introspection_functions()

    print time.asctime(), 'Application Starting.'
    server.serve_forever()
    print time.asctime(), 'Application Finishing.'
}}}

-- LionKimbro [[DateTime(2005-04-14T21:27:45Z)]]

The page contents below were copied with permission of author (BrianDorsey) from [http://www.seapig.org/DocXMLRPCServer DocXMLRPCServer]. I'd like to rework the page to fit the form of WorkingWithTime, RssLibraries, etc.,. See also: XmlRpc -- LionKimbro DateTime(2004-04-28T05:58:27Z)

Here is a simple server which implements the above message procedure as well as a wait procedure. This server is based on the DocXMLRPCServer included with Python2.3; In Python2.2, use SimpleXMLRPCServer instead, and don't call server.register_introspection_functions().

   1 # ExampleServer.py
   2 import time
   3 import socket
   4 from DocXMLRPCServer import DocXMLRPCServer
   5 
   6 class SimpleShareServer:
   7     def message(self, msg):
   8         """message('Print me!') => True 
   9         
  10         Log everything passed to this function"""
  11         print time.asctime(), msg
  12         return True
  13 
  14     def wait(self, seconds):
  15         """wait(5) => 5 
  16         
  17         Wait for a certain number of seconds before returning.
  18         Returns the same number passed in."""
  19         print time.asctime(), "Waiting %s seconds" % seconds
  20         time.sleep(seconds)
  21         print time.asctime(), "Finished waiting %s seconds" % seconds
  22         return seconds
  23 
  24     
  25 if __name__ == '__main__':
  26     server = DocXMLRPCServer(("", 8000), logRequests=0)
  27     server.register_introspection_functions()
  28     server.register_instance(SimpleShareServer())
  29 
  30     print time.asctime(), 'Application Starting.'
  31     server.serve_forever()
  32     print time.asctime(), 'Application Finishing.'

The benefit of using DocXMLRPCServer is that it automatically creates documentation for your XML-RPC server, just open a browser and head to http://localhost:8000 after starting the server.

Writing a client to call the wait function is left as an exercise for the reader. :)

Resources

Discussion

I'd like a Python script where:

  • You stick the script in a directory and run it to start a DocXmlRpcServer.

    • command line options (OptParse) for host, port,...

  • Scans all modules in the directory for "XMLRPC_namespace='eggs'"
  • Publishes the functions in the modules that name their XML-RPC namespace.
  • Functions that start with an underscore, don't get published.

This way, you can just write:

   1 XMLRPC_namespace = "eggs"
   2 
   3 def spam():
   4     return ["eggs", "and", "spam"]

..., and, given the script, you have everything you need to make your service callable remotely.

I'll probably end up making this myself, and posting it here. It's not terribly complicated. The only part I don't know well is the ModulesAsPlugins part-- automatically detecting modules, loading them, and looping through them.

-- LionKimbro DateTime(2005-04-14T20:45:05Z)

Here's the frame. If someone knows how to fill in the guts, I'd be much obliged.

   1 """Serve specially marked modules by XML-RPC.
   2 
   3   -Hhostname   host name, default ""
   4   -Pportnum    port number, default 8000
   5 
   6 This script starts an XML-RPC server, and publishes auto-detected
   7 modules from the working directory.
   8 
   9 Functions within Modules that define the name "XMLRPC_namespace" are
  10 published. Function names that begin with an underscore (ex: _eggs) are
  11 not published. Functions are published within the XML-RPC namespace
  12 designated by the XMLRPC_namespace value, or the base namespace if the
  13 value is None.
  14 """
  15 
  16 import time
  17 
  18 import optparse
  19 import DocXMLRPCServer
  20 
  21 
  22 def find_modules():
  23     """Find modules that define XMLRPC_namespace.
  24 
  25     Modules are searched for in the current working directory.
  26 
  27     Modules can define the XMLRPC_namespace to be None, in which case,
  28     it's functions are placed in the XML-RPC server's base namespace.
  29     """
  30     return []  # How do I do this?
  31 
  32 
  33 def functions_in_module(module):
  34     """Find all functions in a module."""
  35     return []  # How do I do this?
  36 
  37 
  38 if __name__ == "__main__":
  39     parser = optparse.OptionParser("usage: %prog [options]\n" + __doc__)
  40     parser.add_option("-H", "--host", dest="hostname",
  41                       default="127.0.0.1", type="string",
  42                       help="specify hostname to run on")
  43     parser.add_option("-p", "--port", dest="portnum", default=8000,
  44                       type="int", help="port number to run on")
  45 
  46     (options, args) = parser.parse_args()
  47     if len(args) != 0:
  48         parser.error("incorrect number of arguments")
  49 
  50     ServerClass = DocXMLRPCServer.DocXMLRPCServer
  51     server = ServerClass((options.hostname, options.portnum),
  52                          logRequests=0)
  53 
  54     for module in find_modules():
  55         for func in functions_in_module(module):
  56             full_name = func.__name__
  57             if module.XMLRPC_namespace is not None:
  58                 full_name = full_name + ".%s" % module.XMLRPC_namespace
  59             server.register_function(func, full_name)
  60 
  61     server.set_server_title("xrserver")
  62     server.register_introspection_functions()
  63 
  64     print time.asctime(), 'Application Starting.'
  65     server.serve_forever()
  66     print time.asctime(), 'Application Finishing.'

-- LionKimbro DateTime(2005-04-14T21:27:45Z)

DocXmlRpcServer (last edited 2008-11-15 14:00:01 by localhost)

Unable to edit the page? See the FrontPage for instructions.