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.2.tar.gz (181.8 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.2-py3-none-any.whl (22.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: pysignalr-1.3.2.tar.gz
  • Upload date:
  • Size: 181.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","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.2.tar.gz
Algorithm Hash digest
SHA256 1b3d965addb6db4c86510efd5072ecb38356a95d3f219c926de8ae9e8c69d754
MD5 d4c14982fe6e21a95c9e4a80b1385693
BLAKE2b-256 c5196cbbf7bbe3785270e3e71913cbb87c5ac2ea4946361e0a700beba3c5e16f

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pysignalr-1.3.2-py3-none-any.whl
  • Upload date:
  • Size: 22.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 6793bec6a7b05c9366bd6f173f7a40da6989c4cb916ba04acedb1370564a8feb
MD5 4a877faa611e9f90e7df8e141a5116d9
BLAKE2b-256 28bcd146eb0658cb7a576a57a1e0ef6ffbcb5aea25c4a1d43c02e5e4b7842999

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