Tiny lightweight, flexible HTTP framework.
Project description
PyMicroHTTP
PyMicroHTTP is a lightweight, flexible HTTP framework built from scratch in Python. It provides a simple way to create HTTP services without heavy external dependencies, making it ideal for learning purposes or small projects.
Features
- Built on raw TCP sockets
- Routing with HTTP verb and path matching
- Middleware support with easy chaining
- JSON response handling
- Zero external dependencies
Installation
You can install the package via pip:
$ pip install pymicrohttp
Quick Start
Here's a simple example to get you started:
from pymicrohttp.server import Server
s = Server(port=8080)
@s.register('GET /hello')
def hello(request):
return {"message": "Hello, World!"}
if __name__ == "__main__":
s.start_server()
Run this script, and you'll have a server running on http://localhost:8080. Access it with:
curl http://localhost:8080/hello
Routing
Routes are defined using the @s.register decorator:
@s.register('GET /ping')
def ping_handler(request):
return "pong"
Example:
@s.register('POST /login')
def login_handler(request):
try:
body = json.loads(request['body'])
if 'username' not in body or 'password' not in body:
# do somthing
except:
return { 'error': 'invalid data' }
Request Object
The request object is a dict containing these key and value:
{
'verb': ...
'path': ...
'body': ...
'headers': ... # { 'key': 'value' }
'params': ... # { 'key': 'value' }
'query': ... # { 'key': 'value' }
}
You can access it via the handler:
@s.register('GET /ping')
def ping_handler(request):
# accessing request headers
if 'double' in request['headers']:
return "pong-pong"
return "pong"
Examples:
# say hello
s.register('GET /hello/:name')
def hello(request):
name = request['params']['name']
return "Hello " + name
# say hello `n` times
s.register('GET /hello/:name/:n')
def hello(request):
name = request['params']['name']
n = request['params']['n']
return "Hello " * int(n) + name
# say hello `n` times
# read n from query params
# with default value of 3
s.register('GET /hello/:name/:n')
def hello(request):
name = request['params']['name']
n = request['query'].get('n', 3)
return "Hello " * n + name
Response Handling
The framework supports different types of responses:
-
Dictionary (automatically converted to JSON):
return {"key": "value"}
-
String:
return "Hello, World!"
-
Tuple for custom status codes and headers:
return "Not Found", 404 # or return "Created", 201, {"Location": "/resource/1"}
Middleware
Middleware functions can be used to add functionality to your routes:
def log_middleware(next):
def handler(request):
print(f"Request: {request['verb']} {request['path']}")
return next(request)
return handler
@s.register('GET /logged', log_middleware)
def logged_route(request):
return {"message": "This is a logged route"}
Before all
If you want to run a middleware before every single request you can use the s.beforeAll() decorator:
@s.beforeAll()
def logger(next):
def handler(request):
verb, path = request['verb'], request['path']
print(f'{datetime.datetime.now()} {verb} {path}')
return next(request)
return handler
Middleware chaining
You can chain multiple middlwares together
def log_middleware(next):
def handler(request):
# do your loggin logic here
return next(request)
return handler
def auth_middleware(next):
def handler(request):
# do your auth logic here
return next(request)
return handler
@s.register('GET /protected', [log_middleware, auth_middleware])
def protected_route(request):
return {"message": "This is a protected route"}
Running the Server
To run the server:
if __name__ == "__main__":
s = Server(port=8080)
# Register your routes here
s.start_server()
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
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
Hashes for pymicrohttp-0.1.1-py3-none-any.whl
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 | af82966fd3ad0ec47a42f27e99ed620603635b1d2bca25f3729de29e95e9e219 |
|
| MD5 | 1fe548689d07afc309337f7e8e0f9c7f |
|
| BLAKE2b-256 | ed9bd11e28a1ef721b77ead1498dc26b0b2ed98f8dec9a0fc9490f482a12170b |