pymicrohttp


Namepymicrohttp JSON
Version 0.1.1 PyPI version JSON
download
home_pagehttps://github.com/hasssanezzz/PyMicroHTTP
SummaryTiny lightweight, flexible HTTP framework.
upload_time2024-08-12 19:53:58
maintainerNone
docs_urlNone
authorHassan Ezz
requires_python>=3.6
licenseNone
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 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"
}
        
Elapsed time: 0.31000s