Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
dd605d7
feat: implement global exception handlers for sync and async routes
ZhuchkaTriplesix Jun 21, 2026
7238344
chore: format app.py
ZhuchkaTriplesix Jun 21, 2026
64ef662
chore: format rust code
ZhuchkaTriplesix Jun 21, 2026
f4ce726
chore: remove debug print
ZhuchkaTriplesix Jun 21, 2026
cab8952
chore: fix clippy warnings
ZhuchkaTriplesix Jun 21, 2026
a303e6d
Merge pull request #121 from QueryaHub/issue-99-exception-handlers
ZhuchkaTriplesix Jun 21, 2026
02eb862
docs: update development workflow instructions
ZhuchkaTriplesix Jun 21, 2026
108101f
feat(validation): runtime body_model validation with 422 errors
ZhuchkaTriplesix Jun 21, 2026
bb9d2a8
Merge pull request #122 from QueryaHub/issue-100-validation
ZhuchkaTriplesix Jun 21, 2026
f3ae3af
feat(request): introduce typed Request object with lazy headers
ZhuchkaTriplesix Jun 21, 2026
7c94990
Merge pull request #123 from QueryaHub/issue-101-request
ZhuchkaTriplesix Jun 21, 2026
eb91f5b
feat(testing): ship oxyroute.testing.TestClient
ZhuchkaTriplesix Jun 21, 2026
b866188
Merge pull request #124 from QueryaHub/issue-102-testclient
ZhuchkaTriplesix Jun 21, 2026
da45828
feat(streaming): generic stream responses (generators) for non-SSE ch…
ZhuchkaTriplesix Jun 21, 2026
0a24fe3
Merge pull request #125 from QueryaHub/issue-103-streaming
ZhuchkaTriplesix Jun 21, 2026
e5ba58a
feat(static): add StaticFiles and App.mount
ZhuchkaTriplesix Jun 21, 2026
8b03342
Merge pull request #126 from QueryaHub/issue-104-static
ZhuchkaTriplesix Jun 21, 2026
e1af4ab
feat(observability): request id, access log, metrics hooks
ZhuchkaTriplesix Jun 22, 2026
2155e06
style: sort ProtocolWrapper __slots__ to pass ruff RUF023
ZhuchkaTriplesix Jun 22, 2026
0ded643
style: format oxyroute/app.py to pass ruff format
ZhuchkaTriplesix Jun 22, 2026
ffd8d23
Merge pull request #127 from QueryaHub/feat/observability-hooks
ZhuchkaTriplesix Jun 22, 2026
94b0533
perf(router): avoid path-param allocs on fast paths
ZhuchkaTriplesix Jun 22, 2026
2769775
style: format rust files
ZhuchkaTriplesix Jun 22, 2026
a388de5
Merge pull request #128 from QueryaHub/feat/router-perf
ZhuchkaTriplesix Jun 22, 2026
bf8272d
perf(openapi): cache serialized string
ZhuchkaTriplesix Jun 22, 2026
25cb2a9
fix(tests): replace HashMap with Vec in test mocks to fix compilation
ZhuchkaTriplesix Jun 22, 2026
27ad05d
Merge pull request #129 from QueryaHub/feat/openapi-cache
ZhuchkaTriplesix Jun 22, 2026
18cd856
feat(openapi): docs UI, path/JWT enrichment, Granian lifespan
ZhuchkaTriplesix Jul 20, 2026
a86067a
style: ruff format oxyroute/app.py
ZhuchkaTriplesix Jul 20, 2026
539948f
style: cargo fmt lib.rs and state.rs
ZhuchkaTriplesix Jul 20, 2026
4ed2d73
Merge pull request #131 from QueryaHub/issue-130-openapi-docs-ui
ZhuchkaTriplesix Jul 20, 2026
4380422
perf(jwt): prebuild DecodingKey and Validation per route
ZhuchkaTriplesix Jul 20, 2026
5d249a3
Merge pull request #132 from QueryaHub/issue-109-jwt-prebuild
ZhuchkaTriplesix Jul 20, 2026
73a16f6
perf(cors): skip Python CORS merge when Origin is absent
ZhuchkaTriplesix Jul 20, 2026
c8a3a45
Merge pull request #133 from QueryaHub/issue-108-cors-skip-origin
ZhuchkaTriplesix Jul 20, 2026
8c69e14
test(perf): Criterion microbenches and wrk scenarios
ZhuchkaTriplesix Jul 20, 2026
36d5957
Merge pull request #134 from QueryaHub/issue-110-criterion-benches
ZhuchkaTriplesix Jul 20, 2026
970943e
chore: stop tracking .cursor; keep workflow in docs
ZhuchkaTriplesix Jul 20, 2026
2363577
Merge pull request #135 from QueryaHub/chore-remove-cursor-dir
ZhuchkaTriplesix Jul 20, 2026
28224a5
chore(release): prepare 0.5.0
ZhuchkaTriplesix Jul 20, 2026
c3d2003
docs: align usage guide with v0.5.0
ZhuchkaTriplesix Jul 20, 2026
ea12ec9
Merge pull request #137 from QueryaHub/release-0.5.0
ZhuchkaTriplesix Jul 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .github/workflows/perf-smoke.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: perf-smoke

