Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

tasgi

tasgi means Thread ASGI. It is an experimental ASGI-compatible framework/runtime that keeps transport and protocol handling on the event loop while allowing handler execution on either the asyncio loop or a thread runtime.

Runtime design goal:

  • the tasgi package itself depends only on the Python standard library
  • external tools like coverage, build, and twine are used only for CI, testing, and packaging

Status

tasgi is currently an alpha-stage project.

  • public APIs are still settling
  • auth APIs are still evolving
  • router/module composition is still evolving
  • native HTTP/2 support is still a prototype subset

Treat the current release line as experimental, not stable.

Install

From source:

pip install -e .

tasgi does not require Poetry at runtime. The project is packaged from pyproject.toml using the standard PEP 517 build flow, so CI and publishing use pip, build, and twine directly instead of a Poetry-specific workflow.

After packaging to TestPyPI, the intended trial install flow is:

pip install --index-url https://test.pypi.org/simple/ tasgi

Hello World

from tasgi import TasgiApp, TextResponse

app = TasgiApp(docs=True, debug=True)

@app.route.get("/")
async def home(request):
    return TextResponse("hello from tasgi")

Run it:

tasgi

Or run the bundled demo app:

python3 examples/service_api/main.py

Router Usage

tasgi now treats app.route as the main HTTP registration surface.

from tasgi import JsonResponse, Router, TasgiApp

users = Router(tags=["users"])

@users.get("/users")
def list_users(request):
    return ["alice", "bob"]

app = TasgiApp()
app.include_router(users, prefix="/api")

@app.route.get("/status")
async def status(request):
    return JsonResponse({"ok": True})

Core Model

tasgi is layered like this:

socket/transport
  -> ASGI boundary
  -> tasgi runtime
  -> tasgi framework
  -> user handlers

Rules:

  • network I/O stays on the event loop
  • HTTP protocol handling stays on the event loop
  • async handlers run on the asyncio loop
  • sync handlers run in the tasgi thread runtime
  • worker threads never write directly to sockets

Dual Execution Model

App-level execution policy is explicit:

from tasgi import ASYNC_EXECUTION, THREAD_EXECUTION, TasgiApp

app = TasgiApp(default_execution=THREAD_EXECUTION)

@app.route.get("/cpu")
def cpu(request):
    ...

@app.route.get("/status", execution=ASYNC_EXECUTION)
async def status(request):
    ...

Request And Response Types

Main public HTTP types:

  • TasgiApp
  • Router
  • Request
  • Response
  • TextResponse
  • JsonResponse
  • StreamingResponse

Handlers may return Response objects directly, or return typed values when a response model is declared.

OpenAPI And Docs

Built-in docs can be enabled from app config:

from dataclasses import dataclass
from tasgi import TasgiApp

@dataclass
class EchoIn:
    message: str

@dataclass
class EchoOut:
    echoed: str

app = TasgiApp(
    docs=True,
    title="tasgi demo",
    version="0.1.0a1",
)

@app.route.post("/echo", request_model=EchoIn, response_model=EchoOut)
def echo(request, body: EchoIn) -> EchoOut:
    return EchoOut(echoed=body.message)

Default docs endpoints:

  • /openapi.json
  • /docs

Auth

tasgi includes an experimental pluggable auth layer.

Built-in starters:

  • BearerTokenBackend
  • APIKeyBackend
  • BasicAuthBackend
  • RequireAuthenticated
  • RequireScope
  • RequireRole

Example:

from tasgi import BearerTokenBackend, Identity, RequireScope, TasgiApp

def validate_token(token: str):
    if token == "demo-token":
        return Identity(subject="alice", scopes=frozenset({"profile"}))
    if token == "admin-token":
        return Identity(subject="admin", scopes=frozenset({"admin"}))
    return None

app = TasgiApp(auth_backend=BearerTokenBackend(validate_token), docs=True)

