cerasus


Namecerasus JSON
Version 0.0.1 PyPI version JSON
download
home_pagehttps://github.com/amateur80lvl/cerasus
SummarySimple quickstarter/dispatcher for ASGI apps based on Hypercorn with Request/Response objects from Starlette.
upload_time2023-09-01 08:48:12
maintainer
docs_urlNone
authoramateur80lvl
requires_python
license
keywords asgi asyncio
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Cerasus

Cerasus is a simple dispatcher and quickstart function for ASGI apps based on Hypercorn
with Request/Response objects from Starlette.

The dispatcher uses a mapping like this:

``` python
{
    'GET': {
        '': webapp.index,
        '/': webapp.index,
        '/items/get': webapp.api.items.get
    },
    'POST': {
        '/items/add': webapp.api.items.add
    }
}
```

No REST. No Routes. What can be simpler?

The mapping is constructed by `expose` decorators. Here's an example that matches the mapping above:

``` python
from cerasus import expose, quickstart
from starlette.requests import Request
from starlette.responses import HTMLResponse, JSONResponse

class APIError(Exception):

    def __init__(self, status_code, description):
        self.status_code = status_code
        self.description = description

class Items:

    @expose
    async def get(self, request):
        items = []
        # get items
        # ...
        return JSONResponse(dict(status='success', items=items))

    @expose(methods='POST')
    async def add(self, request):
        item = await request.json()
        # add item
        # ...
        return JSONResponse(dict(status='success'))

class Api:
    # Customized error handling for API.
    # Error handlers can be either coroutines that return Starlette Response objects, or just objects:
    _undefined_method = JSONResponse(dict(status='error', description='Method not allowed'), status_code=405)
    _undefined_handler = JSONResponse(dict(status='error', description='Bad endpoint'), status_code=404)

    async def _exception_handler(self, request, exc):
        return JSONResponse(dict(status='error', description=exc.description), status_code=exc.status_code)

    # Note that children "inherit" error responses, i.e. we do not define them for Items
    items = Items()

class Webapp:
    api = Api()

    @expose(name='/')
    async def index(self, request):
        return HTMLResponse('<h1>Hello</h1>')

async def open_db():
    pass

async def close_db():
    pass

if __name__ == "__main__":
    quickstart(
        Api(),
        {
            'bind': ['127.0.0.1:12345']
            'alpn_protocols': ['h2']
        },
        base_urlpath = '/',
        on_startup = open_db,
        on_shutdown = close_db
    )
```

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/amateur80lvl/cerasus",
    "name": "cerasus",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "asgi,asyncio",
    "author": "amateur80lvl",
    "author_email": "amateur80lvl@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/1b/83/851c5b2459abcf86a0c2f6eaf499a26268404f02418b781a25c8a77b0197/cerasus-0.0.1.tar.gz",
    "platform": null,
    "description": "# Cerasus\n\nCerasus is a simple dispatcher and quickstart function for ASGI apps based on Hypercorn\nwith Request/Response objects from Starlette.\n\nThe dispatcher uses a mapping like this:\n\n``` python\n{\n    'GET': {\n        '': webapp.index,\n        '/': webapp.index,\n        '/items/get': webapp.api.items.get\n    },\n    'POST': {\n        '/items/add': webapp.api.items.add\n    }\n}\n```\n\nNo REST. No Routes. What can be simpler?\n\nThe mapping is constructed by `expose` decorators. Here's an example that matches the mapping above:\n\n``` python\nfrom cerasus import expose, quickstart\nfrom starlette.requests import Request\nfrom starlette.responses import HTMLResponse, JSONResponse\n\nclass APIError(Exception):\n\n    def __init__(self, status_code, description):\n        self.status_code = status_code\n        self.description = description\n\nclass Items:\n\n    @expose\n    async def get(self, request):\n        items = []\n        # get items\n        # ...\n        return JSONResponse(dict(status='success', items=items))\n\n    @expose(methods='POST')\n    async def add(self, request):\n        item = await request.json()\n        # add item\n        # ...\n        return JSONResponse(dict(status='success'))\n\nclass Api:\n    # Customized error handling for API.\n    # Error handlers can be either coroutines that return Starlette Response objects, or just objects:\n    _undefined_method = JSONResponse(dict(status='error', description='Method not allowed'), status_code=405)\n    _undefined_handler = JSONResponse(dict(status='error', description='Bad endpoint'), status_code=404)\n\n    async def _exception_handler(self, request, exc):\n        return JSONResponse(dict(status='error', description=exc.description), status_code=exc.status_code)\n\n    # Note that children \"inherit\" error responses, i.e. we do not define them for Items\n    items = Items()\n\nclass Webapp:\n    api = Api()\n\n    @expose(name='/')\n    async def index(self, request):\n        return HTMLResponse('<h1>Hello</h1>')\n\nasync def open_db():\n    pass\n\nasync def close_db():\n    pass\n\nif __name__ == \"__main__\":\n    quickstart(\n        Api(),\n        {\n            'bind': ['127.0.0.1:12345']\n            'alpn_protocols': ['h2']\n        },\n        base_urlpath = '/',\n        on_startup = open_db,\n        on_shutdown = close_db\n    )\n```\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "Simple quickstarter/dispatcher for ASGI apps based on Hypercorn with Request/Response objects from Starlette.",
    "version": "0.0.1",
    "project_urls": {
        "Homepage": "https://github.com/amateur80lvl/cerasus"
    },
    "split_keywords": [
        "asgi",
        "asyncio"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "d0dfd600e247c0803360626d608f16d2dd7f4094ac5d9185d0a1549830e99abc",
                "md5": "0ef8b483050f7803a9a554bcf3213d7e",
                "sha256": "d881526a1e4babfc94271c0d1c63f47349b84c94ceead4273cda386bdcaa7be6"
            },
            "downloads": -1,
            "filename": "cerasus-0.0.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "0ef8b483050f7803a9a554bcf3213d7e",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 7624,
            "upload_time": "2023-09-01T08:48:11",
            "upload_time_iso_8601": "2023-09-01T08:48:11.004512Z",
            "url": "https://files.pythonhosted.org/packages/d0/df/d600e247c0803360626d608f16d2dd7f4094ac5d9185d0a1549830e99abc/cerasus-0.0.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "1b83851c5b2459abcf86a0c2f6eaf499a26268404f02418b781a25c8a77b0197",
                "md5": "5f9f9dfd3e34e5d0761345a4a9f9c942",
                "sha256": "2ba0aa9beeef1a675ae9068197f7c9f974fb4ce16d890da9fc2aac818f2fd8bf"
            },
            "downloads": -1,
            "filename": "cerasus-0.0.1.tar.gz",
            "has_sig": false,
            "md5_digest": "5f9f9dfd3e34e5d0761345a4a9f9c942",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 7152,
            "upload_time": "2023-09-01T08:48:12",
            "upload_time_iso_8601": "2023-09-01T08:48:12.984045Z",
            "url": "https://files.pythonhosted.org/packages/1b/83/851c5b2459abcf86a0c2f6eaf499a26268404f02418b781a25c8a77b0197/cerasus-0.0.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-09-01 08:48:12",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "amateur80lvl",
    "github_project": "cerasus",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "cerasus"
}
        
Elapsed time: 0.11824s