Library for building WebSocket servers and clients in Python

Overview

websockets

rtd pypi-v pypi-pyversions pypi-l pypi-wheel circleci codecov

What is websockets?

websockets is a library for building WebSocket servers and clients in Python with a focus on correctness and simplicity.

Built on top of asyncio, Python's standard asynchronous I/O framework, it provides an elegant coroutine-based API.

Documentation is available on Read the Docs.

Here's how a client sends and receives messages:

#!/usr/bin/env python

import asyncio
import websockets

async def hello(uri):
    async with websockets.connect(uri) as websocket:
        await websocket.send("Hello world!")
        await websocket.recv()

asyncio.get_event_loop().run_until_complete(
    hello('ws://localhost:8765'))

And here's an echo server:

#!/usr/bin/env python

import asyncio
import websockets

async def echo(websocket, path):
    async for message in websocket:
        await websocket.send(message)

asyncio.get_event_loop().run_until_complete(
    websockets.serve(echo, 'localhost', 8765))
asyncio.get_event_loop().run_forever()

Does that look good?

Get started with the tutorial!


websockets for enterprise

Available as part of the Tidelift Subscription

The maintainers of websockets and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. Learn more.


(If you contribute to websockets and would like to become an official support provider, let me know.)

Why should I use websockets?

The development of websockets is shaped by four principles:

  1. Simplicity: all you need to understand is msg = await ws.recv() and await ws.send(msg); websockets takes care of managing connections so you can focus on your application.
  2. Robustness: websockets is built for production; for example it was the only library to handle backpressure correctly before the issue became widely known in the Python community.
  3. Quality: websockets is heavily tested. Continuous integration fails under 100% branch coverage. Also it passes the industry-standard Autobahn Testsuite.
  4. Performance: memory use is configurable. An extension written in C accelerates expensive operations. It's pre-compiled for Linux, macOS and Windows and packaged in the wheel format for each system and Python version.

Documentation is a first class concern in the project. Head over to Read the Docs and see for yourself.

Why shouldn't I use websockets?

  • If you prefer callbacks over coroutines: websockets was created to provide the best coroutine-based API to manage WebSocket connections in Python. Pick another library for a callback-based API.
  • If you're looking for a mixed HTTP / WebSocket library: websockets aims at being an excellent implementation of RFC 6455: The WebSocket Protocol and RFC 7692: Compression Extensions for WebSocket. Its support for HTTP is minimal β€” just enough for a HTTP health check.
  • If you want to use Python 2: websockets builds upon asyncio which only works on Python 3. websockets requires Python β‰₯ 3.6.1.

What else?

Bug reports, patches and suggestions are welcome!

To report a security vulnerability, please use the Tidelift security contact. Tidelift will coordinate the fix and disclosure.

For anything else, please open an issue or send a pull request.

Participants must uphold the Contributor Covenant code of conduct.

websockets is released under the BSD license.

