Skip to main content

PoridhiFrame Python Web Framework built for learning purposes.

Project description

PoridhiWeb

PoridhiWeb 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 poridhiweb

Quick Start

  • Create a minimal app
from poridhiweb.framework import PoridhiFrame
app = PoridhiFrame()

@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 poridhiweb.framework import PoridhiFrame
from poridhiweb.models.responses import JSONResponse

app = PoridhiFrame()

@app.route('/hello')
def hello(request):
    return JSONResponse({"message": "Hello from PoridhiWeb"})

Class-based Handler

Poridhiweb 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 poridhiweb.framework import PoridhiFrame
from poridhiweb.models.responses import JSONResponse

app = PoridhiFrame()

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 poridhiweb.middlewares package.
  • ResponseError: Raise poridhiweb.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 poridhiweb.framework import PoridhiFrame
from poridhiweb.middlewares import ErrorHandlerMiddleware
from poridhiweb.exceptions import ResponseError

app = PoridhiFrame()
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 poridhiweb.framework import PoridhiFrame
from poridhiweb.models.responses import HTMLResponse

app = PoridhiFrame(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 PoridhiFrame 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

poridhiweb-0.0.3.tar.gz (18.0 kB view details)

Uploaded Source

Built Distribution

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

poridhiweb-0.0.3-py3-none-any.whl (17.8 kB view details)

Uploaded Python 3

File details

Details for the file poridhiweb-0.0.3.tar.gz.

File metadata

  • Download URL: poridhiweb-0.0.3.tar.gz
  • Upload date:
  • Size: 18.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for poridhiweb-0.0.3.tar.gz
Algorithm Hash digest
SHA256 733e0b7b6442e41969f8ebe980707f211271b9a563083d0c81f258ab14cf4dde
MD5 2a27f5263e339484ead45fa97036dc23
BLAKE2b-256 100b6a3747f91b9d179bcd65d87bd5036e4c64aef8749314df0df4a0f0f5a66c

See more details on using hashes here.

File details

Details for the file poridhiweb-0.0.3-py3-none-any.whl.

File metadata

  • Download URL: poridhiweb-0.0.3-py3-none-any.whl
  • Upload date:
  • Size: 17.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for poridhiweb-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 f14c77dc29deeaabe4120d067dc2d49203e35af4d34bf9aa6b8a38baabf11cec
MD5 1c89065ce679ab212e5134ca008203e1
BLAKE2b-256 cd969603c2c86202b2f7047076c1e1373b626c3ba5fe985b1c32a1d8203c537b

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