|
1 | | -import logging |
2 | | -from collections.abc import AsyncGenerator |
3 | | -from contextlib import asynccontextmanager |
4 | | -from logging import Logger |
5 | | - |
6 | 1 | from aspy_dependency_injection.service_collection import ServiceCollection |
7 | | -from azure.cosmos import PartitionKey |
8 | | -from azure.cosmos.aio import CosmosClient, DatabaseProxy |
9 | | -from azure.identity import DefaultAzureCredential |
10 | | -from azure.monitor.opentelemetry import ( |
11 | | - configure_azure_monitor, # pyright: ignore[reportUnknownVariableType] |
12 | | -) |
13 | 2 | from fastapi import FastAPI |
14 | 3 |
|
15 | 4 | from python_template.api.application_settings import ApplicationSettings |
| 5 | +from python_template.api.service_collection_extensions import ( |
| 6 | + add_observability, |
| 7 | + add_sqlmodel, |
| 8 | +) |
16 | 9 | from python_template.api.services.email_service import EmailService |
17 | 10 | from python_template.api.workflows.products.discontinue_product.discontinue_product_workflow import ( |
18 | 11 | DiscontinueProductWorkflow, |
|
22 | 15 | PublishProductWorkflow, |
23 | 16 | ) |
24 | 17 | from python_template.common.application_environment import ApplicationEnvironment |
25 | | -from python_template.domain.entities.product import Product |
26 | | - |
27 | | - |
28 | | -def inject_application_settings() -> ApplicationSettings: |
29 | | - return ApplicationSettings() # ty:ignore[missing-argument] |
30 | | - |
31 | | - |
32 | | -def inject_logging() -> Logger: |
33 | | - return logging.getLogger(__name__) |
34 | | - |
35 | | - |
36 | | -def inject_cosmos_client( |
37 | | - application_settings: ApplicationSettings, |
38 | | -) -> CosmosClient: |
39 | | - return CosmosClient( |
40 | | - url=application_settings.cosmos_db_no_sql_url, |
41 | | - credential=application_settings.cosmos_db_no_sql_key.get_secret_value(), |
42 | | - ) |
43 | | - |
44 | 18 |
|
45 | | -def inject_cosmos_database( |
46 | | - application_settings: ApplicationSettings, cosmos_client: CosmosClient |
47 | | -) -> DatabaseProxy: |
48 | | - return cosmos_client.get_database_client( |
49 | | - application_settings.cosmos_db_no_sql_database |
50 | | - ) |
51 | | - |
52 | | - |
53 | | -def configure_services() -> ServiceCollection: |
54 | | - services = ServiceCollection() |
55 | | - services.add_singleton(inject_application_settings) |
56 | | - services.add_singleton(inject_logging) |
57 | | - services.add_singleton(inject_cosmos_client) |
58 | | - services.add_transient(inject_cosmos_database) |
59 | | - services.add_transient(EmailService) |
60 | | - services.add_transient(PublishProductWorkflow) |
61 | | - services.add_transient(DiscontinueProductWorkflow) |
62 | | - return services |
63 | | - |
64 | | - |
65 | | -def create_app() -> FastAPI: |
66 | | - @asynccontextmanager |
67 | | - async def lifespan(_: FastAPI) -> AsyncGenerator[None]: |
68 | | - async with configure_services().build_service_provider() as service_provider: |
69 | | - application_settings = await service_provider.get_required_service( |
70 | | - ApplicationSettings |
71 | | - ) |
72 | | - logging.basicConfig(level=application_settings.logging_level) |
73 | | - |
74 | | - if ApplicationEnvironment.get_current() != ApplicationEnvironment.LOCAL: |
75 | | - configure_azure_monitor( |
76 | | - connection_string=application_settings.application_insights_connection_string, |
77 | | - credential=DefaultAzureCredential(), |
78 | | - enable_live_metrics=True, |
79 | | - ) |
80 | | - |
81 | | - if ApplicationEnvironment.get_current() == ApplicationEnvironment.LOCAL: |
82 | | - cosmos_client = await service_provider.get_required_service( |
83 | | - CosmosClient |
84 | | - ) |
85 | | - await cosmos_client.create_database_if_not_exists( |
86 | | - application_settings.cosmos_db_no_sql_database |
87 | | - ) |
88 | | - cosmos_database = await service_provider.get_required_service( |
89 | | - DatabaseProxy |
90 | | - ) |
91 | | - await cosmos_database.create_container_if_not_exists( |
92 | | - id=Product.__name__, partition_key=PartitionKey("/id") |
93 | | - ) |
94 | | - yield |
95 | | - |
96 | | - openapi_url = ( |
97 | | - "/openapi.json" |
98 | | - if ApplicationEnvironment.get_current() != ApplicationEnvironment.PRODUCTION |
99 | | - else None |
100 | | - ) |
101 | | - app = FastAPI(openapi_url=openapi_url, lifespan=lifespan) |
102 | | - app.include_router(product_router) |
103 | | - return app |
104 | | - |
105 | | - |
106 | | -app = create_app() |
107 | | -services = configure_services() |
| 19 | +openapi_url = ( |
| 20 | + "/openapi.json" |
| 21 | + if ApplicationEnvironment.get_current() != ApplicationEnvironment.PRODUCTION |
| 22 | + else None |
| 23 | +) |
| 24 | +app = FastAPI(openapi_url=openapi_url) |
| 25 | +app.include_router(product_router) |
| 26 | + |
| 27 | +services = ServiceCollection() |
| 28 | +application_settings = ApplicationSettings() # ty:ignore[missing-argument] |
| 29 | +services.add_singleton(ApplicationSettings, application_settings) |
| 30 | +add_observability(services, application_settings) |
| 31 | +add_sqlmodel(services) |
| 32 | +services.add_transient(EmailService) |
| 33 | +services.add_transient(PublishProductWorkflow) |
| 34 | +services.add_transient(DiscontinueProductWorkflow) |
108 | 35 | services.configure_fastapi(app) |
0 commit comments