pydantic-settings
pydantic-settings copied to clipboard
Can my custom PydanticBaseSettingsSource get values already retrieved from other PydanticBaseSettingsSources?
I also opened an SO post FYI: https://stackoverflow.com/questions/78486685/is-it-possible-for-a-custom-pydanticbasesettingssource-to-retrieve-computed-valu
I know the way it generally works is you use the field_name to locate the value, but I want to have a field that is a model with additional data that my custom PydanticBaseSettingsSource will use to retrieve the actual value and I don't think json_schema_extra
would work here because I want to use the actual field value that will be retrieved from the dotenv source.
For example:
config = MyApp(
# I want my custom source to read the input assigned test01 and return the secret value
test01 = ExternalSecret(
id="sdfsdfds", account="sdfsdfsd")
)
And then in settings_customise_sources
@classmethod
def settings_customise_sources(
cls,
settings_cls: Type[BaseSettings],
init_settings: PydanticBaseSettingsSource,
env_settings: PydanticBaseSettingsSource,
dotenv_settings: PydanticBaseSettingsSource,
file_secret_settings: PydanticBaseSettingsSource,
) -> Tuple[PydanticBaseSettingsSource, ...]:
return (
init_settings,
env_settings,
dotenv_settings,
file_secret_settings,
MyCustomSource(settings_cls),
)
I have MyCustomSource run after all the other sources here. Is there a way to, from inside a PydanticBaseSettingsSource, get the currently computed values of a field? Where is that info stored?
I'm assuming that you continuously clobbler/re-write a fields value for each source, but maybe it doesn't work that way? What I'm trying to do I guess might be impossible if you process all sources and then set the value a single time instead of continuously re-assigning it.
What would also work for me would be a post-processor method that just runs at the end of all sources that could loop over all the fields, get their values, and reassign some of the fields values. Is there such a method?
I just found out about pydantic_init_subclass, but I don't know how to get the field values inside of it. This just gives me the field names:
@classmethod
def __pydantic_init_subclass__(cls):
for field_name, field in cls.model_fields.items():
Edit
So just found out about this method, is this the best way to implement what I want? Not using a custom source at all and just looping over all the fields like this?
def model_post_init(self, __context) -> None:
for field_name, field_value in self:
print(field_name)
print(field_value)