π MiniExpress β A Python HTTP Server From Scratch A lightweight Express.js-style HTTP framework built using only Python sockets. .
π Overview
This project implements a complete HTTP/1.1 web server from scratch using Pythonβs standard library only. No frameworks like Flask, Django, Express, FastAPI, or high-level HTTP libraries were used.
It provides:
Routing (GET, POST, DELETE, etc.)
Query parameters & path parameters
Static file serving
JSON request parsing
In-memory data storage
CORS support
Basic logging middleware
Express.jsβstyle API (app.get(), app.post(), β¦)
This server is built fully manually using:
socket
threading
json
re It demonstrates understanding of low-level HTTP, server architecture, and socket programming.
π Project Structure project/ β βββ server.py # Custom MiniExpress framework (core server) βββ app.py # Your application routes βββ static/ # Public static files served under /static β βββ index.html βββ README.md
π§ How It Works (Beginner Friendly)
- Sockets
The server manually creates a TCP socket:
socket.socket(socket.AF_INET, socket.SOCK_STREAM)
It binds to:
0.0.0.0:8080
and waits for incoming connections.
- HTTP Request Parsing
Each incoming HTTP request is manually parsed:
Request line β GET /path HTTP/1.1
Headers β Host, Content-Length, Content-Type, etc.
Body β Parsed for POST/PUT requests
Query parameters β ?message=hello
Path parameters β /user/:id
- Routing System
You register routes just like Express.js:
@app.get("/echo") @app.post("/data") @app.get("/data/:id")
The server internally converts paths like /data/:id into regex and extracts parameters.
- Threaded Handling
Each request is processed in a separate thread for concurrency.
- Response Building
Every HTTP response is manually constructed:
HTTP/1.1 200 OK Content-Type: application/json Content-Length: 27 Access-Control-Allow-Origin: *
π How to Run the Server
- Install Python 3
Ensure Python 3.8+ is installed.
- Run the server
In the terminal:
python3 app.py
You will see:
MiniExpress listening on port 8080
Your server is now live at:
π§ͺ API Endpoints β GET /
Returns welcome message
Request
GET /
Response
Welcome to MiniExpress!
β GET /echo?message=hello
Echoes the query param.
Response
Echo: hello
β GET /user/:id
Example:
GET /user/10
Response:
{"user_id": "10"}
β POST /data
Stores JSON in memory.
Example Request
POST /data Content-Type: application/json
{"name":"Soham","value":123}
Response
{"id": 1}
β GET /data
Returns all records.
[ {"id":1,"data":{"name":"Soham","value":123}} ]
β GET /data/:id GET /data/1
Response
{"id": 1, "data": {"name":"Soham","value":123}}
If not found β 404 Not Found
π Static File Serving
Any file placed in:
./static
is served from URL:
/static/
Example:
static/index.html β http://localhost:8080/static/index.html
π Bonus Features Implemented β 1. Request Logging Middleware
Every request prints:
('127.0.0.1', 42022) - GET /data
β 2. Static File Serving
Automatically serves files under /static.
β 3. CORS Support
All responses include:
Access-Control-Allow-Origin: *
π§± Design Decisions Why build from scratch?
To understand:
How browsers communicate with servers
How HTTP requests look before frameworks parse them
How routing works internally
How to build low-level I/O logic
How modern frameworks (Express/Flask/FastAPI) work internally
Why threading?
The assignment needs ability to handle many simultaneous connections.
Why in-memory storage?
Meet the requirement: βstore data in RAMβ
Regex-based routing
Used to support:
/user/:id /data/:id
π§ͺ Test Using cURL Home: curl http://localhost:8080/
Echo: curl "http://localhost:8080/echo?message=hello"
POST data:
curl -X POST http://localhost:8080/data
-H "Content-Type: application/json"
-d '{"name":"Soham","value":123}'
GET all data: curl http://localhost:8080/data
π Limitations Data is not persistent (RAM only)
No HTTPS support
Single-thread performance may vary
No authentication (can be added)
os
It demonstrates understanding of low-level HTTP, server architecture, and socket programming.