I have the following structure (relevant portion) for a small API:
app
|--main.py
|-models
|--base.py
|--ModelUser.py
|--ModelCompany.py
|--ModelUser.py
|-schemas
|--SchemaUser.py
|--SchemaCompany.py
|--SchemaReview.py
|-routes
|--auth_router.py
|--companies_router.py
|_users_router.py
|-utils
|--crud_company.py
|--crud_review.py
|--crud_user.py
For the most part, it works and keeps an acceptable degree of separation of concerns (ie., UserModel contains the SQLAlchemy User model, SchemaCompany contains the Pydantic Company model, etc.). Thing is, the namespace has become a little too cluttered and redundant, as each class or function call requires me to type, for example, SchemaReview.Review
or ModelUser.User
or crud_company.get_companies
(you get the idea).
I'd much rather have something like model.User
, schema.Company
and crud.get_reviews
, but in order to achieve this I would have to put every model in a single model.py
file, every schema in a single schema.py
file, etc., which is exactly what I'm trying to avoid by modularizing the code.
So, what would the best approach here? I've thought of aliasing the imports, but that may lead to inconsistencies along the way, which I'd rather not get into. So I think the ideal approach would come from a directory/filename convention, that will force me to maintain coherence.
All ideas wellcome. Thanks!
Have a look into the FastAPI's creator template for FastAPI-Postgres App.
I've seen the convention of never naming python files in PascalCase
and use snake_case
exclusively.
The way you can achieve model.User
is to import relevant classes in __init__.py
of relevant file.
Let's say models.__init__.py
from .ModelUser import User
from .ModelCompany import Company
from .ModelReview import ModelReview
Then you can import models
and have models.User
used throughout the code. This might create naming conflicts if you use PascalCase for file names, so that's also why snake_case is more practical.
FYI, you can also post questions on the FastAPI discussions board.