An opinionated, msgspec-first ASGI micro-framework
Project description
What is jero?
jero is opinionated on purpose. It makes one bet: that being aggressively prescriptive — rather than flexible — is exactly what lets a framework be both extremely fast and a joy to build on. Three pillars, all non-negotiable:
- Speed. Introspection happens once, at startup. The request path is dict lookup → msgspec decode → call → encode, and nothing else is ever added to it.
- Opinionated DX. One blessed way to do each thing, encoded so you can't get it
wrong. Contracts fail loud at startup with a precise
WiringError, never quietly at runtime. - Strict typing. Fully static under pyright-strict — the types are the contract, and the source of the coming OpenAPI spec. If you don't like typing, this isn't your framework.
And no DI container: dependencies are hand-wired in _wire; the framework adds only
lifecycle — the one thing plain Python doesn't give you.
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.6.tar.gz.
File metadata
- Download URL: jero-0.0.6.tar.gz
- Upload date:
- Size: 376.9 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 |
747a571e11d5e65db9d77f11714c33494bf9ecd2f0c5e5e4c927e5c6a7fecf87
|
|
| MD5 |
2a8ccbf86f304e83b92ac78c65972891
|
|
| BLAKE2b-256 |
7e7f05babcf4976bffa4021bd3eb171b87849af3e342d680b6f7562fb4391160
|
File details
Details for the file jero-0.0.6-py3-none-any.whl.
File metadata
- Download URL: jero-0.0.6-py3-none-any.whl
- Upload date:
- Size: 24.8 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 |
f4db6d1e72ada5271565bdc64a58bbffad49bbcc471b51094e78dbeb24dc2123
|
|
| MD5 |
dd88c4ab196d3ed6d4295e31f6026f99
|
|
| BLAKE2b-256 |
cffb82f1c14c0143a99c50c7f843ace8f9fe11b9c086326085253c679826d51b
|