For educational purposes: yet another Python web framework, but written in Rust.
(Say the line, Bart) it's blazingly fast.
The implementation is meant to demonstrate concepts, not optimize the implementation.
For a proper implementation of a Rust / Python web framework, see https://github.com/sparckles/Robyn
A Makefile is provided to smooth over some of the DX. For example, triggering a maturin dev build and then running UV, etc.
You could run the maturin, uv, etc. directly, Make is just used since it's ubiquitous.
- Python app spins up event loop
uvloop - Python app adds routes
- From the py loop, start the rust loop
- In the rust loop
- bind to a socket
- capture python tasks locals
- Need to pass these back when calling the python handlers
- create request handler that responds to incoming request
- Incoming request handled by rust request handler
- Impl request incoming for hyper
- Send static files OR Look up route from router
- For dynamic route
- Build a request object to hand off to python (PyperRequest)
- Call python function from Rust to get response body (String)
- Take the response body string from Python and then build a response (in Rust)
- Send response back to client
NOTE: the project layout is non standard with the python and rust codebases being separate. This is to demonstrate using the rust code as a external dependency (even though in reality the two are tightly coupled).
See https://www.maturin.rs/project_layout.html for traditional / recommended layouts.
- https://www.maturin.rs/installation.html
- https://docs.astral.sh/uv/getting-started/
- https://pyo3.rs/
- https://github.com/PyO3/pyo3-async-runtimes
- https://hyper.rs/
maturin new rs
# pyo3
# also note project name differencematurin build -ruv inituv add uvloop
uv add --editable ../rshttps://github.com/PyO3/pyo3-async-runtimes?tab=readme-ov-file#non-standard-python-event-loops
Python allows you to use alternatives to the default asyncio event loop. One popular alternative is uvloop. In v0.13 using non-standard event loops was a bit of an ordeal, but in v0.14 it's trivial.
See benchmark/README.md.


