Python Web Framework built for learning purposes.
Project description
ZohidPy
A minimal 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:
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:
- process_request
- route handler
- 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:
- WSGI entry point receives request
- Static files handled via WhiteNoise
- Middleware layer executes
- Route resolution via pattern matching
- Handler execution
- 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
- GitHub: @zohidjon-m
- Email: zohidjon.mah@gmail.com
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
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 zohidpy-0.1.3.tar.gz.
File metadata
- Download URL: zohidpy-0.1.3.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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9f74179fb3189415e6a015e7ef144c768ab29e0b246c28b017027520de75c0a1
|
|
| MD5 |
6a6d4e3ac27e28108298394a2993a47c
|
|
| BLAKE2b-256 |
91ab77f4a8c224745054bd43b5734ea45e399c4ca8e2bae1110bf305ad01308f
|
File details
Details for the file zohidpy-0.1.3-py2.py3-none-any.whl.
File metadata
- Download URL: zohidpy-0.1.3-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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4087c70e7145c8d59ad2b18f8dbfedb84d563ff40e3b6f8a932109204453cc61
|
|
| MD5 |
6067de6507fffdc79a861bed8ba404ea
|
|
| BLAKE2b-256 |
0e270b64546cccad4ee28d9ed5759b7fc758308dd49fbdf3352802a1cfc054b7
|