An opinionated, msgspec-first ASGI micro-framework
Project description
jero
An opinionated, msgspec-first ASGI micro-framework for Python 3.14.
- GitHub: https://github.com/RogerThomas/jero/
- Documentation: https://RogerThomas.github.io/jero/
What is jero?
jero is built on three non-negotiable pillars:
- Speed. All introspection happens once, at wiring time. The per-request path is just dict lookup → msgspec decode → call → encode — nothing else.
- Opinionated, scaffolded DX. There is one blessed way to do each thing.
Contracts are checked at startup and fail loud with a precise
WiringError, never silently at runtime. - Strict, expressive typing. Everything is fully, statically typed under pyright-strict. Types are the contract — the binding, the wiring errors, and (on the roadmap) the source of the OpenAPI spec.
It deliberately has no DI container: you hand-wire dependencies in _wire, and
the framework owns only what the language doesn't give you for free — lifecycle.
Example
from msgspec import Struct
from jero import BaseApp, Endpoint, Resource, TestClient
class Widget(Struct):
id: str
name: str
class WidgetResource(Resource):
async def read_one(self, path: "WidgetPath") -> Widget:
return Widget(id=path.widget_id, name="widget-name")
class WidgetPath(Struct):
widget_id: str
class HealthEndpoint(Endpoint):
async def get(self) -> Widget:
return Widget(id="health", name="ok")
class App(BaseApp):
async def _wire(self) -> None:
self._include_resource(WidgetResource(), path="/widgets")
self._include_endpoint(HealthEndpoint(), path="/healthz")
app = App()
# Test it in-process — no socket, no server:
with TestClient(app) as client:
resp = client.get("/widgets/abc")
assert resp.status_code == 200
assert resp.json() == {"id": "abc", "name": "widget-name"}
Run it under any ASGI server, e.g. granian:
granian --interface asgi myapp:app
Development
task install # create the venv and install pre-commit hooks
task check # lock check + ruff, pyright, deptry, pylint (via prek)
task test # run the test suite with coverage
See AGENTS.md for the design philosophy and the contract, and
style-guide.md for project conventions.
Releasing a new version
Publishing uses PyPI Trusted Publishing (OIDC) — no token required.
- Bump
versioninpyproject.tomland commit it tomain. - Create a GitHub release
tagged with the same version — a bare PEP 440 string, e.g.
0.1.0(nov).
The release workflow verifies the tag matches pyproject.toml, builds, publishes
to PyPI, and deploys the docs. A version mismatch fails the release.
Repository initiated with osprey-oss/cookiecutter-uv.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jero-0.0.2.tar.gz.
File metadata
- Download URL: jero-0.0.2.tar.gz
- Upload date:
- Size: 101.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4c877055c82ec3237f65fae919998a26d468faa484b1850e8bc41667dce79082
|
|
| MD5 |
4381506f71f93986411c5fcd2ec44b21
|
|
| BLAKE2b-256 |
46306af54fe9f832385ef5d5c9237b4136f02d43fcda2f6d6e46202bbaed5dd2
|
File details
Details for the file jero-0.0.2-py3-none-any.whl.
File metadata
- Download URL: jero-0.0.2-py3-none-any.whl
- Upload date:
- Size: 24.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8325ffabf7a6b9c1d30babe1e37b807cd499795d7fa4bd949b6e518533e4e0ff
|
|
| MD5 |
78801e9a6329f6e1a86e3907f48d13d2
|
|
| BLAKE2b-256 |
bfad8637e90dc7e589eceedbe006a6cdcf38a8197cf42cb676e1c6bef79e6bc4
|