# websocket-client: a low-level WebSocket client for Python

> websocket-client gives Python code direct access to the WebSocket framing layer, with callbacks, a run_forever loop and optional C accelerators. It is a good fit for scripted clients and protocol work, and a poor fit if you want compression or a managed reconnect story out of the box.

**websocket-client/websocket-client** — WebSocket client for Python

- Repository: https://github.com/websocket-client/websocket-client
- Website: https://websocket-client.readthedocs.io/
- Stars: 3,709 · Forks: 780
- Language: Python
- License: Apache-2.0
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/websocket-client-websocket-client

## What websocket-client is for, and who should reach for it

The README describes websocket-client as a WebSocket client for Python that "provides access to low level APIs for WebSockets" and implements version hybi-13 of the protocol. That phrase, low level, is the whole positioning. This is not a framework that hides the connection lifecycle behind an async context manager. It is a library that lets you open a socket, send frames, register callbacks and decide for yourself what happens when the connection drops.

The audience follows from that. If you are writing a script that talks to a market data feed, a device that speaks WebSocket, or a server you are debugging, the short-lived API is a handful of lines. If you are building a long-running subscriber that must survive network loss, WebSocketApp and its run_forever loop are the intended entry point. If you are writing an async service on top of asyncio, this is probably not the library you want, because the documented model is callback-based and the project itself flags threading as a weak spot.

One detail worth noticing: the package metadata lists zero install_requires. A plain install pulls in nothing beyond the standard library. That is unusual for a protocol client and it is a real reason to choose this over heavier alternatives when dependency surface matters.

## The mechanism: create_connection versus WebSocketApp

There are two distinct entry points and they map to two different lifetimes.

The short-lived path uses create_connection, which returns a connected socket object. You call recv to read a message and send to write one, then close. The README's own example connects to ws://echo.websocket.events/, prints the greeting, sends "Hello, World", reads the reply and closes. Nothing is buffered behind a callback; control flow is yours.

The long-lived path uses WebSocketApp, which wraps the connection in an event loop. You supply on_open, on_message, on_error and on_close callbacks, then call run_forever. According to the README, run_forever will automatically try to reconnect when a network connection is lost, but only if it is given a dispatcher argument (an async dispatcher such as rel or pyevent) and a non-zero reconnect argument, which is the delay between disconnection and the reconnection attempt.

That conditional is the part people miss. The README states plainly that run_forever does not automatically reconnect if the server closes the WebSocket gracefully with a standard close code, and that customizing behaviour for that case belongs in on_close. The project links to a pull request comment explaining the reasoning. So the reconnect machinery covers transport failure, not a clean server-side shutdown, and you are expected to write the latter yourself.

## Installing websocket-client and running a first connection

Installation is a single pip command, and the README notes the module is tested on Python 3.10 and above. The package metadata agrees, declaring python_requires >=3.10.

```bash
pip install websocket-client
```

The README also documents editable installs from a local copy with pip install -e ., and warns that some shells, zsh in particular, require escaping the square brackets in the extras syntax. Optional dependency groups are defined: optional brings in python-socks for proxy support and wsaccel for a performance boost; test brings in pytest and websockets to run the unit tests against a local echo server; docs brings in Sphinx, sphinx_rtd_theme and myst-parser.

```bash
pip install websocket-client[optional]
```

For a first real use, the shortest useful program is the echo test from the README. It confirms the server is reachable and that framing works end to end.

```python
from websocket import create_connection

ws = create_connection("ws://echo.websocket.events/")
print(ws.recv())
print("Sending 'Hello, World'...")
ws.send("Hello, World")
print("Sent")
print("Receiving...")
result = ws.recv()
print("Received '%s'" % result)
ws.close()
```

You should see the server's initial greeting, the three progress lines, and then your own message echoed back. If the connection fails, the exception surfaces from create_connection rather than from a callback, which makes this form easier to debug than the WebSocketApp form.

## Reconnection needs rel, and graceful closes are your problem

The README's long-lived example is the one to read closely, because it shows how much wiring the library expects from you. It imports rel, defines the four callbacks, sets websocket.enableTrace(True), constructs WebSocketApp against wss://api.gemini.com/v1/marketdata/BTCUSD, and then calls run_forever with dispatcher=rel and reconnect=5. The final two lines register a SIGINT handler through rel.signal(2, rel.abort) and hand control to rel.dispatch().

```python
ws.run_forever(dispatcher=rel, reconnect=5)
rel.signal(2, rel.abort)
rel.dispatch()
```

So automatic reconnection is not a property of the library on its own. It is a property of the library plus a dispatcher. rel is described in the README as useful rather than required, and it is not in install_requires; you install it separately. That is a deliberate design choice, and it has a cost: the reconnect behaviour you get depends on which dispatcher you pick, and the library does not ship one.

The second half of the same constraint is the graceful-close rule. A server that sends a standard close code ends the connection, and run_forever will not bring it back. If your upstream restarts on a schedule, or closes idle sessions, you will see the connection stop and stay stopped unless on_close does something about it. The README points at on_close as the place for that logic. This is the single most common way a working prototype becomes a silent production failure.

## No permessage-deflate: the compression gap and what it costs

The README states that websocket-client does not currently support the permessage-deflate extension from RFC 7692. It repeats this under known issues, alongside minimal threading documentation and support.

This matters more than it sounds. Servers that negotiate permessage-deflate compress payloads on the wire. A client that cannot negotiate it will either connect without compression or fail the handshake, depending on how the server is configured. For high-volume text feeds, that is a bandwidth difference you cannot tune away from the client side. If your use case is a chat client sending short messages, the gap is irrelevant. If it is a market data or telemetry stream, it is a real constraint and you should confirm the server's behaviour before building on this library.

