Skip to main content

easyssf-receiver-fastapi

The easyssf SSF receiver for FastAPI: the push endpoint as a router, the rejection of revoked access tokens as a dependency or middleware, and the receiver's lifecycle as a lifespan, with its health as a route. The Python counterpart of the Rust easyssf-receiver-axum crate. Everything else, the configuration, the handlers, the stream management and polling, is easyssf-receiver; see its README.

uv add easyssf-receiver-fastapi      # or: pip install easyssf-receiver-fastapi

The receiver with the application

receiver_lifespan starts the receiver when the application starts (streams are registered and polling begins in the background) and closes it on shutdown (the acknowledgements it owes are sent, the HTTP client it made for itself is closed). With a lifespan of your own, the receiver starts after yours entered and stops before it exits, so the handlers find what the application set up:

from fastapi import FastAPI
from easyssf.fastapi import receiver_lifespan
from easyssf.receiver import Receiver, ReceiverConfig

receiver = Receiver(ReceiverConfig.from_mapping(settings["easyssf"]["receiver"]), handlers=[audit])
app = FastAPI(lifespan=receiver_lifespan(receiver))  # or receiver_lifespan(receiver, my_lifespan)

The push endpoint

push_router_for mounts POST easyssf.receiver.push.endpoint-path (/ssf/push by default), push_router(handler, path) any push handler at any path. The transmitter authenticates with its Authorization header and the SET with its signature, so the route belongs outside the authentication of the application; it is left out of the OpenAPI schema. The response is the one of RFC 8935: 202 for an accepted SET, 400 with an error document (application/json, Content-Language: en) for an invalid one, 401 for a transmitter that could not be authenticated, 413 for a body beyond 256 KiB, 503 or 500 to have the SET delivered again.

from easyssf.fastapi import push_router_for

app.include_router(push_router_for(receiver))

Rejecting revoked access tokens

The receiver's revocation handler records the sessions and users that CaepSessionRevoked events name in receiver.token_revocation_store. revocation_dependency turns the store into a dependency that answers 401 with WWW-Authenticate: Bearer error="invalid_token", error_description="The token was revoked" for a token of a revoked session or user, and 503 when the store cannot answer (it fails closed). It does not validate tokens: extract reads the claims the authentication of the application left on the request, None for a request without one.

from datetime import UTC, datetime
from fastapi import Depends, Request
from easyssf.fastapi import revocation_dependency
from easyssf.receiver import TokenClaims


def token_claims(request: Request) -> TokenClaims | None:
    token = getattr(request.state, "token", None)  # left there by your authentication dependency
    if token is None:
        return None
    return TokenClaims(
        issuer=token["iss"],
        subject=token["sub"],
        session_id=token.get("sid", ""),
        issued_at=datetime.fromtimestamp(token["iat"], tz=UTC),
    )


reject_revoked = revocation_dependency(receiver.token_revocation_store, token_claims)


@app.get("/api/orders", dependencies=[Depends(require_access_token), Depends(reject_revoked)])
async def orders() -> list[str]: ...

For the whole application, the raw ASGI RevocationMiddleware of the receiver does the same from the scope, added after (inside) the middleware that validates the tokens:

from easyssf.fastapi import RevocationMiddleware

app.add_middleware(
    RevocationMiddleware,
    store=receiver.token_revocation_store,
    extract=lambda scope: scope["state"].get("token_claims"),
)

Health

health_router serves receiver.health() as JSON at /health: 200 while the receiver is healthy or degraded (no contact with a transmitter yet; the application starts without it), 503 when it is unhealthy (a poll failed, a stream cannot be used).

from easyssf.fastapi import health_router

app.include_router(health_router(receiver))  # or health_router(receiver, path="/ready")

Example

examples/fastapi/resource-server is an OAuth2 resource server on FastAPI against the Keycloak of examples/keycloak: it registers its stream, validates access tokens with the keys of the transmitter and rejects them once their session was revoked; see examples/README.md.

Metadata

Release files for easyssf-receiver-fastapi 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 easyssf-receiver-fastapi 0.7.0
File Size Uploaded Provenance Actions
easyssf_receiver_fastapi-0.7.0.tar.gz 9.9 kB With provenance Details for easyssf_receiver_fastapi-0.7.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for easyssf-receiver-fastapi 0.7.0
File Interpreter ABI Platform Actions
easyssf_receiver_fastapi-0.7.0-py3-none-any.whl Python 3 none any Details for easyssf_receiver_fastapi-0.7.0-py3-none-any.whl

Total release size: 18.8 kB

Release files / easyssf_receiver_fastapi-0.7.0.tar.gz

Download URL easyssf_receiver_fastapi-0.7.0.tar.gz
Size 9.9 kB
Tags Source
SHA-256 checksum
How to use checksums
c8d193513581c17352fcfa340d378b87e3ae5d75a9fc7b685dafe46abf305c27
BLAKE2b-256 checksum
How to use checksums
57a1f0a3a7ab8f737c48f76b8e85d1d92620744ef881a3051acd6db370cefcf1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.

Transparency log

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

Download URL easyssf_receiver_fastapi-0.7.0-py3-none-any.whl
Size 9.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cf44035a600bcadf46a72752b5e01d98185c908c6af953e6c8e846d6907bef82
BLAKE2b-256 checksum
How to use checksums
9e457979e4203e6ca6de1ccba13ac7728ebeb1c7449da09549fdbb769a6b11d7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.

Transparency log

Security for easyssf-receiver-fastapi 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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for easyssf_receiver_fastapi-0.7.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.

Transparency log

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.

Release history Release notifications | RSS feed

This release

0.7.0 This release

2 release files Full provenance

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