Comments
  • Documentation: How can server broadcast to all connected clients at regular interval?

    Documentation: How can server broadcast to all connected clients at regular interval?

    I'm trying to implement a WebSocket server that, once it's ready to accept connections, starts generating data periodically. Whenever data is generated (e.g. every 2 seconds), I want to broadcast the data to all connected clients.

    I looked at the documentation and could not find an example like that. There is an example where the WebSocket server sends a message periodically to connected clients, but each client has its own "interval" (i.e. all clients won't receive the message at the same time).

    It would be great if the documentation had such an example. I'm coming from Node.js and this is pretty easy to do with the 'ws' npm package. I'm new to Python, so I hope my question is not ridiculously stupid.

    documentation 
    opened by felix-pb 38
  • Consider making websocket protocols context managers

    Consider making websocket protocols context managers

    From https://github.com/aaugustin/websockets/issues/77#issuecomment-152921813

    it would also be nice to use pythons context manager syntax to guarantee client code can be robust without any need for checking on their end.

    something like this:

    def echo_handler(websocket):
        with websocket as ws:
            # as long as the socket is open do your thing
            while True:
                message = yield from ws.recv()
                yield from ws.send(message)
    

    it's not necessarily pretty (it took 3 indents to write anything useful), but it'll take some responsibility off a client.


    I'm not sold on this approach yet but I think it's interesting and deserves its own ticket.

    enhancement 
    opened by aaugustin 33
  • Deployment tips to deal with a lot of connections

    Deployment tips to deal with a lot of connections

    Hi there,

    I am thinking about the best way to handle a bunch of connections using the least amount of machines (2 to 4 beefy servers probably), and I wonder if folks here have insights. With http I've been using gunicorn which makes it very easy to use many cores, but I'm a bit lost with asyncio on how to use all my cores. My application will likely just push data into redis and do little CPU work, but if there are a bunch of connected clients cpu might become an issue.

    I thought about running multiple servers on multiple ports, and use nginx who's serving on port 80 as a load-balancer + proxy_pass (is that even possible) to go to multiple daemon running the websockets app (something like that?).

    And then I'd have multiple services (each one, on a given machine, running under systemd) / each proxy_pass talk to one.

    start_server = websockets.serve(hello, 'localhost', 8000) # for 'proxy_pass A'
    start_server = websockets.serve(hello, 'localhost', 8001) # for 'proxy_pass B'
    start_server = websockets.serve(hello, 'localhost', 8002) # for 'proxy_pass C, etc...'
    

    I know it's a very vague question and not really an issue, but in absence of a better place to discuss this ... here we go !

    Thanks,

    • Benjamin
    documentation high priority 
    opened by bsergean 31
  • Release 9.0 breaks mypy (and pylint etc.)

    Release 9.0 breaks mypy (and pylint etc.)

    Running a project that uses websockets 9.0 against mypy, throws:

    error: Module has no attribute "connect"
    

    for

    import websockets
    await websockects.connect(uri)
    

    and

    Module 'websockets' has no attribute 'connect'
    

    for

    from websockets import connect
    

    Version 8.1 of websockets has no such issue. Using the latest mypy 0.812.

    bug 
    opened by vertti 29
  • Default compression settings of 10.0 trigger bug in AWS API Gateway server

    Default compression settings of 10.0 trigger bug in AWS API Gateway server

    Hello,

    I've noticed an issue that appears to have started with websockets version 10.0. I have a websocket server run by the AWS API gateway. I use the websockets library to connect with my python program. Under 9.1 there was no issue receiving messages, but I noticed that as of 10.0 I stopped receiving the messages the server continuously sends (verified through wscat).

    When I run with the logger I'd observe the connection being made as expected:

    async with websockets.connect(my_url) as websocket:

    DEBUG, > Upgrade: websocket
    DEBUG, > Connection: Upgrade
    DEBUG, > Sec-WebSocket-Key: cSPm5HYtYSZU3BoudrY91w==
    DEBUG, > Sec-WebSocket-Version: 13
    DEBUG, > Sec-WebSocket-Extensions: permessage-deflate; server_max_window_bits=12; client_max_window_bits=12
    DEBUG, > User-Agent: Python/3.7 websockets/10.0
    DEBUG, < HTTP/1.1 101 Switching Protocols
    DEBUG, < Date: Wed, 06 Oct 2021 17:57:43 GMT
    DEBUG, < Connection: upgrade
    DEBUG, < upgrade: websocket
    DEBUG, < sec-websocket-accept: e9Ztme4JDr4o30+FPAUZwoJMZcE=
    DEBUG, < sec-websocket-extensions: permessage-deflate;server_max_window_bits=12
    DEBUG, = connection is OPEN
    

    Note that the server does not reply with any compression options. I think this is valid if the server doesn't support compression.

    I then wait on messages like so:

    while True:
        msg = await websocket.recv()
    

    Everything appears normal from a connection perspective, except messages should be flowing regularly instead of just default ping / pong style responses:

    DEBUG, %% sending keepalive ping
    DEBUG, > PING 3c 93 7f 61 [binary, 4 bytes]
    DEBUG, < PONG 3c 93 7f 61 [binary, 4 bytes]
    

    I discovered if I set compression=None in connect ie:

    async with websockets.connect(my_url, compression=None) as websocket:
    

    Then messages from my server flow as usual as they did in 9.1.

    It seems like compression should be something AWS supports on their side and will also engage with their support. However, since things appear to work with wscat, I think there may also be an issue with the websockets library itself in supporting servers that do not support compression.

    To help debugging, I'm hosting a websocket server through the API Gateway which outputs regular messages to any connected client and does not require any authentication. I won't guarantee it will stay up indefinitely (sorry to any future readers!)

    To test, run: wscat -c wss://n36vwxc045.execute-api.us-east-2.amazonaws.com/test This should work and you'll see the output < {"thanks": "for investigating this"} at about 1/2 Hz.

    If you use the following code with the websockets 10.0 library to read the messages:

    import asyncio
    import websockets
    import socket
    
    import logging
    
    logging.basicConfig(
        format="%(message)s",
        level=logging.DEBUG,
    )
    
    def main() -> None:
        asyncio.get_event_loop().run_until_complete(
            listen_forever(
                "wss://n36vwxc045.execute-api.us-east-2.amazonaws.com/test"
            )
        )
    
    
    async def listen_forever(
        url: str
    ) -> None:
        """
        Listen for a websocket message, reconnecting if something bad happens.
    
        Args:
          url (str): The URL to which to connect.
    
        """
        # outer loop restarted every time the connection fails
        while True:
            try:
                async with websockets.connect(
                    url,
                    # compression=None  # UNCOMMENT THIS LINE TO GET MESSAGES
                ) as websocket:
                    print('Websocket connected, waiting for messages...')
                    while True:
                        msg = await websocket.recv()
                        print(msg)
            except socket.gaierror as exp:
                print(exp)
                continue
            except ConnectionRefusedError as exp:
                print(exp)
                continue
            except websockets.exceptions.ConnectionClosedOK:
                print(
                    'Server closed connection (2 hour timeout?), reconnecting.'
                )
                continue
            except websockets.exceptions.InvalidStatusCode as exp:
                print(
                    'Server returned an InvalidStatusCode - {}. Reconnecting.'.format(
                        exp
                    )
                )
                continue
            except asyncio.streams.IncompleteReadError as exp:
                print(
                    'Server an IncompleteReadError - {}. Reconnecting.'.format(
                        exp
                    )
                )
                continue
            except Exception as exp:
                print(
                    'Unhandled exception - {}. Reconnecting.'.format(
                        exp
                    )
                )
                continue
    
    
    if __name__ == '__main__':
        main()
    

    You'll observe no message output unless you uncomment line 35.

    Thanks for all your great work on this project!

    enhancement blocked 
    opened by rez10191 28
  • Control not released while sending multiple messages

    Control not released while sending multiple messages

    TL;DR: Sending many messages in a loop (via a loop of await ws.send(...) or via passing an async generator to send() once), does not release control, and disconnects clients due to unanswered pings.

    The longer story: I have a server that generates large messages to send to clients. Sending those messages takes time (about a minute), both because it takes some time to generate the messages themselves (CPU-intensive), but also because the network is rather slow.

    The problem that I've noticed, is that await ws.send(...) does not release control even once done. I also tried to pass an async generator to send, and didn't get control back also (see example code below).

    The outcome from that is that websocket's pings are not getting answered, and the client disconnects.

    Example code: Here's a simple server that sends 20 packets of data to the client. I use time.sleep(1) instead of asyncio.sleep(1) to simulate actual CPU-intensive processing.

    import asyncio
    import time
    import websockets
    
    async def handler(websocket, path):
        async for request in websocket:
            print("Got a request to send stuff")
            for x in range(20):
                print("Sending", x)
                await websocket.send(str(x))
                time.sleep(1)  # Simulate CPU-intensive operation
            print("Done sending")
    
    async def heartbeat():
        while True:
            await asyncio.sleep(1)
            print("Heartbeat: ", time.time())
    
    async def main():
        await websockets.serve(handler, "localhost", 6789)
        await heartbeat()
    
    asyncio.run(main())
    

    The output looked something like this:

    Heartbeat:  1607622802.574514
    Got a request to send stuff
    Sending 0
    Sending 1
    <... No heartbeats here ...>
    Sending 18
    Sending 19
    Done sending
    Heartbeat:  1607622823.145667
    Heartbeat:  1607622824.1507761
    

    As you can see, there're no hearbeats at all while in the sending loop, even though we do await each websocket.send() individually.

    Adding await asyncio.sleep(0) right after the send, as a patch, does somewhat fixes the problem. (I start to get heardbeats every few (~5) seconds)

    I also tried passing an async iterator into ws.send() (since the documentation of send clearly states that in that case control will be released), but no luck. Here's the new handler() function:

    async def handler(websocket, path):
        async def gen():
            for x in range(20):
                yield str(x)
                time.sleep(1)  # Simulate CPU-heavy operation
    
        async for request in websocket:
            print("Got a request to send stuff")
            await websocket.send(gen())
            print("Done sending")
    

    This is actually worse, as I didn't have a good place to add an await asyncio.sleep(0) in.

    I've tested with Websockets 8.1, and both python3.7 and python3.8.

    opened by mishas 25
  • when the network is bad, it shows fatal read error message

    when the network is bad, it shows fatal read error message

    Fatal read error on socket transport protocol: <asyncio.sslproto.SSLProtocol object at 0x1177ce940> transport: <_SelectorSocketTransport fd=47 read=polling write=<idle, bufsize=0>> Traceback (most recent call last): File "/var/containers/Bundle/Application/9F565D30-C54B-4210-902B-874D7A5AB814/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/asyncio/selector_events.py", line 725, in _read_ready data = self._sock.recv(self.max_size) TimeoutError: [Errno 60] Operation timed out

    question 
    opened by yjqiang 24
  • Common pattern for reconnections

    Common pattern for reconnections

    In several projects of mines I do something like the following, in order to handle scenario that may happen with connection errors and reconnection attempts:

        async def listen_forever(self):
            while True:
            # outer loop restarted every time the connection fails
                try:
                    async with websockets.connect(self.url) as ws:
                        while True:
                        # listener loop
                            try:
                                reply = await asyncio.wait_for(ws.recv(), timeout=***)
                            except (asyncio.TimeoutError, websockets.exceptions.ConnectionClosed):
                                try:
                                    pong = await ws.ping()
                                    await asyncio.wait_for(pong, timeout=self.ping_timeout)
                                    logger.debug('Ping OK, keeping connection alive...')
                                    continue
                                except:
                                    await asyncio.sleep(self.sleep_time)
                                    break  # inner loop
                            # do stuff with reply object
                except socket.gaierror:
                    # log something
                    continue
                except ConnectionRefusedError:
                    # log something else
                    continue
    

    and I was wondering whether (1) this makes sense at all, and (2) there is any shortcut already provided in websockets to what seems quite a recurrent behavior (assuming that is correct!)

    enhancement high priority 
    opened by pgrandinetti 23
  • Websocket Server: Closing handshake failed in v10, v9.1 was ok

    Websocket Server: Closing handshake failed in v10, v9.1 was ok

    Hello Augustin, from version 10 occurs an error during closing browser tab connected to my websocket server. It occurs only in approximately 30% cases. But everything was ok in version 9.1.

    Tested in Google Chrome 94.

    Traceback:

    closing handshake failed
    Traceback (most recent call last):
      File "/usr/local/lib/python3.9/site-packages/websockets/legacy/server.py", line 232, in handler
        await self.close()
      File "/usr/local/lib/python3.9/site-packages/websockets/legacy/protocol.py", line 779, in close
        await asyncio.shield(self.close_connection_task)
      File "/usr/local/lib/python3.9/site-packages/websockets/legacy/protocol.py", line 1309, in close_connection
        self.transport.write_eof()
      File "/usr/local/lib/python3.9/asyncio/selector_events.py", line 972, in write_eof
        self._sock.shutdown(socket.SHUT_WR)
    OSError: [Errno 107] Socket not connected
    

    Websocket server simplified code:

    import asyncio
    import signal
    import websockets
    import sys
    
    
    class Chat(object):
    	async def process(self, websocket: websockets.WebSocketServerProtocol, path: str):
    		async for event in websocket:
    			print(event)
    			sys.stdout.flush()
    
    	__call__ = process
    
    
    async def server(stop):
    	async with websockets.serve(Chat(), "0.0.0.0", 8765):
    		await stop
    
    
    if __name__ == "__main__":
    	loop = asyncio.get_event_loop()
    	stop = loop.create_future()
    	loop.add_signal_handler(signal.SIGTERM, stop.set_result, None)
    	loop.run_until_complete(server(stop))
    
    

    Can you help me, please?

    Thanks a lot, Jaromir

    bug high priority 
    opened by chuckyblack 22
  • asyncio.streams.IncompleteReadError: 0 bytes read on a total of 2 expected bytes - unclear error reporting

    asyncio.streams.IncompleteReadError: 0 bytes read on a total of 2 expected bytes - unclear error reporting

    I'm not sure how to fix this error:

      Traceback (most recent call last):
        File "/root/src/streamer/stocks_producer.py", line 44, in <module>
          main()
        File "/root/src/streamer/stocks_producer.py", line 40, in main
          streamer.start()
        File "/root/src/streamer/polygon_streamer.py", line 67, in start
          self.loop.run_until_complete(asyncio.gather(*tasks))
        File "uvloop/loop.pyx", line 1451, in uvloop.loop.Loop.run_until_complete
        File "/root/src/streamer/polygon_streamer.py", line 47, in connect
          raise Exception(error_message)
      Exception: resetting connection: ()
      103 - 2019-02-13 15:30:14,095 - streamer.polygon_streamer - ERROR - resetting connection: ('WebSocket connection is closed: code = 1006 (connection closed abnormally [internal]), no reason',)
      Traceback (most recent call last):
        File "/opt/conda/lib/python3.7/site-packages/websockets/protocol.py", line 528, in transfer_data
          msg = yield from self.read_message()
        File "/opt/conda/lib/python3.7/site-packages/websockets/protocol.py", line 580, in read_message
          frame = yield from self.read_data_frame(max_size=self.max_size)
        File "/opt/conda/lib/python3.7/site-packages/websockets/protocol.py", line 645, in read_data_frame
          frame = yield from self.read_frame(max_size)
        File "/opt/conda/lib/python3.7/site-packages/websockets/protocol.py", line 710, in read_frame
          extensions=self.extensions,
        File "/opt/conda/lib/python3.7/site-packages/websockets/framing.py", line 100, in read
          data = yield from reader(2)
        File "/opt/conda/lib/python3.7/asyncio/streams.py", line 677, in readexactly
          raise IncompleteReadError(incomplete, n)
      asyncio.streams.IncompleteReadError: 0 bytes read on a total of 2 expected bytes
    

    here is my code snippet, thank you!

    async def connect(self):
    	while True:
    		async with websockets.connect(self.url, max_queue=8 * 2**10,) as websocket:
    			await websocket.send(json.dumps({"action": "auth", "params": self._api_key}))
    			await websocket.send(json.dumps({"action": "subscribe", "params": self._symbols_str}))
    			log.info("connected: {}".format(websocket.remote_address))
    			while(True):
    				try:
    					message_str = await asyncio.wait_for(websocket.recv(), timeout=self._timeout)
    					# await self.queue.put(message_str)
    					self.queue.put_nowait(message_str)
    				except asyncio.TimeoutError:
    					log.warn("timeout error - no data in {} seconds, pinging connection".format(self._timeout))
    					pong_waiter = await asyncio.wait_for(websocket.ping(data="keepalive"), timeout=self._timeout)
    					await asyncio.wait_for(pong_waiter, timeout=2 * self._timeout)
    					log.warn('ping/pong received, keeping connection alive...')
    				except Exception as e:
    					error_message = "resetting connection: {}".format(e.args)
    					log.error(error_message)
    					raise Exception(error_message)
    
    enhancement 
    opened by vgoklani 21
  • Any idea what might cause

    Any idea what might cause "Cannot call write() after write_eof()"?

    Traceback (most recent call last): File "/srv/locix/locix/websocket/server.py", line 184, in ping_handler await websocket.ping() File "/usr/local/lib/python3.5/dist-packages/websockets/protocol.py", line 433, in ping yield from self.write_frame(OP_PING, data) File "/usr/local/lib/python3.5/dist-packages/websockets/protocol.py", line 654, in write_frame extensions=self.extensions, File "/usr/local/lib/python3.5/dist-packages/websockets/framing.py", line 210, in write writer(output.getvalue()) File "/usr/lib/python3.5/asyncio/streams.py", line 294, in write self._transport.write(data) File "/usr/lib/python3.5/asyncio/selector_events.py", line 687, in write raise RuntimeError('Cannot call write() after write_eof()')

    bug has patch 
    opened by jacksonofalltrades 21
  • Bump pypa/cibuildwheel from 2.11.1 to 2.11.4

    Bump pypa/cibuildwheel from 2.11.1 to 2.11.4

    Bumps pypa/cibuildwheel from 2.11.1 to 2.11.4.

    Release notes

    Sourced from pypa/cibuildwheel's releases.

    v2.11.4

    • πŸ› Fix a bug that caused missing wheels on Windows when a test was skipped using CIBW_TEST_SKIP (#1377)
    • πŸ›  Updates CPython 3.11 to 3.11.1 (#1371)
    • πŸ›  Updates PyPy 3.7 to 3.7.10, except on macOS which remains on 7.3.9 due to a bug. (#1371)
    • πŸ“š Added a reference to abi3audit to the docs (#1347)

    v2.11.3

    • ✨ Improves the 'build options' log output that's printed at the start of each run (#1352)
    • ✨ Added a friendly error message to a common misconfiguration of the CIBW_TEST_COMMAND option - not specifying path using the {project} placeholder (#1336)
    • πŸ›  The GitHub Action now uses Powershell on Windows to avoid occasional incompabilities with bash (#1346)

    v2.11.2

    • πŸ›  Updates CPython 3.11 to 3.11.0 - final release (#1327)
    • πŸ›  Simplify the default macOS repair command (#1322)
    • πŸ›  Fix the default MACOSX_DEPLOYMENT_TARGET on arm64 (#1312)
    • πŸ›  Hide irrelevant pip warnings on linux (#1311)
    • πŸ› Fix a bug that caused the stdout and stderr of commands in containers to be in the wrong order Previously, stdout could appear after stderr. (#1324)
    • πŸ“š Added a FAQ entry describing how to perform native builds of CPython 3.8 wheels on Apple Silicon. (#1323)
    • πŸ“š Other docs improvements
    Changelog

    Sourced from pypa/cibuildwheel's changelog.

    v2.11.4

    24 Dec 2022

    • πŸ› Fix a bug that caused missing wheels on Windows when a test was skipped using CIBW_TEST_SKIP (#1377)
    • πŸ›  Updates CPython 3.11 to 3.11.1 (#1371)
    • πŸ›  Updates PyPy to 7.3.10, except on macOS which remains on 7.3.9 due to a bug on that platform. (#1371)
    • πŸ“š Added a reference to abi3audit to the docs (#1347)

    v2.11.3

    5 Dec 2022

    • ✨ Improves the 'build options' log output that's printed at the start of each run (#1352)
    • ✨ Added a friendly error message to a common misconfiguration of the CIBW_TEST_COMMAND option - not specifying path using the {project} placeholder (#1336)
    • πŸ›  The GitHub Action now uses Powershell on Windows to avoid occasional incompabilities with bash (#1346)

    v2.11.2

    26 October 2022

    • πŸ›  Updates CPython 3.11 to 3.11.0 - final release (#1327)
    • πŸ›  Simplify the default macOS repair command (#1322)
    • πŸ›  Fix the default MACOSX_DEPLOYMENT_TARGET on arm64 (#1312)
    • πŸ›  Hide irrelevant pip warnings on linux (#1311)
    • πŸ› Fix a bug that caused the stdout and stderr of commands in containers to be in the wrong order Previously, stdout could appear after stderr. (#1324)
    • πŸ“š Added a FAQ entry describing how to perform native builds of CPython 3.8 wheels on Apple Silicon. (#1323)
    • πŸ“š Other docs improvements
    Commits
    • 27fc88e Bump version: v2.11.4
    • a7e9ece Merge pull request #1371 from pypa/update-dependencies-pr
    • b9a3ed8 Update cibuildwheel/resources/build-platforms.toml
    • 3dcc2ff fix: not skipping the tests stops the copy (Windows ARM) (#1377)
    • 1c9ec76 Merge pull request #1378 from pypa/henryiii-patch-3
    • 22b433d Merge pull request #1379 from pypa/pre-commit-ci-update-config
    • 98fdf8c [pre-commit.ci] pre-commit autoupdate
    • cefc5a5 Update dependencies
    • e53253d ci: move to ubuntu 20
    • e9ecc65 [pre-commit.ci] pre-commit autoupdate (#1374)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • The answer of

    The answer of "How can I pass arguments to a custom protocol subclass?" in docs can't work on Python 3.10

    https://websockets.readthedocs.io/en/stable/faq/common.html#how-can-i-pass-arguments-to-a-custom-protocol-subclass The code did't work on Python 3.10 now.

    Here is a example about the reson behind:

    import functools
    class a:
        def __init__(self,extra_argument,*args,**kwargs):
            print(extra_argument)
            print(args)
            print(kwargs)
    A=functools.partial(a,extra_argument=1)
    hello=A(2)
    

    The output is:

    Traceback (most recent call last):
      File "/home/***/test.py", line 8, in <module>
        hello=A(2)
    TypeError: a.__init__() got multiple values for argument 'extra_argument'
    

    Maybe this way is outdated?

    documentation 
    opened by chinese-wzq 1
  • Refactor create_protocol to represent the real type

    Refactor create_protocol to represent the real type

    [Any] means one argument of Any type, ... means "ignore". This is relevant since WebSocketServerProtocol and similar in fact have multiple arguments. Ideally a Protocol with a __call__ method included should be used, but that's up for discussion since that would add maintainability issues as the signature would be duplicated in multiple places.

    opened by ooliver1 0
  • Regarding websocket library selection

    Regarding websocket library selection

    Can we please publish a document or update in ReadMe about

    How to make a choice between websockets and websocket-client

    If we can get elaborated comments on the downsides and upsides of using one over the other, it will be very helpful.

    documentation 
    opened by tushargoyal22 3
  • Add CIFuzz GitHub action

    Add CIFuzz GitHub action

    Add CIFuzz workflow action to have fuzzers build and run on each PR.

    This is a service offered by OSS-Fuzz where websockets was recently integrated. CIFuzz can help detect regressions and catch fuzzing build issues early, and has a variety of features (see the URL above). In the current PR the fuzzers gets build on a pull request and will run for 300 seconds.

    opened by DavidKorczynski 1
An abstract and extensible framework in python for building client SDKs and CLI tools for a RESTful API.

django-rest-client An abstract and extensible framework in python for building client SDKs and CLI tools for a RESTful API. Suitable for APIs made wit

Certego 4 Aug 25, 2022
Sierra is a lightweight Python framework for building and integrating web applications

A lightweight Python framework for building and Integrating Web Applications. Sierra is a Python3 library for building and integrating web applications with HTML and CSS using simple enough syntax. You can develop your web applications with Python, taking advantage of its functionalities and integrating them to the fullest.

null 83 Sep 23, 2022
Flask Sugar is a web framework for building APIs with Flask, Pydantic and Python 3.6+ type hints.

Flask Sugar is a web framework for building APIs with Flask, Pydantic and Python 3.6+ type hints. check parameters and generate API documents automatically. Flask Sugarζ˜―δΈ€δΈͺ基于flask,pyddantic,η±»εž‹ζ³¨θ§£ηš„APIζ‘†ζžΆ, 可δ»₯ζ£€ζŸ₯参数幢θ‡ͺεŠ¨η”ŸζˆAPIζ–‡ζ‘£

null 162 Dec 26, 2022
The Python micro framework for building web applications.

Flask Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to co

The Pallets Projects 61.5k Jan 6, 2023
A high-level framework for building GitHub applications in Python.

A high-level framework for building GitHub applications in Python. Core Features Async Proper ratelimit handling Handles interactions for you (

Vish M 3 Apr 12, 2022
A comprehensive reference for all topics related to building and maintaining microservices

This pandect (πανδέκτης is Ancient Greek for encyclopedia) was created to help you find and understand almost anything related to Microservices that i

Ivan Bilan 64 Dec 9, 2022
Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed.

Tornado Web Server Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed. By using non-blocking ne

null 20.9k Jan 1, 2023
An effective, simple, and async security library for the Sanic framework.

Sanic Security An effective, simple, and async security library for the Sanic framework. Table of Contents About the Project Getting Started Prerequis

Sunset Dev 72 Nov 30, 2022
The comprehensive WSGI web application library.

Werkzeug werkzeug German noun: "tool". Etymology: werk ("work"), zeug ("stuff") Werkzeug is a comprehensive WSGI web application library. It began as

The Pallets Projects 6.2k Jan 1, 2023
The no-nonsense, minimalist REST and app backend framework for Python developers, with a focus on reliability, correctness, and performance at scale.

The Falcon Web Framework Falcon is a reliable, high-performance Python web framework for building large-scale app backends and microservices. It encou

Falconry 9k Jan 1, 2023
The Modern And Developer Centric Python Web Framework. Be sure to read the documentation and join the Slack channel questions: http://slack.masoniteproject.com

NOTE: Masonite 2.3 is no longer compatible with the masonite-cli tool. Please uninstall that by running pip uninstall masonite-cli. If you do not unin

Masonite 1.9k Jan 4, 2023
Free and open source full-stack enterprise framework for agile development of secure database-driven web-based applications, written and programmable in Python.

Readme web2py is a free open source full-stack framework for rapid development of fast, scalable, secure and portable database-driven web-based applic

null 2k Dec 31, 2022
Ape is a framework for Web3 Python applications and smart contracts, with advanced functionality for testing, deployment, and on-chain interactions.

Ape Framework Ape is a framework for Web3 Python applications and smart contracts, with advanced functionality for testing, deployment, and on-chain i

ApeWorX Ltd. 552 Dec 30, 2022
Bionic is Python Framework for crafting beautiful, fast user experiences for web and is free and open source

Bionic is fast. It's powered core python without any extra dependencies. Bionic offers stateful hot reload, allowing you to make changes to your code and see the results instantly without restarting your app or losing its state.

 βš“ 0 Mar 5, 2022
A Python package to easily create APIs in Python.

API_Easy An Python Package for easily create APIs in Python pip install easy-api-builder Requiremnets: <= python 3.6 Required modules --> Flask Docume

Envyre-Coding 2 Jan 4, 2022
Asynchronous HTTP client/server framework for asyncio and Python

Async http client/server framework Key Features Supports both client and server side of HTTP protocol. Supports both client and server Web-Sockets out

aio-libs 13.2k Jan 5, 2023
Fast, asynchronous and elegant Python web framework.

Warning: This project is being completely re-written. If you're curious about the progress, reach me on Slack. Vibora is a fast, asynchronous and eleg

vibora.io 5.7k Jan 8, 2023
Screaming-fast Python 3.5+ HTTP toolkit integrated with pipelining HTTP server based on uvloop and picohttpparser.

Japronto! There is no new project development happening at the moment, but it's not abandoned either. Pull requests and new maintainers are welcome. I

PaweΕ‚ Piotr Przeradowski 8.6k Dec 29, 2022
bottle.py is a fast and simple micro-framework for python web-applications.

Bottle: Python Web Framework Bottle is a fast, simple and lightweight WSGI micro web-framework for Python. It is distributed as a single file module a

Bottle Micro Web Framework 7.8k Dec 31, 2022