The threading note is the second gap and it is less concrete. The README labels threading documentation and support as minimal and links to a documentation page on the subject. If your design assumes a documented thread-safety contract for concurrent sends, that contract is not spelled out in the README. Treat it as something to verify against the documentation rather than assume.

## Performance knobs: skip_utf8_validation and wsaccel

The README is unusually candid here. It names send and validate_utf8 as methods that "can sometimes be bottleneck", and lists three levers.

First, the skip_utf8_validation parameter disables UTF-8 validation in the library, which the README says brings a performance enhancement. That is a correctness trade: you are telling the library not to check that outgoing text is valid UTF-8. Only do this when you control the payload and know it is valid.

Second, wsaccel. It is optional, not a dependency, and will be used if available. The README gives specific figures: wsaccel doubles the speed of UTF8 validation and offers a very minor 10% performance boost when masking payload data as part of send. Those numbers come from the project, not from independent measurement, and the gain is concentrated in validation rather than in send itself.

Third, a negative result. The README records that Numpy used to be suggested as a performance enhancement alternative, but issue #687 found it did not help. That kind of retraction is rare in a README and it is worth taking at face value: installing Numpy for this library's sake is not indicated.

## websocket-client versus websockets, and how to choose

The comparison people actually search for is websocket-client against websockets, the other widely used Python WebSocket library. The README does not compare them, but the repository does expose one concrete relationship: websockets appears in the test extra, used to run unit tests against a local echo server. The two libraries coexist in this project's own tooling.

The difference in approach is the API model. websocket-client presents a synchronous, callback-driven client with a low-level API, and its long-lived loop is run_forever with a dispatcher for reconnection. The websockets project is built around asyncio coroutines. If your application already runs an event loop, the coroutine style is a better structural match, and you avoid bridging a callback loop into async code. If your application is a plain script, a thread, or a tool that polls a socket and moves on, websocket-client's synchronous calls are simpler to reason about.

The second axis is dependencies. websocket-client declares no install_requires, so a plain install adds nothing. Extras are opt-in. That is a meaningful difference for packaged applications, CLI tools and anything with a tight dependency budget. Note also that websocket-client is not a server; the name describes a client, and the README frames the project entirely around connecting out.

## Licence, release cadence and upgrade cost

websocket-client is licensed under Apache-2.0, and the setup.py header carries the standard Apache notice. The classifier in the package metadata reads Development Status :: 4 - Beta, which is worth knowing before you treat the API as frozen, even though the version number is past 1.9. Apache-2.0 includes an explicit patent grant and requires preservation of notices; if you redistribute the library or a modified copy, read the LICENSE file rather than relying on a summary. Nothing here is legal advice.

The recent release history shows v1.9.0 on 2025-10-07, then v1.9.1 on 2026-08-29 and v1.9.2 on 2026-08-31. The last push to the repository was on 2026-08-31. That pattern, a long quiet stretch followed by two releases two days apart, is consistent with a maintenance release pair rather than continuous churn. The repository is not archived.

Upgrade cost is low by construction. With no required dependencies, an upgrade cannot drag transitive packages along with it. The risks that remain are behavioural: the callback contract for on_close, the reconnect semantics tied to your dispatcher, and any reliance on skip_utf8_validation. The repository includes a ChangeLog file, so pinning a version and reading that file before moving is the practical path. For a library at Beta status, that is the check that matters.

## Conclusion

Adopt websocket-client when you need a small, dependency-free client that exposes the WebSocket frame layer and callback model, and when you are willing to handle reconnection, compression and threading yourself. Do not adopt it if permessage-deflate is a requirement, if you want a managed reconnection loop without pulling in a dispatcher such as rel, or if you expect the threading model to be spelled out in the documentation. Before committing, verify that your Python version is 3.10 or newer, confirm which optional extras you actually need (python-socks, wsaccel), and read the on_close callback semantics, because run_forever will not reconnect after a graceful server close.

## FAQ

### How do I install websocket-client?

Run pip install websocket-client. The README also documents pip install -e . to install from a local copy of the code, and notes the module is tested on Python 3.10 and above.

### How do I use websocket-client for a short message and then disconnect?

Use create_connection to get a socket, then call send and recv directly and close when finished. The README's example connects to ws://echo.websocket.events/, sends "Hello, World", reads the reply and calls ws.close().

### What is the difference between a websocket-client and a WebSocket server?

websocket-client is a client library: it connects out to a WebSocket endpoint, as in the README's create_connection call against a remote URL. The README describes the project only in terms of connecting, sending and receiving, and does not present it as a server implementation.

### websocket client vs websockets in Python: which should I use?

websocket-client exposes a low-level API with a callback model and a run_forever loop, and declares no required dependencies. The websockets package is used in this project's own test extra to run unit tests against a local echo server, which shows the two can coexist in one toolchain.

### What is websocket-client and who is it for?

It is a WebSocket client for Python that provides access to low level APIs, implementing version hybi-13 of the protocol. It suits scripted clients and protocol work rather than async services built on asyncio.

## Sources

- [License: Apache-2.0](https://github.com/websocket-client/websocket-client/blob/master/LICENSE)
- [Project website](https://websocket-client.readthedocs.io/)
- [README](https://github.com/websocket-client/websocket-client/blob/master/README.md)
- [Releases](https://github.com/websocket-client/websocket-client/releases)
- [websocket-client/websocket-client on GitHub](https://github.com/websocket-client/websocket-client)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/websocket-client-websocket-client