# Opt-in smoke for Criterion + short wrk (issue #110). Not part of default PR CI.
on:
workflow_dispatch:
schedule:
- cron: "0 6 * * 1" # Mondays 06:00 UTC

jobs:
criterion:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- uses: astral-sh/setup-uv@v4
with:
enable-cache: true
- name: Sync + Criterion smoke
run: |
uv sync --frozen --extra dev
# Quiet, short Criterion run (still builds the bench binary).
cargo bench --bench hot_path -- --sample-size 10 --warm-up-time 1 --measurement-time 2

wrk-scenarios:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- uses: astral-sh/setup-uv@v4
with:
enable-cache: true
- name: Install wrk
run: sudo apt-get update && sudo apt-get install -y wrk
- name: Build oxyroute and run short scenarios
run: |
set -euo pipefail
uv sync --frozen --extra dev --extra bench
rm -f target/wheels/oxyroute-*.whl
uv run maturin build --release
shopt -s nullglob
wheels=(target/wheels/oxyroute-*.whl)
shopt -u nullglob
uv pip install --force-reinstall "${wheels[0]}"
chmod +x perf-test/bench_scenarios.sh
OXYROUTE_BENCH_DURATION=1s OXYROUTE_BENCH_CONNECTIONS=8 OXYROUTE_BENCH_THREADS=1 \
./perf-test/bench_scenarios.sh
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ env/

# --- IDE / editor ---
.idea/
.cursor/
*.swp
*~

Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Notes for AI agents (OxyRoute)

- **Git / branches / PRs / validation** — [`.cursor/rules/git-workflow.mdc`](.cursor/rules/git-workflow.mdc) (`alwaysApply`).
- **Git / branches / PRs / validation** — [docs/development-workflow.md](docs/development-workflow.md) (integration branch `dev`, issue branches, atomic commits, PR to `dev`).
- **Validation (ruff, cargo, `make test`, pytest, maturin):** the **maintainer runs these** before push. **Do not** run that full pipeline in the agent unless the user explicitly asks (e.g. “run `make test`”, “fix the failing test”). If something failed in CI or locally, the user will say so — then fix what they report.
60 changes: 60 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,66 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.5.0] - 2026-07-20

### Added

