Example #1
0
from Pyro5.api import expose, Daemon

fmt = '%Y-%m-%d %H:%M:%S %Z%z'


@expose
class Server(object):
    def echo(self, date):
        print("ECHO:")
        print(" [raw] ", repr(date))
        if hasattr(date, "isoformat"):
            print(" [iso] ", date.isoformat())
        return date

    def pytz(self):
        tz_nl = pytz.timezone("Europe/Amsterdam")
        return tz_nl.localize(datetime.datetime.now())

    def dateutil(self):
        tz_nl = dateutil.tz.gettz("Europe/Amsterdam")
        return datetime.datetime.now(tz_nl)

    def pendulum(self):
        tz_nl = pendulum.now("Europe/Amsterdam")
        return tz_nl


# main program

Daemon.serveSimple({Server: "example.timezones"}, ns=False)
Example #2
0
        self.number = number
        self.callback = callback
        print("Worker %d created" % self.number)

    @expose
    @oneway
    def work(self, amount):
        print("Worker %d busy..." % self.number)
        time.sleep(amount)
        print("Worker %d done. Informing callback client." % self.number)
        self._pyroDaemon.unregister(self)
        self.callback._pyroClaimOwnership(
        )  # because this method may run in a different thread every time it's called
        self.callback.done(self.number)  # invoke the callback object


class CallbackServer(object):
    def __init__(self):
        self.number = 0

    @expose
    def addworker(self, callback):
        self.number += 1
        print("server: adding worker %d" % self.number)
        worker = Worker(self.number, callback)
        self._pyroDaemon.register(worker)  # make it a Pyro object
        return worker


Daemon.serveSimple({CallbackServer: "example.callback"})
Example #3
0
from Pyro5.api import Daemon
import excep

Daemon.serveSimple({excep.TestClass: "example.exceptions"},
                   ns=True,
                   verbose=True)
Example #4
0
import logging
from Pyro5.api import expose, Daemon
import Pyro5.config

logging.basicConfig(level=logging.DEBUG)
logging.getLogger("Pyro5").setLevel(logging.DEBUG)

Pyro5.config.COMMTIMEOUT = 5.0
Pyro5.config.POLLTIMEOUT = 5.0  # only used for multiplexing server


class TestDisconnect(object):
    @expose
    def echo(self, arg):
        print("echo: ", arg)
        return arg


Daemon.serveSimple({TestDisconnect: "example.disconnect"}, ns=False)
Example #5
0
from Pyro5.api import expose, Daemon, config


@expose
class CalcServer(object):
    def add(self, num1, num2):
        print("calling add: %d, %d" % (num1, num2))
        return num1 + num2


config.COMMTIMEOUT = 0.5  # the server should time out easily now

Daemon.serveSimple({CalcServer: "example.autoretry"})
Example #6
0

# for 'Thingy' we register both serialization and deserialization hooks
SerializerBase.register_dict_to_class("waheeee-custom-thingy", thingy_dict_to_class)
SerializerBase.register_class_to_dict(mycustomclasses.Thingy, thingy_class_to_dict)

# for 'OtherThingy' we only register a deserialization hook (and for serialization depend on serpent's default behavior)
SerializerBase.register_dict_to_class("mycustomclasses.OtherThingy", otherthingy_dict_to_class)


# regular Pyro server stuff

@expose
class Server(object):
    def method(self, arg):
        print("\nmethod called, arg=", arg)
        response = mycustomclasses.Thingy(999)
        return response

    def othermethod(self, arg):
        print("\nothermethod called, arg=", arg)
        response = mycustomclasses.OtherThingy(999)
        return response


Daemon.serveSimple(
    {
        Server: "example.customclasses"
    },
    ns=False)
Example #7
0
        self.collection.discard(self)


@expose
@behavior(instance_mode="single")
class Service(object):
    def __init__(self):
        self.resources = set()      # the allocated resources

    def allocate(self, name):
        resource = Resource(name, self.resources)
        self.resources.add(resource)
        current_context.track_resource(resource)
        print("service: allocated resource", name, " for client", current_context.client_sock_addr)

    def free(self, name):
        resources = {r for r in self.resources if r.name == name}
        self.resources -= resources
        for r in resources:
            r.close()
            current_context.untrack_resource(r)

    def list(self):
        return [r.name for r in self.resources]


