# 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:
```python
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:
```python
@s.register('GET /ping')
def ping_handler(request):
return "pong"
```
Example:
```python
@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:
```py
@s.register('GET /ping')
def ping_handler(request):
# accessing request headers
if 'double' in request['headers']:
return "pong-pong"
return "pong"
```
Examples:
```py
# say hello
s.register('GET /hello/:name')
def hello(request):
name = request['params']['name']
return "Hello " + name
```
```py
# 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
```
```py
# 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:
1. Dictionary (automatically converted to JSON):
```python
return {"key": "value"}
```
2. String:
```python
return "Hello, World!"
```
3. Tuple for custom status codes and headers:
```python
return "Not Found", 404
# or
return "Created", 201, {"Location": "/resource/1"}
```
## Middleware
Middleware functions can be used to add functionality to your routes:
```python
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:
```py
@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
```py
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:
```python
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.
Raw data
{
"_id": null,
"home_page": "https://github.com/hasssanezzz/PyMicroHTTP",
"name": "pymicrohttp",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": null,
"keywords": null,
"author": "Hassan Ezz",
"author_email": "dhassanezz@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/21/2a/7b827ddc7a8c30fd52f900cd218c09e30bd495222d82c021862d2b1e7b75/pymicrohttp-0.1.1.tar.gz",
"platform": null,
"description": "# PyMicroHTTP\n\nPyMicroHTTP 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.\n\n## Features\n\n- Built on raw TCP sockets\n- Routing with HTTP verb and path matching\n- Middleware support with easy chaining\n- JSON response handling\n- Zero external dependencies\n\n## Installation\n\nYou can install the package via pip:\n```\n$ pip install pymicrohttp\n```\n\n## Quick Start\n\nHere's a simple example to get you started:\n\n```python\nfrom pymicrohttp.server import Server\n\ns = Server(port=8080)\n\n@s.register('GET /hello')\ndef hello(request):\n return {\"message\": \"Hello, World!\"}\n\nif __name__ == \"__main__\":\n s.start_server()\n```\n\nRun this script, and you'll have a server running on `http://localhost:8080`. Access it with:\n\n```\ncurl http://localhost:8080/hello\n```\n\n## Routing\n\nRoutes are defined using the `@s.register` decorator:\n\n```python\n@s.register('GET /ping')\ndef ping_handler(request):\n return \"pong\"\n```\n\nExample:\n\n```python\n@s.register('POST /login')\ndef login_handler(request):\n try:\n body = json.loads(request['body'])\n if 'username' not in body or 'password' not in body:\n # do somthing\n except:\n return { 'error': 'invalid data' }\n```\n\n## Request Object\n\nThe request object is a dict containing these key and value:\n```\n{\n 'verb': ...\n 'path': ...\n 'body': ...\n 'headers': ... # { 'key': 'value' }\n 'params': ... # { 'key': 'value' }\n 'query': ... # { 'key': 'value' }\n}\n```\n\nYou can access it via the handler:\n```py\n@s.register('GET /ping')\ndef ping_handler(request):\n # accessing request headers\n if 'double' in request['headers']:\n return \"pong-pong\"\n return \"pong\"\n```\n\nExamples:\n```py\n# say hello\ns.register('GET /hello/:name')\ndef hello(request):\n name = request['params']['name']\n return \"Hello \" + name\n```\n\n```py\n# say hello `n` times\ns.register('GET /hello/:name/:n')\ndef hello(request):\n name = request['params']['name']\n n = request['params']['n']\n return \"Hello \" * int(n) + name\n```\n\n```py\n# say hello `n` times\n# read n from query params\n# with default value of 3\ns.register('GET /hello/:name/:n')\ndef hello(request):\n name = request['params']['name']\n n = request['query'].get('n', 3)\n return \"Hello \" * n + name\n```\n\n## Response Handling\n\nThe framework supports different types of responses:\n\n1. Dictionary (automatically converted to JSON):\n ```python\n return {\"key\": \"value\"}\n ```\n\n2. String:\n ```python\n return \"Hello, World!\"\n ```\n\n3. Tuple for custom status codes and headers:\n ```python\n return \"Not Found\", 404\n # or\n return \"Created\", 201, {\"Location\": \"/resource/1\"}\n ```\n\n\n## Middleware\nMiddleware functions can be used to add functionality to your routes:\n\n```python\ndef log_middleware(next):\n def handler(request):\n print(f\"Request: {request['verb']} {request['path']}\")\n return next(request)\n return handler\n\n@s.register('GET /logged', log_middleware)\ndef logged_route(request):\n return {\"message\": \"This is a logged route\"}\n```\n\n### Before all\n\nIf you want to run a middleware before every single request you can use the `s.beforeAll()` decorator:\n```py\n@s.beforeAll()\ndef logger(next):\n def handler(request):\n verb, path = request['verb'], request['path']\n print(f'{datetime.datetime.now()} {verb} {path}')\n return next(request)\n return handler\n```\n\n### Middleware chaining\nYou can chain multiple middlwares together\n```py\ndef log_middleware(next):\n def handler(request):\n # do your loggin logic here\n return next(request)\n return handler\n\ndef auth_middleware(next):\n def handler(request):\n # do your auth logic here\n return next(request)\n return handler\n\n@s.register('GET /protected', [log_middleware, auth_middleware])\ndef protected_route(request):\n return {\"message\": \"This is a protected route\"}\n```\n\n## Running the Server\n\nTo run the server:\n\n```python\nif __name__ == \"__main__\":\n s = Server(port=8080)\n # Register your routes here\n s.start_server()\n```\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n",
"bugtrack_url": null,
"license": null,
"summary": "Tiny lightweight, flexible HTTP framework.",
"version": "0.1.1",
"project_urls": {
"Homepage": "https://github.com/hasssanezzz/PyMicroHTTP"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "ed9bd11e28a1ef721b77ead1498dc26b0b2ed98f8dec9a0fc9490f482a12170b",
"md5": "1fe548689d07afc309337f7e8e0f9c7f",
"sha256": "af82966fd3ad0ec47a42f27e99ed620603635b1d2bca25f3729de29e95e9e219"
},
"downloads": -1,
"filename": "pymicrohttp-0.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "1fe548689d07afc309337f7e8e0f9c7f",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 6648,
"upload_time": "2024-08-12T19:53:57",
"upload_time_iso_8601": "2024-08-12T19:53:57.067155Z",
"url": "https://files.pythonhosted.org/packages/ed/9b/d11e28a1ef721b77ead1498dc26b0b2ed98f8dec9a0fc9490f482a12170b/pymicrohttp-0.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "212a7b827ddc7a8c30fd52f900cd218c09e30bd495222d82c021862d2b1e7b75",
"md5": "7d1217b2a83e916ba48b5344650be2ad",
"sha256": "808bb942819a4737b0f9c823e536324d36e097313ef907566b00bd272ea08157"
},
"downloads": -1,
"filename": "pymicrohttp-0.1.1.tar.gz",
"has_sig": false,
"md5_digest": "7d1217b2a83e916ba48b5344650be2ad",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 6005,
"upload_time": "2024-08-12T19:53:58",
"upload_time_iso_8601": "2024-08-12T19:53:58.902443Z",
"url": "https://files.pythonhosted.org/packages/21/2a/7b827ddc7a8c30fd52f900cd218c09e30bd495222d82c021862d2b1e7b75/pymicrohttp-0.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-08-12 19:53:58",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "hasssanezzz",
"github_project": "PyMicroHTTP",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "pymicrohttp"
}