33from typing import Any , Final
44
55from aiohttp import web
6+ from common_library .pydantic_fields_extension import is_nullable
67from models_library .basic_types import (
78 BootModeEnum ,
89 BuildTargetEnum ,
1112 VersionTag ,
1213)
1314from models_library .utils .change_case import snake_to_camel
14- from pydantic import AnyHttpUrl , parse_obj_as , root_validator , validator
15- from pydantic .fields import Field , ModelField
15+ from pydantic import (
16+ AliasChoices ,
17+ AnyHttpUrl ,
18+ TypeAdapter ,
19+ ValidationInfo ,
20+ field_validator ,
21+ model_validator ,
22+ )
23+ from pydantic .fields import Field
1624from pydantic .types import PositiveInt
1725from settings_library .base import BaseCustomSettings
1826from settings_library .email import SMTPSettings
@@ -53,7 +61,7 @@ class ApplicationSettings(BaseCustomSettings, MixinLoggingSettings):
5361 # CODE STATICS ---------------------------------------------------------
5462 API_VERSION : str = API_VERSION
5563 APP_NAME : str = APP_NAME
56- API_VTAG : VersionTag = parse_obj_as (VersionTag , API_VTAG )
64+ API_VTAG : VersionTag = TypeAdapter (VersionTag ). validate_python ( API_VTAG )
5765
5866 # IMAGE BUILDTIME ------------------------------------------------------
5967 # @Makefile
@@ -83,13 +91,13 @@ class ApplicationSettings(BaseCustomSettings, MixinLoggingSettings):
8391 SIMCORE_VCS_RELEASE_TAG : str | None = Field (
8492 default = None ,
8593 description = "Name of the tag that marks this release, or None if undefined" ,
86- example = "ResistanceIsFutile10" ,
94+ examples = [ "ResistanceIsFutile10" ] ,
8795 )
8896
8997 SIMCORE_VCS_RELEASE_URL : AnyHttpUrl | None = Field (
9098 default = None ,
9199 description = "URL to release notes" ,
92- example = "https://github.com/ITISFoundation/osparc-simcore/releases/tag/staging_ResistanceIsFutile10" ,
100+ examples = [ "https://github.com/ITISFoundation/osparc-simcore/releases/tag/staging_ResistanceIsFutile10" ] ,
93101 )
94102
95103 SWARM_STACK_NAME : str | None = Field (
@@ -105,13 +113,14 @@ class ApplicationSettings(BaseCustomSettings, MixinLoggingSettings):
105113 )
106114 WEBSERVER_LOGLEVEL : LogLevel = Field (
107115 default = LogLevel .WARNING .value ,
108- env = [ "WEBSERVER_LOGLEVEL" , "LOG_LEVEL" , "LOGLEVEL" ] ,
116+ validation_alias = AliasChoices ( "WEBSERVER_LOGLEVEL" , "LOG_LEVEL" , "LOGLEVEL" ) ,
109117 # NOTE: suffix '_LOGLEVEL' is used overall
110118 )
111-
112119 WEBSERVER_LOG_FORMAT_LOCAL_DEV_ENABLED : bool = Field (
113120 default = False ,
114- env = ["WEBSERVER_LOG_FORMAT_LOCAL_DEV_ENABLED" , "LOG_FORMAT_LOCAL_DEV_ENABLED" ],
121+ validation_alias = AliasChoices (
122+ "WEBSERVER_LOG_FORMAT_LOCAL_DEV_ENABLED" , "LOG_FORMAT_LOCAL_DEV_ENABLED"
123+ ),
115124 description = "Enables local development log format. WARNING: make sure it is disabled if you want to have structured logs!" ,
116125 )
117126 # TODO: find a better name!?
@@ -120,100 +129,117 @@ class ApplicationSettings(BaseCustomSettings, MixinLoggingSettings):
120129 description = "host name to serve within the container."
121130 "NOTE that this different from WEBSERVER_HOST env which is the host seen outside the container" ,
122131 )
123- WEBSERVER_HOST : str | None = Field (None , env = ["WEBSERVER_HOST" , "HOST" , "HOSTNAME" ])
124- WEBSERVER_PORT : PortInt = parse_obj_as (PortInt , DEFAULT_AIOHTTP_PORT )
132+ WEBSERVER_HOST : str | None = Field (
133+ None , validation_alias = AliasChoices ("WEBSERVER_HOST" , "HOST" , "HOSTNAME" )
134+ )
135+ WEBSERVER_PORT : PortInt = TypeAdapter (PortInt ).validate_python (DEFAULT_AIOHTTP_PORT )
125136
126137 WEBSERVER_FRONTEND : FrontEndAppSettings | None = Field (
127- auto_default_from_env = True , description = "front-end static settings"
138+ json_schema_extra = {"auto_default_from_env" : True },
139+ description = "front-end static settings" ,
128140 )
129141
130142 # PLUGINS ----------------
131143
132144 WEBSERVER_ACTIVITY : PrometheusSettings | None = Field (
133- auto_default_from_env = True ,
145+ json_schema_extra = { "auto_default_from_env" : True } ,
134146 description = "activity plugin" ,
135147 )
136148 WEBSERVER_CATALOG : CatalogSettings | None = Field (
137- auto_default_from_env = True , description = "catalog service client's plugin"
149+ json_schema_extra = {"auto_default_from_env" : True },
150+ description = "catalog service client's plugin" ,
138151 )
139152 # TODO: Shall be required
140153 WEBSERVER_DB : PostgresSettings | None = Field (
141- auto_default_from_env = True , description = "database plugin"
154+ json_schema_extra = { "auto_default_from_env" : True } , description = "database plugin"
142155 )
143156 WEBSERVER_DIAGNOSTICS : DiagnosticsSettings | None = Field (
144- auto_default_from_env = True , description = "diagnostics plugin"
157+ json_schema_extra = {"auto_default_from_env" : True },
158+ description = "diagnostics plugin" ,
145159 )
146160 WEBSERVER_DIRECTOR_V2 : DirectorV2Settings | None = Field (
147- auto_default_from_env = True , description = "director-v2 service client's plugin"
161+ json_schema_extra = {"auto_default_from_env" : True },
162+ description = "director-v2 service client's plugin" ,
148163 )
149164 WEBSERVER_EMAIL : SMTPSettings | None = Field (
150- auto_default_from_env = True , description = "email plugin"
165+ json_schema_extra = { "auto_default_from_env" : True } , description = "email plugin"
151166 )
152167 WEBSERVER_EXPORTER : ExporterSettings | None = Field (
153- auto_default_from_env = True , description = "exporter plugin"
168+ json_schema_extra = { "auto_default_from_env" : True } , description = "exporter plugin"
154169 )
155170 WEBSERVER_GARBAGE_COLLECTOR : GarbageCollectorSettings | None = Field (
156- auto_default_from_env = True , description = "garbage collector plugin"
171+ json_schema_extra = {"auto_default_from_env" : True },
172+ description = "garbage collector plugin" ,
157173 )
158174
159175 WEBSERVER_INVITATIONS : InvitationsSettings | None = Field (
160- auto_default_from_env = True , description = "invitations plugin"
176+ json_schema_extra = {"auto_default_from_env" : True },
177+ description = "invitations plugin" ,
161178 )
162179
163180 WEBSERVER_LOGIN : LoginSettings | None = Field (
164- auto_default_from_env = True , description = "login plugin"
181+ json_schema_extra = { "auto_default_from_env" : True } , description = "login plugin"
165182 )
166183
167184 WEBSERVER_PAYMENTS : PaymentsSettings | None = Field (
168- auto_default_from_env = True , description = "payments plugin settings"
185+ json_schema_extra = {"auto_default_from_env" : True },
186+ description = "payments plugin settings" ,
169187 )
170188
171189 WEBSERVER_DYNAMIC_SCHEDULER : DynamicSchedulerSettings | None = Field (
172- auto_default_from_env = True , description = "dynamic-scheduler plugin settings"
190+ description = "dynamic-scheduler plugin settings" ,
191+ json_schema_extra = {"auto_default_from_env" : True },
173192 )
174193
175- WEBSERVER_REDIS : RedisSettings | None = Field (auto_default_from_env = True )
194+ WEBSERVER_REDIS : RedisSettings | None = Field (
195+ json_schema_extra = {"auto_default_from_env" : True }
196+ )
176197
177198 WEBSERVER_REST : RestSettings | None = Field (
178- auto_default_from_env = True , description = "rest api plugin"
199+ description = "rest api plugin" , json_schema_extra = { "auto_default_from_env" : True }
179200 )
180201
181202 WEBSERVER_RESOURCE_MANAGER : ResourceManagerSettings = Field (
182- auto_default_from_env = True , description = "resource_manager plugin"
203+ description = "resource_manager plugin" ,
204+ json_schema_extra = {"auto_default_from_env" : True },
183205 )
184206 WEBSERVER_RESOURCE_USAGE_TRACKER : ResourceUsageTrackerSettings | None = Field (
185- auto_default_from_env = True ,
186207 description = "resource usage tracker service client's plugin" ,
208+ json_schema_extra = {"auto_default_from_env" : True },
187209 )
188210 WEBSERVER_SCICRUNCH : SciCrunchSettings | None = Field (
189- auto_default_from_env = True , description = "scicrunch plugin"
211+ description = "scicrunch plugin" ,
212+ json_schema_extra = {"auto_default_from_env" : True },
190213 )
191214 WEBSERVER_SESSION : SessionSettings = Field (
192- auto_default_from_env = True , description = "session plugin"
215+ description = "session plugin" , json_schema_extra = { "auto_default_from_env" : True }
193216 )
194217
195218 WEBSERVER_STATICWEB : StaticWebserverModuleSettings | None = Field (
196- auto_default_from_env = True , description = "static-webserver service plugin"
219+ description = "static-webserver service plugin" ,
220+ json_schema_extra = {"auto_default_from_env" : True },
197221 )
198222 WEBSERVER_STORAGE : StorageSettings | None = Field (
199- auto_default_from_env = True , description = "storage service client's plugin"
223+ description = "storage service client's plugin" ,
224+ json_schema_extra = {"auto_default_from_env" : True },
200225 )
201226 WEBSERVER_STUDIES_DISPATCHER : StudiesDispatcherSettings | None = Field (
202- auto_default_from_env = True , description = "studies dispatcher plugin"
227+ description = "studies dispatcher plugin" ,
228+ json_schema_extra = {"auto_default_from_env" : True },
203229 )
204230
205231 WEBSERVER_TRACING : TracingSettings | None = Field (
206- auto_default_from_env = True , description = "tracing plugin"
232+ description = "tracing plugin" , json_schema_extra = { "auto_default_from_env" : True }
207233 )
208234
209235 WEBSERVER_PROJECTS : ProjectsSettings | None = Field (
210- auto_default_from_env = True , description = "projects plugin"
236+ description = "projects plugin" , json_schema_extra = { "auto_default_from_env" : True }
211237 )
212238 WEBSERVER_RABBITMQ : RabbitSettings | None = Field (
213- auto_default_from_env = True , description = "rabbitmq plugin"
239+ description = "rabbitmq plugin" , json_schema_extra = { "auto_default_from_env" : True }
214240 )
215241 WEBSERVER_USERS : UsersSettings | None = Field (
216- auto_default_from_env = True , description = "users plugin"
242+ description = "users plugin" , json_schema_extra = { "auto_default_from_env" : True }
217243 )
218244
219245 # These plugins only require (for the moment) an entry to toggle between enabled/disabled
@@ -242,7 +268,7 @@ class ApplicationSettings(BaseCustomSettings, MixinLoggingSettings):
242268 "Currently this is a system plugin and cannot be disabled" ,
243269 )
244270
245- @root_validator ( )
271+ @model_validator ( mode = "after" )
246272 @classmethod
247273 def build_vcs_release_url_if_unset (cls , values ):
248274 release_url = values .get ("SIMCORE_VCS_RELEASE_URL" )
@@ -260,39 +286,43 @@ def build_vcs_release_url_if_unset(cls, values):
260286
261287 return values
262288
263- @validator (
289+ @field_validator (
264290 # List of plugins under-development (keep up-to-date)
265291 # TODO: consider mark as dev-feature in field extras of Config attr.
266292 # Then they can be automtically advertised
267293 "WEBSERVER_META_MODELING" ,
268294 "WEBSERVER_VERSION_CONTROL" ,
269- pre = True ,
270- always = True ,
295+ mode = "before" ,
271296 )
272297 @classmethod
273- def enable_only_if_dev_features_allowed (cls , v , values , field : ModelField ):
298+ def enable_only_if_dev_features_allowed (cls , v , info : ValidationInfo ):
274299 """Ensures that plugins 'under development' get programatically
275300 disabled if WEBSERVER_DEV_FEATURES_ENABLED=False
276301 """
277- if values ["WEBSERVER_DEV_FEATURES_ENABLED" ]:
302+ if info . data ["WEBSERVER_DEV_FEATURES_ENABLED" ]:
278303 return v
279304 if v :
280305 _logger .warning (
281- "%s still under development and will be disabled." , field . name
306+ "%s still under development and will be disabled." , info . field_name
282307 )
283- return None if field .allow_none else False
308+
309+ return (
310+ None
311+ if info .field_name and is_nullable (cls .model_fields [info .field_name ])
312+ else False
313+ )
284314
285315 @cached_property
286316 def log_level (self ) -> int :
287317 level : int = getattr (logging , self .WEBSERVER_LOGLEVEL .upper ())
288318 return level
289319
290- @validator ("WEBSERVER_LOGLEVEL" , pre = True )
320+ @field_validator ("WEBSERVER_LOGLEVEL" )
291321 @classmethod
292- def valid_log_level (cls , value : str ) -> str :
322+ def valid_log_level (cls , value ) :
293323 return cls .validate_log_level (value )
294324
295- @validator ("SC_HEALTHCHECK_TIMEOUT" , pre = True )
325+ @field_validator ("SC_HEALTHCHECK_TIMEOUT" , mode = "before" )
296326 @classmethod
297327 def get_healthcheck_timeout_in_seconds (cls , v ):
298328 # Ex. HEALTHCHECK --interval=5m --timeout=3s
0 commit comments