with CustomDaemon() as daemon:
    Daemon.serveSimple({
        Service: "service"
    }, ns=False, daemon=daemon)
Example #8
0
@behavior(instance_mode="session")
@expose
class SessionboundDatabase(object):
    """
    This pyro object will work fine when used from multiple proxies at the same time
    because you'll get a new instance for every new session (proxy connection)
    """
    def __init__(self):
        # get the user-token from the USER annotation
        user_annotation = current_context.annotations["USER"]
        user = bytes(user_annotation).decode("utf-8")
        self.connection = database.connect(user)
        print("[%s] new instance and connection for user: %s" %
              (self.__class__.__name__, user))

    def store(self, key, value):
        self.connection.store(key, value)

    def retrieve(self, key):
        return self.connection.retrieve(key)

    def ping(self):
        return "hi"


Daemon.serveSimple({
    SingletonDatabase: "example.usersession.singletondb",
    SessionboundDatabase: "example.usersession.sessiondb"
})
Example #9
0
import time
from Pyro5.api import expose, Daemon


@expose
class Thingy(object):
    def multiply(self, a, b):
        return a * b

    def add(self, a, b):
        return a + b

    def divide(self, a, b):
        return a // b

    def error(self):
        return 1 // 0

    def delay(self, seconds):
        time.sleep(seconds)
        return seconds

    def printmessage(self, message):
        print(message)
        return 0


Daemon.serveSimple({Thingy: "example.batched"}, ns=False)
Example #10
0
        for (n, c) in self.channels[channel]:
            if n == nick:
                self.channels[channel].remove((n, c))
                break
        self.publish(channel, 'SERVER', '** ' + nick + ' left **')
        if len(self.channels[channel]) < 1:
            del self.channels[channel]
            print('REMOVED CHANNEL %s' % channel)
        self.nicks.remove(nick)
        print("%s LEFT %s" % (nick, channel))

    def publish(self, channel, nick, msg):
        if channel not in self.channels:
            print('IGNORED UNKNOWN CHANNEL %s' % channel)
            return
        for (n, c) in self.channels[channel][:]:  # use a copy of the list
            c._pyroClaimOwnership()
            try:
                c.message(nick, msg)  # oneway call
            except Pyro5.errors.ConnectionClosedError:
                # connection dropped, remove the listener if it's still there
                # check for existence because other thread may have killed it already
                if (n, c) in self.channels[channel]:
                    self.channels[channel].remove((n, c))
                    print('Removed dead listener %s %s' % (n, c))


Daemon.serveSimple({
    ChatBox: "example.chatbox.server"
})
Example #11
0
from Pyro5.api import expose, behavior, Daemon


@expose
@behavior(instance_mode="single")
class Warehouse(object):
    def __init__(self):
        self.contents = ["chair", "bike", "flashlight", "laptop", "couch"]

    def list_contents(self):
        return self.contents

    def take(self, name, item):
        self.contents.remove(item)
        print("{0} took the {1}.".format(name, item))

    def store(self, name, item):
        self.contents.append(item)
        print("{0} stored the {1}.".format(name, item))


Daemon.serveSimple({Warehouse: "example.warehouse"}, ns=False)
Example #12
0
from collections import defaultdict
from Pyro5.api import behavior, expose, Daemon

# note: the dispatcher doesn't know anything about the CustomData class from the customdata module!


@behavior(instance_mode="single")
class Dispatcher(object):
    def __init__(self):
        self.listeners = defaultdict(list)

    @expose
    def register(self, topic, listener):
        self.listeners[topic].append(listener)
        print("New listener for topic {} registered: {}".format(
            topic, listener._pyroUri))

    @expose
    def process_blob(self, blob):
        print("Dispatching blob with name:", blob.info)
        listeners = self.listeners.get(blob.info, [])
        for listener in listeners:
            listener._pyroClaimOwnership(
            )  # because this process_blob call may run in a different thread every time it is invoked
            listener.process_blob(blob)


Daemon.serveSimple({Dispatcher: "example.blobdispatcher"})
Example #13
0
from Pyro5.api import expose, Daemon
from thingy import Thingy


