{"id":38371172,"url":"https://github.com/wangxin688/fastapi-enterprise-template","last_synced_at":"2026-01-17T03:29:08.062Z","repository":{"id":217905444,"uuid":"741063690","full_name":"wangxin688/fastapi-enterprise-template","owner":"wangxin688","description":"FastAPI backend enterprise template","archived":false,"fork":false,"pushed_at":"2025-03-29T00:19:53.000Z","size":234,"stargazers_count":13,"open_issues_count":0,"forks_count":6,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-29T01:25:03.196Z","etag":null,"topics":["fastapi","fastapi-boilerplate","fastapi-cache","fastapi-crud","fastapi-jwt","fastapi-rabbitmq","fastapi-rbac","fastapi-redis","fastapi-sqlalchemy","fastapi-template","fastapi-users"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wangxin688.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2024-01-09T16:16:01.000Z","updated_at":"2025-03-29T00:19:57.000Z","dependencies_parsed_at":"2025-03-02T15:21:44.800Z","dependency_job_id":null,"html_url":"https://github.com/wangxin688/fastapi-enterprise-template","commit_stats":null,"previous_names":["wangxin688/fastapi-enterprise-template"],"tags_count":2,"template":true,"template_full_name":null,"purl":"pkg:github/wangxin688/fastapi-enterprise-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wangxin688%2Ffastapi-enterprise-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wangxin688%2Ffastapi-enterprise-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wangxin688%2Ffastapi-enterprise-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wangxin688%2Ffastapi-enterprise-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wangxin688","download_url":"https://codeload.github.com/wangxin688/fastapi-enterprise-template/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wangxin688%2Ffastapi-enterprise-template/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28493014,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T02:39:23.645Z","status":"ssl_error","status_checked_at":"2026-01-17T02:34:19.649Z","response_time":85,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["fastapi","fastapi-boilerplate","fastapi-cache","fastapi-crud","fastapi-jwt","fastapi-rabbitmq","fastapi-rbac","fastapi-redis","fastapi-sqlalchemy","fastapi-template","fastapi-users"],"created_at":"2026-01-17T03:29:07.285Z","updated_at":"2026-01-17T03:29:08.053Z","avatar_url":"https://github.com/wangxin688.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FastAPI enterprise backend template\n\u003e fastapi+async sqlalchemy, support both mysql/postgres/sqlite backed, use postgresql as default.\n\n## Features\n- [x] Template repository\n- [x] Class-based view decrator for better code structure and reduce the duplicated code.\n- [x] Sqlalchemy 2.0 with asyncpg integration, with well type annotations and autocompletion support.\n- [x] Generic CRUD repository class for very easy and fast restapi development, provide good support for type hint and user friendly error message for database.\n- [x] Create and apply almebic migration\n- [x] Jwt authentication with access token and refresh token.\n- [x] Run app with Uvicorn/Gunicorn with well tuned configuration\n- [x] Rye for python package and dependencies management.\n- [x] Unified error message and format management\n- [x] pre-commit hooks/ruff/typo for static code check\n- [x] Basic user/group/role management with crud api.\n- [x] Flexible RBAC management\n- [x] x-request-id/x-request-time middleware\n- [x] x-request-id in log message for tracing\n- [x] sqlalchemy costom types and mixins: GUID/EncryptString/AuditLogMixin\n- [x] I18N support\n- [x] dockerfile and docker-compose support\n\n## QuickStart\n\n### 1. Create repository from a template\nSee [docs](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template).\n\n### 2. Install dependencies with [Rye](https://rye.astral.sh/guide/installation/)\n```bash\ncd your_project_name\nrye sync\n```\nNote, be sure to use `python3.12` with this template with either rye or standard venv \u0026 pip, if you need to stick to some earlier python version, you should adapt it yourself (change `.python-version` to the version you want and update `pyproject.toml requires-python = \"\u003c= 3.x\"`)\n\n### 3. Setup .env and database\n```bash\n### Setup env, change the ENV as you need\nmv .env.example .env\n### Setup database\ndocker-compose up -d\n\n### Run Alembic migrations\nalembic upgrade head\n```\n\n### 4. Run init db\n```bash\n### default email: admin@system.com\n### default password: admin\npython deploy/init_pg.py\n```\n\n### 5. Now you can run app\n\n```bash\n### And this is it:\npython3 src/__main__.py\n### or run app directly as you wish\nuvicorn src.app:app --reload\n```\n\nYou should then use `git init` (if needed) to initialize git repository and access OpenAPI spec at http://localhost:8000/ by default. To customize docs url, cors and allowed hosts settings,\nsee `src/core/config.py` options\n\n### 5. Activate pre-commit\n\n[pre-commit](https://pre-commit.com/) is de facto standard now for pre push activities like isort or black or its nowadays replacement ruff.\n\nRefer to `.pre-commit-config.yaml` file to see my current opinionated choices.\n\n```bash\n# Install pre-commit\npre-commit install --install-hooks\n\n# Run on all files\npre-commit run --all-files\n```\n\n### 6. Running tests\n\nNote, it will create databases for session and run tests in many processes by default (using pytest-xdist) to speed up execution, based on how many CPU are available in environment.\n\nFor more details about initial database setup, see logic `tests/conftest.py` file, `fixture_setup_new_test_database` function.\n\n\n\n```bash\n# see all pytest configuration flags in pyproject.toml\npytest\n```\n\n# Project structures\n```\nsrc/\n├── __init__.py\n├── __main__.py                             # uvicorn/gunicorn start entry\n├── app.py                                  # fastapi app\n├── core\n│   ├── __init__.py\n│   ├── _types.py                           # project reusable types\n│   ├── config.py                           # project configuration files\n│   ├── database                            # database utils\n│   │   ├── __init__.py\n│   │   ├── engine.py                       # sqlalchemy engine configuration\n│   │   ├── session.py                      # sqlalchemy async session\n│   │   └── types                           # sqlalchemy custom types\n│   │       ├── __init__.py\n│   │       ├── annotated.py\n│   │       ├── datetime.py\n│   │       ├── encrypted_string.py\n│   │       ├── enum.py\n│   │       └── guid.py\n│   ├── errors                              # unified errors\n│   │   ├── __init__.py\n│   │   ├── _error.py\n│   │   ├── auth_exceptions.py\n│   │   └── base_exceptions.py\n│   ├── models                              # ORM model\n│   │   ├── __init__.py\n│   │   ├── base.py                         # sqlalchemy ORM Base\n│   │   └── mixins                          # sqlalchemy mixins\n│   │       ├── __init__.py\n│   │       ├── audit_log.py\n│   │       ├── audit_time.py\n│   │       └── audit_user.py\n│   ├── repositories                        # Sqlachemy db Generic CRUD class, will suite with pydantic model\n│   │   ├── __init__.py\n│   │   └── repository.py\n│   └── utils                               # project utils\n│       ├── __init__.py\n│       ├── cbv.py\n│       ├── context.py\n│       ├── i18n.py\n│       ├── processors.py\n│       ├── singleton.py\n│       ├── translations.py\n│       └── validators.py\n├── deps.py                                 # auth and other fastapi dependencies\n├── features                                # features entry, development here\n│   └── admin\n│       ├── __init__.py\n│       ├── api.py\n│       ├── consts.py\n│       ├── models.py\n│       ├── schemas.py\n│       ├── security.py\n│       ├── services.py\n│       └── utils.py\n├── libs                                    # external system sdk\n│   ├── __init__.py\n│   ├── rabbitmq\n│   │   ├── __init__.py\n│   │   ├── client.py\n│   │   └── session.py\n│   └── redis\n│       ├── __init__.py\n│       ├── cache.py\n│       ├── rate_limiter.py\n│       └── redis.py\n├── loggers.py\n├── openapi.py\n├── py.typed\n└── register\n    ├── __init__.py\n    ├── middlewares.py\n    └── routers.py\ntests/                                      # pytest entry\n├── __init__.py\n├── admin\n│   └── __init__.py\n├── conftest.py\n├── factories.py\n└── test_01_main.py\n```\n\n# Step by step examples\n---\n\u003e I will show you a example to write a crud api to create a Book with Author and Publisher\n\u003e to show one-to-many and many-to-many cases.\n\u003e add a new app to `src/features` is recommend directory for business logic.\n\n- `POST` endpoint for create a new object\n- `PUT` endpoint for update object\n- `GET` endponit for get object\n- `DELETE` endpoint for delete object\n\n## Create Sqlalchemy Model\nAdd `Book` `Author` `Publisher` model to `src/features/books/models.py`.\n\u003e Sqlalchemy 2.x is strongly recommend for type annotations. New \u003e style API is very easy to use.\n```python3\n(...)\nfrom src.core.models.base import Base\nfrom src.core.database.types.annotated import int_pk\nfrom src.core.models.mixins import AuditTimeMixin, AuditLogMixin, AuditUserMixin\n\nclass Book(Base, AuditTimeMixin):\n    __tablename__ = 'book'\n    id: Mapped[int_pk]\n    name: Mapped[str] = mapped_column(unique=True, index=True)\n    author_id: Mapped[int] = mapped_colunm(ForeignKey(\"author.id\", ondelete=\"CASCADE\"))\n    author: Mapped[\"Author\"] = relationship(back_populates=\"book\")\n    publisher: Mapped[list[\"Publisher\"]] = relationship(\n        secondary=\"book_publisher\", back_populates=\"book\"\n    )\n\nclass Author(Base, AuditLogMixin):\n    __tablename__ = \"author\"\n    id: Mapped[int_pk]\n    name: Mapped[str]\n    books: Mapped[list[\"Book\"]] = relationship(back_populates=\"author\")\n\n\nclass BookPublisher(Base):\n    __tablename__ = \"book_publisher\"\n    id: Mapped[int_pk]\n    book_id: Mapped[int] = mapped_colunm(ForeignKey(\"book.id\"), primary_key=True)\n    publisher_id: Mapped[int] = mapped_colunm(ForeignKey(\"author.id\"), primary_key=True)\n\nclass Publisher(Base, AuditUserMixin):\n    __tablename__ = \"publisher\"\n    id: Mapped[int_pk]\n    name: Mapped[str]\n    book: Mapped[list[\"Book\"]] = relationship(\n        secondary=\"book_publisher\", back_populates=\"publisher\"\n    )\n\n```\n## 2. create alembic migration\n\u003e import models to `alembic/env.py` first\n```\n### Use below commands in root folder in virtualenv ###\n\n# if you see FAILED: Target database is not up to date.\n# first use alembic upgrade head\n\n# Create migration with alembic revision\nalembic revision --autogenerate -m \"create_book_model\"\n\n\n# a new version file \"xxxx_create_book_model_xxxxx.py\" should appear in `/alembic/versions` folder\n\n\n# Apply migration using alembic upgrade\nalembic upgrade head\n\n# (...)\n# INFO  [alembic.runtime.migration] Running upgrade xxxxx -\u003e xxxx, create_book_model\n```\n\n## 3. create pedantic schema for response and request\n```python\n(...)\nfrom fastapi import Query\n\nfrom src.core._types import AuditTime, BaseModel, IdCreate, QueryParams\n\nclass BookBase(BaseModel):\n    name: str\n\nclass BookCreate(BookBase):\n    author_id: int | None = None\n    publisher: list[IdCreate] | None = None\n\nclass BookQuery(QueryParams)\n    name: list[str] | None = Field(Query(default=[]))\n    created_at__gte: datetime | None = None\n    created_at__lte: datetime | None = None\n\nclass Book(BookCreate, AuditTime):\n    id: int\n    author: \"Author\" | None = None\n\nclass AuthorBase(BaseModel):\n    name: str\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwangxin688%2Ffastapi-enterprise-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwangxin688%2Ffastapi-enterprise-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwangxin688%2Ffastapi-enterprise-template/lists"}