Skip to content

thevahidal/another

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Another

"Another" Python backend framework, for fun.

justforfunnoreally.dev badge

Installation

pip install another

You also need an ASGI server, such as Uvicorn or Granian.

pip install uvicorn
# or
pip install granian

Usage

Create 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:app

Now open this link localhost:8000/hello?first_name=Mads&last_name=Mikkelsen in your browser.

Path parameters

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.

Middleware

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 req

Error handling

Raise 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)

Async handlers

Handlers (and middleware) can be async def as well as regular functions — another awaits them automatically.

Testing your app

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"}}

Running the tests

This project uses uv for dependency management.

uv sync
uv run pytest

About

🕳️ "Another" Python backend framework, for fun.

Topics

Resources

License

Stars

5 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors

Languages