# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['fastapi_controllers', 'tests', 'tests.functional', 'tests.unit']

package_data = \
{'': ['*']}

install_requires = \
['fastapi']

setup_kwargs = {
    'name': 'fastapi-controllers',
    'version': '0.2.1',
    'description': 'Simple Controller implementation for FastAPI',
    'long_description': '<p>\n    <h1 align="center">fastapi-controllers</h1>\n    <p align="center">\n        A simple solution for organizing your FastAPI endpoints\n    </p>\n    <p align="center">\n    <img src="https://badgen.net/pypi/v/fastapi-controllers"/>\n    <img src="https://badgen.net/pypi/license/fastapi-controllers"/>\n    <img src="https://badgen.net/pypi/python/fastapi-controllers"/>\n    <img src="https://github.com/goraje/fastapi-controllers/actions/workflows/test.yml/badge.svg">\n    </p>\n</p>\n\n## Organize your API endpoints\n\n`fastapi-controllers` offers a simple solution for organizing your API endpoints by means of a `Controller` class embracing the concept of class-based views.\n\n## Features\n\n- class-based approach to organizing FastAPI endpoints\n- class-scoped definition of APIRouter parameters\n- instance-scoped definition of FastAPI dependencies\n- it integrates seamlessly with the FastAPI framework\n- works with both sync and async endpoints\n\n## Installation\n\n```sh\npip install fastapi-controllers\n```\n\n## Minimal working example\n\n```python\nimport uvicorn\nfrom fastapi import FastAPI, Response, status\nfrom fastapi.websockets import WebSocket\n\nfrom fastapi_controllers import Controller, get, websocket\n\n\nclass ExampleController(Controller):\n    @get("/example", response_class=Response)\n    async def get_example(self) -> Response:\n        return Response(status_code=status.HTTP_200_OK)\n\n    @websocket("/ws")\n    async def ws_example(websocket: WebSocket) -> None:\n        await websocket.accept()\n        while True:\n            data = await websocket.receive_text()\n            await websocket.send_text(f"Received: {data}")\n\n\nif __name__ == "__main__":\n    app = FastAPI()\n    app.include_router(ExampleController.create_router())\n    uvicorn.run(app)\n```\n\nFastAPI\'s `APIRouter` is created and populated with API routes by the `Controller.create_router` method and can be incorporated into the application in the usual way via `app.include_router`.\n\n## Seamless integration\n\nThe router-related parameters as well as those of HTTP request-specific and websocket decorators are expected to be the same as those used by `fastapi.APIRouter`, `fastapi.APIRouter.<request_method>` and `fastapi.APIRouter.websocket`. Validation of the provided parameters is performed during initialization via the `inspect` module. This ensures compatibility with the FastAPI framework and prevents the introduction of a new, unnecessary naming convention.\n\n### Available decorators\n\n```python\nfrom fastapi_controllers import delete, get, head, options, patch, post, put, trace, websocket\n```\n\n## Use class variables to customize your APIRouter\n\nClass variables can be used to set the commonly used APIRouter parameters: `prefix`, `dependencies` and `tags`.\n\n```python\nimport uvicorn\nfrom fastapi import Depends, FastAPI, Response, status\nfrom fastapi.security import HTTPBasic, HTTPBasicCredentials\nfrom pydantic import BaseModel\n\nfrom fastapi_controllers import Controller, get, post\n\nsecurity = HTTPBasic()\n\n\nasync def authorized_user(credentials: HTTPBasicCredentials = Depends(security)) -> None:\n    ...\n\n\nclass ExampleRequest(BaseModel):\n    name: str\n\n\nclass ExampleResponse(BaseModel):\n    message: str\n\n\nclass ExampleController(Controller):\n    prefix = "/example"\n    tags = ["example"]\n    dependencies = [Depends(authorized_user)]\n\n    @get("", response_class=Response)\n    async def get_example(self) -> Response:\n        return Response(status_code=status.HTTP_200_OK)\n\n    @post("", response_model=ExampleResponse)\n    async def post_example(self, data: ExampleRequest) -> ExampleResponse:\n        return ExampleResponse(message=f"Hello, {data.name}!")\n\n\nif __name__ == "__main__":\n    app = FastAPI()\n    app.include_router(ExampleController.create_router())\n    uvicorn.run(app)\n```\n### Additional APIRouter parameters\nAdditional APIRouter parameters can be provided via the `__router_params__` class variable in form of a mapping.\n\n```python\nimport uvicorn\nfrom fastapi import FastAPI, Response, status\n\nfrom fastapi_controllers import Controller, get\n\n\nclass ExampleController(Controller):\n    prefix = "/example"\n    tags = ["example"]\n    __router_params__ = {"deprecated": True}\n\n    @get("", response_class=Response)\n    async def get_example(self) -> Response:\n        return Response(status_code=status.HTTP_200_OK)\n\n\nif __name__ == "__main__":\n    app = FastAPI()\n    app.include_router(ExampleController.create_router())\n    uvicorn.run(app)\n```\n> :warning: **Important**: Beware of assigning values to the same parameter twice (directly on class-level and through `__router_params__`). The values stored in `__router_params__` have precedence and will override your other settings if a name conflict arises. E.g. the following `Controller` would create an `APIRouter` with `prefix=/override`, `tags=["override"]` and `dependencies=[Depends(override)]`\n\n```python\nfrom fastapi import Depends\n\nfrom fastapi_controllers import Controller\n\n\nclass ExampleController(Controller):\n    prefix = "/example"\n    tags = ["example"]\n    dependencies = [Depends(example)]\n    __router_params__ = {\n        "prefix": "/override",\n        "tags": ["override"],\n        "dependencies": [Depends(override)],\n    }\n```\n\n\n## Instance-scoped dependencies\n\nInstance-scoped attributes can be defined in the `__init__` method of the `Controller` and offer an easy way to access common dependencies for all endpoints.\n\n```python\nimport json\n\nimport uvicorn\nfrom fastapi import Depends, FastAPI, Response, status\n\nfrom fastapi_controllers import Controller, get\n\n\nclass DbSession:\n    @property\n    def status(self) -> str:\n        return "CONNECTED"\n\n\nasync def get_db_session() -> DbSession:\n    return DbSession()\n\n\nclass ExampleController(Controller):\n    prefix = "/example"\n\n    def __init__(self, session: DbSession = Depends(get_db_session)) -> None:\n        self.session = session\n\n    @get("", response_class=Response)\n    async def get_status(self) -> Response:\n        return Response(\n            content=json.dumps({"status": f"{self.session.status}"}),\n            status_code=status.HTTP_200_OK,\n            media_type="application/json",\n        )\n\n\nif __name__ == "__main__":\n    app = FastAPI()\n    app.include_router(ExampleController.create_router())\n    uvicorn.run(app)\n```\n',
    'author': 'Jerzy Góra',
    'author_email': 'j.gora89@gmail.com',
    'maintainer': 'None',
    'maintainer_email': 'None',
    'url': 'https://github.com/goraje/fastapi-controllers',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.8,<4.0',
}


setup(**setup_kwargs)