@expose
class Factory(object):
    def createSomething(self, number):
        # create a new item
        thing = Thingy(number)
        # connect it to the Pyro daemon to make it a Pyro object
        self._pyroDaemon.register(thing)
        # Return it. Pyro's autoproxy feature turns it into a proxy automatically.
        # If that feature is disabled, the object itself (a copy) is returned,
        # and the client won't be able to interact with the actual Pyro object here.
        return thing


Daemon.serveSimple({Factory: "example.autoproxy"}, ns=False)
Example #14
0
        self.resultqueue = queue.Queue()

    def putWork(self, item):
        self.workqueue.put(item)

    def getWork(self, timeout=5):
        try:
            return self.workqueue.get(block=True, timeout=timeout)
        except queue.Empty:
            raise ValueError("no items in queue")

    def putResult(self, item):
        self.resultqueue.put(item)

    def getResult(self, timeout=5):
        try:
            return self.resultqueue.get(block=True, timeout=timeout)
        except queue.Empty:
            raise ValueError("no result available")

    def workQueueSize(self):
        return self.workqueue.qsize()

    def resultQueueSize(self):
        return self.resultqueue.qsize()


# main program

Daemon.serveSimple({DispatcherQueue: "example.distributed.dispatcher"})
Example #15
0
        return self.callcount  # the number of completed calls

    def getconfig(self):
        return Pyro5.config.as_dict()

    def delay(self):
        threadname = threading.current_thread().getName()
        print("delay called in thread %s" % threadname)
        time.sleep(1)
        self.callcount += 1
        return threadname

    @oneway
    def onewaydelay(self):
        threadname = threading.current_thread().getName()
        print("onewaydelay called in thread %s" % threadname)
        time.sleep(1)
        self.callcount += 1


# main program

Pyro5.config.SERVERTYPE = "undefined"
servertype = input("Servertype threaded or multiplex (t/m)?")
if servertype == "t":
    Pyro5.config.SERVERTYPE = "thread"
else:
    Pyro5.config.SERVERTYPE = "multiplex"

Daemon.serveSimple({Server: "example.servertypes"})
Example #16
0
class SessionInstance(object):
    @expose
    def msg(self, message):
        print("[%s] %s.msg: %s" % (id(self), self.__class__.__name__, message))
        return id(self), self.correlation_id

    @classmethod
    def create_instance(cls):
        obj = cls()
        obj.correlation_id = current_context.correlation_id
        return obj


@behavior(instance_mode="percall")
class PercallInstance(object):
    @expose
    def msg(self, message):
        print("[%s] %s.msg: %s" % (id(self), self.__class__.__name__, message))
        return id(self)


if __name__ == "__main__":
    # please make sure a name server is running somewhere first.
    Daemon.serveSimple(
        {
            SingleInstance: "instance.single",
            SessionInstance: "instance.session",
            PercallInstance: "instance.percall"
        },
        verbose=True)
Example #17
0
    def payCart(self, cart, name=None):
        receipt = []
        if name:
            receipt.append("Receipt for %s." % name)
        receipt.append("Receipt Date: " + time.asctime())
        total = 0.0
        for item in cart.getContents():
            price = self.inventory[item]
            total += price
            receipt.append("%13s  %.2f" % (item, price))
        receipt.append("")
        receipt.append("%13s  %.2f" % ("total:", total))
        cart.empty()
        return "\n".join(receipt)

    def leave(self, name):
        print("Customer %s leaves." % name)
        cart = self.customersInStore[name]
        print("  their shopping cart contains: %s" % cart.getContents())
        if cart.getContents():
            print("  it is not empty, they are trying to shoplift!")
            raise Exception("attempt to steal a full cart prevented")
        # delete the cart and unregister it with pyro
        del self.customersInStore[name]
        self._pyroDaemon.unregister(cart)


# main program

Daemon.serveSimple({Shop: "example.shop"})
Example #18
0
import time
import threading
from Pyro5.api import expose, oneway, behavior, Daemon


@expose
@behavior("single")
class Server(object):
    def __init__(self):
        self.counter = 0

    @oneway
    def increment_oneway(self):
        print("oneway call executing in thread", threading.get_ident())
        time.sleep(0.5)
        self.counter += 1

    def increment(self):
        time.sleep(0.5)
        self.counter += 1

    def getcount(self):
        return self.counter


