Skip to main content

Class based routing for FastAPI


Package version


Documentation: https://XDeepZeroX.github.io/class-based-fastapi

Source Code: https://github.com/XDeepZeroX/class-based-fastapi


FastAPI is a modern, fast web framework for building APIs with Python 3.6+.


Features

Write Fast API Controllers (Classes) that can inherit route information from it's parent.

  • This also allows to create a path prefix from a template and add api version information in the template.
  • You don't need to duplicate the code, you can inherit it.
  • To generate OpenAPI documentation, you do not need to explicitly specify the type of the return value, use Generics !

Do the same with API methods as before, only more convenient.

See the docs for more details and examples.

Requirements

This package is intended for use with any recent version of FastAPI (depending on pydantic>=1.8.2), and Python 3.6+.

Installation

pip install class-based-fastapi

Example

import uuid
from typing import List, Generic, TypeVar  # 0. Import

import sqlalchemy
import uvicorn
from class_based_fastapi import Routable, get, put, post, delete
from fastapi import FastAPI, Depends
from sqlalchemy import select
from sqlmodel import Session, create_engine

from database import run_async_upgrade
from models.models import Category, CategoryPUT, Book, BookPUT

app = FastAPI(debug=True)

engine = create_engine('postgresql://postgres:123456@localhost:5432/fastapi_example', echo=True)


@app.on_event("startup")
def on_startup():
    print("Start migration")
    run_async_upgrade()
    print("DB success upgrade !")


def get_session() -> Session:
    with Session(engine) as conn:
        yield conn


T = TypeVar('T')  # 1. Create generic type
TPut = TypeVar('TPut')  # 1. Create generic type


class BaseAPI(Routable, Generic[T, TPut]):  # 2. Create generic base API controller
    conn: Session = Depends(get_session)

    def __init__(self):
        self._type_db_model = self._get_type_generic(T)

    def _get_type_generic(self, tvar: TypeVar):
        return next(filter(lambda x: x['name'] == tvar.__name__, self.__class__.__generic_attribute__))['type']

    @get("")
    def get_list_categories(self) -> List[T]:  # 3. Specifying  generic types
        items = self.conn.execute(select(self._type_db_model)).scalars().all()
        return items

    @post("")
    def add_category(self, model: T) -> T:
        self.conn.add(model)
        self.conn.commit()
        return model

    @delete("{guid}")
    def delete_category(self, guid: str) -> bool:
        self.conn.execute(
            sqlalchemy.delete(self._type_db_model).filter(self._type_db_model.guid == uuid.UUID(guid))
        )
        self.conn.commit()
        return True

    @put("{guid}")
    def update_category(self, guid: str, model: TPut) -> T:  # 3. Specifying  generic types
        model_db = self.conn.execute(
            select(self._type_db_model).filter(self._type_db_model.guid == uuid.UUID(guid))
        ).scalar()
        # Update fields
        for name, val in model.dict(exclude_unset=True).items():
            setattr(model_db, name, val)
        self.conn.commit()
        self.conn.refresh(model_db)
        return model_db


# Categories
class CategoryAPI(BaseAPI[Category, CategoryPUT]):  # 4. Inheriting the base controller
    NAME_MODULE = Category.__name__


# Books
class BookAPI(BaseAPI[Book, BookPUT]):  # 4. Inheriting the base controller
    NAME_MODULE = Book.__name__


app.include_router(CategoryAPI.routes())  # 5. Include routes
app.include_router(BookAPI.routes())  # 5. Include routes

if __name__ == "__main__":
    uvicorn.run('main:app', host="localhost", port=8001, reload=True, debug=True)

Class base API OpenAPI Docs

Next steps >>>

License

This project is licensed under the terms of the MIT license.

Metadata

Release files for class-based-fastapi 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for class-based-fastapi 1.1.0
File Interpreter ABI Platform Actions
class_based_fastapi-1.1.0-py3-none-any.whl Python 3 none any Details for class_based_fastapi-1.1.0-py3-none-any.whl

Release files / class_based_fastapi-1.1.0-py3-none-any.whl

Download URL class_based_fastapi-1.1.0-py3-none-any.whl
Size 14.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0ec5963a93a3990cdba75530ed897ea1840f8bd0820b47559c135b169654738c
BLAKE2b-256 checksum
How to use checksums
eae8bcbd6d2469303148ca80b24f32457ad2ace05a75c455285b2c0d23ca14d6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.0

Security for class-based-fastapi 1.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page