Roob Python Web Framework built for learning purposes.
Project description
Roob
Roob is a small, educational WSGI-compatible Python web framework built from scratch to help you understand how web frameworks work. It's intentionally lightweight and opinionated for learning and experimentation.
Features
- WSGI Compatible: The framework exposes a callable application usable with any WSGI server.
- Routing: Supports both automatic (path pattern) and explicit route registration.
- Handlers: Function-based and class-based handlers are supported.
- Middlewares: Compose request/response processing via middleware classes. Includes
ErrorHandlerMiddlewareand helpers. - Templating: Provides a templating system accessible via the
template()helper on the app. - Static Files: Static files (CSS/JS/images) can be served from a
static/directory. - Error Handling: Built-in
ResponseErrorand optional middleware to convert exceptions into JSON responses. - HTTP Method Control: Route definitions can restrict allowed HTTP methods.
- Published: The package is available on PyPI for easy installation.
Installation
- From PyPI:
pip install Roob
Quick Start
- Create a minimal app
from Roob.framework import Roob
app = Roob()
@app.route('/')
def index(request):
return app.templates_env.get_template('dashboard.html').render()
if __name__ == '__main__':
from wsgiref.simple_server import make_server
server = make_server('0.0.0.0', 8080, app)
print('Serving on http://0.0.0.0:8080')
server.serve_forever()
Function-based handler
from Roob.framework import Roob
from Roob.models.responses import JSONResponse
app = Roob()
@app.route('/hello')
def hello(request):
return JSONResponse({"message": "Hello from Roob"})
Class-based Handler
Roob support both automatic and manually registered Class Based handlers
Self registered Class-based Handler
The function names should matched with HTTP request method.
@app.route('/items')
class ItemHandler:
def __init__(self):
self.service = ItemService()
# get all products
def get(self, request):
items: list[dict] = self.service.get_items()
return JSONResponse(items)
# create a product
def post(self, request):
items: dict = self.service.create_items()
return JSONResponse(items)
Notes:
- Self registered Class-based handlers are registered as classes. The framework will instantiate the class and call the method matching the HTTP method name (e.g.,
get,post).
Manually registerd Class-based Handler
If you need both custom handlers in a class then you can register routes manually
from Roob.framework import Roob
from Roob.models.responses import JSONResponse
app = Roob()
class ItemHandlerCustomRouting:
def get_by_id(self, request, item_id=None):
return JSONResponse({"item_id": item_id})
def get_by_category(self, request, category=None):
# JSONResponse also supports list of classes
items: list[Item] = items_service.get_by_category()
return JSONResponse(items)
handler = ItemHandlerCustomRouting()
app.add_route('/items/{item_id:d}', handler.get_by_id)
app.add_route('/items/{category}', handler.get_by_category)
Routing & Path Variables
- Paths can include variables using the
{name}syntax. The framework will parse them and pass as kwargs to your handler. - Example:
app.add_route('/users/{user_id}', handler)— handler will receiveuser_idas a keyword argument.
Middlewares & Error Handling
- Built-in middlewares:
ErrorHandlerMiddleware,ReqResLoggingMiddleware, andExecutionTimeMiddlewareare provided inRoob.middlewarespackage. - ResponseError: Raise
Roob.exceptions.ResponseError(or its subclasses) from handlers to return structured JSON error responses. TheErrorHandlerMiddlewareconvertsResponseErrorinto an appropriate JSON response with the specified HTTP status.
Example — adding middleware and a simple error:
from Roob.framework import Roob
from Roob.middlewares import ErrorHandlerMiddleware
from Roob.exceptions import ResponseError
app = Roob()
app.add_middleware(ErrorHandlerMiddleware)
@app.route('/fail')
def fail(request):
raise ResponseError('This is a custom error', 400)
- Response JSON
{
"message": "This is a custom error"
}
Templating
- The app provides a templating system. Templates are loaded from the
templatesdirectory by default. Useapp.template(template_name, context)to generate view from a template dynamically.
Example: Register the template if you have a customer template directory
from Roob.framework import Roob
from Roob.models.responses import HTMLResponse
app = Roob(template_dir=f"{cwd}/templates")
@app.route('/dashboard')
def dashboard(request) -> Response:
name = "Hello User"
title = "Dashboard View"
html_content = app.template(
"dashboard.html",
context={"name": name, "title": title}
)
return HTMLResponse(html_content)
Static Files
- Static assets under the
staticdirectory are served automatically. Place CSS/JS/images instatic/and reference them from your templates.
WSGI Compatibility
- The
Roobinstance is a valid WSGI application. You can run it with any WSGI server (uWSGI, Gunicorn, orwsgirefduring development).
You can run the demo application with Gunicorn service using
make run
Tests & Examples
- See the
tests/anddemo_app/directories in this repository for usage examples and test coverage.
Contributing
- This project is intended for learning. Contributions that improve docs, add examples, or clarify internals are welcome.
License
- See the
LICENSEfile in this repository.
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 roob-0.0.3.tar.gz.
File metadata
- Download URL: roob-0.0.3.tar.gz
- Upload date:
- Size: 19.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
deb0ffd9bdd478d844fb89c6e4434a95362e7c9d860878047575765900b7c5f1
|
|
| MD5 |
6082fe16f956bf7ddb7331ca81a96336
|
|
| BLAKE2b-256 |
7ac21dc8a83f1f0e2c9fab12615f5a72b22da8edcd08c68efb28fa19d8aad2f5
|
File details
Details for the file roob-0.0.3-py3-none-any.whl.
File metadata
- Download URL: roob-0.0.3-py3-none-any.whl
- Upload date:
- Size: 23.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a55bae5ff2eff4e55cb94d09538edea35c80e6c6cbf138bbe04cc0fc55decbe7
|
|
| MD5 |
468283973fdc88fecc0cfa1f67aaaca4
|
|
| BLAKE2b-256 |
1e3f1946719b024bbaf5ad7640deca1efb99c2fedc43ca5115c0e0e0fdc92987
|