Skip to main content

Python Web Framework built for learning purposes.

Project description

ZohidPy

PyPI version License purpose

A lightweight WSGI web framework built from scratch to understand how web frameworks work internally.

ZohidPy is intentionally small and explicit.
It is designed for learning, experimentation, and understanding routing, middleware, request/response handling, templating, and static file serving without heavy abstractions.


Installation

pip install zohidpy

Quick Start

from waitress import serve
from zohidpy.app import ZohidPy

app = ZohidPy()

@app.route("/home")
def home(request, response):
    response.text = "Hello from ZohidPy!"

if __name__ == "__main__":
    serve(app, listen="localhost:8000")

Run:

python main.py

Visit:

http://localhost:8000/home


Features

  • Function-based routing
  • Class-based routing
  • Dynamic URL parameters
  • JSON / Text / HTML response helpers
  • Jinja2 template rendering
  • Static file serving (WhiteNoise)
  • Middleware system
  • Custom exception handlers
  • Built-in test client
  • Fully WSGI compatible

Routing

Function-Based Routing

@app.route("/home")
def home(request, response):
    response.text = "Hello from home"

Dynamic Routes

@app.route("/hello/{name}")
def greet(request, response, name):
    response.text = f"Hello {name}"

Class-Based Routing

@app.route("/books")
class Books:
    def get(self, request, response):
        response.text = "Books page"

    def post(self, request, response):
        response.text = "Create a book"

If a method is not defined, the framework returns:

405 Method Not Allowed

Restricting Allowed Methods

@app.route("/home", allowed_methods=["post"])
def home(request, response):
    response.text = "POST only"

Response Helpers

JSON

resp.json = {"name": "zohid"}

Automatically sets:

Content-Type: application/json

Plain Text

resp.text = "Hello world"

Sets:

Content-Type: text/plain

HTML

resp.html = "<h1>Hello</h1>"

Sets:

Content-Type: text/html

Templates (Jinja2)

Default directory:

templates/

Example:

@app.route("/template")
def template_handler(req, resp):
    resp.html = app.template(
        "home.html",
        context={"title": "My Page"}
    )

Custom template directory:

app = ZohidPy(templates_dir="my_templates")

Static Files

Static files are served using WhiteNoise.

Default directory:

static/

Accessible via:

/static/filename.css

Custom directory:

app = ZohidPy(static_dir="assets")

Middleware

Create middleware by subclassing Middleware:

from zohidpy.middleware import Middleware

class LoggingMiddleware(Middleware):
    def process_request(self, req):
        print("Request:", req.url)

    def process_response(self, req, resp):
        print("Response generated")

app.add_middleware(LoggingMiddleware)

Middleware lifecycle:

  1. process_request
  2. route handler
  3. process_response

Custom Exception Handling

def on_exception(req, resp, exc):
    resp.text = "Something went wrong"

app.add_exception_handler(on_exception)

Testing

ZohidPy includes a built-in test client:

test_client = app.test_session()

Example test:

def test_home(app, test_client):
    @app.route("/home")
    def home(req, resp):
        resp.text = "Hello"

    response = test_client.get("http://testingserver/home")
    assert response.text == "Hello"

Deployment

ZohidPy is fully WSGI-compatible.

Waitress

waitress-serve --listen=0.0.0.0:8000 main:app

Gunicorn

gunicorn main:app

Internal Architecture Overview

High-level request flow:

  1. WSGI entry point receives request
  2. Static files handled via WhiteNoise
  3. Middleware layer executes
  4. Route resolution via pattern matching
  5. Handler execution
  6. Response object constructs final WebOb response

The design favors clarity over abstraction.


License

This project is licensed under the Apache License 2.0 — see the LICENSE file for details.


Author

Zohidjon Mahmudjonov

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

zohidpy-0.1.4.tar.gz (12.7 kB view details)

Uploaded Source

Built Distribution

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

zohidpy-0.1.4-py2.py3-none-any.whl (9.9 kB view details)

Uploaded Python 2Python 3

File details

Details for the file zohidpy-0.1.4.tar.gz.

File metadata

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

File hashes

Hashes for zohidpy-0.1.4.tar.gz
Algorithm Hash digest
SHA256 d99b0d083f0ea5dcbed840f58d975a1340b951d0d3f881f3c4901da8cb83bf34
MD5 afb271cbb966c469676ada8fb0610fb5
BLAKE2b-256 fa86827beafbea275f4965159fb4f831adff4768a888e85894d59747cd17884e

See more details on using hashes here.

File details

Details for the file zohidpy-0.1.4-py2.py3-none-any.whl.

File metadata

  • Download URL: zohidpy-0.1.4-py2.py3-none-any.whl
  • Upload date:
  • Size: 9.9 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for zohidpy-0.1.4-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 50007a7be8082dd9a89d1021a7f8a814dd48d81d9350b72e5dff23171e780402
MD5 30aa4527640835a68b1c9c1e8936702f
BLAKE2b-256 16c76feed8bb2fd5b241d17dd570a19e400fd991636342dbdfca8e619fd44e1d

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