{"id":20280331,"url":"https://github.com/yezz123/fastapi-class","last_synced_at":"2025-04-12T22:28:59.100Z","repository":{"id":39894041,"uuid":"413233165","full_name":"yezz123/fastapi-class","owner":"yezz123","description":"provides a class-based View decorator to help reduce the amount of boilerplate necessary when developing related routes. ✨🚀","archived":false,"fork":false,"pushed_at":"2025-03-24T20:53:42.000Z","size":444,"stargazers_count":114,"open_issues_count":4,"forks_count":13,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-04-04T01:42:00.058Z","etag":null,"topics":["class","decorators","dependency-injection","fastapi","fastapi-template","pydantic","python","python3"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yezz123.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["yezz123"]}},"created_at":"2021-10-04T00:47:19.000Z","updated_at":"2025-03-03T16:08:07.000Z","dependencies_parsed_at":"2023-02-15T06:46:16.191Z","dependency_job_id":"3c2201e3-06f4-4094-a1c1-02bfdd6f7b47","html_url":"https://github.com/yezz123/fastapi-class","commit_stats":{"total_commits":218,"total_committers":6,"mean_commits":"36.333333333333336","dds":"0.38990825688073394","last_synced_commit":"503be923a4ddc91f43fdc2eb7f7c1dc64db34f79"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yezz123%2Ffastapi-class","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yezz123%2Ffastapi-class/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yezz123%2Ffastapi-class/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yezz123%2Ffastapi-class/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yezz123","download_url":"https://codeload.github.com/yezz123/fastapi-class/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248639333,"owners_count":21137825,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["class","decorators","dependency-injection","fastapi","fastapi-template","pydantic","python","python3"],"created_at":"2024-11-14T13:35:20.271Z","updated_at":"2025-04-12T22:28:59.062Z","avatar_url":"https://github.com/yezz123.png","language":"Python","funding_links":["https://github.com/sponsors/yezz123"],"categories":[],"sub_categories":[],"readme":"![Class](https://user-images.githubusercontent.com/52716203/137606695-f110f129-08b1-45f3-a445-962c1f28378c.png)\n\n\u003cp align=\"center\"\u003e\n    \u003cem\u003eClasses and Decorators to use FastAPI with Class based routing\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/yezz123/fastapi-class/actions/workflows/ci.yml\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://github.com/yezz123/fastapi-class/actions/workflows/ci.yml/badge.svg\" alt=\"Continuous Integration\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://codecov.io/gh/yezz123/fastapi-class\"\u003e\n    \u003cimg src=\"https://codecov.io/gh/yezz123/fastapi-class/branch/main/graph/badge.svg\"/\u003e\n\u003c/a\u003e\n\u003ca href=\"https://pypi.org/project/fastapi-class\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/v/fastapi-class?color=%2334D058\u0026label=pypi%20package\" alt=\"Package version\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://pypi.org/project/fastapi-class\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/pyversions/fastapi-class.svg?color=%2334D058\" alt=\"Supported Python versions\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://pepy.tech/project/fastapi_class\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://static.pepy.tech/badge/fastapi_class\" alt=\"Test\"\u003e\n\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n**Source Code**: \u003chttps://github.com/yezz123/fastapi-class\u003e\n\n**Install the project**: `pip install fastapi-class`\n\n---\n\nAs you create more complex FastAPI applications, you may find yourself frequently repeating the same dependencies in multiple related endpoints.\n\nA common question people have as they become more comfortable with FastAPI is how they can reduce the number of times they have to copy/paste the same dependency into related routes.\n\n`fastapi_class` provides a `class-based view` decorator `@View` to help reduce the amount of boilerplate necessary when developing related routes.\n\n\u003e Highly inspired by [Fastapi-utils](https://fastapi-utils.davidmontague.xyz/user-guide/class-based-views/), Thanks to [@dmontagu](https://github.com/dmontagu) for the great work.\n\n- Example:\n\n```python\nfrom fastapi import FastAPI, Query\nfrom pydantic import BaseModel\nfrom fastapi_class import View\n\napp = FastAPI()\n\nclass ItemModel(BaseModel):\n    id: int\n    name: str\n    description: str = None\n\n@View(app)\nclass ItemView:\n    async def post(self, item: ItemModel):\n        return item\n\n    async def get(self, item_id: int = Query(..., gt=0)):\n        return {\"item_id\": item_id}\n\n```\n\n### Response model 📦\n\n`Exception` in list need to be either function that return `fastapi.HTTPException` itself. In case of a function it is required to have all of it's arguments to be `optional`.\n\n```py\nfrom fastapi import FastAPI, HTTPException, status\nfrom fastapi.responses import PlainTextResponse\nfrom pydantic import BaseModel\n\nfrom fastapi_class import View\n\napp = FastAPI()\n\nNOT_AUTHORIZED = HTTPException(401, \"Not authorized.\")\nNOT_ALLOWED = HTTPException(405, \"Method not allowed.\")\nNOT_FOUND = lambda item_id=\"item_id\": HTTPException(404, f\"Item with {item_id} not found.\")\n\nclass ItemResponse(BaseModel):\n    field: str | None = None\n\n@View(app)\nclass MyView:\n    exceptions = {\n        \"__all__\": [NOT_AUTHORIZED],\n        \"put\": [NOT_ALLOWED, NOT_FOUND]\n    }\n\n    RESPONSE_MODEL = {\n        \"put\": ItemResponse\n    }\n\n    RESPONSE_CLASS = {\n        \"delete\": PlainTextResponse\n    }\n\n    async def get(self):\n        ...\n\n    async def put(self):\n        ...\n\n    async def delete(self):\n        ...\n```\n\n### Customized Endpoints\n\n```py\nfrom fastapi import FastAPI, HTTPException\nfrom fastapi.responses import PlainTextResponse\nfrom pydantic import BaseModel\n\nfrom fastapi_class import View, endpoint\n\napp = FastAPI()\n\nNOT_AUTHORIZED = HTTPException(401, \"Not authorized.\")\nNOT_ALLOWED = HTTPException(405, \"Method not allowed.\")\nNOT_FOUND = lambda item_id=\"item_id\": HTTPException(404, f\"Item with {item_id} not found.\")\nEXCEPTION = HTTPException(400, \"Example.\")\n\nclass UserResponse(BaseModel):\n    field: str | None = None\n\n@View(app)\nclass MyView:\n    exceptions = {\n        \"__all__\": [NOT_AUTHORIZED],\n        \"put\": [NOT_ALLOWED, NOT_FOUND],\n        \"edit\": [EXCEPTION]\n    }\n\n    RESPONSE_MODEL = {\n        \"put\": UserResponse,\n        \"edit\": UserResponse\n    }\n\n    RESPONSE_CLASS = {\n        \"delete\": PlainTextResponse\n    }\n\n    async def get(self):\n        ...\n\n    async def put(self):\n        ...\n\n    async def delete(self):\n        ...\n\n    @endpoint((\"PUT\"), path=\"edit\")\n    async def edit(self):\n        ...\n```\n\n**Note:** The `edit()` endpoint is decorated with the `@endpoint((\"PUT\",), path=\"edit\")` decorator, which specifies that this endpoint should handle `PUT` requests to the `/edit` path,\nusing `@endpoint(\"PUT\", path=\"edit\")` has the same effect\n\n## Development 🚧\n\n### Setup environment 📦\n\n__Note:__ You should have `uv` installed, if not you can install it with:\n\n```bash\npip install uv\n```\n\nThen you can install the dependencies with:\n\n```bash\n# Install dependencies\nuv sync --all-extras\n```\n\n### Run tests 🌝\n\nYou can run all the tests with:\n\n```bash\nbash scripts/test.sh\n```\n\n### Format the code 🍂\n\nExecute the following command to apply `pre-commit` formatting:\n\n```bash\nbash scripts/format.sh\n```\n\nExecute the following command to apply `mypy` type checking:\n\n```bash\nbash scripts/lint.sh\n```\n\n## License\n\nThis project is licensed under the terms of the MIT license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyezz123%2Ffastapi-class","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyezz123%2Ffastapi-class","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyezz123%2Ffastapi-class/lists"}