Python project¶
Common files for a Python project.
Dependencies¶
poetry add python-dotenv ipython deescovery
Top-level files¶
File myproject/config.py
"""Configuration.
The module doesn't depend on the project. The configuration file is initialized
with python-dotenv, and we don't read environment variables in the rest of the
project.
What config.py can import?
--------------------------
The module doesn't import anything from the project.
Who can import config.py?
---------------------------
The module is imported by the app.py to create services. It can also be imported in
the other parts of the application: for example, to get access to PROJECT_ROOT, or to
create project-specific services from requisites, provided in the config.
"""
import os
import pathlib
import dotenv
PROJECT_ROOT = pathlib.Path(__file__).parents[1]
dotenv.load_dotenv((PROJECT_ROOT / ".env").as_posix())
# --------------------------------------------------------------------------------
# Server configuration
# --------------------------------------------------------------------------------
HOST = os.environ.get("HOST", "0.0.0.0")
PORT = int(os.environ.get("PORT", 5000))
File myproject/services.py
"""Services.
The module provides a "registry" or "service locator" for other modules of the
application. It may initialize stub objects for extensions, that are configured
inside the app.py later on.
What services.py can import?
----------------------------
The module doesn't import anything from the project.
Who can import services.py?
--------------------------
The module is imported by different modules across the project, as necessary.
"""
# FastAPI example
from fastapi import FastAPI
fastapi_app = FastAPI()
File myproject/app.py
"""Application.
The module is used to initialize the main project: load configuration and
initialize services.
What app.py can import?
-----------------------
Services, configuration, and everything that is needed to initialize application,
including controllers and models inside apps. In other words, app.py depends on
a lot of things in the project.
Who can import app.py?
----------------------
The module is not imported from anywhere except from a WSGI/ASGI server in
production, and conftests.py for pytest.
"""
from importlib import import_module
from deescovery import ModuleRule, discover
from deescovery.matchers import MatchByPattern
from myproject import config
api_loader = ModuleRule(
name="FastAPI API endpoints loader",
module_matches=MatchByPattern(patterns=["myproject.*.api"]),
module_action=import_module,
)
def init(**kwargs):
update_config(kwargs)
discover("myproject", rules=[api_loader])
def update_config(kwargs):
"""Override values of the myproject.config.
Helpful for tests, when we need to dynamically override some settings.
"""
for k, v in kwargs.items():
setattr(config, k, v)
File manage.py
#!/usr/bin/env python
"""Management script."""
import datetime
from typing import Iterable, List
import click
from IPython import embed
from myproject import app
@click.group()
def cli():
app.init()
@cli.command()
def shell():
"""Open IPython console."""
embed(colors="neutral")
if __name__ == "__main__":
cli()