The format is loosely based on Keep a Changelog. Versions follow SemVer.
0.1.7 - 2026-05-16
Static-response cache. Plaintext throughput jumped from #2 to #1 in the competitive suite, and we lead all six scenarios on both throughput and p99 latency now.
- Static-response cache. Handlers that just
return PlainTextResponse("Hello, World!")(orJSONResponse(...)/HTMLResponse(...)/Response(...)with literal args, no params) get their two ASGI messages built once at registration via AST inspection. Dispatch is one branch + two awaits. Local micro-bench: 0.89 µs/req, 1.1M req/s on raw ASGI. Other handlers fall through unchanged.
- README leads with "Why HawkAPI" (Performance / Production rigor / Unique features). Added a p99-latency table — we win every scenario there too.
0.1.6 - 2026-05-16
Security audit. Five SAST/dep/secrets scanners added to CI. Three HIGH findings fixed.
get_flagsno longer reads identity fromX-User-Id/X-Tenant-Idheaders (CWE-290). Identity must come from an authenticated dependency. Raw headers still onctx.headersfor non-identity rules.- GraphQL
GETrejects mutations and subscriptions for every operation in the document, not just the first token (CWE-352). - GraphQL endpoints now have
max_depth=15andtimeout_s=30.0defaults;make_graphql_handlerwraps the executor inasyncio.wait_for(CWE-770). mount_graphqlshipsgraphiql=Falseby default (CWE-200). Opt in for dev environments.mount_grpcaddsmaximum_concurrent_rpcs=1000default. PassNoneto opt out.doctorDOC050 explicit-scheme-checks its hard-coded PyPI URL; clean under bandit B310 and semgrep.
SECURITY.md,docs/security/threat-model.md(STRIDE per subsystem),docs/security/owasp-api-top10-2023.md,docs/security/code-review-2026-05-16.md..github/workflows/security.ymlruns Bandit + Semgrep + pip-audit + Gitleaks + CodeQL on every push, PR, and weekly..github/dependabot.ymlfor weekly pip + actions updates.
0.1.5 - 2026-04-19
Fixes from the full code review.
- Static-response handler returning
StreamingResponse/FileResponsecould run twice through the trivial fast-path fallback._compute_trivialnow excludes streaming-return handlers at registration; the fast path also guards in-place. - Typed path params (
{id:int}etc.) were not coerced on the trivial fast-path. Now they are. - GraphiQL HTML pins exact versions (
graphiql@3.0.9,react@18.3.1,react-dom@18.3.1) and adds SRIintegrity=hashes on every script/stylesheet. FileFlagProvidernow writes_cachebefore_mtimeso concurrent readers can't observe a new mtime with a stale cache.- Hoist
ParamSource/_coerce_fastimports out of_execute_trivial_route— small per-request win.
hawkapi doctor --offlineskips rules that hit the network (DOC050 PyPI version check). Rules opt in viarequires_network = True.- README note: use
secrets.compare_digestto compare credentials fromHTTPBasic/HTTPBearer.
build_mypyc.pydocuments the MSVC__is_trivial/__has_*trait trap so future private attributes avoid the C++11 keyword collisions.- ruff config excludes local venvs, build artefacts, and non-library code (
benchmarks/,examples/,hatch_build.py).
0.1.4 - 2026-04-19
Wave 3 perf, hawkapi doctor CLI, badge + logo for downstream projects.
hawkapi doctor <APP_SPEC>— 18-rule health check across security / observability / performance / correctness / deps. Human or JSON output,--severityfilter, exit 0/1/2.docs/assets/hawk-icon.svg+ "Using HawkAPI?" README section with a dynamic PyPI-version badge and copy-paste snippets.
- Trivial-route fast path. Routes with no DI, deps, permissions, background tasks, response model, deprecation, or per-route middleware skip all bookkeeping and call the handler directly. Eligibility computed once at registration. Targeted at plaintext throughput.
hawkapi devinstallsuvloop.EventLoopPolicy()when available;--no-uvloopto opt out.- Added
routing/router.pyanddi/resolver.pyto mypycHOT_MODULES.app.pyandrequests/request.pystay interpreted (user subclassing).
0.1.3 - 2026-04-19
Tier 2 (Bulkhead / Feature flags / GraphQL / gRPC), Tier 3 (OpenAPI codegen, typed routes), DX parity with FastAPI.
app.mount_grpc(servicer, add_to_server=..., port=50051)— thin gRPC overgrpc.aiowith ASGI lifespan, built-in observability interceptor, reflection toggle, TLS passthrough, port-merge. Zero default deps (grpciolazy).app.mount_graphql(path, executor=...)— POST + GET wire protocol, GraphiQL UI,context_factory, andfrom_graphql_core/from_strawberryadapters (lazy).- Feature flags:
FlagProviderProtocol, Static / Env / File providers (File with mtime hot-reload, JSON+TOML+YAML),Flagsfacade,Depends(get_flags),@requires_flag,on_flag_evaluatedplugin hook. hawkapi gen-client— zero-dep TypeScript and Python client SDKs from OpenAPI 3.1.response_modelauto-inferred from the handler's return annotation (msgspec, Pydantic, generics, Optionals). Explicitresponse_model=still wins.hawkapi migrate— FastAPI → HawkAPI codemod via AST rewriting.- Bulkhead primitive (
@bulkhead(name, limit=...)) with Local and Redis backends; opt-in Prometheus metrics. hawkapi.status— HTTP + WebSocket status constants (FastAPI parity).- Route- and router-level
dependencies=[Depends(...)]for side-effect deps. Security(dep, scopes=[...])+SecurityScopes+ OpenAPIoperation.securityreflection.response_model_exclude_none/_unset/_defaultsflags on routes.- Free-threaded Python 3.13 wheels (
cp313t-cp313t) via cibuildwheel;hawkapi._threadinghelpers for PEP 703. - Performance regression gate (5% mean threshold) and pytest-memray memory budget tests in CI.
- Distributed Redis-backed circuit breaker and adaptive concurrency limiter.
- HTTP/2 deployment guide.
- Competitive benchmark CI: weekly cron + release trigger, auto-PR with refreshed
RESULTS.md.
0.1.2 - 2026-04-05
- CSRF (double-submit cookie), Session (signed cookie), Redis rate limiter.
- Per-route middleware:
@app.get("/x", middleware=[...]). - Streaming request body (
request.stream()). - MessagePack content negotiation.
- W3C Trace Context propagation.
- Plugin hooks:
on_startup,on_shutdown,on_exception,on_middleware_added. hawkapi initCLI.- TestClient cookie jar,
CaseInsensitiveDictheaders,is_success/is_redirect/raise_for_statushelpers.
- Multipart
rstripcorrupting binary uploads. StreamingResponsenot sending terminal ASGI chunk on error.- CRLF injection in
RedirectResponse. - Radix tree silent param name / type conflicts.
- Circuit breaker holding
asyncio.Lockduring I/O. X-Forwarded-ForIP spoofing (now uses rightmost non-trusted).- HEAD responses preserving correct
Content-Length. - Generator dependency cleanup distinguishes success / error.
- Duplicate
Content-Lengthfrom middlewareafter_response. - GZip double-compression of already-encoded responses.
FileResponsemore_bodyflag on exact chunk boundaries.- DI
Providerasyncio.Lockcreated lazily. Settings._coercecrash onOptional[T].- WebSocket send methods check connection state.
- Cookie parser strips RFC 6265 quoted values.
- ~40 more bug fixes.
app.pysplit into_docs.py/_health.py/_execute_route().- Controllers instantiated per request (was shared singleton).
- Middleware stack uses
MiddlewareEntrydataclass.
0.1.1 - 2026-03-04
- Middleware:
Prometheus,StructuredLogging(structlog),CircuitBreaker(closed → open → half-open),TrustedProxy,RequestLimits,Debug. /readyz+/livezhealth probes.- Deprecation headers:
Deprecation,Sunset,Link. - Pagination:
Page[T],CursorPage[T],PaginationParams,CursorParams. - OpenAPI
exampleonQuery,Path,Header,Body,Cookie. - CLI:
hawkapi new,hawkapi check,hawkapi changelog,hawkapi diff. - DI container introspection (JSON + Mermaid graph).
- Plugin API: route registration + schema generation hooks.
- TypeScript / Python client SDK templates.
- Docker template + deployment guide; FastAPI migration guide.
- E2E benchmark suite + GitHub Action.
- PyPI trusted publishing workflow.
- Singleton provider race: eager lock +
_UNSETsentinel forNonecaching. StreamingResponseonly sends terminal frame on successful completion.CircuitBreakerMiddlewarestate transitions underasyncio.Lock.ObservabilityMiddlewarerecords viatry/finally.- WebSocket 404: consume
websocket.connectbefore close frame (ASGI protocol). HTTPBearer/HTTPBasic/OAuth2PasswordBearerreturnWWW-Authenticateon 401.- Empty bearer / OAuth2 tokens rejected.
BackgroundTaskshandlesfunctools.partialviagetattr(func, "__name__", repr(func)).Pagedivision by zero onsize <= 0.detect_breaking_changeskeys parameters by(name, in)and resolves$refin responses.TrustedProxyMiddlewarevalidates IPs viaipaddress.ip_address().JSONResponsededupesContent-Typewhen caller sets one.- Radix tree
find_allowed_methodspath normalization matcheslookup(). - OpenAPI schema shallow-copies operation dict for multi-method routes.
- Middleware guide:
before_request/after_responsehooks (washandle(call_next)). - Middleware table: 6 → 15 entries.
StreamingResponse:media_type→content_type.- Removed phantom
shutdown_drain_timeout,Settings.Config. metricsandloggingextras documented.- README fixes:
credentials.credentials, pagination ctor, cursor param.
0.1.0 - 2026-03-03
Initial release.
- ASGI 3.0 core, custom middleware pipeline.
- Radix tree router with typed path params (
int/str/float/uuid). - Responses: JSON, HTML, PlainText, Redirect, Streaming, File, SSE.
- DI container: singleton / scoped / transient lifecycles, generator deps with
yield, nestedDepends()cleanup. response_modelfiltering.- OpenAPI 3.1 auto-gen + Swagger UI, ReDoc, Scalar.
- Middleware: CORS, GZip, Timing, TrustedHost, SecurityHeaders, RequestID, HTTPSRedirect, RateLimit, ErrorHandler.
- Security schemes: API Key (header/query/cookie), HTTPBearer, HTTPBasic, OAuth2PasswordBearer.
- WebSocket with async iteration + DI.
- Class-based controllers.
- Router with prefix, tags, mounts.
Settingswith env binding and profiles.TestClient(sync, pytest-friendly), scoped DI overrides.BackgroundTasks,StaticFiles(with path traversal protection, ETag, 304).HTTPExceptionwith RFC 9457 Problem Details.- Request body size limits.
hawkapi devCLI (uvicorn auto-reload).- Sync handler support via threadpool.
- API versioning (
VersionRouter, per-version OpenAPI). - Breaking-changes detector (
detect_breaking_changes()). - RBAC via
PermissionPolicy+permissions=on routes/WS. ObservabilityMiddlewarewith structured logs + traces + metrics.- Cold-start optimizations: lazy imports,
serverless=True. - Health endpoint (
/healthz), request timeout, graceful shutdown. py.typed, pyright-strict clean, MkDocs site.