Phase 2.2–2.5 docs + Phase 3 feature parity (openapi_extra, Enum coercion, CLI)#27
Merged
Phase 2.2–2.5 docs + Phase 3 feature parity (openapi_extra, Enum coercion, CLI)#27
Conversation
…s UX 2.2 Advanced User Guide: - docs/advanced/additional-responses.md: document extra OpenAPI status codes, response headers, multiple content types, and the "default" response key 2.3 Deployment Guides: - docs/deployment/systemd.md: systemd unit file, EnvironmentFile, socket activation, journald log commands, zero-downtime reload via SIGHUP - docs/deployment/gunicorn.md: Gunicorn + UvicornWorker setup, gunicorn.conf.py, worker sizing formula, preload_app caveats, systemd integration - docs/deployment/https.md: Let's Encrypt + Certbot, hardened Nginx TLS config, HSTS, auto-renewal deploy hook, TLS verification commands 2.4 Conceptual Docs: - docs/concepts/msgspec-vs-pydantic.md: philosophy comparison, perf table, API side-by-side (decode, encode, validators, field opts), coercion differences, migration table and step-by-step guide - docs/concepts/radix-tree-routing.md: O(k) complexity proof, iterative walk algorithm, __slots__ rationale, static-before-param priority, benchmark table, limitations (no regex constraints, no catch-all wildcards) 2.5 Docs Site UX (mkdocs.yml): - navigation.footer: prev/next page links at bottom of every page - content.action.edit / content.action.view: edit-on-GitHub and view-source buttons (backed by existing edit_uri) - content.code.annotate, search.highlight/suggest/share: enhanced search UX - custom_dir: docs/overrides with main.html for OpenGraph + Twitter card meta tags on every page - mike plugin: version selector in navbar with alias_type=symlink, canonical_version=latest and extra.version.provider=mike - pymdownx.snippets, pymdownx.emoji, footnotes markdown extensions added https://claude.ai/code/session_01JXqCtpvUCzfGyHNbcxe9D9
3.2 Core Feature Gaps — resolved:
openapi_extra= on route decorators
- app.py _add_route and _route_decorator: accept and store openapi_extra
- router.py _add_route and _route_kw: same treatment
- openapi/generator.py _build_operation: deep-merge openapi_extra into the
operation dict; responses key is merged rather than replaced so the primary
200 response is preserved alongside any extra ones
Enum path parameter coercion
- dependencies.py: add enum import and _coerce_path_value() helper that:
* Is a no-op for non-Enum annotations (strings, ints, etc.)
* For string-valued Enums: passes raw string directly to annotation()
* For numeric Enums (IntEnum, etc.): coerces string → value_type first
to handle "2" → Priority(2) correctly
* Returns 422 with clear permitted-values message on invalid input
- _resolve_path() and the implicit-path fallback in _resolve_from_specs
both route through _coerce_path_value()
3.3 CLI Tool — new FasterAPI/cli.py:
fasterapi run [app] [--host] [--port] [--workers] [--log-level]
Wraps uvicorn in production mode; auto-expands bare module names to
module:app; worker count defaults to 2×cores+1
fasterapi dev [app] [--host] [--port] [--log-level]
Same as run but passes --reload; no --workers flag
fasterapi new <name>
Scaffolds a complete project: app/main.py with lifespan, app/routers/items.py
with CRUD routes, pyproject.toml, Dockerfile, .gitignore, .env
fasterapi migrate-from-fastapi <path> [--dry-run]
Rewrites fastapi imports to FasterAPI across a file or directory tree using
ordered regex substitutions covering: FastAPI→Faster, APIRouter→FasterRouter,
fastapi.responses, fastapi.middleware, fastapi.security, fastapi.staticfiles,
fastapi.templating, fastapi.websockets, fastapi.testclient
pyproject.toml:
- Added [project.scripts] fasterapi = "FasterAPI.cli:main"
- Added mike>=2.0.0 to docs extras
tests/test_phase3.py: 29 new tests covering all three feature areas;
full test suite 291/291 green.
https://claude.ai/code/session_01JXqCtpvUCzfGyHNbcxe9D9
Contributor
Benchmark results
🟢 Benchmark status: improvement detected. HTTP throughput (FasterAPI vs FastAPI vs Fiber)
Direct ASGI (no HTTP; 50,000 iterations)
Routing (radix vs regex, 1,500,000 lookups)
How to read this
|
…ests - ruff format: reformat cli.py, dependencies.py, test_phase3.py to match project style (line length, blank lines, import ordering) - ruff I001: fix import block ordering in cli.py and test_phase3.py - ruff F401: remove unused imports (sys, Path, Annotated, pytest) from test_phase3.py - ruff B904: add `from None` to raise-in-except in _coerce_path_value so the chained exception context is suppressed intentionally - mypy no-any-return: annotate the result of args.func(args) in cli.main() explicitly as `int` to satisfy strict return-type checking All 291 tests pass; ruff and mypy both clean. https://claude.ai/code/session_01JXqCtpvUCzfGyHNbcxe9D9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR completes Phase 2.2–2.5 (docs expansion + site UX) and Phase 3 (feature parity + CLI) from the project roadmap.
Phase 2.2 — Advanced User Guide
docs/advanced/additional-responses.md(new) — Documents theresponses=parameter: multiple status codes with schemas, shared error models (COMMON_ERRORSdict pattern), response headers, multiple content types, and the"default"catch-all key.Phase 2.3 — Deployment Guides
docs/deployment/systemd.md(new) — Full systemd unit file with security hardening (PrivateTmp,ProtectSystem,NoNewPrivileges),EnvironmentFilefor secrets, socket activation, journald log commands, zero-downtime SIGHUP reload.docs/deployment/gunicorn.md(new) — Gunicorn +UvicornWorkersetup,gunicorn.conf.pywithmax_requestsjitter andpreload_appcaveats, worker sizing formula, Docker and systemd integration.docs/deployment/https.md(new) — Let's Encrypt + Certbot walkthrough, hardened Nginx TLS config (TLS 1.2/1.3, HSTS, security headers), auto-renewal deploy hook, TLS verification commands.Phase 2.4 — Conceptual Docs
docs/concepts/msgspec-vs-pydantic.md(new) — Philosophy table, performance benchmark table (~5× across encode/decode/construction), full API side-by-side comparisons (decode, encode, field opts, validators), coercion and mutability differences, migration table, step-by-step migration guide.docs/concepts/radix-tree-routing.md(new) — O(k) complexity proof vs linear/regex routers, visual tree diagram, annotated iterative_walkalgorithm,__slots__rationale, static-before-param priority, routing benchmark table, documented limitations (no regex constraints, no catch-all).Phase 2.5 — Docs Site UX (
mkdocs.yml)navigation.footerfeaturecontent.action.edit/content.action.viewdocs/overrides/main.htmlinjectsog:*andtwitter:*on every page viacustom_dirmikeplugin +extra.version.provider: mikefor navbar version selectorsearch.highlight,search.suggest,search.sharecontent.code.annotatepymdownx.snippets,pymdownx.emoji,footnotesmike>=2.0.0added todocsoptional depsPhase 3.2 — Core Feature Gaps
openapi_extra=on route decorators (app.py,router.py,openapi/generator.py)openapi_extra: dict | Noneresponseskey is deep-merged so the primary 200 response is preserved alongside any extra onesFasterapp decorators andFasterRouterdecoratorsEnum path parameter coercion (
dependencies.py)_coerce_path_value()helper called from both explicitPathmarkers and the implicit fallbackannotation()directlyIntEnum): coerces string → value type first, so"2"→Priority(2)422with a clear"permitted: [...]"messagePhase 3.3 — CLI Tool (
FasterAPI/cli.py+pyproject.toml)New
fasterapientrypoint with four sub-commands:fasterapi run [app]2×cores+1fasterapi dev [app]--reload; no workers flagfasterapi new <name>fasterapi migrate-from-fastapi <path> [--dry-run]fastapiimports toFasterAPIacross a file/directory treeTest plan
tests/test_phase3.py— 29 new tests coveringopenapi_extra(5 cases), Enum coercion (6 cases includingIntEnumnumeric coercion), and all CLI commands (18 cases including scaffold file creation, migration rewriting, dry-run, edge cases)master(no stale benchmark-sync commits)