- First-class OpenAPI docs UI: `App(..., docs_ui="scalar"|"swagger")` and
`app.mount_docs(...)` serve CDN-backed Scalar / Swagger UI at `/docs` against
`/openapi.json` ([#130](https://github.com/QueryaHub/OxyRoute/issues/130)).
- OpenAPI enrichment for interactive explorers: matchit `:param` / `*rest` → `{param}` /
`{rest}` with path `parameters`; JWT `bearerAuth` when `require_jwt=True`; operation
`tags=` / `include_router(..., tags=[...])`; `set_openapi_info` and constructor
`openapi_description` / `openapi_contact` / `openapi_servers`.
- Granian-compatible lifespan: sync `__rsgi_init__(loop)` / `__rsgi_del__(loop)` run
`on_startup` / `on_shutdown` via `loop.run_until_complete`. Prefer overriding
`on_startup` / `on_shutdown` instead of `async def __rsgi_init__`.
- `oxyroute.testing.TestClient` for in-process HTTP tests ([#102](https://github.com/QueryaHub/OxyRoute/issues/102)).
- Typed `Request` with lazy headers ([#101](https://github.com/QueryaHub/OxyRoute/issues/101)).
- Runtime `body_model` validation with HTTP 422 ([#100](https://github.com/QueryaHub/OxyRoute/issues/100)).
- Global exception handlers for sync and async routes
([#99](https://github.com/QueryaHub/OxyRoute/issues/99)).
- Optional request / response middleware chain
([#98](https://github.com/QueryaHub/OxyRoute/issues/98)).
- `StaticFiles` and `App.mount` ([#104](https://github.com/QueryaHub/OxyRoute/issues/104)).
- Generic streaming responses (non-SSE chunked generators)
([#103](https://github.com/QueryaHub/OxyRoute/issues/103)).
- Observability hooks: request id, access log, metrics
([#127](https://github.com/QueryaHub/OxyRoute/pull/127)).
- SQLx / Postgres pool helpers on `AppState` and dynamic query execution from Python
dependencies ([#116](https://github.com/QueryaHub/OxyRoute/issues/116),
[#118](https://github.com/QueryaHub/OxyRoute/issues/118)).
- Criterion microbenchmarks (`cargo bench --bench hot_path`) and expanded wrk scenarios
(`perf-test/bench_scenarios.sh`); optional `perf-smoke` workflow
([#110](https://github.com/QueryaHub/OxyRoute/issues/110)).

### Changed

- OpenAPI path keys use `{param}` form (breaking for consumers that asserted matchit
`:param` strings in `openapi_json()`).
- JWT hot path reuses prebuilt `DecodingKey` and `Validation` per route
([#109](https://github.com/QueryaHub/OxyRoute/issues/109)).
- CORS response merge skips the Python `response_header_pairs` call when the request has
no `Origin` header ([#108](https://github.com/QueryaHub/OxyRoute/issues/108)).
- OpenAPI document string is cached until the next registration change
([#129](https://github.com/QueryaHub/OxyRoute/pull/129)).
- Router / dispatch hot-path improvements: fewer path-param allocations, sync short-circuit
for trivial routes, direct `json_to_py`, cheaper str/bytes responses, env-flag caching
([#94](https://github.com/QueryaHub/OxyRoute/issues/94)–[#97](https://github.com/QueryaHub/OxyRoute/issues/97),
[#128](https://github.com/QueryaHub/OxyRoute/pull/128)).

### Migration

- Prefer `async def on_startup` / `on_shutdown` for worker lifecycle under Granian. Do not
override `__rsgi_init__` as `async def` (the coroutine is never awaited).
- Update any tooling that expected OpenAPI paths with matchit `:param` syntax to `{param}`.
- Interactive docs: `App(..., docs_ui="scalar")` (or `mount_docs`) instead of app-local HTML.

## [0.4.0] - 2026-05

RSGI-only line with native WebSockets, forms, CORS/CSRF/security headers, and related
hardening after the v0.3.0 ASGI removal. See `git log v0.3.0..v0.4.0` for the full list.

## [0.3.0] - 2026-04-27

### Added
Expand Down
Loading
Loading