Skip to main content

FastAPI struct

Project description

Openfund-server

Features

  • Async SQLAlchemy session
  • Custom user class
  • Dependencies for specific permissions
  • Celery
  • Dockerize(Hot reload)
  • Event dispatcher
  • Cache

Run

Launch docker

> docker-compose -f docker/docker-compose.yml up

Install dependency

> poetry shell
> poetry install

Apply alembic revision

> alembic upgrade head

Run server

> python3 main.py --env local|dev|prod --debug

Run test codes

> make test

Make coverage report

> make cov

Formatting

> pre-commit

SQLAlchemy for asyncio context

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.

Query with asyncio.gather()

When executing queries concurrently through asyncio.gather(), you must use the session_factory context manager rather than the globally used session.

from core.db import session_factory


async def get_by_id(self, *, user_id) -> User:
    stmt = select(User)
    async with session_factory() as read_session:
        return await read_session.execute(query).scalars().first()


async def main() -> None:
    user_1, user_2 = await asyncio.gather(
        get_by_id(user_id=1),
        get_by_id(user_id=2),
    )

If you do not use a database connection like session.add(), it is recommended to use a globally provided session.

Multiple databases

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.

Custom user for authentication

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.

  1. core/fastapi/schemas/current_user.py
  2. core/fastapi/middlewares/authentication.py

CurrentUser

class CurrentUser(BaseModel):
    id: int = Field(None, description="ID")

Simply add more fields based on your needs.

AuthBackend

current_user = CurrentUser()

After line 18, assign values that you added on CurrentUser.

Top-level dependency

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

Dependencies for specific permissions

Permissions IsAdmin, IsAuthenticated, AllowAll 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 = Query(10, description="Limit"),
    prev: int = Query(None, description="Prev ID"),
):
    pass

Insert permission through dependencies argument.

If you want to make your own permission, inherit BasePermission and implement has_permission() function.

Note. In order to use swagger's authorize function, you must put PermissionDependency as an argument of dependencies.

Event dispatcher

Refer the README of https://github.com/teamhide/fastapi-event

Cache

Caching by prefix

from core.helpers.cache import Cache


@Cache.cached(prefix="get_user", ttl=60)
async def get_user():
    ...

Caching by tag

from core.helpers.cache import Cache, CacheTag


@Cache.cached(tag=CacheTag.GET_USER_LIST, ttl=60)
async def get_user():
    ...

Use the Cache 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.

Custom Key builder

from core.helpers.cache.base import BaseKeyMaker


class CustomKeyMaker(BaseKeyMaker):
    async def make(self, function: Callable, prefix: str) -> str:
        ...

If you want to create a custom key, inherit the BaseKeyMaker class and implement the make() method.

Custom Backend

from core.helpers.cache.base import BaseBackend


class RedisBackend(BaseBackend):
    async def get(self, key: str) -> Any:
        ...

    async def set(self, response: Any, key: str, ttl: int = 60) -> None:
        ...

    async def delete_startswith(self, value: str) -> None:
        ...

If you want to create a custom key, inherit the BaseBackend class and implement the get(), set(), delete_startswith() method.

Pass your custom backend or keymaker as an argument to init. (/app/server.py)

def init_cache() -> None:
    Cache.init(backend=RedisBackend(), key_maker=CustomKeyMaker())

Remove all cache by prefix/tag

from core.helpers.cache import Cache, CacheTag


await Cache.remove_by_prefix(prefix="get_user_list")
await Cache.remove_by_tag(tag=CacheTag.GET_USER_LIST)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

openfund_server-0.4.2.tar.gz (34.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

openfund_server-0.4.2-py3-none-any.whl (56.4 kB view details)

Uploaded Python 3

File details

Details for the file openfund_server-0.4.2.tar.gz.

File metadata

  • Download URL: openfund_server-0.4.2.tar.gz
  • Upload date:
  • Size: 34.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.4 CPython/3.12.7 Darwin/22.6.0

File hashes

Hashes for openfund_server-0.4.2.tar.gz
Algorithm Hash digest
SHA256 faaea3e5f70bb092cad232d91684de428ac3fef477d52c000c6eb5206f8ee2d8
MD5 1128a21fb14273c7804d8747fbf4b1ff
BLAKE2b-256 fbd688c0e8eb08b67a66bd1d64f71c4e0efa5c38735d5c0ba73d92742cf27bd3

See more details on using hashes here.

File details

Details for the file openfund_server-0.4.2-py3-none-any.whl.

File metadata

  • Download URL: openfund_server-0.4.2-py3-none-any.whl
  • Upload date:
  • Size: 56.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.4 CPython/3.12.7 Darwin/22.6.0

File hashes

Hashes for openfund_server-0.4.2-py3-none-any.whl
Algorithm Hash digest
SHA256 f83a0e1c5ad6a70a5ddd52a19a25fc95908828248547c3ff63fca14d6cc4aef8
MD5 7b34c33db6dcc33cf7662c2cccb751b3
BLAKE2b-256 7815ae458a73fa22ee1958a5363b01c432aa56645654ec1c1f1d5ea51b82f7f2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page