Websocket RPC and Pub/Sub for Python applications and microservices

Overview

Travis Python36 Python37 Python37 Python38

image

wampy

[whomp-ee]

For a background as to what WAMP is, please see here.

This is a Python implementation of WAMP using Gevent, but you can also configure wampy to use eventlet, if that is how your application does async. Wampy is is a light-weight alternative to autobahn.

With wampy, you can quickly and easily create your own WAMP clients, whether this is in a web app, a microservice, a script or just in a Python shell. You can integrate wampy into your existing applications without having to re-write or re-design anything.

wampy tries to provide an intuitive API for your WAMP messaging.

See ReadTheDocs for more detailed documentation, but the README here is detailed enough to get going.

wampy features

  • Remote Procedure Calls over websockets
  • Publish and Subscribe over websockets
  • Open Source and Open Thoughts - see internals and then the entire WIKI
  • Use wampy as a microservice/app, or in your Flask or nameko apps, or in scripts.... or just in a Python shell!
  • Client Authentication (Ticket and WCA)
  • Transport Layer Security
  • CLI for easy and rapid development
  • Pytest fixtures to use when testing your projects, including a Crossbar.io fixture that tears down between each test
  • nameko integration with namekowwamp
  • Flask integration with flaskwwamp
  • Compatible with gevent, eventlet and asyncio
  • Alpha features (see below)

QuickStart - Connect and Go!

If you've already got access to a running Router which has other Peers connected, then stay here. If not, jump to the next section. If you're still here...

pip install wampy

...and then open a Python shell.

The example here assumes a Peer connected to a Router on localhost, port 8080, that has registered a remote procedure called get_foobar, and you want to call that procedure.

from wampy.peers import Client

with Client() as client:
    response = client.rpc.get_foobar()

# do something with the response here

The same example here, but the Router is on a remote host.

from wampy.peers import Client

with Client(url="ws://example.com:8080") as client:
    response = client.rpc.get_foobar()

# do something with the response here

The WAMP Session is "context managed", meaning it begins as you enter, and ends as you exit the scope of the client instance.

See ReadTheDocs for much more detail on this.

Running and Calling a wampy Application

Before any messaging can happen you need a Router. Messages are then routed between Clients over an administrative domain on the Router called a Realm.

For the quickest of starts I suggest that you use Crossbar.io and start it up on the default host and port, and with the default realm and roles. See the Crossbar.io docs for the instructions on this or alternatively run with wampy's testing setup.

Note, if you already have Crossbar installed and running you do not need these steps, because the dev requirements also include Crossbar.

$ make dev-install

$ crossbar start --config ./wampy/testing/configs/crossbar.json

wampy RPC

Now open your preferred text editor and we'll write a few lines of Python constructing a simple WAMP service that takes a decimal number and returns the binary representation of it - wowzers!

from wampy.peers.clients import Client
from wampy.roles import callee

class BinaryNumberService(Client):

    @callee
    def get_binary_number(self, number):
        return bin(number)

Save this module somewhere on your Python path and we'll use a wampy command line interface tool to start the service.

$ wampy run path.to.your.module.including.module_name:BinaryNumberService

For example, running one of the wampy example applications against the Router suggested previously:

$ wampy run docs.examples.services:DateService --config ./wampy/testing/configs/crossbar.json

Actually - no need to panic! The BinaryNumberService example already exists in the wampy examples so put that text editor away if you like. Just execute from the command line:

$ wampy run docs.examples.services:BinaryNumberService --config ./wampy/testing/configs/crossbar.json

