Skip to content

Add packaged FastAPI service and performance runner - #93

Merged
forhappy merged 2 commits into
mainfrom
codex/python-fastapi-deployment
Oct 21, 2026
Merged

forhappy merged 2 commits into
mainfrom
codex/python-fastapi-deployment

Conversation

@forhappy

@forhappy forhappy commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

FastAPI applications can serve validated HTTP routes inside Cellar's embedded Python host while keeping durable business state in native cells. This adds a runnable order-draft service plus a complete dependency-packaging and deployment example.

  • Async FastAPI routes provide validation, OpenAPI and request-scoped Cellar dependencies. Each order uses a named cell, integer-cent totals, checked version/status changes and a creation receipt committed atomically with its state. Matching creation retries replay the sealed response after later writes and restart; conflicting requests return 409.
  • An example-local ASGI HTTP transport preserves binary bodies, repeated headers and request context, bounds buffered output, propagates cancellation and refuses incomplete responses. It supports async buffered HTTP; lifespan hooks, WebSockets and live streaming remain outside this example.
  • The packaging helper provisions CPython 3.14.5 or 3.14.5t, installs hash-locked FastAPI/Pydantic wheels, captures native prerequisites and builds the verified runtime archive/native package. The guide covers local execution, bucket publication, per-node installation, supervision and versioned process replacement.
  • The deployment drill moves the original runtime aside, publishes/restores through the native package API, then exercises the installed executable with a cleared environment. It tests real HTTP, concurrent orders, exact creation-response replay, conflicts, preserving restart and complete combined drain. All fixtures use a private SQLite development bucket.
  • A dedicated Linux workflow runs packaging, ASGI boundaries and installed-host deployment independently for both threading ABIs. Existing evidence/audit/baseline reports remain excluded.
  • A reusable performance runner measures read/new-cell creation/checked update throughput and p50/p95/p99 latency at configurable concurrency. It verifies every acknowledged mutation by readback, requires complete shutdown, records raw samples outside Git and optionally leaves a fresh server running. CI adds a functional harness smoke without performance thresholds.

Validation passed locally on macOS ARM64:

  • Complete package/build/restore/deployment smoke on CPython 3.14.5 and 3.14.5t; the free-threaded health check requires GIL-disabled execution.
  • Five buffered-ASGI boundary/framework tests per ABI, including cancellation, context separation, response limits and real FastAPI validation/OpenAPI.
  • Existing-environment packaging refusal preserves the inventory and creates no output package.
  • Strict Clippy for both Python binaries and the deployment example; Rust formatting/module layout, no-JavaScript dependency graph, documentation/local links and diff whitespace checks.

At the current head (0fc9eb5), the dedicated Linux Python application workflows passed for CPython 3.14.5 and 3.14.5t on both push and pull request, including packaging/deployment and performance-harness correctness checks. The broader Rust framework/SDK matrix is still running. Python example CI; SDK CI.

These measurements use one Mac M2 Max, loopback HTTP and a private local SQLite development bucket. They do not qualify remote object-store performance, fleet capacity or general ASGI lifecycle/streaming behavior.

Local performance measurements

Operation Clients Requests/s p50 ms p95 ms p99 ms Requests Errors
read 1 184.7 5.22 5.58 8.82 2956 0
create 1 32.6 29.20 34.48 41.32 1024 0
update 1 53.9 17.41 24.09 43.10 1024 0
read 8 1472.8 5.19 6.04 9.67 23586 0
create 8 90.8 64.43 182.37 362.90 1024 0
update 8 138.6 29.12 149.68 310.25 1024 0
read 32 3949.6 6.48 14.82 23.02 63397 0
create 32 130.8 165.08 470.21 913.88 1024 0
update 32 169.8 39.53 658.15 1396.45 1024 0

Two repetitions per concurrency; throughput aggregates successful requests over measured wall time, and percentiles pool individual request samples. All 96,083 timed requests succeeded; every one of the 6,144 acknowledged mutations passed readback, and all six benchmark servers completed combined native/Python shutdown. A separate smoke of the final runner also passed.

Read requests target 32 warm orders. Each create uses a new durable cell/SQLite database and includes ownership acquisition; each update confirms a distinct pre-created order with a version check. Setup and readback are excluded from timing; writes are submitted once without automatic retries.

Hardware/runtime: Apple M2 Max (12 CPUs, 32 GiB), macOS ARM64, optimized lab profile, four Rust workers, embedded CPython 3.14.5 with the GIL enabled, and a free-threaded Python load generator using persistent HTTP/1.1 connections. Client and server share the machine. The 32-client read runs varied from 2,932 to 4,973 requests/s, so the aggregate is a local observation rather than a capacity guarantee. Higher write concurrency increases tail latency substantially.

Reproduction instructions are in examples/python-fastapi/README.md. Raw samples and generated reports stay outside Git; no evidence/audit/baseline files are added.

@forhappy forhappy changed the title Add packaged FastAPI order service example Add packaged FastAPI service and performance runner Oct 21, 2026
@forhappy
forhappy merged commit bc540b6 into main Oct 21, 2026
9 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant