"Another" Python backend framework, for fun.
pip install anotherYou also need an ASGI server, such as Uvicorn or Granian.
pip install uvicorn
# or
pip install granianCreate a main.py file and copy-paste the following snippet into it.
from another import Another, Status, Request, Response
app = Another()
@app.get("/hello")
def hellow_another(req: Request):
return Response({
"message": "Hello!",
"extra": req.query
}, status=Status.HTTP_200_OK)And then run the server:
uvicorn main:appNow open this link localhost:8000/hello?first_name=Mads&last_name=Mikkelsen in your browser.
Use {name} segments in a route to capture path parameters; they show up in req.params.
@app.get("/users/{id}")
def get_user(req: Request):
return Response({"id": req.params["id"]}, status=Status.HTTP_200_OK)Requests to an unregistered path return 404, and requests to a known path with the wrong HTTP method return 405.
A middleware is a function that receives the current Request and either returns it (possibly modified) to continue processing, or returns a Response to short-circuit the chain (e.g. an auth guard). Middlewares run in registration order, before the route handler. Both sync and async middleware are supported.
@app.use()
def auth_guard(req: Request):
if req.headers.get("authorization") != "secret":
return Response({"error": "unauthorized"}, status=Status.HTTP_401_UNAUTHORIZED)
return reqRaise HTTPException(status, message) from a handler or middleware to return a specific error response. Any other unhandled exception is logged and results in a 500.
from another import HTTPException
@app.get("/users/{id}")
def get_user(req: Request):
if req.params["id"] == "0":
raise HTTPException(Status.HTTP_404_NOT_FOUND, "User not found")
return Response({"id": req.params["id"]}, status=Status.HTTP_200_OK)Handlers (and middleware) can be async def as well as regular functions — another awaits them automatically.
Use TestClient to call your app in-process, without running a real server.
from another.testclient import TestClient
from main import app
client = TestClient(app)
response = client.get("/hello", query={"first_name": "Mads"})
assert response.status_code == 200
assert response.json() == {"message": "Hello!", "extra": {"first_name": "Mads"}}This project uses uv for dependency management.
uv sync
uv run pytest