Now, open a Python console in a new terminal, allowing the BinaryNumberService to run uninterupted in your original terminal (but once you're done with it Ctrl-C is required).

In [1]: from wampy.peers.clients import Client

In [2]: with Client(url="ws://localhost:8080") as client:
            result = client.rpc.get_binary_number(number=100)

In [3]: result
Out[3]: u'0b1100100'

wampy RPC for Crossbar.io

The RPC pattern above was inspired by the nameko project, but this pattern may not feel intuitive for those familiar with Crossbar.io, the primary Router used by wampy.

For this reason there also exists the CallProxy object which implements the call API by more loosely wrapping wampy's Call Message. In this pattern, applications and their endpoints are identified by dot delimented strings rather than a single API name, e.g.

"com.example.endpoint"

Just like the rpc API, the call API is directly available on every wampy client. Lets look at the two examples side by side.

>>> client.rpc.get_foo_bar(eggs, foo=bar, spam=ham)
>>> client.call("get_foo_bar", eggs, foo=bar, spam=ham)

Noted these are very similar and achieve the same, but the intention here is for the call API to behave more like a classic Crossbar.io application and the rpc to be used in namekowwamp.

The call API however does allow calls of the form...

>>> client.call("com.myapp.foo.bar", eggs, foo=bar, spam=ham) 

...which you will not be able to do with the rpc API.

Publishing and Subscribing is equally as simple

To demonstrate, first of all you need a Subscriber. You can either create one yourself in a Python module (as a subclass of a wampy Client) or use the example Client already for you in docs.examples.services.

Here we use the said example service, but all a Subscriber is is a wampy Client with a method decorated by subscribe. Take a look and see for yourself in the examples.

Let's start up that example service.

$ wampy run docs.examples.services:SubscribingService --config ./wampy/testing/configs/crossbar.json

Now we have a service running that subscribes to the topic "foo".

In another terminal, with a wampy virtualenv, you can create a Publisher - which is no different to any other wampy Client.

In [1]: from wampy.peers import Client

In [2]: with Client() as client:
            result = client.publish(topic="foo", message="spam")

Hopefully you'll see any message you send printed to the screen where the example service is running. You'll also see the meta data that wampy chooses to send.

Please note. wampy believes in explicit kwargs and not bare args, so you can only publish keyword arguments. Bare arguments don't tell readers enough about the call, so even though WAMP supports them, wampy does not.

It doesn't matter what the kwargs are they will be published, but you might find a call like this is not supported by subscribers of other WAMP implementations (sorry) e.g.

In [1]: from wampy.peers import Client

In [2]: with Client() as client:
            client.publish(
                topic="foo",
                ham="spam",
                birds={'foo_bird': 1, 'bar_bird': 2},
                message="hello world",
            )

Notice topic is always first, followed by kwargs. Happy to explore how implementations like autobahn can be supported here.

See ReadTheDocs for more detailed documentation.

Have Fun With Wampy

You can simply import a wampy client into a Python shell and start creating WAMP apps. Open a few shells and start clients running! Or start an example app and open a shell and start calling it. Don't forget to start Crossbar first though!

$ make install

$ crossbar start --config ./wampy/testing/configs/crossbar.json

Extensions

Wampy is a "simple" WAMP client and so it can easily be integrated with other frameworks. The current extensions are:

Extensions for other Python Frameworks are encouraged!

Async Networking

The default backend for async networking is gevent, but you can switch this to eventlet if that is what your applications already use.

$ export WAMPY_ASYNC_NAME=eventlet

Swapping back is easy.

$ export WAMPY_ASYNC_NAME=gevent

Gevent is officially supported but eventlet no longer is, sorry. There were issues with Eventlet and Python 3.7 that I cannot currently work around.

Async.io would require a complete re-write, and if you're already using the standard library and want to use wampy that is not a problem - just roll with the default gevent - as the two event loops can run side by side.

Why does wampy support both eventlet and gevent? Because wampy is not a framework like Flask or nameko, and wampy tries to make as few assumptions about the process it is running in as possible. Wampy is intended to be integrated into existing Python apps as an easy way to send and receive WAMP messages, and if your app is already committed to a paritcular async architecture, then wampy may not be usable unless he can switch between them freely. And do remember: both options are compatible with the core asyncio library, so don't be put off if your app uses this.

Alpha Features

WebSocket Client -> Server Pings

Disabled by default, but by setting the environment variable DEFAULT_HEARTBEAT_SECONDS you can tell wampy to start Pinging the Router/Broker, i.e. Crossbar.

$ export DEFAULT_HEARTBEAT_SECONDS=5

There is also HEARTBEAT_TIMEOUT_SECONDS (defaults to 2 seconds) which on missed will incrmeent a missed Pong counter. That's it for now; WIP.

WAMP Call TimeOuts

WAMP advacned protocol describes an RPC timeout which wampy implements but Crossbar as yet does not. See https://github.com/crossbario/crossbar/issues/299. wampy does pass your preferred value to the Router/Broker in the Call Message, but the actual timeout is implemented by wampy, simply cutting the request off at the head. Sadly this does mean the server still may return a value for you and your app will have to handle this. We send the Cancel Message too, but there are issues here as well: Work In Progress.

Running the tests

$ pip install --editable .[dev]
$ py.test ./test -v

Build the docs

$ pip install -r rtd_requirements.txt
$ sphinx-build -E -b html ./docs/ ./docs/_build/

If you like this project, then Thank You, and you're welcome to get involved.

Contributing

Firstly. thank you everyone who does. And everyone is welcome to. And thanks for reading the CONTRIBUTING guidelines. And for adding yourselves to the CONTRIBUTORS list on your PR - you should! Many thanks. It's also great to hear how everyone uses wampy, so please do share how with me on your PR in comments.

Then, please read about the internals.

Finally.... get coding!!

Thanks!

TroubleShooting

Crossbar.io is used by the test runner and has many dependencies.

Mac OS

snappy/snappymodule.cc:31:10: fatal error: 'snappy-c.h' file not found #include

Fix by brew install snappy

Comments
  • feature request: expose session timeout to Client & caller

    feature request: expose session timeout to Client & caller

    Hi,

    I try to proxy do a wamp2 proxy to a slow rest api (response time > 10 seconde), I get constant timeout, because the timeout is hardcoded to 5 secondes in session.recv_message .

    Could you add a Client scope timeout, and a caller, suscriber timeout?

    class BinaryNumberService(Client):
    
        @callee(timeout=15)
        def get_binary_number(self, number):
            return bin(number)
    

    not sure if we can change the client timeout when we subclassing the Client class?

    and

    with Client(timeout=15) as client:
        response = client.rpc.get_foobar()
    
    opened by keiser1080 13
  • Issue with UTF-8 caracters as parameters with python 3

    Issue with UTF-8 caracters as parameters with python 3

    Hello !

    I have an issue when I'm trying to call a remote function with a UTF-8 caracter. Here my example

    Server

    from wampy.peers.clients import Client
    from wampy.roles.callee import callee
    
    class BinaryNumberService(Client):
    
        @callee
        def get_binary_number(self, text):
            print(text)
    
    
    toto  = BinaryNumberService()
    
    toto.start()
    
    try:
        import time
        time.sleep(9999)
    except:
        print('stopping')
    toto.stop()
    

    Client

    from wampy.peers.clients import Client
    
    with Client(url="ws://localhost:8080") as client:
                result = client.rpc.get_binary_number(text='100éfa')
    

    And the error:

    python client.py 
    Traceback (most recent call last):
      File "/home/tcohen/perso/gits/github.com/noisyboiler/wampy/wampy/transports/websocket/frames.py", line 239, in __init__
        self.payload = json.loads(str(self.body.decode()))
    UnicodeDecodeError: 'utf-8' codec can't decode byte 0xea in position 1: invalid continuation byte
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/home/tcohen/perso/gits/github.com/noisyboiler/wampy/env3.6/lib/python3.6/site-packages/eventlet-0.21.0-py3.6.egg/eventlet/hubs/poll.py", line 114, in wait
        listener.cb(fileno)
      File "/home/tcohen/perso/gits/github.com/noisyboiler/wampy/env3.6/lib/python3.6/site-packages/eventlet-0.21.0-py3.6.egg/eventlet/greenthread.py", line 218, in main
        result = function(*args, **kwargs)
      File "/home/tcohen/perso/gits/github.com/noisyboiler/wampy/wampy/session.py", line 159, in connection_handler
        frame = connection.receive()
      File "/home/tcohen/perso/gits/github.com/noisyboiler/wampy/wampy/transports/websocket/connection.py", line 83, in receive
        frame = ServerFrame(received_bytes)
      File "/home/tcohen/perso/gits/github.com/noisyboiler/wampy/wampy/transports/websocket/frames.py", line 242, in __init__
        'Failed to load JSON object from: "%s"', self.body
    wampy.errors.WebsocktProtocolError: ('Failed to load JSON object from: "%s"', bytearray(b"\x03\xeaWAMP Protocol Error (invalid serialization of WAMP message (Expecting \',\' delimiter: line 1 column 56 (char 55)))"))
    Removing descriptor: 3
    Traceback (most recent call last):
      File "/home/tcohen/perso/gits/github.com/noisyboiler/wampy/wampy/session.py", line 115, in recv_message
        message = self._wait_for_message(timeout)
      File "/home/tcohen/perso/gits/github.com/noisyboiler/wampy/wampy/session.py", line 184, in _wait_for_message
        eventlet.sleep()
      File "/home/tcohen/perso/gits/github.com/noisyboiler/wampy/env3.6/lib/python3.6/site-packages/eventlet-0.21.0-py3.6.egg/eventlet/greenthread.py", line 35, in sleep
        hub.switch()
      File "/home/tcohen/perso/gits/github.com/noisyboiler/wampy/env3.6/lib/python3.6/site-packages/eventlet-0.21.0-py3.6.egg/eventlet/hubs/hub.py", line 295, in switch
        return self.greenlet.switch()
    eventlet.timeout.Timeout: 5 seconds
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "client.py", line 6, in <module>
        result = client.rpc.get_binary_number(text='100éfa')
      File "/home/tcohen/perso/gits/github.com/noisyboiler/wampy/wampy/roles/caller.py", line 63, in wrapper
        response = self.client.make_rpc(message)
      File "/home/tcohen/perso/gits/github.com/noisyboiler/wampy/wampy/peers/clients.py", line 211, in make_rpc
        response = self.session.recv_message()
      File "/home/tcohen/perso/gits/github.com/noisyboiler/wampy/wampy/session.py", line 118, in recv_message
        "no message returned (timed-out in {})".format(timeout)
    wampy.errors.WampProtocolError: no message returned (timed-out in 5)
    
    opened by titilambert 12
  • unale to run the example

    unale to run the example

    Hi,

    First i have installed lastest version off crossbar into a virtual pypy3 vritualenvironement. Then I have installed wampy using pip inside the virtualenvironement. Thn i have the following crossbar config https://github.com/noisyboiler/wampy/blob/master/wampy/testing/configs/crossbar.json and the following example https://github.com/noisyboiler/wampy/blob/master/docs/examples/services.py runing the router => crossbar start --config crossbar.json And try to launch the service using the run command. It fail

    then i have cloned the repo and followed your instruction pip install --editable .[dev] crossbar, and many other lib downgraded to very old version

      Found existing installation: autobahn 18.9.2
        Uninstalling autobahn-18.9.2:
          Successfully uninstalled autobahn-18.9.2
      Found existing installation: crossbar 18.9.2
        Uninstalling crossbar-18.9.2:
          Successfully uninstalled crossbar-18.9.2
      Found existing installation: wampy 0.9.17
        Uninstalling wampy-0.9.17:
          Successfully uninstalled wampy-0.9.17
      Running setup.py develop for wampy
    Successfully installed autobahn-0.17.2 colorlog-3.1.4 coverage-4.5.1 crossbar-0.15.0 enum-compat-0.0.2 eventlet-0.20.1 flake8-3.5.0 gevent-websocket-0.10.1 mccabe-0.6.1 mock-1.3.0 pbr-4.3.0 py-1.7.0 pycodestyle-2.3.1 pyflakes-1.6.0 pytest-3.1.3 pytest-capturelog-0.7 shutilwhich-1.1.0 wampy
    

    Running again the router & all the stuff as specified in the doc, And again the same probleme

    wampy run docs.examples.services:BinaryNumberService --config ./wampy/testing/configs/crossbar.json
    Traceback (most recent call last):
      File "/home/erc/.virtualenvs/pypy3/bin/wampy", line 11, in <module>
        load_entry_point('wampy', 'console_scripts', 'wampy')()
      File "/home/rep/icham/golden/crossbar/wampy/wampy/cli/main.py", line 27, in main
        args.main(args)
      File "/home/rep/icham/golden/crossbar/wampy/wampy/cli/run.py", line 104, in main
        run(app, config_path)
      File "/home/rep/icham/golden/crossbar/wampy/wampy/cli/run.py", line 70, in run
        router = Crossbar(config_path)
      File "/home/rep/icham/golden/crossbar/wampy/wampy/peers/routers.py", line 43, in __init__
        with open(config_path) as data_file:
    FileNotFoundError: [Errno 2] No such file or directory: './crossbar/config.json'
    
    ls -al wampy/testing/configs/crossbar.json
    -rw-rw-r-- 1 erc erc 1324 Oct 13 19:11 wampy/testing/configs/crossbar.json
    
    opened by keiser1080 10
  • add ticket authentication support [closes #66]

    add ticket authentication support [closes #66]

    Hi, here is my first attempt to implement ticket authentication to wampy.

    Unfortunately some tests have been failing for me right when I cloned this repository, so I'm not 100% sure I didn't break something else.

    Please let me know if there are some issues.

    Thanks!

    opened by wodCZ 9
  • flask example

    flask example

    Hi,

    On the description i see wampy can be used in a webapp. I have read the doc, and there are multiple example for standalone application, but no example of using wampy inside a web application. Could you post or add on the docs or on the example folder a simple flask example ? I have a flask aplication exposing an http service, and i want to extend it by publishing toward a crossbar router some event.

    opened by keiser1080 7
  • unicode bug

    unicode bug

    this is far from perfect. just fixes python 2.7 and is a way of appreciating the problem.

    • test case that exposes a unicode bug
    • suggested Python 2.7 fix

    Likely still broken on Python 3

    opened by noisyboiler 7
  • ping handling

    ping handling

    Hi!

    Creating and starting a long running client leads to disconnects due to unhandled pings from the router.

    with wampy.Client(url="ws://localhost:8080/ws") as client:
        client.publish(topic="test", foo="bar")
        time.sleep(10)
        client.publish(topic="test", foo="bar")
    
     Traceback (most recent call last):
      File "/home/marcus/local/python/python3env/lib/python3.6/site-packages/wampy/transports/websocket/frames.py", line 253, in __init__
        self.payload = json.loads(self.body.decode('utf-8'))
      File "/usr/lib64/python3.6/json/__init__.py", line 354, in loads
        return _default_decoder.decode(s)
      File "/usr/lib64/python3.6/json/decoder.py", line 342, in decode
        raise JSONDecodeError("Extra data", s, end)
    json.decoder.JSONDecodeError: Extra data: line 1 column 2 (char 1)
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/home/marcus/local/python/python3env/lib/python3.6/site-packages/eventlet/hubs/poll.py", line 114, in wait
        listener.cb(fileno)
      File "/home/marcus/local/python/python3env/lib/python3.6/site-packages/eventlet/greenthread.py", line 218, in main
        result = function(*args, **kwargs)
      File "/home/marcus/local/python/python3env/lib/python3.6/site-packages/wampy/session.py", line 158, in connection_handler
        frame = connection.receive()
      File "/home/marcus/local/python/python3env/lib/python3.6/site-packages/wampy/transports/websocket/connection.py", line 86, in receive
        frame = ServerFrame(received_bytes)
      File "/home/marcus/local/python/python3env/lib/python3.6/site-packages/wampy/transports/websocket/frames.py", line 256, in __init__
        'Failed to load JSON object from: "%s"', self.body
    wampy.errors.WebsocktProtocolError: ('Failed to load JSON object from: "%s"', bytearray(b'6xLI'))
    Removing descriptor: 3
    

    Are there plans to add ping-handling?

    opened by fnordian 6
  • Example: Ticket authentication

    Example: Ticket authentication

    Hello, for beginning, thank you for this package.

    I've just implemented wampy to our stack, and I have some code that I think would be useful for readme or examples. In our stack, Crossbar router runs in separate docker container, and is configured to use ticket authentication (which is not natively supported in wampy).

    First, I created a new TicketAuthenticate class - message that will be sent after ticket challenge. It receives ticket in constructor.

    class TicketAuthenticate(object):
        WAMP_CODE = 5
        name = "authenticate"
    
        def __init__(self, ticket, kwargs_dict=None):
            super(TicketAuthenticate, self).__init__()
    
            self.ticket = ticket
            self.kwargs_dict = kwargs_dict or {}
    
        @property
        def message(self):
            return [
                self.WAMP_CODE, self.ticket, self.kwargs_dict
            ]
    

    Then, I extended MessageHandler to respond with this message in handle_challenge. It receives ticket in constructor and passes it to TicketAuthenticate once requested.

    from wampy.message_handler import MessageHandler, logger
    
    class TicketMessageHandler(MessageHandler):
    
        ticket = None
    
        def __init__(self, ticket) -> None:
            super().__init__()
            self.ticket = ticket
    
        def handle_challenge(self, message_obj):
            logger.debug("client has been Challenged")
            message = TicketAuthenticate(self.ticket)
            self.session.send_message(message)
    

    And finally usage example

            roles = {
                'roles': {
                    'subscriber': {},
                    'publisher': {},
                    'callee': {
                        'shared_registration': True,
                    },
                    'caller': {},
                },
                'authmethods': ['ticket'],
                'authid': settings.WAMP_BACKEND_PRINCIPAL
            }
            self.client = Client(
                url=f"ws://{settings.WAMP_BACKEND_HOST}:{settings.WAMP_BACKEND_PORT}",
                realm=settings.WAMP_BACKEND_REALM,
                roles=roles,
                message_handler=TicketMessageHandler(settings.WAMP_BACKEND_TICKET)
            )
            self.client.start()
    

    I'm not a Python developer, but I feel that this code is not the best approach - that's why I'm creating this issue - it's not suitable for a pull request. It could save some time to anyone though, maybe it would be an inspiration for adding a support for ticket auth to wampy.

    Please let me know whether you want this issue to be closed without discussion (just kept for reference), or you'd like to discuss this topic.

    Thanks!

    opened by wodCZ 5
  • replace eventlet with gevent

    replace eventlet with gevent

    I would love to be able to use wampy within my gevent-based application, but I'm pretty sure the use of eventlet precludes that. I've never used eventlet so I can't speak to the technical differences between the two libraries, but gevent is very widely adopted at this point and eventlet is not. Would you accept a PR that ports this project to gevent? All the tests are passing.

    opened by chadrik 5
  • Doc : how to setup the URL in the config.json file of crossbar

    Doc : how to setup the URL in the config.json file of crossbar

    Hi,

    I think it could be useful to add something in the doc about how to setup the URL in the config.json file of crossbar. Because when starting from scratch, there is no URL parms.

    So When running the app we get the error

    wampy.errors.WampyError: The ``url`` value is required by Wampy. Please add to your configuration file. Thanks.
    

    And I had to digg in the source to find where to wampy expected to see the URL parm to be able to add it in the config.json file of the crossbar router.

    opened by foxmask 5
  • ujson vs simplejson

    ujson vs simplejson

    Hi, I don't know if you've considered this already, but I started using "ujson" instead of "json" a little while back, seems to be completely stable / reliable, and around 4x faster than "simplejson". If your app does a lot of WAMP type work, it can make a noticeable difference ..

    https://github.com/esnme/ultrajson

    good first issue 
    opened by oddjobz 5
Releases(1.1.0)
  • 1.1.0(Apr 5, 2021)

  • 1.0.0(Aug 28, 2020)

    • breaking change: replace Client init param message_handler with message_handler_cls
    • removes a weird testing pattern from the early days where a Router instance was modelled inside the Client.
    • fixes wampy run command not working
    • fixes noisy teardowns
    • fixes #100 , cannot send very long strings
    Source code(tar.gz)
    Source code(zip)
  • 0.9.21(Jan 12, 2019)

    • bumps Eventlet, Six, Pytest and Crossbar
    • fixes #78 (expose call timeout to Client public API)
    • fixes #67 (double slash in paths)
    • fixes #88 (dependencies too strict)
    • fixes #86 (WebSocket client->server pings)
    • fixes GoodBye never received from the server
    • fixes WebSocket tests accidentally fixed
    Source code(tar.gz)
    Source code(zip)
  • 0.9.20(Dec 30, 2018)

  • 0.9.19(Dec 21, 2018)

  • 0.9.18(Dec 20, 2018)

    • fixes the forgotten AppRunner and adds test coverage
    • adds ticket authentication
    • Fixes RPC result args handling from Autobahn
    • optional Eventlet for async networking
    Source code(tar.gz)
    Source code(zip)
  • 0.9.17(Mar 18, 2018)

  • v0.9.16(Mar 17, 2018)

    • refactors websocket implementation to better handle control and binary frames
    • adds FrameFactory to process incoming bytes
    • adds a test case pattern to the websocket level using gevent-websocket
    • adds a Ping websocket frame
    Source code(tar.gz)
    Source code(zip)
  • 0.9.15(Mar 9, 2018)

  • 0.9.14(Feb 10, 2018)

    • removes tenacity
    • fixes documentation errors
    • adds docs to wampy's wrapper around Crossbar
    • removes deprecated URL key from Crossbar config
    • flakes
    Source code(tar.gz)
    Source code(zip)
  • 0.9.13(Nov 25, 2017)

  • 0.9.12(Oct 31, 2017)

  • 0.9.11(Oct 30, 2017)

  • 0.9.10(Oct 10, 2017)

  • 0.9.9(Oct 1, 2017)

    • adds connect to a Router by a URL
    • adds Transport decision by URL protocol/scheme not on Client init
    • adds quick start connection details to README
    • adds detailed connection details to ReadTheDocs
    • adds simple Router representation for Sessions based on the given URL when a Router instance is not provided to a Client
    • removes forgotten features of MessageHandler
    • MessageTypeMap now maps to classes instead of strings
    • adds test cases for URL handling
    • minor tweaks to logging, layout and Exception handling
    • adds more internal docs and comments
    Source code(tar.gz)
    Source code(zip)
  • 0.9.8(Sep 11, 2017)

    • instead of registering Roles as functions, register a reference to them and allow clients to decide how the actual implementation is looked up (to support nameko-wamp)
    • remove TopicProxy because this can be (and should be) implemented on the client application now (see nameko-wamp for an example)
    • remove dead test modules
    • register_roles promoted to a public API on a Client that can be over-ridden by applications who want to control how their app registers Roles.
    • update TLS docs
    Source code(tar.gz)
    Source code(zip)
  • 0.9.7(Aug 24, 2017)

    • Shared Secret Authentication (static)
    • fixes: README URLs in examples
    • simplify message classes
    • pluggable message serializer
    • pluggable transport
    • remove unnecessary wamp_code on each Message
    • add WAMP protocol for reference
    • fixes multiple crossbars running in test suite
    • simpler TLS
    • simpler Session construction
    Source code(tar.gz)
    Source code(zip)
  • 0.9.6(Jul 18, 2017)

    • added remote Exception handling
    • MessageHandler moved to the Session object to reduce miss-direction in RPC call protocol
    • No behaviour now on a Message object - all behaviour is on the MessageHandler
    • remove "call with meta" as patterns such as this should be implemented by overriding the appropriate method in the MessageHandler
    • added some docs on the MessageHandler and how it can be used to customise wampy behaviour
    • remove CalleeProxy as this is never used, no use-cases have been presented and maintenance is annoying
    • remove all message handling from the Client and delegate to the Session
    • much internal tidy up and miss-direction removed
    Source code(tar.gz)
    Source code(zip)
  • 0.9.5(Jun 29, 2017)

  • 0.9.4(May 7, 2017)

  • 0.9.3(Apr 23, 2017)

    • test coverage for CallProxy
    • docs for CallProxy
    • remove some dead code
    • flakes
    • launch message handling in separate gthread
    • global pytest features for using wampy as a library
    • fix duped logging when using wampy as a library
    • optional name attr on wampy clients
    Source code(tar.gz)
    Source code(zip)
  • 0.9.2(Apr 18, 2017)

  • 0.9.1(Apr 17, 2017)

  • 0.9.0(Apr 17, 2017)

  • 0.8.4(Apr 15, 2017)

    • fixes: missing params on Error msg
    • handle no connection established
    • separate Yield message from Invocation to allow overriding behaviour by other applications
    • simplify message handler class
    • improve test coverage
    Source code(tar.gz)
    Source code(zip)
  • 0.8.3(Apr 8, 2017)

    • can override Crossbar config in tests
    • optionally Invoke callees with meta data
    • simpler client instantiation
    • fix socket already shutdown error
    Source code(tar.gz)
    Source code(zip)
  • 0.8.2(Apr 5, 2017)

  • 0.8.1(Mar 29, 2017)

    • handle ipv4 and ipv6 websockets
    • optimise websocket reads
    • simpler TLS API
    • change callee entrypoint decorator from "rpc" to "callee"
    • update README
    • fix test runner router not always shutting down
    Source code(tar.gz)
    Source code(zip)
  • 0.8.0(Mar 18, 2017)

    • unify wampy's WAMPish features as "wamp clients"
    • async handling of messaging
    • message handling logic pushed to pluggable message classes
    • remove meta event handling and service cluster features which are were all experimental
    Source code(tar.gz)
    Source code(zip)
  • 0.7.8(Mar 29, 2017)

Owner
simon
simon
alien.py - Python interface to websocket endpoint of ALICE Grid Services

alien.py - Python interface to websocket endpoint of ALICE Grid Services Quick containerized testing: singularity

Adrian Sevcenco 6 Dec 14, 2022
Websockify is a WebSocket to TCP proxy/bridge. This allows a browser to connect to any application/server/service. Implementations in Python, C, Node.js and Ruby.

websockify: WebSockets support for any application/server websockify was formerly named wsproxy and was part of the noVNC project. At the most basic l

noVNC 3.3k Jan 03, 2023
Tetri5 - Multiplayer Websocket Backend

Tetri5 - Multiplayer Websocket Backend This repository is the backend of the multiplayer portion of the Tetri5 game client. It uses the python websock

Giovani Rodriguez 1 Dec 10, 2022
Discord.py Connect to Discord voice call with websocket

Discord.py Connect to Discord voice call with websocket

WoahThatsHot 3 Apr 22, 2022
Library for easily creating and managing websockets.

Documentation coming in version 0.1.4 GitHub PyPI Discord Features Easy to use with object oriented syntax. Intellisense support with typehints and do

ZeroIntensity 0 Aug 27, 2022
一款为 go-cqhttp 的正向 WebSocket 设计的 Python SDK

Nakuru Project 一款为 go-cqhttp 的正向 WebSocket 设计的 Python SDK 在 kuriyama 的基础上改动 项目名来源于藍月なくる,图标由せら绘制 食用方法 将 nakuru 文件夹移至 Python 的 Lib/site-packages 目录下。

35 Dec 21, 2022
A Security Tool for Enumerating WebSockets

STEWS: Security Testing and Enumeration of WebSockets STEWS is a tool suite for security testing of WebSockets This research was first presented at OW

175 Jan 01, 2023
Python framework for AsyncAPI-documented Websocket, PubSub, and other async constructs

asyncapi-eventrouter Work in Progress Write Python code for Event-Driven Architectures! The asyncapi-eventrouter prototype library creates Websocket,

noteable 4 Jan 27, 2022
Synci - Learning project to create a websocket based client server messaging application

Synci Learning project to create a websocket based client server messaging appli

2 Jan 13, 2022
Using python-binance to provide websocket data to freqtrade

The goal of this project is to provide an alternative way to get realtime data from Binance and use it in freqtrade despite the exchange used. It also uses talipp for computing

58 Jan 01, 2023
WebSocket client for Python

websocket-client The websocket-client module is a WebSocket client for Python. It provides access to low level APIs for WebSockets. All APIs are for s

3.1k Jan 02, 2023
WebSocket implementation in Python built on top of websockets python library. Similar to Node.js's ws.

ws WebSocket implementation in Python built on top of websockets python library. Similar to Node.js's ws. Basic usage. server.py import ws server = w

AceExpert 7 Jun 27, 2022
wssh ("wish") is a command-line utility/shell for WebSocket inpsired by netcat.

wssh ("wish") is a command-line utility/shell for WebSocket inspired by netcat

Jeff Lindsay 256 Nov 16, 2022
Websocket RPC and Pub/Sub for Python applications and microservices

wampy [whomp-ee] For a background as to what WAMP is, please see here. This is a Python implementation of WAMP using Gevent, but you can also configur

simon 121 Nov 22, 2022
Connects microservices through a mesh of websockets

WebMesh WebMesh is a WebSocket based communication library for microservices. It uses a WebSocket server based on wsproto that distributes clients on

Charles Smith 9 Apr 29, 2022
Official repository for gevent-socketio

Presentation gevent-socketio is a Python implementation of the Socket.IO protocol, developed originally for Node.js by LearnBoost and then ported to o

Alexandre Bourget 1.2k Dec 12, 2022
This websocket program is for data transmission between server and client. Data transmission is for Federated Learning in Edge computing environment.

websocket-for-data-transmission This websocket program is for data transmission between server and client. Data transmission is for Federated Learning

9 Jul 19, 2022
SocketIO 转发台,保持 botoy 能力和插件功能的同时,透传其接口,以此使用更灵活、生态更好的技术进行开发

bot_sio_transfer SocketIO 转发台,保持 botoy 能力和插件功能的同时,透传其接口,以此使用更灵活、生态更好的技术进行开发 Usage 请参考 botoy 文档接入本插件 Example 考虑一种图文混排场景,如何从复杂结构内快速获取第一张图片的 url ? ( 假设图片

OPQ Open Source Community 3 Oct 18, 2021
WebSocket emulation - Python server

SockJS-tornado server SockJS-tornado is a Python server side counterpart of SockJS-client browser library running on top of Tornado framework. Simplif

Serge S. Koval 854 Nov 19, 2022
Terminals served by tornado websockets

This is a Tornado websocket backend for the Xterm.js Javascript terminal emulator library. It evolved out of pyxterm, which was part of GraphTerm (as

Project Jupyter 332 Dec 27, 2022