{"id":13820813,"url":"https://github.com/iam-abbas/FastAPI-Production-Boilerplate","last_synced_at":"2025-05-16T10:33:02.299Z","repository":{"id":65829756,"uuid":"597525960","full_name":"iam-abbas/FastAPI-Production-Boilerplate","owner":"iam-abbas","description":"A scalable and production ready boilerplate for FastAPI","archived":false,"fork":false,"pushed_at":"2023-10-05T13:58:38.000Z","size":495,"stargazers_count":428,"open_issues_count":6,"forks_count":65,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-11-05T09:10:25.421Z","etag":null,"topics":["api","boilerplate","fastapi","fastapi-boilerplate","fastapi-template","python","rest-api","restful-api","template"],"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/iam-abbas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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}},"created_at":"2023-02-04T20:17:41.000Z","updated_at":"2024-11-02T18:29:40.000Z","dependencies_parsed_at":null,"dependency_job_id":"f4014a96-1703-4855-b310-6e3c66586e20","html_url":"https://github.com/iam-abbas/FastAPI-Production-Boilerplate","commit_stats":null,"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iam-abbas%2FFastAPI-Production-Boilerplate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iam-abbas%2FFastAPI-Production-Boilerplate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iam-abbas%2FFastAPI-Production-Boilerplate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iam-abbas%2FFastAPI-Production-Boilerplate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iam-abbas","download_url":"https://codeload.github.com/iam-abbas/FastAPI-Production-Boilerplate/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225423726,"owners_count":17472178,"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":["api","boilerplate","fastapi","fastapi-boilerplate","fastapi-template","python","rest-api","restful-api","template"],"created_at":"2024-08-04T08:01:09.505Z","updated_at":"2024-11-19T20:31:21.808Z","avatar_url":"https://github.com/iam-abbas.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"## FastAPI Production Template\n\nA scalable and production ready boilerplate for FastAPI\n\n### Table of Contents\n\n- [Project Overview](#project-overview)\n- [Features](#features)\n- [Installation Guide](#installation-guide)\n- [Usage Guide](#usage-guide)\n- [Advanced Usage](#advanced-usage)\n- [Contributing](#contributing)\n- [License](#license)\n- [Acknowledgements](#acknowledgements)\n\n### Project Overview\n\nThis boilerplate follows a layered architecture that includes a model layer, a repository layer, a controller layer, and an API layer. Its directory structure is designed to isolate boilerplate code within the core directory, which requires minimal attention, thereby facilitating quick and easy feature development. The directory structure is also generally very predictable. The project's primary objective is to offer a production-ready boilerplate with a better developer experience and readily available features. It also has some widely used features like authentication, authorization, database migrations, type checking, etc which are discussed in detail in the [Features](#features) section.\n\n### Features\n\n- Python 3.11+ support\n- SQLAlchemy 2.0+ support\n- Asynchoronous capabilities\n- Database migrations using Alembic\n- Basic Authentication using JWT\n- Row Level Access Control for permissions\n- Redis for caching\n- Celery for background tasks\n- Testing suite\n- Type checking using mypy\n- Dockerized database and redis\n- Readily available CRUD operations\n- Linting using pylint\n- Formatting using black\n\n### Installation Guide\n\nYou need following to run this project:\n\n- Python 3.11\n- [Docker with Docker Compose](https://docs.docker.com/compose/install/)\n- [Poetry](https://python-poetry.org/docs/#installation)\n\nI use [asdf](https://asdf-vm.com/#/) to manage my python versions. You can use it too. However, it is only supported on Linux and macOS. For Windows, you can use something like pyenv.\n\nOnce you have installed the above and have cloned the repository, you can follow the following steps to get the project up and running:\n\n1. Create a virtual environment using poetry:\n\n```bash\npoetry shell\n```\n\n2. Install the dependencies:\n\n```bash\npoetry install\n```\n\n3. Run the database and redis containers:\n\n```bash\ndocker-compose up -d\n```\n\n4. Copy the `.env.example` file to `.env` and update the values as per your needs.\n\n5. Run the migrations:\n\n```bash\nmake migrate\n```\n\n6. Run the server:\n\n```bash\nmake run\n```\n\nThe server should now be running on `http://localhost:8000` and the API documentation should be available at `http://localhost:8000/docs`.\n\n### Usage Guide\n\nThe project is designed to be modular and scalable. There are 3 main directories in the project:\n\n1. `core`: This directory contains the central part of this project. It contains most of the boiler plate code like security dependencies, database connections, configuration, middlewares etc. It also contains the base classes for the models, repositories, and controllers. The `core` directory is designed to be as minimal as possible and usually requires minimal attention. Overall, the `core` directory is designed to be as generic as possible and can be used in any project. While building additional feature you may not need to modify this directory at all except for adding more controllers to the `Factory` class in `core/factory.py`.\n\n2. `app`: This directory contains the actual application code. It contains the models, repositories, controllers, and schemas for the application. This is the directory you will be spending most of your time in while building features. The directory has following sub-directories:\n\n   - `models` Here is where you add new tables\n   - `repositories` For each model, you need to create a repository. This is where you add the CRUD operations for the model.\n   - `controllers` For each logical unit of the application, you need to create a controller. This is where you add the business logic for the application.\n   - `schemas` This is where you add the schemas for the application. The schemas are used for validation and serialization/deserialization of the data.\n\n3. `api`: This directory contains the API layer of the application. It contains the API router, it is where you add the API endpoints.\n\n### Advanced Usage\n\nThe boilerplate contains a lot of features some of which are used in the application and some of which are not. The following sections describe the features in detail.\n\n#### Database Migrations\n\nThe migrations are handled by Alembic. The migrations are stored in the `migrations` directory. To create a new migration, you can run the following command:\n\n```bash\nmake generate-migration\n```\n\nIt will ask you for a message for the migration. Once you enter the message, it will create a new migration file in the `migrations` directory. You can then run the migrations using the following command:\n\n```bash\nmake migrate\n```\n\nIf you need to downgrade the database or reset it. You can use `make rollback` and `make reset-database` respectively.\n\n#### Authentication\n\nThe authentication used is basic implementation of JWT with bearer token. When the `bearer` token is supplied in the `Authorization` header, the token is verified and the user is automatically authenticated by setting `request.user.id` using middleware. To use the user model in any endpoint you can use the `get_current_user` dependency. If for any endpoint you want to enforce authentication, you can use the `AuthenticationRequired` dependency. It will raise a `HTTPException` if the user is not authenticated.\n\n#### Row Level Access Control\n\nThe boilerplate contains a custom row level permissions management module. It is inspired by [fastapi-permissions](https://github.com/holgi/fastapi-permissions). It is located in `core/security/access_control.py`. You can use this to enforce different permissions for different models. The module operates based on `Principals` and `permissions`. Every user has their own set of principals which need to be set using a function. Check `core/fastapi/dependencies/permissions.py` for an example. The principals are then used to check the permissions for the user. The permissions need to be defined at the model level. Check `app/models/user.py` for an example. Then you can use the dependency directly in the route to raise a `HTTPException` if the user does not have the required permissions. Below is an incomplete example:\n\n```python\nfrom fastapi import APIRouter, Depends\nfrom core.security.access_control import AccessControl, UserPrincipal, RolePrincipal, Allow\nfrom core.database import Base\n\nclass User(Base):\n    __tablename__ = \"users\"\n    id = Column(Integer, primary_key=True)\n    name = Column(String)\n    email = Column(String, unique=True)\n    password = Column(String)\n    role = Column(String)\n\n    def __acl__(self):\n        return [\n            (Allow, UserPrincipal(self.id), \"view\"),\n            (Allow, RolePrincipal(\"admin\"), \"delete\"),\n        ]\n\ndef get_user_principals(user: User = Depends(get_current_user)):\n    return [UserPrincipal(user.id)]\n\nPermission = AccessControl(get_user_principals)\n\nrouter = APIRouter()\n\n@router.get(\"/users/{user_id}\")\ndef get_user(user_id: int, user: User = get_user(user_id), assert_access = Permission(\"view\")):\n    assert_access(user)\n    return user\n\n```\n\n#### Caching\n\nYou can directly use the `Cache.cached` decorator from `core.cache`. Example\n\n```python\nfrom core.cache import Cache\n\n@Cache.cached(prefix=\"user\", ttl=60)\ndef get_user(user_id: int):\n    ...\n```\n\n#### Celery\n\nThe celery worker is already configured for the app. You can add your tasks in `worker/` to run the celery worker, you can run the following command:\n\n```bash\nmake celery-worker\n```\n\n#### Session Management\n\nThe sessions are already handled by the middleware and `get_session` dependency which injected into the repositories through fastapi dependency injection inside the `Factory` class in `core/factory.py`. There is also `Transactional` decorator which can be used to wrap the functions which need to be executed in a transaction. Example:\n\n```python\n@Transactional()\nasync def some_mutating_function():\n    ...\n```\n\nNote: The decorator already handles the commit and rollback of the transaction. You do not need to do it manually.\n\nIf for any case you need an isolated sessions you can use `standalone_session` decorator from `core.database`. Example:\n\n```python\n@standalone_session\nasync def do_something():\n    ...\n```\n\n#### Repository Pattern\n\nThe boilerplate uses the repository pattern. Every model has a repository and all of them inherit `base` repository from `core/repository`. The repositories are located in `app/repositories`. The repositories are injected into the controllers inside the `Factory` class in `core/factory/factory.py.py`.\n\nThe base repository has the basic crud operations. All customer operations can be added to the specific repository. Example:\n\n```python\nfrom core.repository import BaseRepository\nfrom app.models.user import User\nfrom sqlalchemy.sql.expression import select\n\nclass UserRepository(BaseRepository[User]):\n    async def get_by_email(self, email: str):\n        return await select(User).filter(User.email == email).gino.first()\n\n```\n\nTo facilitate easier access to queries with complex joins, the `BaseRepository` class has a `_query` function (along with other handy functions like `_all()` and `_one_or_none()`) which can be used to write compplex queries very easily. Example:\n\n```python\nasync def get_user_by_email_join_tasks(email: str):\n    query = await self._query(join_)\n    query = query.filter(User.email == email)\n    return await self._one_or_none(query)\n```\n\nNote: For every join you want to make you need to create a function in the same repository with pattern `_join_{name}`. Example: `_join_tasks` for `tasks`. Example:\n\n```python\nasync def _join_tasks(self, query: Select) -\u003e Select:\n    return query.options(joinedload(User.tasks))\n```\n\n#### Controllers\n\nKind of to repositories, every logical unit of the application has a controller. The controller also has a primary repository which is injected into it. The controllers are located in `app/controllers`.\n\nThese controllers contain all the business logic of the application. Check `app/controllers/auth.py` for an example.\n\n#### Schemas\n\nThe schemas are located in `app/schemas`. The schemas are used to validate the request body and response body. The schemas are also used to generate the OpenAPI documentation. The schemas are inherited from `BaseModel` from `pydantic`. The schemas are primarily isolated into `requests` and `responses` which are pretty self explainatory.\n\n#### Formatting\n\nYou can use `make format` to format the code using `black` and `isort`.\n\n#### Linting\n\nYou can use `make lint` to lint the code using `pylint`.\n\n#### Testing\n\nThe project contains tests for all endpoints, some of the logical components like `JWTHander` and `AccessControl` and an example of testing complex inner components like `BaseRepository`. The tests are located in `tests/`. You can run the tests using `make test`.\n\n## Contributing\n\nContributions are higly welcome. Please open an issue or a PR if you want to contribute.\n\n## License\n\nThis project is licensed under the terms of the MIT license. See the LICENSE file.\n\n## Acknowledgements\n\n- This project uses several components from [teamhide/fastapi-boilerplate](https://github.com/teamhide/fastapi-boilerplate)\n- The row level access control is inspired by [fastapi-permissions](https://github.com/holgi/fastapi-permissions)\n- CRUD pattern is inspired by [full-stack-fastapi-postgresql](https://github.com/tiangolo/full-stack-fastapi-postgresql)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiam-abbas%2FFastAPI-Production-Boilerplate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fiam-abbas%2FFastAPI-Production-Boilerplate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiam-abbas%2FFastAPI-Production-Boilerplate/lists"}