print("main thread:", threading.get_ident())
Daemon.serveSimple({Server: "example.oneway2"})
Example #19
0
@expose
class Streamer(object):
    def list(self):
        return [1, 2, 3, 4, 5, 6, 7, 8, 9]

    def iterator(self):
        return iter([1, 2, 3, 4, 5, 6, 7, 8, 9])

    def generator(self):
        i = 1
        while i < 10:
            yield i
            i += 1

    def slow_generator(self):
        i = 1
        while i < 10:
            time.sleep(0.5)
            yield i
            i += 1

    def fibonacci(self):
        a, b = 0, 1
        while True:
            yield a
            a, b = b, a + b


Daemon.serveSimple({Streamer: "example.streamer"}, ns=False)
Example #20
0
from Pyro5.api import behavior, expose, locate_ns, Daemon
import Pyro5.config
from diffiehellman import DiffieHellman

Pyro5.config.SERVERTYPE = "multiplex"

ns = locate_ns()


@behavior(instance_mode="session")
class KeyExchange(object):
    def __init__(self):
        print("New KeyExchange, initializing Diffie-Hellman")
        self.dh = DiffieHellman(group=14)

    @expose
    def exchange_key(self, other_public_key):
        print("received a public key, calculating shared secret...")
        self.dh.make_shared_secret_and_key(other_public_key)
        print("shared secret key = ", self.dh.key)
        return self.dh.public_key


Daemon.serveSimple({KeyExchange: "example.dh.keyexchange"}, ns=True)
Example #21
0
        with futures.ThreadPoolExecutor() as pool:
            roundrobin_counters = cycle(all_counters.values())
            tasks = []
            for chunk in grouper(200, lines):
                tasks.append(pool.submit(self.count_chunk, next(roundrobin_counters), chunk))

            # gather the results
            print("Collecting %d results (counted in parallel)..." % len(tasks))
            totals = Counter()
            for task in futures.as_completed(tasks):
                try:
                    totals.update(task.result())
                except Pyro5.errors.CommunicationError as x:
                    raise Pyro5.errors.PyroError("Something went wrong in the server when collecting the responses: "+str(x))
            return totals


if __name__ == "__main__":
    print("Spinning up 5 word counters, and 1 dispatcher.")
    config.SERVERTYPE = "thread"
    Daemon.serveSimple(
        {
            WordCounter(): "example.dc2.wordcount.1",
            WordCounter(): "example.dc2.wordcount.2",
            WordCounter(): "example.dc2.wordcount.3",
            WordCounter(): "example.dc2.wordcount.4",
            WordCounter(): "example.dc2.wordcount.5",
            Dispatcher:    "example.dc2.dispatcher"
        }, verbose=False
    )
Example #22
0
import Pyro5.config

# Pyro5.config.COMMTIMEOUT=2


class Testclass(object):
    @expose
    def transfer(self, data):
        if Pyro5.config.SERIALIZER == "serpent" and type(data) is dict:
            data = serpent.tobytes(data)  # in case of serpent encoded bytes
        print("received %d bytes" % len(data))
        return len(data)

    @expose
    def download_chunks(self, size):
        print("client requests a 'streaming' download of %d bytes" % size)
        data = bytearray(size)
        i = 0
        chunksize = 200000
        print("  using chunks of size", chunksize)
        while i < size:
            yield data[i:i + chunksize]
            i += chunksize


Daemon.serveSimple({Testclass: "example.hugetransfer"},
                   host=Pyro5.socketutil.get_ip_address("localhost",
                                                        workaround127=True),
                   ns=False,
                   verbose=True)
Example #23
0
        self.sub = {"name": "value"}
        self.value = 42
        self._value = 123
        self.__value = 999

    def __dunder__(self):
        return "yep"

    def __len__(self):
        return 200

    def getValue(self):
        return self.value

    @property
    def prop_value(self):
        return self.value

    @prop_value.setter
    def prop_value(self, value):
        self.value = value

    @property
    def prop_sub(self):
        return self.sub


Daemon.serveSimple({
    Thingy: "example.attributes"
}, ns=False)