{"id":31214992,"url":"https://github.com/mts-ai/fastapi-jsonapi","last_synced_at":"2025-09-21T10:04:28.486Z","repository":{"id":50443242,"uuid":"519090608","full_name":"mts-ai/FastAPI-JSONAPI","owner":"mts-ai","description":"JSON:API for FastAPI","archived":false,"fork":false,"pushed_at":"2025-04-07T09:16:37.000Z","size":6662,"stargazers_count":134,"open_issues_count":8,"forks_count":14,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-09-21T03:49:08.205Z","etag":null,"topics":["asyncio","fastapi","python","sqlalchemy","tortoise-orm"],"latest_commit_sha":null,"homepage":"https://mts-ai.github.io/FastAPI-JSONAPI/","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/mts-ai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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}},"created_at":"2022-07-29T05:26:02.000Z","updated_at":"2025-09-09T02:42:14.000Z","dependencies_parsed_at":"2023-11-30T07:25:14.350Z","dependency_job_id":"afb09032-3e7d-4d23-bad2-b22a9bb4a5fd","html_url":"https://github.com/mts-ai/FastAPI-JSONAPI","commit_stats":null,"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/mts-ai/FastAPI-JSONAPI","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mts-ai%2FFastAPI-JSONAPI","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mts-ai%2FFastAPI-JSONAPI/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mts-ai%2FFastAPI-JSONAPI/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mts-ai%2FFastAPI-JSONAPI/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mts-ai","download_url":"https://codeload.github.com/mts-ai/FastAPI-JSONAPI/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mts-ai%2FFastAPI-JSONAPI/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276223309,"owners_count":25605808,"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","status":"online","status_checked_at":"2025-09-21T02:00:07.055Z","response_time":72,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["asyncio","fastapi","python","sqlalchemy","tortoise-orm"],"created_at":"2025-09-21T10:04:27.247Z","updated_at":"2025-09-21T10:04:28.481Z","avatar_url":"https://github.com/mts-ai.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Last Commit](https://img.shields.io/github/last-commit/mts-ai/FastAPI-JSONAPI?style=for-the-badge)](https://github.com/mts-ai/FastAPI-JSONAPI)\n[![PyPI](https://img.shields.io/pypi/v/fastapi-jsonapi?label=PyPI\u0026style=for-the-badge)](https://pypi.org/project/FastAPI-JSONAPI/)\n[![](https://img.shields.io/pypi/pyversions/FastAPI-JSONAPI?style=for-the-badge)](https://pypi.org/project/FastAPI-JSONAPI/)\n[![](https://img.shields.io/github/license/ycd/manage-fastapi?style=for-the-badge)](https://pypi.org/project/FastAPI-JSONAPI/)\n[![GitHub Actions](https://img.shields.io/github/actions/workflow/status/mts-ai/FastAPI-JSONAPI/testing.yml?style=for-the-badge)](https://github.com/mts-ai/FastAPI-JSONAPI/actions)\n[![Read the Docs](https://img.shields.io/readthedocs/fastapi-jsonapi?style=for-the-badge)](https://fastapi-jsonapi.readthedocs.io/en/latest/)\n[![Codecov](https://img.shields.io/codecov/c/github/mts-ai/FastAPI-JSONAPI?style=for-the-badge)](https://codecov.io/gh/mts-ai/FastAPI-JSONAPI)\n\n[![📖 Docs (gh-pages)](https://github.com/mts-ai/FastAPI-JSONAPI/actions/workflows/documentation.yaml/badge.svg)](https://mts-ai.github.io/FastAPI-JSONAPI/)\n\n\n# FastAPI-JSONAPI\n\nFastAPI-JSONAPI is a FastAPI extension for building REST APIs.\nImplementation of a strong specification [JSONAPI 1.0](http://jsonapi.org/).\nThis framework is designed to quickly build REST APIs and fit the complexity\nof real life projects with legacy data and multiple data storages.\n\n## Architecture\n\n![docs/img/schema.png](docs/img/schema.png)\n\n## Install\n\n```bash\npip install FastAPI-JSONAPI\n```\n\n## A minimal API\n\nCreate a test.py file and copy the following code into it\n\n```python\nimport sys\nfrom collections.abc import AsyncIterator\nfrom contextlib import asynccontextmanager\nfrom pathlib import Path\nfrom typing import Any, ClassVar, Optional\nfrom typing import Union\n\nimport uvicorn\nfrom fastapi import Depends, FastAPI\nfrom fastapi.responses import ORJSONResponse as JSONResponse\nfrom pydantic import ConfigDict\nfrom sqlalchemy.engine import URL\nfrom sqlalchemy.engine import make_url\nfrom sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker, create_async_engine\nfrom sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column\n\nfrom fastapi_jsonapi import ApplicationBuilder\nfrom fastapi_jsonapi.misc.sqla.generics.base import ViewBaseGeneric\nfrom fastapi_jsonapi.schema_base import BaseModel\nfrom fastapi_jsonapi.views import ViewBase, Operation, OperationConfig\n\nCURRENT_DIR = Path(__file__).resolve().parent\nsys.path.append(f\"{CURRENT_DIR.parent.parent}\")\n\n\nclass DB:\n    def __init__(\n        self,\n        url: Union[str, URL],\n        echo: bool = False,\n        echo_pool: bool = False,\n    ):\n        self.engine: AsyncEngine = create_async_engine(\n            url=url,\n            echo=echo,\n            echo_pool=echo_pool,\n        )\n\n        self.session_maker: async_sessionmaker[AsyncSession] = async_sessionmaker(\n            autocommit=False,\n            bind=self.engine,\n            expire_on_commit=False,\n        )\n\n    async def dispose(self):\n        await self.engine.dispose()\n\n    async def session(self) -\u003e AsyncIterator[AsyncSession]:\n        async with self.session_maker() as session:\n            yield session\n\n\ndb = DB(\n    url=make_url(f\"sqlite+aiosqlite:///{CURRENT_DIR}/db.sqlite3\"),\n)\n\n\nclass Base(DeclarativeBase):\n    pass\n\n\nclass User(Base):\n    __tablename__ = \"users\"\n\n    id: Mapped[int] = mapped_column(primary_key=True)\n    name: Mapped[Optional[str]]\n\n\nclass UserSchema(BaseModel):\n    \"\"\"User base schema.\"\"\"\n\n    model_config = ConfigDict(\n        from_attributes=True,\n    )\n\n    name: str\n\n\nclass SessionDependency(BaseModel):\n    model_config = ConfigDict(\n        arbitrary_types_allowed=True,\n    )\n\n    session: AsyncSession = Depends(db.session)\n\n\ndef session_dependency_handler(view: ViewBase, dto: SessionDependency) -\u003e dict[str, Any]:\n    return {\n        \"session\": dto.session,\n    }\n\n\nclass UserView(ViewBaseGeneric):\n    operation_dependencies: ClassVar = {\n        Operation.ALL: OperationConfig(\n            dependencies=SessionDependency,\n            prepare_data_layer_kwargs=session_dependency_handler,\n        ),\n    }\n\n\ndef add_routes(app: FastAPI):\n    builder = ApplicationBuilder(app)\n    builder.add_resource(\n        path=\"/users\",\n        tags=[\"User\"],\n        view=UserView,\n        schema=UserSchema,\n        model=User,\n        resource_type=\"user\",\n    )\n    builder.initialize()\n\n\n# noinspection PyUnusedLocal\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n    add_routes(app)\n\n    async with db.engine.begin() as conn:\n        await conn.run_sync(Base.metadata.create_all)\n\n    yield\n\n    await db.dispose()\n\n\napp = FastAPI(\n    title=\"FastAPI and SQLAlchemy\",\n    lifespan=lifespan,\n    debug=True,\n    default_response_class=JSONResponse,\n    docs_url=\"/docs\",\n    openapi_url=\"/openapi.json\",\n)\n\n\nif __name__ == \"__main__\":\n    uvicorn.run(\n        app,\n        host=\"0.0.0.0\",\n        port=8080,\n    )\n```\n\nThis example provides the following API structure:\n\n| URL                | method | endpoint    | Usage                         |\n|--------------------|--------|-------------|-------------------------------|\n| `/users/`          | GET    | user_list   | Get a collection of users     |\n| `/users/`          | POST   | user_list   | Create a user                 |\n| `/users/`          | DELETE | user_list   | Delete users                  |\n| `/users/{obj_id}/` | GET    | user_detail | Get user details              |\n| `/users/{obj_id}/` | PATCH  | user_detail | Update a user                 |\n| `/users/{obj_id}/` | DELETE | user_detail | Delete a user                 |\n| `/operations/`     | POST   | atomic      | Create, update, delete users  |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmts-ai%2Ffastapi-jsonapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmts-ai%2Ffastapi-jsonapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmts-ai%2Ffastapi-jsonapi/lists"}