Skip to main content

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 ErrorHandlerMiddleware and 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 ResponseError and 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 receive user_id as a keyword argument.

Middlewares & Error Handling

  • Built-in middlewares: ErrorHandlerMiddleware, ReqResLoggingMiddleware, and ExecutionTimeMiddleware are provided in Roob.middlewares package.
  • ResponseError: Raise Roob.exceptions.ResponseError (or its subclasses) from handlers to return structured JSON error responses. The ErrorHandlerMiddleware converts ResponseError into 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 templates directory by default. Use app.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 static directory are served automatically. Place CSS/JS/images in static/ and reference them from your templates.

WSGI Compatibility

  • The Roob instance is a valid WSGI application. You can run it with any WSGI server (uWSGI, Gunicorn, or wsgiref during development).

You can run the demo application with Gunicorn service using

make run

Tests & Examples

  • See the tests/ and demo_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 LICENSE file in this repository.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

roob-0.0.3.tar.gz (19.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

roob-0.0.3-py3-none-any.whl (23.2 kB view details)

Uploaded Python 3

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

Hashes for roob-0.0.3.tar.gz
Algorithm Hash digest
SHA256 deb0ffd9bdd478d844fb89c6e4434a95362e7c9d860878047575765900b7c5f1
MD5 6082fe16f956bf7ddb7331ca81a96336
BLAKE2b-256 7ac21dc8a83f1f0e2c9fab12615f5a72b22da8edcd08c68efb28fa19d8aad2f5

See more details on using hashes here.

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

Hashes for roob-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 a55bae5ff2eff4e55cb94d09538edea35c80e6c6cbf138bbe04cc0fc55decbe7
MD5 468283973fdc88fecc0cfa1f67aaaca4
BLAKE2b-256 1e3f1946719b024bbaf5ad7640deca1efb99c2fedc43ca5115c0e0e0fdc92987

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page