Skip to content

Class Resource

Source module: fastapi_utils.cbv_base


If you familiar with Flask-RESTful and you want to quickly create CRUD application, full of features and resources, and you also support OOP you might want to use this Resource based class


Similar to Flask-RESTful all we have to do is create a class at inherit from Resource

from fastapi_utils import Resource


class MyApi(Resource):
    def get(self):
        return "done"

And then in app.py

from fastapi import FastAPI

from docs.src.class_resource_view1 import MyApi
from fastapi_utils import Api


def create_app():
    app = FastAPI()
    api = Api(app)

    myapi = MyApi()
    api.add_resource(myapi, "/uri")

    return app


main = create_app()

And that’s it, You now got an app.


Now how to handle things when it starting to get complicated:

Resource with dependencies

Since initialization is taking place before adding the resource to the api, we can just insert our dependencies in the instance init: (app.py)

from fastapi import FastAPI
from pymongo import MongoClient

from docs.src.class_resource_view1 import MyApi
from fastapi_utils import Api


def create_app():
    app = FastAPI()
    api = Api(app)

    mongo_client = MongoClient("mongodb://localhost:27017")
    myapi = MyApi(mongo_client)
    api.add_resource(myapi, "/uri")

    return app


main = create_app()

Responses

FastApi swagger is all beautiful with the responses and fit status codes, it is no sweat to declare those.

Inside the resource class have @set_responses before the function

from pydantic import BaseModel

from fastapi_utils import Resource, set_responses


# Setup
class ResponseModel(BaseModel):
    answer: str


class ResourceAlreadyExistsModel(BaseModel):
    is_found: bool


class ResourceModel(BaseModel):
    ID: str
    name: str


# Setup end


class MyApi(Resource):
    def __init__(self, mongo_client):
        self.mongo = mongo_client

    @set_responses(ResponseModel)
    def get(self):
        return "Done"

    @set_responses(ResponseModel, 200)
    def put(self):
        return "Redone"

    @set_responses(
        ResponseModel,
        201,
        {
            409: {
                "description": "The path can't be found",
                "model": ResourceAlreadyExistsModel,
            }
        },
    )
    def post(self, res: ResourceModel):
        if self.mongo.is_resource_exist(res.name):
            return JSONResponse(409, content={"is_found": true})
        return "Done again"

Additional information about responses can be found here

@set_responses also support kwargs of the original function which includes different response classes and more!