Skip to main content

centrifuge-python

CI pypi versions license

This is a WebSocket real-time SDK for Centrifugo server (and any Centrifuge-based server) on top of Python asyncio library.

Before starting to work with this library check out Centrifugo client SDK API specification as it contains common information about Centrifugal real-time SDK behavior. This SDK supports all major features of Centrifugo client protocol - see SDK feature matrix.

Install

pip install centrifuge-python

Then in your code:

from centrifuge import Client

See example code and how to run it locally.

JSON vs Protobuf protocols

By default, SDK uses JSON protocol. If you want to use Protobuf protocol instead then pass use_protobuf=True option to Client constructor.

When using JSON protocol:

  • all payloads (data to publish, connect/subscribe data) you pass to the library are encoded to JSON internally using json.dumps before sending to server. So make sure you pass only JSON-serializable data to the library.
  • all payloads received from server are decoded to Python objects using json.loads internally before passing to your code.

When using Protobuf protocol:

  • all payloads you pass to the library must be bytes or None if optional. If you pass non-bytes data – exception will be raised.
  • all payloads received from the library will be bytes or None if not present.
  • don't forget that when using Protobuf protocol you can still have JSON payloads - just encode them to bytes before passing to the library.

Custom TLS configuration

When connecting to a wss:// endpoint the SDK uses the default TLS context of the ssl module – i.e. server certificates are verified against the system CA store. To customize TLS – for example to trust a custom CA – pass your own ssl.SSLContext as ssl_context option:

import ssl

ssl_ctx = ssl.create_default_context(cafile="/path/to/ca.pem")

client = Client(
    "wss://localhost:8000/connection/websocket",
    ssl_context=ssl_ctx,
)

The same option allows disabling certificate verification entirely – only do this for local development, never in production:

import ssl

ssl_ctx = ssl.create_default_context()
ssl_ctx.check_hostname = False
ssl_ctx.verify_mode = ssl.CERT_NONE

client = Client(
    "wss://localhost:8000/connection/websocket",
    ssl_context=ssl_ctx,
)

Connecting through a proxy

By default the proxy configuration is taken from the environment (WS_PROXY/WSS_PROXY, HTTP_PROXY/HTTPS_PROXY, honoring NO_PROXY). To set the proxy explicitly – use proxy option of Client constructor:

client = Client(
    "ws://localhost:8000/connection/websocket",
    proxy="http://user:pass@proxy-host:3128",
)

Pass proxy=None to always connect directly, ignoring the environment configuration.

SOCKS proxies (socks5://...) are supported too, but require the python-socks package to be installed:

pip install python-socks

Invalid proxy URLs and a missing python-socks package are reported as ValueError from the Client constructor, rather than in the middle of connecting.

A couple of things to keep in mind when going through a proxy:

  • with a wss:// address the proxy only sees the CONNECT host:port request – the WebSocket traffic inside the tunnel stays encrypted end to end, and the server certificate is still verified as usual. With a ws:// address the proxy sees everything, including the connection token.
  • credentials in an http:// proxy URL are sent to the proxy as a base64-encoded Proxy-Authorization header over an unencrypted connection. They are never forwarded to the Centrifugo server, but use an https:// proxy if the proxy connection itself may be observed.

Callbacks should not block

Event callbacks are called by SDK using await internally, the websocket connection read loop is blocked for the time SDK waits for the callback to be executed. This means that if you need to perform long operations in callbacks consider moving the work to a separate coroutine/task to return fast and continue reading data from the websocket.

The fact WebSocket read is blocked for the time we execute callbacks means that you can not call awaitable SDK APIs from callback – because SDK does not have a chance to read the reply. You will get OperationTimeoutError exception. The rule is the same - do the work asynchronously, for example use asyncio.ensure_future.

Callbacks should not raise

Callbacks are awaited as part of the SDK's own flow, so handle errors inside the callback. The SDK can't know what a callback that raised left undone, so it fails loudly instead of going on as if nothing happened, as centrifuge-js does:

  • the exception is passed to the event loop's exception handler (loop.call_exception_handler; the default one logs it), and not raised to the caller of connect(), subscribe() or unsubscribe();
  • the client disconnects with code 2 ("bad protocol") and the reason exception in event handler: ..., and doesn't reconnect. Call connect() to start again;
  • the SDK's own work completes as if the callback had returned, so the client is left in a consistent state;
  • a publication whose callback raised doesn't count as delivered: after connect(), a recoverable subscription receives it again.

Keep an eye on error logs.

Run example

To run example, first start Centrifugo – the docker-compose.yml of this repo configures everything the example needs (it's the same server the tests use):

docker compose up

And then:

python -m venv env
. env/bin/activate
make dev
python example.py

Run tests

To run tests locally, start test Centrifugo server:

docker compose up

Then:

python -m venv env
. env/bin/activate
make dev
make test

Metadata

Release files for centrifuge-python 0.7.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for centrifuge-python 0.7.0
File Size Uploaded Provenance
centrifuge_python-0.7.0.tar.gz 97.0 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for centrifuge-python 0.7.0
File Interpreter ABI Platform
centrifuge_python-0.7.0-py3-none-any.whl Python 3 none any Details

Total release size: 141.5 kB

Release files / centrifuge_python-0.7.0.tar.gz

Download URL centrifuge_python-0.7.0.tar.gz
Size 97.0 kB
Tags Source
SHA-256 checksum
How to use checksums
11252b45c3f6b6104cfb07fb0fcfc9d2d62832d2af14715dd16fdc5e9c6e5964
BLAKE2b-256 checksum
How to use checksums
5b86c25886d114d2030af6b3c316ad6d73d429a22f818f06f2c2f6c65710ab68
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / centrifuge_python-0.7.0-py3-none-any.whl

Download URL centrifuge_python-0.7.0-py3-none-any.whl
Size 44.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a60741e28d34644aa4b5a7b58ab04d36941821512177ce7e04c45b1b887588e8
BLAKE2b-256 checksum
How to use checksums
74b42c508b18972448fc80e035cb82c435719fe81ba830a604f00dc4fc18fc86
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Security for centrifuge-python 0.7.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page