Skip to main content

Modern, reliable and async-ready client for SignalR protocol

Project description

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pysignalr-1.3.1.tar.gz (179.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pysignalr-1.3.1-py3-none-any.whl (22.7 kB view details)

Uploaded Python 3

File details

Details for the file pysignalr-1.3.1.tar.gz.

File metadata

  • Download URL: pysignalr-1.3.1.tar.gz
  • Upload date:
  • Size: 179.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","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}

File hashes

Hashes for pysignalr-1.3.1.tar.gz
Algorithm Hash digest
SHA256 6b1b46aac1c8a1106f83739e104124227df9319c6048304b4dc580eae439698a
MD5 ba4fb8da9bceaae1fa31448f03e16549
BLAKE2b-256 e87fcccfc3c6407b46363747f0043ef42ea609aa1b48196e1a9d851d241c571f

See more details on using hashes here.

File details

Details for the file pysignalr-1.3.1-py3-none-any.whl.

File metadata

  • Download URL: pysignalr-1.3.1-py3-none-any.whl
  • Upload date:
  • Size: 22.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","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}

File hashes

Hashes for pysignalr-1.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 630a6c5f4699f8ba4c9b2c36b5326657bee34a03fbdaf03437fa918bea305d22
MD5 250b30462573e33cfda0a5ca8188aeb8
BLAKE2b-256 a599fb69860e672b75f8ea73a1d21f88ab05c4f149d8c8f6edb5865f456deab9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page