@app.route.get("/public", auth=False)
async def public_route(request):
    return {"public": True}

@app.route.get("/me", auth=True)
async def me(request):
    return {"subject": request.identity.subject}

@app.route.get("/admin", auth=RequireScope("admin"))
async def admin(request):
    return {"subject": request.identity.subject}

Auth metadata is also reflected automatically in OpenAPI for built-in auth backends.

Demo App

The bundled service example includes:

  • HTTP routes
  • router/module composition
  • OpenAPI + Swagger UI
  • auth examples
  • streaming responses
  • WebSocket echo
  • thread-executed sync handlers

Run:

python3 examples/service_api/main.py

There is also a cleaner modular composition example:

python3 examples/modular_api/main.py

Benchmarks

The benchmark suite exercises loopback TCP requests against a dedicated benchmark app.

Run:

python3 benchmarks/run_benchmarks.py

CI And Publishing

GitHub Actions workflows are set up for both validation and releases:

  • CI runs on every push and pull request
  • the primary CI target is free-threaded CPython 3.14t
  • standard compatibility tests also run on Python 3.14, 3.13, 3.12, and 3.11
  • coverage is reported in CI using coverage run -m unittest discover -s tests
  • package builds are verified in CI with python -m build and python -m twine check --strict dist/*

Publishing is separated from CI:

  • Publish runs only on version tags like v0.1.0a1 or on published GitHub Releases
  • release builds run on CPython 3.14t
  • PyPI upload is configured for Trusted Publishing via GitHub Actions
  • before enabling real PyPI releases, do one TestPyPI dry run and confirm a clean install path

Local commands:

python3 -m unittest discover -s tests -v
python3 -m pip install coverage build twine
coverage run -m unittest discover -s tests
coverage report -m
python3 -m build
python3 -m twine check --strict dist/*

Current Limits

  • HTTP/2 support is prototype-grade, not production-complete
  • auth API is still settling
  • route registration APIs changed recently and may still evolve
  • no middleware ecosystem yet
  • no dependency injection container beyond explicit lightweight helpers
  • no production-hardening claims

License

tasgi is licensed under Apache-2.0. See LICENSE and NOTICE.

That keeps the project free to use, including in companies, while preserving the attribution notices when the software is redistributed.

Release Notes

This repository is currently prepared for an alpha-style release, not a stable release.

Before a public non-alpha release, the project still needs:

  • final public API freeze
  • repository/homepage URLs in package metadata
  • a TestPyPI install-and-verify pass

Metadata

Release files for tasgi 0.1.0a1

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

Source distribution (sdist)

Source distribution for tasgi 0.1.0a1
File Size Uploaded Provenance
tasgi-0.1.0a1.tar.gz 72.0 kB With provenance Details

Built distribution (wheel)

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

Total release size: 134.2 kB

Release files / tasgi-0.1.0a1.tar.gz

Download URL tasgi-0.1.0a1.tar.gz
Size 72.0 kB
Tags Source
SHA-256 checksum
How to use checksums
7ec12ab1489e769ee76b4f1037cc248a8106d933d7a57813c696e31576c225a8
BLAKE2b-256 checksum
How to use checksums
8fa75a78efdf6ce2086ea375980bf49c97d82b84ce2c5cbb40aaaec35c3ab8b1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Mar 18, 2026.

Transparency log

Release files / tasgi-0.1.0a1-py3-none-any.whl

Download URL tasgi-0.1.0a1-py3-none-any.whl
Size 62.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
259f7854b48ebb7b6e2bd02b422e697ba52e060791935abad458a0f4de521870
BLAKE2b-256 checksum
How to use checksums
0bae3e9ab031691d815570c2c6921db5d9e0e7f0af4aee8629d83d9533ba7547
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Mar 18, 2026.

Transparency log

Security for tasgi 0.1.0a1

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 tasgi-0.1.0a1.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 Mar 18, 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
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