|
1 | 1 | import datetime |
2 | 2 | from functools import cached_property |
3 | | -from typing import Final, cast |
| 3 | +from typing import Annotated, Final, cast |
4 | 4 |
|
| 5 | +from common_library.basic_types import DEFAULT_FACTORY |
5 | 6 | from fastapi import FastAPI |
6 | | -from models_library.basic_types import ( |
7 | | - BootModeEnum, |
8 | | - BuildTargetEnum, |
9 | | - LogLevel, |
10 | | - VersionTag, |
11 | | -) |
12 | | -from pydantic import ( |
13 | | - AliasChoices, |
14 | | - ByteSize, |
15 | | - Field, |
16 | | - PositiveInt, |
17 | | - TypeAdapter, |
18 | | - field_validator, |
19 | | -) |
| 7 | +from models_library.basic_types import LogLevel, VersionTag |
| 8 | +from pydantic import AliasChoices, ByteSize, Field, TypeAdapter, field_validator |
20 | 9 | from servicelib.logging_utils_filtering import LoggerName, MessageSubstring |
21 | | -from settings_library.base import BaseCustomSettings |
| 10 | +from settings_library.application import BaseApplicationSettings |
22 | 11 | from settings_library.efs import AwsEfsSettings |
23 | 12 | from settings_library.postgres import PostgresSettings |
24 | 13 | from settings_library.rabbit import RabbitSettings |
|
31 | 20 | EFS_GUARDIAN_ENV_PREFIX: Final[str] = "EFS_GUARDIAN_" |
32 | 21 |
|
33 | 22 |
|
34 | | -class ApplicationSettings(BaseCustomSettings, MixinLoggingSettings): |
| 23 | +class ApplicationSettings(BaseApplicationSettings, MixinLoggingSettings): |
35 | 24 | # CODE STATICS --------------------------------------------------------- |
36 | 25 | API_VERSION: str = API_VERSION |
37 | 26 | APP_NAME: str = APP_NAME |
38 | 27 | API_VTAG: VersionTag = API_VTAG |
39 | 28 |
|
40 | | - # IMAGE BUILDTIME ------------------------------------------------------ |
41 | | - # @Makefile |
42 | | - SC_BUILD_DATE: str | None = None |
43 | | - SC_BUILD_TARGET: BuildTargetEnum | None = None |
44 | | - SC_VCS_REF: str | None = None |
45 | | - SC_VCS_URL: str | None = None |
46 | | - |
47 | | - # @Dockerfile |
48 | | - SC_BOOT_MODE: BootModeEnum | None = None |
49 | | - SC_BOOT_TARGET: BuildTargetEnum | None = None |
50 | | - SC_HEALTHCHECK_TIMEOUT: PositiveInt | None = Field( |
51 | | - None, |
52 | | - description="If a single run of the check takes longer than timeout seconds " |
53 | | - "then the check is considered to have failed." |
54 | | - "It takes retries consecutive failures of the health check for the container to be considered unhealthy.", |
55 | | - ) |
56 | | - SC_USER_ID: int |
57 | | - SC_USER_NAME: str |
| 29 | + EFS_USER_ID: Annotated[ |
| 30 | + int, Field(description="Linux user ID that the Guardian service will run with") |
| 31 | + ] |
| 32 | + EFS_USER_NAME: Annotated[ |
| 33 | + str, |
| 34 | + Field(description="Linux user name that the Guardian service will run with"), |
| 35 | + ] |
| 36 | + EFS_GROUP_ID: Annotated[ |
| 37 | + int, |
| 38 | + Field( |
| 39 | + description="Linux group ID that the EFS and Simcore linux users are part of" |
| 40 | + ), |
| 41 | + ] |
| 42 | + EFS_GROUP_NAME: Annotated[ |
| 43 | + str, |
| 44 | + Field( |
| 45 | + description="Linux group name that the EFS and Simcore linux users are part of" |
| 46 | + ), |
| 47 | + ] |
| 48 | + EFS_DEFAULT_USER_SERVICE_SIZE_BYTES: ByteSize = TypeAdapter( |
| 49 | + ByteSize |
| 50 | + ).validate_python("500GiB") |
58 | 51 |
|
59 | | - EFS_USER_ID: int = Field( |
60 | | - description="Linux user ID that the Guardian service will run with" |
61 | | - ) |
62 | | - EFS_USER_NAME: str = Field( |
63 | | - description="Linux user name that the Guardian service will run with" |
64 | | - ) |
65 | | - EFS_GROUP_ID: int = Field( |
66 | | - description="Linux group ID that the EFS and Simcore linux users are part of" |
67 | | - ) |
68 | | - EFS_GROUP_NAME: str = Field( |
69 | | - description="Linux group name that the EFS and Simcore linux users are part of" |
70 | | - ) |
71 | | - EFS_DEFAULT_USER_SERVICE_SIZE_BYTES: ByteSize = Field( |
72 | | - default=TypeAdapter(ByteSize).validate_python("500GiB") |
73 | | - ) |
74 | | - EFS_REMOVAL_POLICY_TASK_AGE_LIMIT_TIMEDELTA: datetime.timedelta = Field( |
75 | | - default=datetime.timedelta(days=10), |
76 | | - description="For how long must a project remain unused before we remove its data from the EFS. (default to seconds, or see https://pydantic-docs.helpmanual.io/usage/types/#datetime-types for string formating)", |
77 | | - ) |
| 52 | + EFS_REMOVAL_POLICY_TASK_AGE_LIMIT_TIMEDELTA: Annotated[ |
| 53 | + datetime.timedelta, |
| 54 | + Field( |
| 55 | + description="For how long must a project remain unused before we remove its data from the EFS. (default to seconds, or see https://pydantic-docs.helpmanual.io/usage/types/#datetime-types for string formating)", |
| 56 | + ), |
| 57 | + ] = datetime.timedelta(days=10) |
78 | 58 |
|
79 | 59 | # RUNTIME ----------------------------------------------------------- |
80 | | - EFS_GUARDIAN_DEBUG: bool = Field( |
81 | | - default=False, |
82 | | - description="Debug mode", |
83 | | - validation_alias=AliasChoices("EFS_GUARDIAN_DEBUG", "DEBUG"), |
84 | | - ) |
85 | | - EFS_GUARDIAN_LOGLEVEL: LogLevel = Field( |
86 | | - LogLevel.INFO, |
87 | | - validation_alias=AliasChoices("EFS_GUARDIAN_LOGLEVEL", "LOG_LEVEL", "LOGLEVEL"), |
88 | | - ) |
89 | | - EFS_GUARDIAN_LOG_FORMAT_LOCAL_DEV_ENABLED: bool = Field( |
90 | | - default=False, |
91 | | - validation_alias=AliasChoices( |
92 | | - "EFS_GUARDIAN_LOG_FORMAT_LOCAL_DEV_ENABLED", |
93 | | - "LOG_FORMAT_LOCAL_DEV_ENABLED", |
| 60 | + EFS_GUARDIAN_DEBUG: Annotated[ |
| 61 | + bool, |
| 62 | + Field( |
| 63 | + description="Debug mode", |
| 64 | + validation_alias=AliasChoices("EFS_GUARDIAN_DEBUG", "DEBUG"), |
94 | 65 | ), |
95 | | - description="Enables local development log format. WARNING: make sure it is disabled if you want to have structured logs!", |
96 | | - ) |
97 | | - EFS_GUARDIAN_LOG_FILTER_MAPPING: dict[LoggerName, list[MessageSubstring]] = Field( |
98 | | - default_factory=dict, |
99 | | - validation_alias=AliasChoices( |
100 | | - "EFS_GUARDIAN_LOG_FILTER_MAPPING", "LOG_FILTER_MAPPING" |
| 66 | + ] = False |
| 67 | + |
| 68 | + EFS_GUARDIAN_LOGLEVEL: Annotated[ |
| 69 | + LogLevel, |
| 70 | + Field( |
| 71 | + validation_alias=AliasChoices( |
| 72 | + "EFS_GUARDIAN_LOGLEVEL", "LOG_LEVEL", "LOGLEVEL" |
| 73 | + ), |
101 | 74 | ), |
102 | | - description="is a dictionary that maps specific loggers (such as 'uvicorn.access' or 'gunicorn.access') to a list of log message patterns that should be filtered out.", |
103 | | - ) |
| 75 | + ] = LogLevel.INFO |
104 | 76 |
|
105 | | - EFS_GUARDIAN_AWS_EFS_SETTINGS: AwsEfsSettings = Field( |
106 | | - json_schema_extra={"auto_default_from_env": True} |
107 | | - ) |
108 | | - EFS_GUARDIAN_POSTGRES: PostgresSettings = Field( |
109 | | - json_schema_extra={"auto_default_from_env": True} |
110 | | - ) |
111 | | - EFS_GUARDIAN_RABBITMQ: RabbitSettings = Field( |
112 | | - json_schema_extra={"auto_default_from_env": True} |
113 | | - ) |
114 | | - EFS_GUARDIAN_REDIS: RedisSettings = Field( |
115 | | - json_schema_extra={"auto_default_from_env": True} |
116 | | - ) |
117 | | - EFS_GUARDIAN_TRACING: TracingSettings | None = Field( |
118 | | - description="settings for opentelemetry tracing", |
119 | | - json_schema_extra={"auto_default_from_env": True}, |
120 | | - ) |
| 77 | + EFS_GUARDIAN_LOG_FORMAT_LOCAL_DEV_ENABLED: Annotated[ |
| 78 | + bool, |
| 79 | + Field( |
| 80 | + validation_alias=AliasChoices( |
| 81 | + "EFS_GUARDIAN_LOG_FORMAT_LOCAL_DEV_ENABLED", |
| 82 | + "LOG_FORMAT_LOCAL_DEV_ENABLED", |
| 83 | + ), |
| 84 | + description="Enables local development log format. WARNING: make sure it is disabled if you want to have structured logs!", |
| 85 | + ), |
| 86 | + ] = False |
| 87 | + EFS_GUARDIAN_LOG_FILTER_MAPPING: Annotated[ |
| 88 | + dict[LoggerName, list[MessageSubstring]], |
| 89 | + Field( |
| 90 | + default_factory=dict, |
| 91 | + validation_alias=AliasChoices( |
| 92 | + "EFS_GUARDIAN_LOG_FILTER_MAPPING", "LOG_FILTER_MAPPING" |
| 93 | + ), |
| 94 | + description="is a dictionary that maps specific loggers (such as 'uvicorn.access' or 'gunicorn.access') to a list of log message patterns that should be filtered out.", |
| 95 | + ), |
| 96 | + ] = DEFAULT_FACTORY |
| 97 | + |
| 98 | + EFS_GUARDIAN_AWS_EFS_SETTINGS: Annotated[ |
| 99 | + AwsEfsSettings, Field(json_schema_extra={"auto_default_from_env": True}) |
| 100 | + ] |
| 101 | + EFS_GUARDIAN_POSTGRES: Annotated[ |
| 102 | + PostgresSettings, Field(json_schema_extra={"auto_default_from_env": True}) |
| 103 | + ] |
| 104 | + EFS_GUARDIAN_RABBITMQ: Annotated[ |
| 105 | + RabbitSettings, Field(json_schema_extra={"auto_default_from_env": True}) |
| 106 | + ] |
| 107 | + EFS_GUARDIAN_REDIS: Annotated[ |
| 108 | + RedisSettings, Field(json_schema_extra={"auto_default_from_env": True}) |
| 109 | + ] |
| 110 | + EFS_GUARDIAN_TRACING: Annotated[ |
| 111 | + TracingSettings | None, |
| 112 | + Field( |
| 113 | + description="settings for opentelemetry tracing", |
| 114 | + json_schema_extra={"auto_default_from_env": True}, |
| 115 | + ), |
| 116 | + ] |
121 | 117 |
|
122 | 118 | @cached_property |
123 | 119 | def LOG_LEVEL(self) -> LogLevel: # noqa: N802 |
124 | 120 | return self.EFS_GUARDIAN_LOGLEVEL |
125 | 121 |
|
126 | 122 | @field_validator("EFS_GUARDIAN_LOGLEVEL", mode="before") |
127 | 123 | @classmethod |
128 | | - def valid_log_level(cls, value: str) -> str: |
| 124 | + def _valid_log_level(cls, value: str) -> str: |
129 | 125 | return cls.validate_log_level(value) |
130 | 126 |
|
131 | 127 |
|
|
0 commit comments