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.
core/fastapi/schemas/current_user.pycore/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)
Metadata
Release files for openfund-server 0.4.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| openfund_server-0.4.3.tar.gz | 34.7 kB | Without provenance | Details for openfund_server-0.4.3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| openfund_server-0.4.3-py3-none-any.whl | Python 3 | none | any | Details for openfund_server-0.4.3-py3-none-any.whl |
Total release size: 91.1 kB
Release files / openfund_server-0.4.3.tar.gz
| Download URL | openfund_server-0.4.3.tar.gz |
|---|---|
| Size | 34.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e0cb16e878338d9728f7e37748e3a05b40ea9cada584eb9a55de25543090c72a
|
|
BLAKE2b-256 checksum How to use checksums |
c17dff3aa496666ce9bb3306c560ea0b547f592e1e64054760c35fa7ace9d0dc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.8.4 CPython/3.12.7 Darwin/22.6.0
|
Release files / openfund_server-0.4.3-py3-none-any.whl
| Download URL | openfund_server-0.4.3-py3-none-any.whl |
|---|---|
| Size | 56.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7487de66bc3a0c7bb4d8c35885e93e91ecae6ca50cd6eeb75b06709e25afa997
|
|
BLAKE2b-256 checksum How to use checksums |
c0a5389f4858cc2c33493fe649be6049257f40acb848337cc8f25935aa851088
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.8.4 CPython/3.12.7 Darwin/22.6.0
|
Security for openfund-server 0.4.3
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.