copier copy . <target_path_of_create_project>
- SQLAlchemy base model with auto-generated
__tablename__
andtype_annotation_map
for more strict python to SQL type conversion. - Local database session defines on reusable database pools.
- Custom types (with
type
keyword - python 3.12+) which require custom mapping intype_annotation_map
. - Generic
mapped_column
helpers.
- All basic CRUD repositories defined as generic methods.
- Works as a layer to communicate with database only.
- Generic services are in line with corresponding CRUD repositories.
- Adding to repositories layers with data validation, exceptions handling and logging.
- Errors are handled by using
@handle_exceptions
decorator, which use single dispatch pattern. All missing exceptions should be handled inapp/utils/exceptions.py
like:
@handle_exception.register
def _(exc: YourCustomException, _: str) -> HTTPException:
return HTTPException(status_code=404, detail={your details})
- Should use just
Mapped
. Ifmapped_column
is needed, it's better to create new generic helper inapp/database.py
.
- Both concrete repositories and services should be created from generic instances. All additional methods should be defined here. If repositories needs to be splitted into different modules, it's suggested to use inheritance and keep all the methods in one repository class.
- API endpoint, which use services to perform operations.
- Services return SQLALchemy models, but
@router.HTTP_METHOD
decorator should useresponse_model
parameter to automatically transform them into pydantic models (which should be defined in sub-applicationschemas.py
). @format_response
decorator (which is implemented using decorator factory pattern inapp/utils/api_utils/py
) transforms pydantic object response into JSONResposne with HATEOAS links attached to create RESTful API.- Additional relations (like user_rels in the example) will be added to HATEOAS links.
- Default status code is 200. If another is required, should be defined in both decorators (
@router
add information to swagger docs, while@format_response
make sure it will be status code returned by an endpoint).