11import datetime
22from functools import cached_property
3- from typing import Any , ClassVar , Final , cast
3+ from typing import Annotated , Final , cast
44
55from aws_library .ec2 import EC2InstanceBootSpecific , EC2Tags
66from fastapi import FastAPI
1414from models_library .clusters import InternalClusterAuthentication
1515from models_library .docker import DockerLabelKey
1616from pydantic import (
17+ AliasChoices ,
1718 AnyUrl ,
1819 Field ,
1920 NonNegativeInt ,
2021 PositiveInt ,
21- parse_obj_as ,
22- root_validator ,
23- validator ,
22+ TypeAdapter ,
23+ field_validator ,
24+ model_validator ,
2425)
26+ from pydantic_settings import SettingsConfigDict
2527from settings_library .base import BaseCustomSettings
2628from settings_library .docker_registry import RegistrySettings
2729from settings_library .ec2 import EC2Settings
@@ -42,10 +44,9 @@ class AutoscalingSSMSettings(SSMSettings):
4244
4345
4446class AutoscalingEC2Settings (EC2Settings ):
45- class Config (EC2Settings .Config ):
46- env_prefix = AUTOSCALING_ENV_PREFIX
47-
48- schema_extra : ClassVar [dict [str , Any ]] = { # type: ignore[misc]
47+ model_config = SettingsConfigDict (
48+ env_prefix = AUTOSCALING_ENV_PREFIX ,
49+ json_schema_extra = {
4950 "examples" : [
5051 {
5152 f"{ AUTOSCALING_ENV_PREFIX } EC2_ACCESS_KEY_ID" : "my_access_key_id" ,
@@ -54,7 +55,8 @@ class Config(EC2Settings.Config):
5455 f"{ AUTOSCALING_ENV_PREFIX } EC2_SECRET_ACCESS_KEY" : "my_secret_access_key" ,
5556 }
5657 ],
57- }
58+ },
59+ )
5860
5961
6062class EC2InstancesSettings (BaseCustomSettings ):
@@ -94,7 +96,7 @@ class EC2InstancesSettings(BaseCustomSettings):
9496
9597 EC2_INSTANCES_SECURITY_GROUP_IDS : list [str ] = Field (
9698 ...,
97- min_items = 1 ,
99+ min_length = 1 ,
98100 description = "A security group acts as a virtual firewall for your EC2 instances to control incoming and outgoing traffic"
99101 " (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html), "
100102 " this is required to start a new EC2 instance" ,
@@ -131,7 +133,7 @@ class EC2InstancesSettings(BaseCustomSettings):
131133 description = "ARN the EC2 instance should be attached to (example: arn:aws:iam::XXXXX:role/NAME), to disable pass an empty string" ,
132134 )
133135
134- @validator ("EC2_INSTANCES_TIME_BEFORE_DRAINING" )
136+ @field_validator ("EC2_INSTANCES_TIME_BEFORE_DRAINING" )
135137 @classmethod
136138 def ensure_draining_delay_time_is_in_range (
137139 cls , value : datetime .timedelta
@@ -142,7 +144,7 @@ def ensure_draining_delay_time_is_in_range(
142144 value = datetime .timedelta (minutes = 1 )
143145 return value
144146
145- @validator ("EC2_INSTANCES_TIME_BEFORE_TERMINATION" )
147+ @field_validator ("EC2_INSTANCES_TIME_BEFORE_TERMINATION" )
146148 @classmethod
147149 def ensure_termination_delay_time_is_in_range (
148150 cls , value : datetime .timedelta
@@ -153,14 +155,14 @@ def ensure_termination_delay_time_is_in_range(
153155 value = datetime .timedelta (minutes = 59 )
154156 return value
155157
156- @validator ("EC2_INSTANCES_ALLOWED_TYPES" )
158+ @field_validator ("EC2_INSTANCES_ALLOWED_TYPES" )
157159 @classmethod
158160 def check_valid_instance_names (
159161 cls , value : dict [str , EC2InstanceBootSpecific ]
160162 ) -> dict [str , EC2InstanceBootSpecific ]:
161163 # NOTE: needed because of a flaw in BaseCustomSettings
162164 # issubclass raises TypeError if used on Aliases
163- parse_obj_as (list [InstanceTypeType ], list (value ))
165+ TypeAdapter (list [InstanceTypeType ]). validate_python ( list (value ))
164166 return value
165167
166168
@@ -182,7 +184,7 @@ class NodesMonitoringSettings(BaseCustomSettings):
182184
183185
184186class DaskMonitoringSettings (BaseCustomSettings ):
185- DASK_MONITORING_URL : AnyUrl = Field (
187+ DASK_MONITORING_URL : Annotated [ str , AnyUrl ] = Field (
186188 ..., description = "the url to the osparc-dask-scheduler"
187189 )
188190 DASK_SCHEDULER_AUTH : InternalClusterAuthentication = Field (
@@ -218,36 +220,39 @@ class ApplicationSettings(BaseCustomSettings, MixinLoggingSettings):
218220
219221 # RUNTIME -----------------------------------------------------------
220222 AUTOSCALING_DEBUG : bool = Field (
221- default = False , description = "Debug mode" , env = ["AUTOSCALING_DEBUG" , "DEBUG" ]
223+ default = False ,
224+ description = "Debug mode" ,
225+ validation_alias = AliasChoices ("AUTOSCALING_DEBUG" , "DEBUG" ),
222226 )
223- AUTOSCALING_REMOTE_DEBUG_PORT : PortInt = PortInt ( 3000 )
227+ AUTOSCALING_REMOTE_DEBUG_PORT : PortInt = 3000
224228
225229 AUTOSCALING_LOGLEVEL : LogLevel = Field (
226- LogLevel .INFO , env = ["AUTOSCALING_LOGLEVEL" , "LOG_LEVEL" , "LOGLEVEL" ]
230+ LogLevel .INFO ,
231+ validation_alias = AliasChoices ("AUTOSCALING_LOGLEVEL" , "LOG_LEVEL" , "LOGLEVEL" ),
227232 )
228233 AUTOSCALING_LOG_FORMAT_LOCAL_DEV_ENABLED : bool = Field (
229234 default = False ,
230- env = [
235+ validation_alias = AliasChoices (
231236 "AUTOSCALING_LOG_FORMAT_LOCAL_DEV_ENABLED" ,
232237 "LOG_FORMAT_LOCAL_DEV_ENABLED" ,
233- ] ,
238+ ) ,
234239 description = "Enables local development log format. WARNING: make sure it is disabled if you want to have structured logs!" ,
235240 )
236241
237242 AUTOSCALING_EC2_ACCESS : AutoscalingEC2Settings | None = Field (
238- auto_default_from_env = True
243+ json_schema_extra = { "auto_default_from_env" : True }
239244 )
240245
241246 AUTOSCALING_SSM_ACCESS : AutoscalingSSMSettings | None = Field (
242- auto_default_from_env = True
247+ json_schema_extra = { "auto_default_from_env" : True }
243248 )
244249
245250 AUTOSCALING_EC2_INSTANCES : EC2InstancesSettings | None = Field (
246- auto_default_from_env = True
251+ json_schema_extra = { "auto_default_from_env" : True }
247252 )
248253
249254 AUTOSCALING_NODES_MONITORING : NodesMonitoringSettings | None = Field (
250- auto_default_from_env = True
255+ json_schema_extra = { "auto_default_from_env" : True }
251256 )
252257
253258 AUTOSCALING_POLL_INTERVAL : datetime .timedelta = Field (
@@ -256,13 +261,21 @@ class ApplicationSettings(BaseCustomSettings, MixinLoggingSettings):
256261 "(default to seconds, or see https://pydantic-docs.helpmanual.io/usage/types/#datetime-types for string formating)" ,
257262 )
258263
259- AUTOSCALING_RABBITMQ : RabbitSettings | None = Field (auto_default_from_env = True )
264+ AUTOSCALING_RABBITMQ : RabbitSettings | None = Field (
265+ json_schema_extra = {"auto_default_from_env" : True }
266+ )
260267
261- AUTOSCALING_REDIS : RedisSettings = Field (auto_default_from_env = True )
268+ AUTOSCALING_REDIS : RedisSettings = Field (
269+ json_schema_extra = {"auto_default_from_env" : True }
270+ )
262271
263- AUTOSCALING_REGISTRY : RegistrySettings | None = Field (auto_default_from_env = True )
272+ AUTOSCALING_REGISTRY : RegistrySettings | None = Field (
273+ json_schema_extra = {"auto_default_from_env" : True }
274+ )
264275
265- AUTOSCALING_DASK : DaskMonitoringSettings | None = Field (auto_default_from_env = True )
276+ AUTOSCALING_DASK : DaskMonitoringSettings | None = Field (
277+ json_schema_extra = {"auto_default_from_env" : True }
278+ )
266279
267280 AUTOSCALING_PROMETHEUS_INSTRUMENTATION_ENABLED : bool = True
268281
@@ -273,7 +286,8 @@ class ApplicationSettings(BaseCustomSettings, MixinLoggingSettings):
273286 "but a docker node label named osparc-services-ready is attached" ,
274287 )
275288 AUTOSCALING_TRACING : TracingSettings | None = Field (
276- auto_default_from_env = True , description = "settings for opentelemetry tracing"
289+ description = "settings for opentelemetry tracing" ,
290+ json_schema_extra = {"auto_default_from_env" : True },
277291 )
278292
279293 AUTOSCALING_DOCKER_JOIN_DRAINED : bool = Field (
@@ -291,21 +305,20 @@ class ApplicationSettings(BaseCustomSettings, MixinLoggingSettings):
291305 def LOG_LEVEL (self ): # noqa: N802
292306 return self .AUTOSCALING_LOGLEVEL
293307
294- @validator ("AUTOSCALING_LOGLEVEL" )
308+ @field_validator ("AUTOSCALING_LOGLEVEL" )
295309 @classmethod
296310 def valid_log_level (cls , value : str ) -> str :
297311 return cls .validate_log_level (value )
298312
299- @root_validator ()
300- @classmethod
301- def exclude_both_dynamic_computational_mode (cls , values ):
313+ @model_validator (mode = "after" )
314+ def exclude_both_dynamic_computational_mode (self , v ):
302315 if (
303- values . get ( " AUTOSCALING_DASK" ) is not None
304- and values . get ( " AUTOSCALING_NODES_MONITORING" ) is not None
316+ v . AUTOSCALING_DASK is not None
317+ and v . AUTOSCALING_NODES_MONITORING is not None
305318 ):
306319 msg = "Autoscaling cannot be set to monitor both computational and dynamic services (both AUTOSCALING_DASK and AUTOSCALING_NODES_MONITORING are currently set!)"
307320 raise ValueError (msg )
308- return values
321+ return v
309322
310323
311324def get_application_settings (app : FastAPI ) -> ApplicationSettings :
0 commit comments