Skip to main content

pondsocket-asgi

Canonical ASGI adapter for pondsocket. Mount under any ASGI host — FastAPI, Starlette, Litestar, Django, raw uvicorn.

Handles WebSocket and SSE (Server-Sent Events) transports. The same PondSocket instance serves both — the adapter detects the request type and dispatches.

Install

pip install pondsocket-asgi

Pulls in pondsocket and pondsocket-common automatically.

Quick start: raw uvicorn

from pondsocket import ConnectionContext, EventContext, JoinContext, PondSocket
from pondsocket_asgi import PondASGIApp


async def auth(ctx: ConnectionContext) -> None:
    ctx.accept()


async def on_join(ctx: JoinContext) -> None:
    await ctx.accept()


async def on_message(ctx: EventContext) -> None:
    await ctx.broadcast(ctx.event_name, ctx.get_payload())


pond = PondSocket()
endpoint = pond.create_endpoint("/socket", auth)
lobby = endpoint.create_channel("/chat/:room_id", on_join)
lobby.on_message("message", on_message)

app = PondASGIApp(pond)
uvicorn module:app --host 127.0.0.1 --port 8000

WebSocket clients connect to ws://127.0.0.1:8000/socket.

Mount under FastAPI

from fastapi import FastAPI
from pondsocket_asgi import PondASGIApp

app = FastAPI()
app.mount("/ws", PondASGIApp(pond))

When mounted at /ws, the adapter sees scope["path"] already stripped of the prefix — register your pond endpoints with the post-mount path (e.g. /socket resolves at ws://host/ws/socket).

See examples/ for FastAPI, Starlette, and raw uvicorn variants.

SSE transport

The same endpoint serves Server-Sent Events to clients that don't have WebSocket:

GET /socket
  Accept: text/event-stream
→ 200, response carries X-Connection-ID header and a `CONNECTION` event with `payload.connectionId`, stream of "event: <name>\ndata: <json>\n\n" frames

POST /socket
  X-Connection-ID: <id>
  Content-Type: application/json
  body: <client message JSON>
→ 204

DELETE /socket
  X-Connection-ID: <id>
→ 204

Use SSE when WebSocket is blocked (some corporate proxies). The connection handler is the same — the adapter routes by Accept header and method.

Lifespan

PondASGIApp handles the ASGI lifespan protocol. On lifespan.startup, it acknowledges immediately. On lifespan.shutdown, it closes the PondSocket (which closes every endpoint, every channel, every transport).

Testing

pondsocket_asgi.testing exposes an in-memory ASGI driver — no real network needed:

from pondsocket_asgi.testing import ASGITestDriver

driver = ASGITestDriver(PondASGIApp(pond))

# WebSocket
session = await driver.connect_websocket("/socket")
await session.send_client_message(
    action="JOIN_CHANNEL",
    channel_name="/chat/1",
    event="join",
)
ack = await session.receive_json()
await session.disconnect()

# SSE
sse = await driver.connect_sse("/socket")
status, _ = await driver.sse_push(sse.connection_id, {"action": "BROADCAST", ...})
frame = await sse.receive_event()
await sse.disconnect()

# Lifespan
lifespan = await driver.open_lifespan()
await lifespan.startup()
await lifespan.shutdown()

Public API

from pondsocket_asgi import ...

  • PondASGIApp — the adapter itself
  • ASGIWebSocketTransport — WebSocket transport (you usually don't construct this directly; the app does)

from pondsocket_asgi.testing import ...

  • ASGITestDriver, WebSocketSession, LifespanSession, SSESession

License

GPL-3.0-or-later.

Metadata

Release files for pondsocket-asgi 0.0.6

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

Source distribution (sdist)

Source distribution for pondsocket-asgi 0.0.6
File Size Uploaded Provenance Actions
pondsocket_asgi-0.0.6.tar.gz 12.6 kB Without provenance Details for pondsocket_asgi-0.0.6.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pondsocket-asgi 0.0.6
File Interpreter ABI Platform Actions
pondsocket_asgi-0.0.6-py3-none-any.whl Python 3 none any Details for pondsocket_asgi-0.0.6-py3-none-any.whl

Total release size: 24.0 kB

Release files / pondsocket_asgi-0.0.6.tar.gz

Download URL pondsocket_asgi-0.0.6.tar.gz
Size 12.6 kB
Tags Source
SHA-256 checksum
How to use checksums
9c41ffdcf8d6a5d9607b9da98a400dd7819ecfc0294c41330f2031a5fd4cce07
BLAKE2b-256 checksum
How to use checksums
7a9b7a1b008e877744466d34833107eccde5083ce0645c57bb2c97642afa9784
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.0

Release files / pondsocket_asgi-0.0.6-py3-none-any.whl

Download URL pondsocket_asgi-0.0.6-py3-none-any.whl
Size 11.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
30d4a4ef4782cb3234e4dd87b0c28598a86648684da3bb7c20c3ed471d2bcd21
BLAKE2b-256 checksum
How to use checksums
4c496da1e40def628336df2f513683641f48f1f385217b676b10699679d5a6ab
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.0

Security for pondsocket-asgi 0.0.6

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