Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Releases: justrach/turboAPI

v1.0.30

11 May 05:50
@github-actions github-actions
ca65dff
This commit was created on GitHub.com and signed with GitHub’s verified signature.
GPG key ID: B5690EEEBB952194
Verified
Learn about vigilant mode.

Choose a tag to compare

v1.0.30 — Real WebSockets + Hot-Path Perf

TL;DR

  1. Real WebSocket support on the Zig HTTP core. @app.websocket() was a stub backed by in-memory queues since day one; this release wires it to actual RFC 6455 frame I/O — handshake, frames, masking, fragmentation, ping/pong, close handshake. Closes #114.
  2. Hot-path handler dispatch is 30–75% faster than v1.0.29 on the TestClient throughput benchmark, from 5 focused perf PRs that strip dead kwargs.get("headers", {}) defaults, cache _returns_model / model_dump detection, and hoist parse_qs / HTTPException imports out of fast-handler closures.
  3. CI version-sync guard (#154) fixed — was failing on every PR since 1.0.28.

Features

Real WebSockets (#167)

from turboapi import TurboAPI
from turboapi.websockets import WebSocket, WebSocketDisconnect
app = TurboAPI()
@app.websocket("/ws")
async def handler(ws: WebSocket):
 await ws.accept()
 try:
 while True:
 msg = await ws.receive_text()
 await ws.send_text(f"echo: {msg}")
 except WebSocketDisconnect:
 pass

Coverage:

  • HTTP Upgrade handshake with Sec-WebSocket-Accept validation
  • All RFC 6455 frame opcodes — text, binary, close, ping, pong, continuation
  • All three payload-length encodings (7-bit / 16-bit / 64-bit)
  • Server enforces client-frame masking; auto-pong on ping; close handshake on either side
  • Fragmented client messages are reassembled before delivery
  • Connected-mode WebSocket wraps the live Zig connection via a PyCapsule; FFI releases the GIL around blocking socket I/O so other threads (and free-threaded interpreters) stay free during recv waits
  • In-memory mode preserved — existing FastAPI-parity tests work unchanged

Not yet supported (follow-ups, not blocking the v1.0.30 ship):

  • Path parameters on WS routes (e.g. /ws/{room}) — exact match only
  • permessage-deflate compression
  • Subprotocol negotiation
  • Routes registered after app.run()

Performance

Five hot-path PRs targeting handler dispatch closures, header kwarg handling, and model-return detection caching. Measured against the pre-1.0.30 baseline committed at benchmarks/baseline.json (2026年04月27日). Same hardware (Apple M-series), same Python 3.14t (free-threaded), same benchmarks/bench_throughput.py harness (TestClient, in-process).

Route v1.0.29 baseline v1.0.30 Δ
GET / 86,806 r/s 132,167 r/s +52%
POST /items 48,826 r/s 85,687 r/s +75%
GET /items/{id} ~80,000 r/s* 77,271 r/s ~flat

*Closest analogue in baseline.json is GET /users/123 at 80,165 r/s — not exactly the same route, take as directional.

Wire-level numbers (real socket, not TestClient) hold the ~140k req/s figure from the project README. The perf PRs in this release matter most under realistic FastAPI-style POST validation + JSON-return handler patterns.

WebSocket throughput (loopback)

5,000-message round-trip latency bench, single connection, 100 warmup. Same code, different platform — Linux numbers from an idle sandbox VM (sandbox.trilok.ai), macOS from a dev box running editors / Chrome.

Route Platform msgs/s p50 p99
/ws-echo (Zig only, no Python in the loop) Linux x86_64 23,529 38 μs 61 μs
/ws-echo macOS arm64 15,666 57 μs 129 μs
/ws-py (Python handler) Linux x86_64 18,519 53 μs 63 μs
/ws-py macOS arm64 15,295 60 μs 124 μs

Sub-millisecond p99 on both platforms; Python overhead is ~15 μs per round-trip on Linux (well-defined) and ~3 μs on macOS (absorbed into ambient scheduling jitter). For an LLM token-stream use case (~50 tok/s producer), the WS path provides &g×ばつ headroom on either platform.

Internals & fixes

  • #154 fix: stale version-sync guard fails CI on every PR since 1.0.28 — the equality check rejected anything that wasn't an exact match; changed to >= so monotonic version bumps pass.
  • #148 perf: hoist parse_qs / HTTPException imports out of fast-handler closures (saves a LOAD_GLOBAL per request).
  • #152 perf: cache joined CORS header strings + max_age str() in __init__.
  • #155, #159 perf: drop wasted {} defaults in kwargs.get("headers", {}) calls — or {} is faster than a default factory.
  • #156 perf: cache model_dump detection at handler-creation time in fast handlers (skip the per-request hasattr check).
  • #161 perf: extend _returns_model caching to pos_handler, async_pos_handler, fast_model_handler (the previous PR only covered fast_sync).
  • #167 feat: real WebSocket support (see above).
  • #168 release: merge v1.0.30 into main.

Issues closed

  • #114 — zig runtime: real WebSocket support on current turboapi-core architecture

Cross-platform verification

WebSocket implementation was verified end-to-end on both macOS arm64 (local dev) and Linux x86_64 (via the turbobox sandbox at sandbox.trilok.ai). The Linux run surfaced a @memcpy length-mismatch bug in a test fixture that macOS Zig 0.16 had elided — fixed in commit d7f14b8 before tagging.

Check macOS arm64 Linux x86_64
zig build test 26/26 pass 26/26 pass
pytest tests/test_websocket_e2e.py 10/10 pass, ~90s 10/10 pass, ~90s
pytest tests/test_fastapi_parity.py::TestWebSocket 4/4 pass (no longer deselected)
Full pytest regression on release tip 404 pass, 0 regress

Upgrade

pip install --upgrade turboapi

Backwards compatible. No code changes required — @app.websocket(...) handlers that previously only worked in test mode now serve real traffic. In-memory WebSocket() instantiation still works for unit tests.

Full Changelog: v1.0.29...v1.0.30

Assets 5
Loading
tosmart01, nwaimo, and wevertonms reacted with thumbs up emoji
3 people reacted

v1.0.29

26 Apr 01:39
@github-actions github-actions

Choose a tag to compare

TurboAPI v1.0.29

This is the real Zig 0.16.0 + Python 3.14t release. It supersedes v1.0.28.

v1.0.28 contained the runtime/performance work, but release smoke testing found packaging problems after publish:

  • free-threaded wheels were tagged as cp314t-cp314t, which pip/uv do not select for python3.14t
  • the macOS extension linked against a GitHub Actions-only PythonT.framework path

v1.0.29 fixes those packaging issues and was smoke-tested from a clean PyPI install with the native Zig backend.

Install

uv python install 3.14t
python3.14t -m pip install turboapi==1.0.29

TurboAPI now requires a free-threaded Python build. A regular GIL-enabled Python 3.14 install will refuse to import TurboAPI and tell you to use python3.14t.

Published artifacts:

  • turboapi-1.0.29-cp314-cp314t-macosx_10_15_universal2.whl
  • turboapi-1.0.29-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
  • turboapi-1.0.29.tar.gz

Major Runtime Changes

  • Migrated the Zig HTTP runtime to Zig 0.16.0.
  • Moved the server onto std.Io.net listener and stream APIs.
  • Centralized the shared std.Io.Threaded lifecycle in zig/src/runtime.zig.
  • Kept TurboAPI's explicit cross-core connection worker pool so each worker owns a reusable Python thread state.
  • Added TURBO_THREAD_POOL_SIZE support for controlling worker count at runtime.
  • Updated runtime synchronization to Zig 0.16-compatible std.Io.Mutex / std.Io.Condition paths where applicable.
  • Updated all CI and release workflows to use Zig 0.16.0.
  • Fixed Zig 0.16 compatibility issues across networking, time APIs, pthread mutexes, Smith fuzz callbacks, libc linking, multipart ownership, and removed std APIs.

Performance Work

  • Added eager no-await async dispatch for simple async routes: simple_async_eager.
  • Added eager no-await async dispatch for async body routes: body_async_eager.
  • Added safety checks so eager async mode is skipped for handlers that actually await, yield, or use loop-sensitive asyncio APIs.
  • Added reusable per-worker asyncio event-loop helpers for true-await async handlers.
  • Added async vectorcall/noargs fast paths.
  • Added cached async response handling.
  • Added entry-local atomic cached body pointers for no-arg handlers.
  • Added cached JSON response writing that avoids re-entering Python on cache hits.
  • Added precomputed scalar JSON body parsing for fast sync/async body wrappers.
  • Avoided redundant defensive body copies when Zig already passed immutable Python bytes.
  • Reused Zig helpers for path_params kwargs and skipped empty path-param dict allocation.
  • Switched hot route/parameter parsing paths to std.StaticStringMap.
  • Added SIMD-assisted header-end scanning and router child dispatch where available.
  • Reworked URL percent-decoding to bulk-copy clean spans and branch only on % / +.
  • Reworked telemetry JSON escaping to bulk-copy clean spans.
  • Replaced DHI field type parsing chains with StaticStringMap.
  • Used PyUnicode_AsUTF8AndSize in SQL value encoding to avoid extra length scans.
  • Reworked SQL literal escaping to bulk-copy normal spans and only escape when needed.

HTTP, Forms, Multipart, and Middleware

  • Added Zig-native multipart/form-data parsing support.
  • Fixed multipart, form, URL-encoded, and raw body handling across native, ASGI fallback, and TestClient paths.
  • Added UploadFile / File() / Form() TestClient coverage.
  • Added raw body: bytes injection.
  • Added populated Request injection for handlers that ask for request: Request.
  • Converted turboapi.middleware into a FastAPI-compatible package with submodules:
    • turboapi.middleware.gzip
    • turboapi.middleware.cors
    • turboapi.middleware.trustedhost
    • turboapi.middleware.httpsredirect
    • turboapi.middleware.sessions
  • Fixed middleware route handling so async routes under middleware stay on the correct enhanced path.
  • Fixed middleware compatibility for HTTPS redirect, custom logging-style middleware hooks, GZip passthrough, and header tunneling.
  • Made app.mount("/static", StaticFiles(...)) register real GET routes so the Zig runtime can serve mounted files.
  • Ensured middleware can apply to static-file responses.

Bug Fixes

  • Fixed implicit HTTP header binding for plain string parameters.
  • Fixed query parameter coercion for annotated types like int, float, bool, lists, and enums.
  • Fixed path parameter detection so parameter names are matched as {param} instead of substring matches.
  • Fixed response normalization to avoid mutating caller dictionaries.
  • Fixed response tuple ABI mismatches in the Zig FFI path.
  • Fixed set_cookie() propagation and multi-cookie response handling.
  • Fixed StreamingResponse / FileResponse cookie initialization.
  • Fixed middleware exception status propagation.
  • Fixed middleware on_error response content handling.
  • Fixed OpenAPI handling for Optional[X] / Union[X, None].
  • Fixed TestClient async dependency resolution.
  • Fixed ASGI lifespan handling to use __aenter__ / __aexit__.
  • Fixed Python 3.14 request failures caused by inline import inspect shadowing.
  • Fixed static file path traversal by replacing string-prefix checks with path ancestry checks.
  • Fixed CORS regex origin matching to use full matches.
  • Fixed CSRF cookie handling so existing cookies are not overwritten.
  • Fixed telemetry JSON hex escaping for control characters.
  • Fixed native turbopg fallback behavior and multiple DB route/runtime issues.
  • Fixed DB query parameter parsing, bool handling, large raw-cell lengths, and insert allocation leaks.
  • Fixed DHI schema arena cleanup.
  • Fixed turboapi-core router partial mutation on allocation failure.

Structured Logging and Telemetry

  • Added zig/src/telemetry.zig with event-sourced log/span/counter/histogram/gauge events.
  • Added text and JSON-lines stderr exporters.
  • Added TURBO_LOG_LEVEL and TURBO_LOG_FORMAT.
  • Added zig/src/logger.zig wrappers for leveled Zig logs.
  • Replaced direct std.debug.print calls in the server and DB layer with structured logger calls.
  • Added Python logging helpers and JSON formatting in python/turboapi/logger.py.
  • Added telemetry/logging regression coverage.

Protocol and Deployment Docs

  • Added docs/HTTP3_QUIC.md.
  • Clarified that native QUIC/HTTP/3 is not implemented in TurboAPI yet.
  • Documented the supported production path for QUIC/HTTP/3: put TurboAPI behind Caddy, nginx, Cloudflare, cloudflared, or another edge/reverse proxy.
  • Updated HTTP/2 docs to avoid claiming unsupported native protocol behavior.
  • Updated TLS docs to recommend edge termination / reverse proxy TLS for production.
  • Updated WebSocket docs to match the current runtime support model.
  • Updated performance tuning docs for worker-pool sizing and TURBO_THREAD_POOL_SIZE.
  • Added Zig 0.16 migration docs and a project-agnostic Zig 0.15.2 to 0.16 migration reference.
  • Added a zigup multi-version workflow guide.
  • Added a frontend release notes page for the 1.0.28/1.0.29 work.

Benchmarking and CI

  • Added PR performance regression gating.
  • Added benchmark trend/history tooling.
  • Added benchmarks/thresholds.json.
  • Added scripts/bench-http.sh.
  • Added worker-count tracking through WORKERS=N ./scripts/bench-http.sh.
  • Updated benchmark result JSON/history/PR output to record worker count, duration, wrk threads, and connections.
  • Raised adversarial benchmark thresholds for GitHub-hosted runner stability.
  • Fixed the release workflow so it can push tags and dispatch the publish workflow.
  • Fixed the build/publish workflow so manual dispatch creates the GitHub Release.
  • Added wheel smoke checks in CI:
    • install the produced wheel into a fresh venv
    • import turboapi.turbonet
    • assert TurboServer and ResponseView exist
    • on macOS, assert the wheel does not link to Python.framework or PythonT.framework
  • Limited release wheels to the actually supported Python 3.14t runtime.

Packaging Fixes in v1.0.29

  • Fixed free-threaded wheel tags from cp314t-cp314t to cp314-cp314t.
  • Stopped linking the Zig extension against libpython for release wheels, so macOS wheels no longer embed a non-portable framework path.
  • Verified the macOS wheel links only against @rpath/libturbonet.dylib and /usr/lib/libSystem.B.dylib.
  • Verified a clean PyPI install of turboapi==1.0.29 imports the native backend.
  • Verified a clean PyPI install starts the native Zig HTTP server.

Performance Results

Local no-await async body route measurements with cache disabled:

Route Before After
POST /body0 ~70.9k req/s ~110.8k req/s
POST /body_params ~67.2k req/s ~103.6k req/s
POST /body_sleep0 ~57k req/s ~57k req/s

body_sleep0 is unchanged because it truly awaits and stays on the event-loop path.

Latest mixed-app local HTTP benchmark with TURBO_DISABLE_CACHE=1, TURBO_THREAD_POOL_SIZE=24, and wrk -t8 -c128 -d5s --latency:

Route Median
GET /sync 91.7k req/s
GET /async no-await 89.0k req/s
POST /body no-await async body 83.1k req/s

The same local POST /body route was 49.2k req/s before the precomputed parser pass, so this was about a 69% improvement under the same load.

Validation

Local validation before merge/release:

  • make check passed
  • full test suite passed: 388 passed, 20 warnings
  • sample app smoke passed for:
    • sync GET
    • no-await async GET
    • async POST body
    • path/query route
    • true-await async route
  • benchmark wrapper smoke passed with WORKERS=4 BENCH_DURATION=1 BENCH_THREADS=2 BENCH_CONNECTIONS=16 ./scripts/bench-http.sh
  • /tmp/bench_results.json recorded "workers": 4

Release validation for v1.0.29:

  • Release workflow passed
  • Build & Publish workflow passed
  • Linux 3.14t wheel built and imported the native backend in CI
  • macOS 3.14t wheel built, imported the native backend in CI, and passed the no-Python-fr...
Read more
Loading
wevertonms reacted with rocket emoji
1 person reacted

v1.0.27

01 Apr 01:16
@github-actions github-actions
f7ec31e
This commit was created on GitHub.com and signed with GitHub’s verified signature.
GPG key ID: B5690EEEBB952194
Verified
Learn about vigilant mode.

Choose a tag to compare

What's Changed

Full Changelog: v1.0.24...v1.0.27

Contributors

justrach
Loading

v1.0.24

31 Mar 06:19
@justrach justrach
d0ee8b9
This commit was created on GitHub.com and signed with GitHub’s verified signature.
GPG key ID: B5690EEEBB952194
Verified
Learn about vigilant mode.

Choose a tag to compare

v1.0.24

Fixes

  • restored Zig-runtime gzip middleware body passthrough so compressed responses keep the correct Content-Encoding: gzip header and the actual compressed body
  • normalized middleware-visible request headers to lowercase before Python-side processing
  • preserved raw bytes response bodies in the Zig bridge instead of JSON-serializing compressed middleware output to null

Packaging

  • synced version metadata to 1.0.24 across pyproject.toml, python/setup.py, and python/turboapi/__init__.py
  • added README and changelog entries for the gzip fix

References

  • fixes #96
  • runtime fix merged in #111
  • release metadata sync merged in #112

What's Changed

Full Changelog: v1.0.23...v1.0.24

Contributors

justrach
Loading
RobertDeRose reacted with hooray emoji
1 person reacted

v1.0.23

27 Mar 13:20
@github-actions github-actions

Choose a tag to compare

What's Changed

  • feat: extract turboapi-core shared Zig library by @justrach in #108

Full Changelog: v1.0.22...v1.0.23

Contributors

justrach
Loading
NameLeSS-93 reacted with thumbs up emoji
1 person reacted

v1.0.22

26 Mar 01:19
@justrach justrach

Choose a tag to compare

What's Changed

  • fix: refresh dhi hash so release builds can package turbonet by @justrach in #106

Full Changelog: v1.0.21...v1.0.22

What's Changed

  • fix: refresh dhi hash so release builds can package turbonet by @justrach in #106

Full Changelog: v1.0.21...v1.0.22

Contributors

justrach
Loading

v1.0.21

26 Mar 00:55
@justrach justrach
b3adabb
This commit was created on GitHub.com and signed with GitHub’s verified signature.
GPG key ID: B5690EEEBB952194
Verified
Learn about vigilant mode.

Choose a tag to compare

What's Changed

  • Fix Zig response cache crash under load by @justrach in #95
  • fix: close verified compat gaps in TestClient, lifespan, docs, router deps, and static mounts by @justrach in #105

Full Changelog: v1.0.20...v1.0.21

Contributors

justrach
Loading

v1.0.20

24 Mar 13:14
@github-actions github-actions

Choose a tag to compare

What's Changed

  • feat: TurboBoto — Zig-accelerated boto3 drop-in replacement by @justrach in #62
  • Tighten benchmark methodology and publish corrected results by @justrach in #77

Full Changelog: v1.0.17...v1.0.20

Contributors

justrach
Loading

v1.0.17

21 Mar 02:34
@github-actions github-actions
43a7191
This commit was created on GitHub.com and signed with GitHub’s verified signature.
GPG key ID: B5690EEEBB952194
Verified
Learn about vigilant mode.

Choose a tag to compare

What's Changed

  • bench: asyncpg vs TurboAPI+pg.zig Docker benchmarks by @justrach in #56
  • fix: add TURBO_DISABLE_CACHE env var by @justrach in #58

Full Changelog: v1.0.16...v1.0.17

Contributors

justrach
Loading
mattsta reacted with rocket emoji
1 person reacted

v1.0.16

20 Mar 10:13
@github-actions github-actions

Choose a tag to compare

What's Changed

  • feat: Claude Code skills for TurboAPI development by @justrach in #53
  • feat: Zig-native Postgres via pg.zig — zero-Python CRUD by @justrach in #50

Full Changelog: v1.0.15...v1.0.16

Contributors

justrach
Loading
Previous 1 3 4 5
Previous

AltStyle によって変換されたページ (->オリジナル) /