Storing modules in a central location, which are used by remote, seperate clients has obvious benefits. This recipe describes a method by which modules can be fetched from a remote server and compiled into bytecode modules which are used by the client.
The recipe has 3 sections (server.py, client.py, test.py) which need to be copied into 3 files.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
#server.py from SimpleXMLRPCServer import SimpleXMLRPCServer def export(module): exec('import %s as m' % module) filename = m.__file__[:-1] #make pyc = py return open(filename).read() server = SimpleXMLRPCServer(('localhost',1979)) server.register_function(export) server.serve_forever() #client.py from xmlrpclib import ServerProxy import sha def remoteImport(module): """ Import a module from a remote server. Returns a module object. """ server = ServerProxy('http://localhost:1979') filename = sha.new(module).hexdigest() #create a temporary filename try: code = server.export(module) except: #if anything goes wrong, try and read from a (possibly) cached file. try: code = open('%s.py' % filename).read() except IOError: #if we don't have a cached file, raise ImportError raise ImportError, 'Module %s is not available.' % module #dump the code to file, import it and return the module open(filename+'.py','w').write(code) exec('import %s as m' % filename) return m if __name__ == "__main__": m = remoteImport('test') print m.add(1,3) #test.py def add(a,b): return a + b
This solution is ideal for storing configuration modules, which can be downloaded by client applications, when the client application is run. If a module cannot be retrieved, a cached copy from a previous session is used.
Modules can be replaced at any time, as long as they maintain the previous module interface.
This recipe uses XMLRPC for transport, however, it could easily use HTTP. This recipe would also benefit (read, needs) from application or transport level authentication and security.