- Async SQLAlchemy session
- Custom user class
- Top-level dependency
- Dependencies for specific permissions
- Celery
- Dockerize(Hot reload)
- Event dispatcher
- Cache
from core.db import Transactional, session
@Transactional()
async def create_user(self):
session.add(User(email="padocon@naver.com"))
Do not use explicit commit()
. Transactional
class automatically do.
According to the current settings, the session is set through middleware.
However, it doesn't go through middleware in tests or background tasks.
So you need to use the @create_session decorator.
from core.db import create_session
@create_session
def test_something():
...
Go to core/config.py
and edit WRITER_DB_URL
and READER_DB_URL
in the config class.
If you need additional logic to use the database, refer to the get_bind()
method of RoutingClass
.
from fastapi import Request
@home_router.get("/")
def home(request: Request):
return request.user.id
Note. you have to pass jwt token via header like Authorization: Bearer 1234
Custom user class automatically decodes header token and store user information into request.user
If you want to modify custom user class, you have to update below files.
core/fastapi/schemas/current_user.py
core/fastapi/middlewares/authentication.py
class CurrentUser(BaseModel):
id: int = None
Simply add more fields based on your needs.
current_user = CurrentUser()
After line 18, assign values that you added on CurrentUser
.
Note. Available from version 0.62 or higher.
Set a callable function when initialize FastAPI() app through dependencies
argument.
Refer Logging
class inside of core/fastapi/dependencies/logging.py
Permissions IsAdmin
and IsAuthenticated
have already been implemented.
from core.fastapi.dependencies import (
PermissionDependency,
IsAdmin,
)
user_router = APIRouter()
@user_router.get(
"",
response_model=List[GetUserListResponseSchema],
response_model_exclude={"id"},
responses={"400": {"model": ExceptionResponseSchema}},
dependencies=[Depends(PermissionDependency([IsAdmin]))], # HERE
)
async def get_user_list(limit: int = 10, prev: int = None):
pass
Insert permission through dependencies
argument.
If you want to make your own permission, inherit BasePermission
and implement has_permission()
function.
Refer the README of https://github.com/teamhide/fastapi-event
from core.helpers.cache import Cacheable
@Cacheable(prefix="get_user", ttl=60)
async def get_user():
...
Use the Cacheable
decorator to cache the return value of a function.
Depending on the argument of the function, caching is stored with a different value through internal processing.
from core.helpers.cache.base import BaseKeyMaker
class CustomKeyMaker(BaseKeyMaker):
async def make(self, function: Callable) -> str:
...
If you want to create a custom key, inherit the BaseKeyMaker
class and implement the make()
method.
@Cacheable(prefix="get_user", ttl=60, key_maker=CustomKeyMaker)
And pass your class via key_maker
arguments.
If no value is given to the key_maker
argument, the function implemented by default is used.
from core.helpers.cache.base import BaseBackend
class RedisBackend(BaseBackend):
async def get(self, key: str) -> Any:
...
async def save(self, response: Any, key: str) -> None:
...
If you want to create a custom key, inherit the BaseBackend
class and implement the get()
and save()
method.
@Cacheable(prefix="get_user", ttl=60, backend=RedisBackend)
And pass your class via backend
arguments.
If no value is given to the backend
argument, the function implemented by default is used.
Cacheable.init_backend(backend=RedisBackend)
Cacheable.init_key_maker(backend=CustomKeyMaker)
Add the above line when the server is startup.