Version 0.4.0
All checks were successful
Run linters on applied template / Python 3.13 lint and build (push) Successful in 1m40s
All checks were successful
Run linters on applied template / Python 3.13 lint and build (push) Successful in 1m40s
Changes: - put ObservabilityMiddleware before ExceptionHandlerMiddleware to avoid repetative code - add application startup and last metrics update metrics along with CPU usage metric and threads count - move host and port to new uvicorn section at config along with new reload and forwarded_allow_ips - add request_id and remove trace_id/span_id generation if tracing is disabled - move logging logic from utils to observability - pass trace_id/span_id in HEX form
This commit is contained in:
@@ -9,16 +9,7 @@ import click
|
||||
import uvicorn
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from .config import LoggingConfig, {{ProjectName}}Config
|
||||
|
||||
LogLevel = tp.Literal["TRACE", "DEBUG", "INFO", "WARNING", "ERROR"]
|
||||
|
||||
|
||||
def _run_uvicorn(configuration: dict[str, tp.Any]) -> tp.NoReturn:
|
||||
uvicorn.run(
|
||||
"{{project_slug}}.fastapi_init:app",
|
||||
**configuration,
|
||||
)
|
||||
from .config import {{ProjectName}}Config
|
||||
|
||||
|
||||
@click.group()
|
||||
@@ -42,34 +33,6 @@ def get_config_example(config_path: Path):
|
||||
|
||||
|
||||
@cli.command("launch")
|
||||
@click.option(
|
||||
"--port",
|
||||
"-p",
|
||||
envvar="PORT",
|
||||
type=int,
|
||||
show_envvar=True,
|
||||
help="Service port number",
|
||||
)
|
||||
@click.option(
|
||||
"--host",
|
||||
envvar="HOST",
|
||||
show_envvar=True,
|
||||
help="Service HOST address",
|
||||
)
|
||||
@click.option(
|
||||
"--logger_verbosity",
|
||||
"-v",
|
||||
type=click.Choice(("TRACE", "DEBUG", "INFO", "WARNING", "ERROR")),
|
||||
envvar="LOGGER_VERBOSITY",
|
||||
show_envvar=True,
|
||||
help="Logger verbosity",
|
||||
)
|
||||
@click.option(
|
||||
"--debug",
|
||||
envvar="DEBUG",
|
||||
is_flag=True,
|
||||
help="Enable debug mode (auto-reload on change, traceback returned to user, etc.)",
|
||||
)
|
||||
@click.option(
|
||||
"--config_path",
|
||||
envvar="CONFIG_PATH",
|
||||
@@ -80,10 +43,6 @@ def get_config_example(config_path: Path):
|
||||
help="Path to YAML configuration file",
|
||||
)
|
||||
def launch(
|
||||
port: int,
|
||||
host: str,
|
||||
logger_verbosity: LogLevel,
|
||||
debug: bool,
|
||||
config_path: Path,
|
||||
):
|
||||
"""
|
||||
@@ -93,14 +52,10 @@ def launch(
|
||||
"""
|
||||
print(
|
||||
"This is a simple method to run the API. You might want to use"
|
||||
"'uvicorn {{project_slug}}.fastapi_init:app' instead to configure more uvicorn options."
|
||||
" 'uvicorn {{project_slug}}.fastapi_init:app' instead to configure more uvicorn options."
|
||||
)
|
||||
|
||||
config = {{ProjectName}}Config.load(config_path)
|
||||
config.app.host = host or config.app.host
|
||||
config.app.port = port or config.app.port
|
||||
config.app.debug = debug or config.app.debug
|
||||
config.observability.logging = config.observability.logging if logger_verbosity is None else LoggingConfig(level=logger_verbosity)
|
||||
|
||||
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
|
||||
temp_yaml_config_path = temp_file.name
|
||||
@@ -111,16 +66,18 @@ def launch(
|
||||
env_file.write(f"CONFIG_PATH={temp_yaml_config_path}\n")
|
||||
try:
|
||||
uvicorn_config = {
|
||||
"host": config.app.host,
|
||||
"port": config.app.port,
|
||||
"log_level": config.observability.logging.level.lower(),
|
||||
"host": config.app.uvicorn.host,
|
||||
"port": config.app.uvicorn.port,
|
||||
"forwarded_allow_ips": config.app.uvicorn.forwarded_allow_ips,
|
||||
"log_level": config.observability.logging.root_logger_level.lower(),
|
||||
"env_file": temp_envfile_path,
|
||||
"access_log": False,
|
||||
}
|
||||
if config.app.debug:
|
||||
try:
|
||||
_run_uvicorn(uvicorn_config | {"reload": True})
|
||||
except: # pylint: disable=bare-except
|
||||
print("Debug reload is not supported and will be disabled")
|
||||
print("Retrying with Uvicorn reload disabled")
|
||||
_run_uvicorn(uvicorn_config)
|
||||
else:
|
||||
_run_uvicorn(uvicorn_config)
|
||||
@@ -131,6 +88,13 @@ def launch(
|
||||
os.remove(temp_yaml_config_path)
|
||||
|
||||
|
||||
def _run_uvicorn(configuration: dict[str, tp.Any]) -> tp.NoReturn:
|
||||
uvicorn.run(
|
||||
"{{project_slug}}.fastapi_init:app",
|
||||
**configuration,
|
||||
)
|
||||
|
||||
|
||||
if __name__ in ("__main__", "{{project_slug}}.__main__"):
|
||||
load_dotenv(os.environ.get("ENVFILE", ".env"))
|
||||
cli() # pylint: disable=no-value-for-parameter
|
||||
|
||||
Reference in New Issue
Block a user