Skip to main content

pysignalr

GitHub stars Latest stable release PyPI - Python Version License: MIT
PyPI monthly downloads GitHub issues GitHub pull requests

pysignalr is a modern, reliable, and async-ready client for the SignalR protocol. This project started as an asyncio fork of mandrewcito's signalrcore library and ended up as a complete rewrite.

Table of Contents

  1. Installation
  2. Basic Usage
  3. Usage with Token Authentication
  4. API Reference
  5. Contributors
  6. License

Installation

To install pysignalr, simply use pip:

pip install pysignalr

Basic Usage

Let's connect to TzKT, an API and block explorer of Tezos blockchain, and subscribe to all operations:

from __future__ import annotations

import asyncio
from contextlib import suppress
from typing import TYPE_CHECKING
from typing import Any

from pysignalr.client import SignalRClient

if TYPE_CHECKING:
    from pysignalr.messages import CompletionMessage


async def on_open() -> None:
    print('Connected to the server')


async def on_close() -> None:
    print('Disconnected from the server')


async def on_message(message: list[dict[str, Any]]) -> None:
    print(f'Received message: {message}')


async def on_client_result(message: list[dict[str, Any]]) -> str:
    """The server can request a result from a client.

    Requires the server to use ISingleClientProxy.InvokeAsync and the client
    to return a result from its .On handler.
    See: https://learn.microsoft.com/en-us/aspnet/core/signalr/hubs?view=aspnetcore-9.0#client-results
    """
    print(f'Received message: {message}')
    return 'reply'


async def on_error(message: CompletionMessage) -> None:
    print(f'Received error: {message.error}')


async def main() -> None:
    client = SignalRClient('https://api.tzkt.io/v1/ws')

    client.on_open(on_open)
    client.on_close(on_close)
    client.on_error(on_error)
    client.on('operations', on_message)
    client.on('client_result', on_client_result)

    await asyncio.gather(
        client.run(),
        client.send('SubscribeToOperations', [{}]),
    )


with suppress(KeyboardInterrupt, asyncio.CancelledError):
    asyncio.run(main())

Usage with Token Authentication

To connect to the SignalR server using token authentication:

from __future__ import annotations

import asyncio
from contextlib import suppress
from typing import TYPE_CHECKING
from typing import Any

from pysignalr.client import SignalRClient

if TYPE_CHECKING:
    from pysignalr.messages import CompletionMessage


async def on_open() -> None:
    print('Connected to the server')


async def on_close() -> None:
    print('Disconnected from the server')


async def on_message(message: list[dict[str, Any]]) -> None:
    print(f'Received message: {message}')


async def on_client_result(message: list[dict[str, Any]]) -> str:
    """The server can request a result from a client.

    Requires the server to use ISingleClientProxy.InvokeAsync and the client
    to return a result from its .On handler.
    See: https://learn.microsoft.com/en-us/aspnet/core/signalr/hubs?view=aspnetcore-9.0#client-results
    """
    print(f'Received message: {message}')
    return 'reply'


async def on_error(message: CompletionMessage) -> None:
    print(f'Received error: {message.error}')


def token_factory() -> str:
    # Replace with logic to fetch or generate the token
    return 'your_access_token_here'


async def main() -> None:
    client = SignalRClient(
        url='https://api.tzkt.io/v1/ws',
        access_token_factory=token_factory,
        headers={'mycustomheader': 'mycustomheadervalue'},
    )

    client.on_open(on_open)
    client.on_close(on_close)
    client.on_error(on_error)
    client.on('operations', on_message)
    client.on('client_result', on_client_result)

    await asyncio.gather(
        client.run(),
        client.send('SubscribeToOperations', [{}]),
    )


with suppress(KeyboardInterrupt, asyncio.CancelledError):
    asyncio.run(main())

API Reference

SignalRClient

Parameters

Parameter Type Default Description
url str required The SignalR server URL
protocol Protocol | None JSONProtocol() Protocol for message encoding/decoding
headers dict[str, str] | None None Additional headers for the WebSocket handshake
ping_interval int 10 Keepalive ping interval in seconds
connection_timeout int 10 Connection timeout in seconds
max_size int | None 1048576 Maximum WebSocket message size (1 MB)
retry_sleep float 1 Initial retry delay in seconds
retry_multiplier float 1.1 Exponential backoff multiplier
retry_count int 10 Maximum number of retries
access_token_factory Callable[[], str] | None None Function that returns an access token
ssl ssl.SSLContext | None None Custom SSL context

Methods

  • run(): Run the client, managing the connection lifecycle.
  • on(event, callback): Register a callback for a specific event. If the callback returns a value, it is sent back as a CompletionMessage (client results).
  • on_open(callback): Register a callback for connection open events.
  • on_close(callback): Register a callback for connection close events.
  • on_error(callback): Register a callback for error events.
  • send(method, arguments, on_invocation=None): Send a message to the server. Without on_invocation, sends a non-blocking (fire-and-forget) invocation. With a callback, tracks the invocation and routes the server's completion response to it.
  • stream(event, event_params, on_next=None, on_complete=None, on_error=None): Start a server-to-client streaming invocation.
  • client_stream(target): Async context manager for client-to-server streaming. Use await stream.send(item) inside the context.

CompletionMessage

A message received from the server upon completion of a method invocation.

Attributes

  • invocation_id (str | None): The ID of the invocation.
  • result (Any | None): The result of the invocation, if any.
  • error (str | None): The error message, if the invocation failed.

Contributors

License

This project is licensed under the MIT License - see the LICENSE file for details.

Metadata

Release files for pysignalr 1.3.3

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

Source distribution (sdist)

Source distribution for pysignalr 1.3.3
File Size Uploaded Provenance
pysignalr-1.3.3.tar.gz 239.0 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for pysignalr 1.3.3
File Interpreter ABI Platform
pysignalr-1.3.3-py3-none-any.whl Python 3 none any Details

Total release size: 262.0 kB

Release files / pysignalr-1.3.3.tar.gz

Download URL pysignalr-1.3.3.tar.gz
Size 239.0 kB
Tags Source
SHA-256 checksum
How to use checksums
d5bb0676f087a06e0ae8177b5791bf060f0f6546658707bb7de290c92da3052b
BLAKE2b-256 checksum
How to use checksums
6190991c2069ea98b6328a87a2380dea6c957cbe81b7954eddbcbf0bff5d62d6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / pysignalr-1.3.3-py3-none-any.whl

Download URL pysignalr-1.3.3-py3-none-any.whl
Size 23.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5012af69a812eb0b8d725b1b8ca075ec1cc8633706da4239012ab7a76b83b23b
BLAKE2b-256 checksum
How to use checksums
59eadc88c56f80c0dfc3649948b1a768592a6e61b27623e88cce655da4ffc609
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for pysignalr 1.3.3

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.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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