#! /usr/bin/env python # by John Wiegley # # This script can be used to quickly and easily export objects, # without tying them to Pyro at all. It only requires a special # global function, named `remote_objects', which is used both to # construct the objects, and name them for the nameserver. # # NOTE: If your module must wait on a socket for input, you should # start that code in a thread, so that `pyrorun' occupies the main # thread. Be sure also to make your thread as a daemon! Otherwise, # the module won't shut down. Here's an example: # # from threading import Thread # # def remote_objects(): # t = Thread(target = main) # t.setDaemon(1) # t.start() # return { 'my_object': my_object() } import os import os.path import string import sys import time import types import Pyro.ext.remote as remote import Pyro.util Pyro.config.PYRO_MULTITHREADED = 0 # Default to simple, single-thraeded from getopt import getopt (opts, args) = getopt(sys.argv[1:], [], longopts = [ "this-host=", "this-port=", "nameserver=", "ns-port=", "verbose", "help", "multithreaded", "compress" ]) true, false = 1, 0 this_host = '' this_port = None nameserver = None ns_port = None verbose = false def usage(): print """usage: pyrorun [options] options are: --help Show this usage screen --verbose Be verbose about object remoting --this-host HOST Externally visible name for this host --this-port PORT The port that the objects are available on --nameserver HOST Use HOST as the Pyro nameserver --ns-port PORT Use PORT for the nameserver's port --multithreaded Enable Pyro's multi-threaded server code --compressed Enable compressed message transmission (Note: This is required on both sides) Every one of MODULES will be loaded, and a function named `remote_objects' within that module called. This function should return a dictionary identifying the objects to be published. For example: class Foo: pass class Bar: pass class Baz: pass def remote_objects(): return { 'foo': Foo(), 'bar': Bar(), 'baz': Baz() }""" sys.exit(0) for opt in opts: if opt[0] == "--this-host": this_host = opt[1] elif opt[0] == "--this-port": this_port = int(opt[1]) elif opt[0] == "--nameserver": nameserver = opt[1] elif opt[0] == "--ns-port": ns_port = int(opt[1]) elif opt[0] == "--verbose": verbose = remote.verbose = true elif opt[0] == "--multithreaded": Pyro.config.PYRO_MULTITHREADED = true elif opt[0] == "--compress": Pyro.config.PYRO_COMPRESSED = true elif opt[0] == "--help": usage() if len(args) == 0: usage() class AttrToDict: def __init__(self, dict): self.dict = dict def __hasattr__(self, item): return self.dict.has_key(item) def __getattr__(self, item): return self.dict[item] remote_ready = false remote.daemon_host = this_host remote.daemon_port = this_port for module in args: try: if os.path.isfile(module): globs = {} execfile(module, globs) mod = AttrToDict(globs) else: mod = __import__(module) components = module.split('.') for comp in components[1:]: mod = getattr(mod, comp) except: sys.stderr.write("Failed to import %s: %s\n" % (module, sys.exc_value)) else: if hasattr(mod, 'remote_objects'): dict = mod.remote_objects() if type(dict) is not types.DictType: sys.stderr.write("`remote_objects' in %s does not " "return a dictionary\n" % module) else: for name, obj in dict.items(): if verbose: print "Remoting", name remote.provide_local_object(obj, name, nameserver, ns_port) remote_ready = true else: sys.stderr.write("%s has no global function " "named `remote_objects'\n" % module) if remote_ready: if verbose: print "Waiting for requests..." sys.exit(remote.handle_requests()) else: sys.stderr.write("There were no objects to remote!\n") sys.exit(1)