⚠️ Drop Support of Python 3.8 | 3.9 & New Break Changes
As you create more complex FastAPI applications, you may find yourself frequently repeating the same dependencies in multiple related endpoints.
We Introduce this new version **showcases the usage of CVB in FastAPI** by yezz123 in https://github.com/yezz123/fastapi-class/pull/82
A 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.
`fastapi_class` provides a `class-based view` decorator `View` to help reduce the amount of boilerplate necessary when developing related routes.
> 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.
- Example:
python
from fastapi import FastAPI, APIRouter, Query
from pydantic import BaseModel
from fastapi_class import View
app = FastAPI()
router = APIRouter()
class ItemModel(BaseModel):
id: int
name: str
description: str = None
View(router)
class ItemView:
def post(self, item: ItemModel):
return item
def get(self, item_id: int = Query(..., gt=0)):
return {"item_id": item_id}
app.include_router(router)
Response model 📦
`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`.
py
from fastapi import FastAPI, APIRouter, HTTPException, status
from fastapi.responses import PlainTextResponse
from pydantic import BaseModel
from fastapi_class import View
app = FastAPI()
router = APIRouter()
NOT_AUTHORIZED = HTTPException(401, "Not authorized.")
NOT_ALLOWED = HTTPException(405, "Method not allowed.")
NOT_FOUND = lambda item_id="item_id": HTTPException(404, f"Item with {item_id} not found.")
class ItemResponse(BaseModel):
field: str | None = None
view(router)
class MyView:
exceptions = {
"__all__": [NOT_AUTHORIZED],
"put": [NOT_ALLOWED, NOT_FOUND]
}
RESPONSE_MODEL = {
"put": ItemResponse
}
RESPONSE_CLASS = {
"delete": PlainTextResponse
}
def get(self):
...
def put(self):
...
def delete(self):
...
app.include_router(router)
Customized Endpoints
py
from fastapi import FastAPI, APIRouter, HTTPException
from fastapi.responses import PlainTextResponse
from pydantic import BaseModel
from fastapi_class import View, endpoint
app = FastAPI()
router = APIRouter()
NOT_AUTHORIZED = HTTPException(401, "Not authorized.")
NOT_ALLOWED = HTTPException(405, "Method not allowed.")
NOT_FOUND = lambda item_id="item_id": HTTPException(404, f"Item with {item_id} not found.")
EXCEPTION = HTTPException(400, "Example.")
class UserResponse(BaseModel):
field: str | None = None
View(router)
class MyView:
exceptions = {
"__all__": [NOT_AUTHORIZED],
"put": [NOT_ALLOWED, NOT_FOUND],
"edit": [EXCEPTION]
}
RESPONSE_MODEL = {
"put": UserResponse,
"edit": UserResponse
}
RESPONSE_CLASS = {
"delete": PlainTextResponse
}
def get(self):
...
def put(self):
...
def delete(self):
...
endpoint(("PUT",), path="edit")
def edit(self):
...
Dependencies 🔨
* ⬆ Bump requests from 2.28.1 to 2.28.2 by dependabot in https://github.com/yezz123/fastapi-class/pull/62
* ⬆ Bump pytest from 7.2.0 to 7.2.1 by dependabot in https://github.com/yezz123/fastapi-class/pull/63
* ⬆ Bump pre-commit from 2.21.0 to 3.0.0 by dependabot in https://github.com/yezz123/fastapi-class/pull/64
* ⬆ Bump pre-commit from 3.0.0 to 3.0.1 by dependabot in https://github.com/yezz123/fastapi-class/pull/65
* ⬆ Bump pre-commit from 3.1.1 to 3.2.0 by dependabot in https://github.com/yezz123/fastapi-class/pull/85
* ⬆ Update fastapi requirement from <0.95.0,>=0.65.2 to >=0.65.2,<0.96.0 by dependabot in https://github.com/yezz123/fastapi-class/pull/86
* ⬆ Bump pytest-asyncio from 0.20.3 to 0.21.0 by dependabot in https://github.com/yezz123/fastapi-class/pull/87
* ⬆ Bump pypa/gh-action-pypi-publish from 1.7.1 to 1.8.1 by dependabot in https://github.com/yezz123/fastapi-class/pull/88
**Full Changelog**: https://github.com/yezz123/fastapi-class/compare/2.0.0...3.1.0