Skip to content
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
282 lines (185 sloc) 6.55 KB

Getting started:


This documentation is written for Python ≥ 3.5. If you’re using Python 3.4, you will have to adapt the code samples.


  • websockets requires Python ≥ 3.4. Install it with:
pip install websockets

Basic example:

  • This section assumes Python ≥ 3.5. For older versions, read below. Here’s a WebSocket server example. It reads a name from the client, sends a greeting, and closes the connection.
#!/usr/bin/env python

import asyncio
import websockets

async def hello(websocket, path):
    name = await websocket.recv()
    print("< {}".format(name))

    greeting = "Hello {}!".format(name)
    await websocket.send(greeting)
    print("> {}".format(greeting))

start_server = websockets.serve(hello, 'localhost', 8765)

  • On the server side, the handler coroutine hello is executed once for each WebSocket connection. The connection is automatically closed when the handler returns.

Here’s a corresponding client example.

#!/usr/bin/env python

import asyncio
import websockets

async def hello():
    async with websockets.connect('ws://localhost:8765') as websocket:
        name = input("What's your name? ")
        await websocket.send(name)
        print("> {}".format(name))

        greeting = await websocket.recv()
        print("< {}".format(greeting))

  • async and await aren’t available in Python < 3.5. Here’s how to adapt the client example for older Python versions.
#!/usr/bin/env python

import asyncio
import websockets

def hello():
    websocket = yield from websockets.connect('ws://localhost:8765/')

        name = input("What's your name? ")
        yield from websocket.send(name)
        print("> {}".format(name))

        greeting = yield from websocket.recv()
        print("< {}".format(greeting))

        yield from websocket.close()


Browser-based example:

  • Here’s an example of how to run a WebSocket server and connect from a browser. Run this script in a console:
#!/usr/bin/env python

import asyncio
import datetime
import random
import websockets

async def time(websocket, path):
    while True:
        now = datetime.datetime.utcnow().isoformat() + 'Z'
        await websocket.send(now)
        await asyncio.sleep(random.random() * 3)

start_server = websockets.serve(time, '', 5678)

  • Then open this HTML file in a browser.
<!DOCTYPE html>
        <title>WebSocket demo</title>
            var ws = new WebSocket("ws://"),
                messages = document.createElement('ul');
            ws.onmessage = function (event) {
                var messages = document.getElementsByTagName('ul')[0],
                    message = document.createElement('li'),
                    content = document.createTextNode(;

Common patterns:

You will usually want to process several messages during the lifetime of a connection. Therefore you must write a loop. Here are the basic patterns for building a WebSocket server.


  • For receiving messages and passing them to a consumer coroutine:
async def consumer_handler(websocket, path):
    async for message in websocket:
        await consumer(message)

Iteration terminates when the client disconnects.

Asynchronous iteration isn’t available in Python < 3.6; here’s the same code for earlier Python versions:

async def consumer_handler(websocket, path):
    while True:
        message = await websocket.recv()
        await consumer(message)

recv() raises a ConnectionClosed exception when the client disconnects, which breaks out of the while True loop.


For getting messages from a producer coroutine and sending them:

async def producer_handler(websocket, path):
    while True:
        message = await producer()
        await websocket.send(message)

send() raises a ConnectionClosed exception when the client disconnects, which breaks out of the while True loop.


You can read and write messages on the same connection by combining the two patterns shown above and running the two tasks in parallel:

async def handler(websocket, path):
    consumer_task = asyncio.ensure_future(consumer_handler(websocket))
    producer_task = asyncio.ensure_future(producer_handler(websocket))
    done, pending = await asyncio.wait(
        [consumer_task, producer_task],

    for task in pending:


If you need to maintain a list of currently connected clients, you must register clients when they connect and unregister them when they disconnect.

connected = set()

async def handler(websocket, path):
    global connected
    # Register.
        # Implement logic here.
        await asyncio.wait([ws.send("Hello!") for ws in connected])
        await asyncio.sleep(10)
        # Unregister.

This simplistic example keeps track of connected clients in memory. This only works as long as you run a single process. In a practical application, the handler may subscribe to some channels on a message broker, for example.

That’s all!

The design of the websockets API was driven by simplicity.

You don’t have to worry about performing the opening or the closing handshake, answering pings, or any other behavior required by the specification.

websockets handles all this under the hood so you don’t have to.

Python < 3.5

  • This documentation uses the await and async syntax introduced in Python 3.5. If you’re using Python 3.4, you must substitute:
async def ...


def ...


await ...


yield from ...

Otherwise you will encounter a SyntaxError.

Have fun... ;)

You can’t perform that action at this time.