Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
286 commits
Select commit Hold shift + click to select a range
a33eb41
WIP
alexeyshockov Mar 19, 2026
bfe63e7
WIP on DI
alexeyshockov Mar 19, 2026
377750e
WIP on DI
alexeyshockov Mar 19, 2026
3dbcd68
WIP on DI
alexeyshockov Mar 19, 2026
1d77944
WIP on DI
alexeyshockov Mar 19, 2026
02517c7
WIP on DI
alexeyshockov Mar 19, 2026
2b213eb
chore: pyright to ty
alexeyshockov Mar 19, 2026
2bfd57a
WIP on DI
alexeyshockov Mar 19, 2026
06cad70
WIP on DI
alexeyshockov Mar 19, 2026
d6f2d5b
WIP on DI
alexeyshockov Mar 19, 2026
33b3d6d
WIP on DI
alexeyshockov Mar 19, 2026
7946adf
WIP on DI
alexeyshockov Mar 19, 2026
9e4856c
WIP on DI
alexeyshockov Mar 19, 2026
71e9408
WIP on DI, Flask
alexeyshockov Mar 19, 2026
33950bd
WIP on DI, Flask via Cheroot
alexeyshockov Mar 20, 2026
0e698fe
WIP on DI, Flask via Cheroot
alexeyshockov Mar 20, 2026
3e3b05a
WIP on DI, Flask via Cheroot (proper contextvar middleware)
alexeyshockov Mar 20, 2026
7f8c731
WIP on DI
alexeyshockov Mar 20, 2026
9f515b1
format
alexeyshockov Mar 20, 2026
368f372
WIP on DI (Flask)
alexeyshockov Mar 20, 2026
78d2131
fix: WIP on DI (Flask)
alexeyshockov Mar 20, 2026
91399b8
WIP on DI
alexeyshockov Mar 21, 2026
1811bcb
WIP on DI
alexeyshockov Mar 21, 2026
ee9ab44
WIP on DI (no magic around close())
alexeyshockov Mar 21, 2026
27c7080
WIP on DI: create_on_enter
alexeyshockov Mar 21, 2026
61684e1
WIP on DI
alexeyshockov Mar 21, 2026
be5da39
WIP on DI
alexeyshockov Mar 21, 2026
65a6cfa
cleanup
alexeyshockov Mar 22, 2026
fc7cee2
WIP on DI
alexeyshockov Mar 22, 2026
ac414e2
docs: refresh CLAUDE.md and add per-module READMEs
alexeyshockov Apr 21, 2026
62ea4b3
WIP
alexeyshockov Apr 24, 2026
4ef3953
feat(http): end-to-end multi-threaded HTTP flow with per-request canc…
alexeyshockov Apr 24, 2026
aba0e5f
refactor(http): split Router into Routes builder + immutable Router
alexeyshockov Apr 24, 2026
e04edd3
feat(http): native Flask adapter in localpost.http.flask
alexeyshockov Apr 24, 2026
613fa0c
feat(http): tailored Sentry integration for Router and Flask
alexeyshockov Apr 24, 2026
929b156
refactor(http): Route dataclass, drop hand-maintained status phrases
alexeyshockov Apr 25, 2026
c65b59c
refactor(http): decouple Server.run from threadtools
alexeyshockov Apr 25, 2026
5edd8f3
test(http): centralize fixtures, drop magic iteration counts
alexeyshockov Apr 25, 2026
4e9a8fe
test: pytest-timeout safety net (30s default)
alexeyshockov Apr 25, 2026
2af57e6
test(http): pin server edge cases (protocol errors, expect-100, HEAD,…
alexeyshockov Apr 25, 2026
c090da8
test(http): property-test URITemplate round-trip with hypothesis
alexeyshockov Apr 25, 2026
3ac12a9
test(http): pin Router method/edge behaviors
alexeyshockov Apr 25, 2026
674e2da
test(http): strengthen hosted http_server invariants
alexeyshockov Apr 25, 2026
ba60356
test(http): expand integration test coverage
alexeyshockov Apr 25, 2026
38da1df
refactor(http): bind handler at server construction, add select_timeout
alexeyshockov Apr 25, 2026
27c9184
feat(http): catch handler exceptions, return 500 instead of crashing
alexeyshockov Apr 25, 2026
6189c2d
feat(http): handle h11 protocol errors, isolate per-connection failures
alexeyshockov Apr 25, 2026
292d56d
feat(http): graceful shutdown — close active connections on exit
alexeyshockov Apr 25, 2026
9fe6afa
feat(http): enforce ServerConfig.max_body_size
alexeyshockov Apr 25, 2026
4c27742
feat(http): emit 408 Request Timeout on stalled mid-request connections
alexeyshockov Apr 25, 2026
c97be64
feat(http): accept Buffer in send + advertise Keep-Alive timeout
alexeyshockov Apr 26, 2026
f2f8dde
feat(http): proper half-close — shutdown(SHUT_WR) before close
alexeyshockov Apr 26, 2026
529b229
docs(http): roadmap entry for self-pipe wakeup, drop matching TODOs
alexeyshockov Apr 26, 2026
ab57a73
WIP
alexeyshockov Apr 26, 2026
ac562e4
WIP on Flask
alexeyshockov Apr 26, 2026
367d497
review follow-ups: fix mid-stream-crash test + resolve stale markers
alexeyshockov Apr 26, 2026
29fb178
test(hosting): cover run_app, _run_many, defer/adefer, signals, conte…
alexeyshockov Apr 27, 2026
30132b0
bench: add HTTP macro + micro benchmark suites
alexeyshockov Apr 27, 2026
0186021
feat(http): worker-pool dispatcher + HTTP-native request cancellation
alexeyshockov Apr 27, 2026
cf7c7cc
perf(http): pre-bake keep-alive header, fold environ pass, drop redun…
alexeyshockov Apr 27, 2026
7b1fdd0
refactor(http): collapse watchdog into pull-based check_cancelled
alexeyshockov Apr 27, 2026
621f98f
docs(http): document check_cancelled + two-state conn model
alexeyshockov Apr 27, 2026
66a7999
perf(http): lock-free op queue + self-pipe wakeup
alexeyshockov Apr 27, 2026
7d338c2
perf(http): lazy _cleanup_stale to skip the O(N) walk per iter
alexeyshockov Apr 27, 2026
90036b1
perf(http): probe selector before modify; drop Keep-Alive timeout header
alexeyshockov Apr 27, 2026
e8af3d4
chore(perf): new benchmark scenario
alexeyshockov Apr 27, 2026
c94a202
refactor(http): split handler / Router / hosting; selector-thread 404…
alexeyshockov Apr 28, 2026
8ce1868
fix(di): use reentrant lock so factories can resolve their own deps
alexeyshockov Apr 28, 2026
b249bef
fix(scheduler): restore working state from 8a40d99 + adapt to current…
alexeyshockov Apr 28, 2026
881f0c8
chore: clean up dead commented imports/__all__ in localpost/__init__.py
alexeyshockov Apr 28, 2026
b9c7b4f
chore: clear remaining ruff/ty errors in stable packages
alexeyshockov Apr 28, 2026
16a15b0
chore(deps): add vulture for dead-code detection
alexeyshockov Apr 28, 2026
3c90dd8
refactor: move consumers and openapi to localpost.experimental
alexeyshockov Apr 28, 2026
70c866f
chore: code-quality follow-ups (dead code, PEP 695, ruff/ty)
alexeyshockov Apr 28, 2026
92b737a
perf(threadtools): inline put_nowait body into Channel.put
alexeyshockov Apr 28, 2026
5ed678a
refactor(scheduler): collapse Scheduler lifecycle into hosting
alexeyshockov Apr 28, 2026
ef6f562
feat(http): optional httptools backend alongside h11
alexeyshockov Apr 29, 2026
4935501
docs(http): add Phase 6 (httptools backend) to PERF_FINDINGS
alexeyshockov Apr 29, 2026
7d94641
feat(http): selectors=N knob and Phase 7/7b validation
alexeyshockov Apr 29, 2026
8e9b838
feat(http): two-phase handler contract + auto-buffered response (Phas…
alexeyshockov Apr 29, 2026
8af0dc5
feat(http): middleware foundations (Middleware type, compose, ctx.attrs)
alexeyshockov Apr 29, 2026
9e2ce4e
refactor(http): make Router a lean middleware-friendly dispatcher
alexeyshockov Apr 29, 2026
71a45cb
feat(http): HttpApp framework — decorators, param injection, response…
alexeyshockov Apr 29, 2026
ead8131
feat(http): streaming_pool_handler + buffer_body=False per route
alexeyshockov Apr 29, 2026
04dda43
docs(http): document Phase 9 — middleware + lean Router + HttpApp
alexeyshockov Apr 29, 2026
5465812
perf(http): drop per-request settimeout, send via non-blocking + fall…
alexeyshockov Apr 29, 2026
7484b84
fix(http): streaming routes — feed body bytes through the parser (htt…
alexeyshockov Apr 29, 2026
d29d852
test(http): parameterize backend parity checks
alexeyshockov Apr 29, 2026
c81afb7
test(http): run slow integration route on workers
alexeyshockov Apr 29, 2026
d6a54fb
perf(http): make settimeout fallback sticky per request
alexeyshockov Apr 30, 2026
4c4e96a
fix(http): reject worker pool overload
alexeyshockov Apr 30, 2026
72cab02
fix(http): defer httptools streaming handoff
alexeyshockov Apr 30, 2026
1fb2dbe
fix(http): handle streaming limits and path decoding
alexeyshockov Apr 30, 2026
adcadf9
perf(http): drop redundant bytes() copies in parser callbacks
alexeyshockov Apr 30, 2026
ce93e62
perf(http): pre-serialize canned protocol-error responses
alexeyshockov Apr 30, 2026
1309f44
perf(http): cache 404/405 responses in Router
alexeyshockov Apr 30, 2026
3634ded
feat(http): pre-split path/query_string on Request
alexeyshockov Apr 30, 2026
ae63fa7
perf(http): use manual target split instead of httptools.parse_url
alexeyshockov Apr 30, 2026
15f64e2
docs(http): document Phase 11 — Tier-3 diet + Request enrichment
alexeyshockov Apr 30, 2026
5eefc36
WIP on Python bench matrix
alexeyshockov Apr 30, 2026
0690aa4
feat(bench-http): typed stack matrix + HTML report
alexeyshockov Apr 30, 2026
3bc02cb
build(bench-http): install only the groups/extras the bench actually …
alexeyshockov Apr 30, 2026
06819e8
build(bench-http): track restructured bench/dev-http groups + http ex…
alexeyshockov Apr 30, 2026
9950bf2
deps
alexeyshockov Apr 30, 2026
7ed3d3e
fix(bench-http): tolerate JSON null in oha output
alexeyshockov Apr 30, 2026
6f13b7e
fix(threadtools): enforce rendezvous channel semantics
alexeyshockov Apr 30, 2026
5690b80
refactor(http): public server/conn on HTTPReqCtx, RouteMatch as attrs…
alexeyshockov Apr 30, 2026
54bf908
WIP
alexeyshockov Apr 30, 2026
63338cc
feat(http): admission semaphore + configurable backlog on thread_pool…
alexeyshockov Apr 30, 2026
1763705
WIP
alexeyshockov Apr 30, 2026
2d0d16f
fix(threadtools): allow N in-flight rendezvous puts with N waiting re…
alexeyshockov Apr 30, 2026
bfeb7fa
test(threadtools): add Hypothesis state-machine tests for Channel
alexeyshockov Apr 30, 2026
0edb99e
focus on stable, drop experimental
alexeyshockov Apr 30, 2026
51f7afc
fix: handle service and http edge cases
alexeyshockov Apr 30, 2026
96f68f9
chore: clean up examples, tests, docs, and pyproject after experiment…
alexeyshockov Apr 30, 2026
d4d2f1a
chore: apply just format-all fixes across the tree
alexeyshockov May 1, 2026
6a9d4ff
refactor(http): unify start_http_server, select backend via ServerConfig
alexeyshockov May 1, 2026
8748c66
refactor(http): split Selector from BaseServer; introduce ConnHandler
alexeyshockov May 1, 2026
408bd80
test(http): add Hypothesis property tests for parser parity and Route…
alexeyshockov May 1, 2026
1c6d34e
docs(http): add connection state diagram to README
alexeyshockov May 1, 2026
7882493
test(http): add acceptor + multi-selector stress suite
alexeyshockov May 1, 2026
0f24935
test(http): consolidate selectors=4, cover acceptor + httptools / pool
alexeyshockov May 1, 2026
e20a00d
bench(http): add acceptor stacks, drop redundant s=2 wrappers
alexeyshockov May 1, 2026
24cf805
docs(perf): write up Phase 12 — acceptor topology bench results
alexeyshockov May 1, 2026
ede306e
bench(http): rename localpost_native → localpost_h11 (parser explicit)
alexeyshockov May 2, 2026
8a7a559
chore: mark localpost as free-threaded ready
alexeyshockov May 2, 2026
e9c0625
refactor(http): small fixes batch — CLI, Response rename, pool/style …
alexeyshockov May 2, 2026
a7d7c39
feat(openapi): new type-driven HTTP framework with OpenAPI 3.2 genera…
alexeyshockov May 2, 2026
74651ce
fix(http): strip trailing OWS in httptools header values
alexeyshockov May 2, 2026
481cdfa
feat(openapi): wire OpFilter end-to-end (app-level + per-op)
alexeyshockov May 2, 2026
ef76ef2
feat(openapi): HttpBearerAuth + HttpBasicAuth concrete filters
alexeyshockov May 2, 2026
94fa52f
feat(openapi): polish — Optional resolvers, fn-name operationId, path…
alexeyshockov May 2, 2026
ec0be34
feat(openapi): Server-Sent Events — generator-typed handlers stream a…
alexeyshockov May 2, 2026
487e0a7
refactor(http): externalise stale-conn cleanup via op queue
alexeyshockov May 2, 2026
4f56c51
chore: refresh .gitignore from upstream Python template, comment out …
alexeyshockov May 4, 2026
821d577
feat(openapi): map T | None returns to 404 NotFound
alexeyshockov May 4, 2026
f96b5d5
feat(openapi): @op_filter — declare filters as tiny operations
alexeyshockov May 4, 2026
e0a7cde
refactor(http): drop server.py shim, hide concrete HTTPReqCtx, unexpo…
alexeyshockov May 4, 2026
d3e90fc
feat(http): static_handler with sendfile, ETag/Range, Cache-Control
alexeyshockov May 4, 2026
b066221
feat(http): compress_handler — gzip/brotli middleware for dynamic res…
alexeyshockov May 4, 2026
5b18e4e
feat(http): streaming compression for compress_handler (SSE etc.)
alexeyshockov May 4, 2026
e8515de
fix(http): honor user-set Transfer-Encoding: chunked on httptools bac…
alexeyshockov May 4, 2026
289d511
feat(openapi): pluggable TypeAdapter registry for schema libraries
alexeyshockov May 4, 2026
4c8afeb
feat(openapi)!: replace OpFilter with OpMiddleware (call_next semantics)
alexeyshockov May 5, 2026
826994a
feat(threadtools)!: ThreadTaskGroup + drop HTTP pool admission gate
alexeyshockov May 5, 2026
90d728f
refactor(threadtools): simpler _Worker, lock-free _record_error
alexeyshockov May 5, 2026
3dd7bcf
feat(threadtools): propagate contextvars across ThreadTaskGroup tasks
alexeyshockov May 5, 2026
52e2585
refactor(http)!: slim HTTPReqCtx; add remote_addr / local_addr / sche…
alexeyshockov May 5, 2026
3ed455e
warmup
alexeyshockov May 5, 2026
016b66a
feat(http): to_wsgi adapter; HttpApp.as_wsgi() / Router.as_wsgi()
alexeyshockov May 5, 2026
9fb7927
refactor(http,openapi): consolidate shared helpers; drop redundant lo…
alexeyshockov May 5, 2026
b855dad
refactor(openapi/spec): replace 23 hand-written to_dict methods with …
alexeyshockov May 5, 2026
7117652
feat(threadtools)!: per-primitive check_cancelled, drop module alias
alexeyshockov May 5, 2026
7e02d49
docs(plans): add attrs/cattrs OpenAPI adapter plan
alexeyshockov May 5, 2026
3f4d4a5
feat(openapi): plumb schema_for callback through TypeAdapter
alexeyshockov May 5, 2026
5033bc8
feat(openapi): attrs/cattrs TypeAdapter
alexeyshockov May 5, 2026
7dbfdc7
format
alexeyshockov May 6, 2026
dbf3b96
refactor(benchmarks): extract shared core for macro suites
alexeyshockov May 6, 2026
0e4aed1
feat(benchmarks): scaffold openapi suite with plaintext scenario
alexeyshockov May 6, 2026
7d8108c
feat(benchmarks): add path_param_typed and body_roundtrip scenarios
alexeyshockov May 6, 2026
bc055eb
feat(benchmarks): add query_validation and validation_failure scenarios
alexeyshockov May 6, 2026
28a43dd
docs(benchmarks): add per-suite READMEs, slim top-level to an index
alexeyshockov May 6, 2026
fe65b97
refactor(openapi): extract type-level core into _operation_core
alexeyshockov May 6, 2026
baaeedd
feat(openapi): add HttpAsyncApp + ASGI deployment
alexeyshockov May 6, 2026
6c7ce1d
test(openapi): add HttpAsyncApp smoke tests + tighten async-mw guard
alexeyshockov May 6, 2026
7605398
test(openapi): drive HttpAsyncApp via httpx + add uvicorn integration
alexeyshockov May 6, 2026
0f46f25
feat(openapi): async example app + benchmark stack
alexeyshockov May 6, 2026
ea59820
docs(openapi): add async-flavour section to README
alexeyshockov May 6, 2026
127598e
refactor(http): hoist async ctx Protocol + ASGI bridge to localpost.http
alexeyshockov May 6, 2026
f8c726d
docs: seed docs/ with request-body-handling design note
alexeyshockov May 6, 2026
3fa1fef
feat(http): add streaming-upload mode to to_asgi + clear ty errors
alexeyshockov May 6, 2026
a39db3e
docs(http): document the ASGI bridge + async ctx surface
alexeyshockov May 6, 2026
9925c2b
feat: add RSGI bridge + HostRSGIApp for Granian deployments
alexeyshockov May 6, 2026
9432e9f
docs: RSGI subsections + [rsgi] extra + deployment-topologies note
alexeyshockov May 6, 2026
ca35b91
feat(benchmarks): add localpost_openapi_granian stack
alexeyshockov May 6, 2026
aec094a
feat(http): add ctx.disconnected to sync HTTPReqCtx
alexeyshockov May 6, 2026
dfa2487
docs(http): document sync vs async ctx asymmetry
alexeyshockov May 6, 2026
033b5c5
feat(http)!: drop imperative trio from public HTTPReqCtx Protocol
alexeyshockov May 6, 2026
20b50a1
feat(http): add read_body / aread_body helpers
alexeyshockov May 6, 2026
e868361
feat(http)!: eliminate BodyHandler; drop ctx.body; align async + sync
alexeyshockov May 6, 2026
a3ccb7c
docs(design): extract HTTP connection-model, backends, threading-topo…
alexeyshockov May 6, 2026
f7f6395
docs(http): trim README, link out to design notes
alexeyshockov May 6, 2026
55568c8
docs: polish hosting/scheduler/di READMEs
alexeyshockov May 6, 2026
929c57b
docs(adr): seed initial decision records
alexeyshockov May 6, 2026
cba1559
docs: bootstrap mkdocs site with end-user landing and module pages
alexeyshockov May 7, 2026
4dc981a
docs: migrate from mkdocs to Zensical; promote module READMEs to site
alexeyshockov May 7, 2026
8636b72
fix(scheduler): keep schedule loop alive across handler exceptions
alexeyshockov May 7, 2026
bdd0113
refactor(scheduler): commit to async-generator middleware in trigger …
alexeyshockov May 7, 2026
83e0787
docs(scheduler): clarify Task.subscribe buffer semantics
alexeyshockov May 7, 2026
7e5aacc
test(scheduler): cover delay() middleware timing
alexeyshockov May 7, 2026
4aaf1a0
chore(scheduler): drop stale buffer() sketch comment
alexeyshockov May 7, 2026
91b1882
fix(scheduler): raise clear error on subscribe-after-finish + cover g…
alexeyshockov May 7, 2026
d79bae9
refactor(threadtools): split into a package
alexeyshockov May 7, 2026
15b547f
feat(threadtools): rename ThreadTaskGroup to TaskGroup + portal-backe…
alexeyshockov May 7, 2026
654644b
feat(threadtools): split TaskGroup spawn into start_soon (None) + cre…
alexeyshockov May 7, 2026
b4404de
fix(threadtools): dedup body and task exceptions by identity in TaskG…
alexeyshockov May 7, 2026
f8c66c5
refactor(threadtools): seed all_errors from _errors, prepend body exc…
alexeyshockov May 7, 2026
026a2f6
build: widen uv-build pin to <0.13
alexeyshockov May 8, 2026
d6058db
ci(release): switch pypi-publish workflow from pdm to uv
alexeyshockov May 8, 2026
5fcee1d
docs(changelog): consolidate unreleased drafts into 0.6.0
alexeyshockov May 8, 2026
1282f80
refactor(benchmarks)!: split into micro/ and macro/ layout
alexeyshockov May 8, 2026
3c05480
chore(release): add just release / release-post recipes
alexeyshockov May 8, 2026
ad7d1a8
docs: add CONTRIBUTING.md, trim README contribute section
alexeyshockov May 8, 2026
137523a
ci: rewrite CI on uv with Python matrix, lint+types gate
alexeyshockov May 8, 2026
41d52e6
ci(release): generate PEP 740 attestations via pypa/gh-action-pypi-pu…
alexeyshockov May 8, 2026
ea48d77
ci(coverage): tighten coverage config + 85% floor
alexeyshockov May 8, 2026
8d4e3ff
feat(hosting): add Click command service adapter
alexeyshockov May 8, 2026
6746ede
chore: cleanup channels
alexeyshockov May 8, 2026
93df87a
chore(docs): localpost.dev
alexeyshockov May 8, 2026
42fb861
WIP on task group rework
alexeyshockov May 8, 2026
779ed80
WIP on task group rework
alexeyshockov May 9, 2026
f08dfd9
Revert "chore: cleanup channels"
alexeyshockov May 9, 2026
5357024
WIP on task group rework
alexeyshockov May 9, 2026
077d3cb
refactor(threadtools)!: rebuild Channel on plain locks, add timeout API
alexeyshockov May 9, 2026
4f262b7
feat(threadtools)!: Executor protocol + Future-based TaskGroup
alexeyshockov May 9, 2026
7c27f97
test(threadtools): rewrite tests for executor / TaskGroup API
alexeyshockov May 9, 2026
b7a4cc4
feat(threadtools)!: AsyncWorkerExecutor / AsyncExecutor as async CMs
alexeyshockov May 9, 2026
408efda
feat(hosting,http,openapi)!: expose hosting portal; default to AsyncW…
alexeyshockov May 9, 2026
1fb1ee3
docs(changelog): refresh 0.6.0 entry with the threadtools rework
alexeyshockov May 9, 2026
86573a7
refactor(threadtools)!: SendChannel / ReceiveChannel are now Protocols
alexeyshockov May 9, 2026
4c8c947
fix(examples,tests): migrate to post-BodyHandler API; align ty ignore…
alexeyshockov May 9, 2026
184493b
test(threadtools): drive channel property tests through the public pr…
alexeyshockov May 9, 2026
13c9cdc
feat(hosting,threadtools)!: run_app raises SystemExit; add threadtool…
alexeyshockov May 9, 2026
52803d6
refactor(hosting)!: drop HostRSGIApp re-export from hosting/__init__.py
alexeyshockov May 9, 2026
ea749ee
cleanup
alexeyshockov May 9, 2026
6d23d33
feat(portal)!: add Portal wrapper for thread-aware loop dispatch
alexeyshockov May 9, 2026
dd8fb28
feat(threadtools): add as_sync_cm helper for worker-thread access to …
alexeyshockov May 10, 2026
ba87218
refactor(threadtools)!: drop idle-timeout self-exit; share one receiver
alexeyshockov May 10, 2026
49dc1ef
simply executor
alexeyshockov May 10, 2026
9c15475
refactor(threadtools)!: deque + Condition pool; drop AsyncExecutor an…
alexeyshockov May 10, 2026
69e6cf0
refactor(threadtools): extract _WorkerPoolBase; add stop() to WorkerE…
alexeyshockov May 10, 2026
9fcdf9d
test(threadtools): guard AsyncWorkerExecutor cancel-unblocks-idle-wor…
alexeyshockov May 10, 2026
5877ce3
version
alexeyshockov May 10, 2026
98012ce
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 10, 2026
3de4ae6
fix(ci): unblock lint-types, signal tests, FT job, flaky pool test
alexeyshockov May 10, 2026
a9681e1
fix(ci): restore PLC0415 noqa stripped by pre-commit, skip more FT tests
alexeyshockov May 10, 2026
ceb3714
fix(tests): harden flaky worker-pool test, skip more httptools-only t…
alexeyshockov May 10, 2026
6f42cea
chore: rename FT job to 3.14t; drop MemoryStream wrapper for sonar
alexeyshockov May 10, 2026
bf0bb1f
no custom domain for now
alexeyshockov May 11, 2026
f726b16
fix(ci): restore valid job ID for the 3.14t check; add actionlint
alexeyshockov May 11, 2026
e8cb4a9
chore(pre-commit): bump revs and expand hook coverage
alexeyshockov May 11, 2026
ab70f31
chore(pre-commit): replace codespell with typos
alexeyshockov May 11, 2026
70e0fe5
docs,http: spell ``unparsable`` consistently
alexeyshockov May 11, 2026
fb3f96f
ci: split tests into stable + free-threaded matrices; sonar self-cont…
alexeyshockov May 11, 2026
bbd7666
ci: drop lint-types job; mark 3.15 as experimental
alexeyshockov May 11, 2026
ec22d7d
chore: tighten types on Channel protocols; ignore PLC0415 in tests
alexeyshockov May 11, 2026
154a640
ci: mark 3.15t as experimental too
alexeyshockov May 11, 2026
25c7e0e
add release pre-flight: just release-check + just api-diff
alexeyshockov May 11, 2026
ba8e233
docs(contributing): doctor + pre-commit setup; release pre-flight step
alexeyshockov May 11, 2026
5e27f9e
local tools
alexeyshockov May 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 0 additions & 2 deletions .aider.conf.yml

This file was deleted.

94 changes: 84 additions & 10 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,101 @@ name: CI

on:
push:
branches: [ master, main ]
branches: [main]
pull_request:
branches: [ master, main ]
branches: [main]

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
tests:
runs-on: ubuntu-latest
# 3.15 is still beta and ``granian``'s PyO3 0.27 doesn't support it yet;
# the entry is kept as an early-signal channel until PyO3 catches up.
continue-on-error: ${{ matrix.experimental || false }}
strategy:
fail-fast: false
matrix:
include:
- python: "3.12"
- python: "3.13"
- python: "3.14"
- python: "3.15"
experimental: true
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
enable-cache: true
- run: uv python install ${{ matrix.python }}
- run: uv sync --python ${{ matrix.python }} --all-groups --all-extras
- name: pytest (unit only)
timeout-minutes: 5
run: uv run --python ${{ matrix.python }} pytest -m "not integration" -v

tests-ft:
runs-on: ubuntu-latest
# 3.15t is still beta (uv ships ``cpython-3.15.0b1+freethreaded``).
continue-on-error: ${{ matrix.experimental || false }}
strategy:
fail-fast: false
matrix:
include:
- python: "3.14t"
- python: "3.15t"
experimental: true
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
enable-cache: true
- name: Install Python ${{ matrix.python }}
run: uv python install ${{ matrix.python }}
- name: Install dependencies (FT-clean subset)
# --no-default-groups + narrow opt-in: avoid C extensions that
# re-enable the GIL on free-threaded builds (httptools 0.7.x,
# grpcio, granian, setproctitle). Covers the pure-Python core
# that the FT marking actually claims. ``dev-http`` (httpx,
# flask), ``dev-sentry`` (sentry-sdk), and the ``click`` extra
# are pure Python — pulled in so tests/http and
# tests/hosting/services collect cleanly.
run: >
uv sync --python ${{ matrix.python }} --no-default-groups
--group tests --group tests-unit
--group dev-http --group dev-sentry
--extra http --extra scheduler --extra cron --extra click
- name: pytest
timeout-minutes: 5
env:
PYTHON_GIL: "0" # fail loudly if any imported C ext re-enables the GIL
# Skip ``tests/openapi`` (msgspec C ext) and ``tests/hosting/rsgi.py``
# (exercises Granian hooks; granian C ext not in the FT subset).
run: >
uv run --python ${{ matrix.python }} pytest -v -m "not integration"
--ignore=tests/openapi
--ignore=tests/hosting/rsgi.py

sonarcloud:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# Disable shallow clone (required for SonarQube to work properly)
fetch-depth: 0
- uses: pdm-project/setup-pdm@v4
fetch-depth: 0 # Sonar needs full history
- uses: astral-sh/setup-uv@v5
with:
enable-cache: true
python-version-file: ".python-version"
cache: true
- name: pdm install
run: pdm install --frozen-lockfile --no-editable
- name: pytest
- run: uv sync --all-groups --all-extras
- name: pytest with coverage
timeout-minutes: 5
run: pdm run pytest --cov-report=term --cov-report=xml --cov-branch --cov -v
run: >
uv run pytest -m "not integration" -v
--cov-report=term --cov-report=xml --cov
- uses: SonarSource/sonarqube-scan-action@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
42 changes: 42 additions & 0 deletions .github/workflows/docs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Docs

on:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: docs-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
enable-cache: true
- name: Sync docs deps
run: uv sync --group docs
- name: Build site
run: uv run zensical build --clean
- uses: actions/configure-pages@v5
- uses: actions/upload-pages-artifact@v4
with:
path: site

deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@v4
26 changes: 17 additions & 9 deletions .github/workflows/pypi-publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,31 @@ on:
release:
types: [ published ]

permissions:
contents: read

jobs:
# https://pdm-project.org/latest/usage/publish/#publish-with-trusted-publishers
publish:
runs-on: ubuntu-latest
permissions:
# Required for PyPI trusted publishing
contents: read
# Required for PyPI trusted publishing + Sigstore-signed PEP 740 attestations
id-token: write
attestations: write
steps:
- uses: actions/checkout@v4
with:
# Just "fetch-tags: true" does not work, probably because of
#
fetch-depth: 0
- uses: pdm-project/setup-pdm@v4
- uses: astral-sh/setup-uv@v5
with:
enable-cache: true
python-version-file: ".python-version"
cache: true
- run: pdm install --no-lock --no-editable
- run: pdm build
- run: pdm publish --no-build
- run: uv build
# uv publish (as of 0.11) only uploads pre-existing attestations; it does
# not generate them. Use the official PyPA action, which generates PEP 740
# PyPI Publish Attestations via Sigstore and uploads them alongside the
# distributions. Track astral-sh/uv#15618 — once landed we can swap back
# to a single `uv publish` step.
- uses: pypa/gh-action-pypi-publish@release/v1
with:
attestations: true
89 changes: 71 additions & 18 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
.venv-*

# --- GitHub template, see https://github.com/github/gitignore/blob/main/Python.gitignore ---

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*.py[codz]
*$py.class

# C extensions
Expand All @@ -27,8 +31,8 @@ share/python-wheels/
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

Expand All @@ -46,7 +50,8 @@ htmlcov/
nosetests.xml
coverage.xml
*.cover
*.py,cover
*.py.cover
*.lcov
.hypothesis/
.pytest_cache/
cover/
Expand Down Expand Up @@ -92,43 +97,65 @@ ipython_config.py
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# Pipfile.lock

# UV
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
#uv.lock
# uv.lock

# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# poetry.lock
# poetry.toml

# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
.pdm.toml
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
# pdm.lock
# pdm.toml
.pdm-python
.pdm-build/

# pixi
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
# pixi.lock
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
# in the .venv directory. It is recommended not to include this directory in version control.
.pixi/*
!.pixi/config.toml

# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat-schedule*
celerybeat.pid

# Redis
*.rdb
*.aof
*.pid

# RabbitMQ
mnesia/
rabbitmq/
rabbitmq-data/

# ActiveMQ
activemq-data/

# SageMath parsed files
*.sage.py

# Environments
.env
.envrc
.venv
env/
venv/
Expand Down Expand Up @@ -161,11 +188,37 @@ dmypy.json
cython_debug/

# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
# .idea/

# Abstra
# Abstra is an AI-powered process automation framework.
# Ignore directories containing user credentials, local state, and settings.
# Learn more at https://abstra.io/docs
.abstra/

# Visual Studio Code
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
# and can be added to the global gitignore or merged into this file. However, if you prefer,
# you could uncomment the following to ignore the entire vscode folder
# .vscode/
# Temporary file for partial code execution
tempCodeRunnerFile.py

# Ruff stuff:
.ruff_cache/

# PyPI configuration file
.pypirc

# Marimo
marimo/_static/
marimo/_lsp/
__marimo__/

# Streamlit
.streamlit/secrets.toml
Loading
Loading