Giter Club home page Giter Club logo

Comments (6)

hramezani avatar hramezani commented on June 19, 2024

Hello @alexdashkov ,

If I understand you correctly, you want to collect first and second with base_prefix_1_ prefix and third with base_prefix_2_ prefix when you initialize the B settings class. right?

from pydantic-settings.

alexdashkov avatar alexdashkov commented on June 19, 2024

Hello @hramezani , Yes, exactly.

from pydantic-settings.

hramezani avatar hramezani commented on June 19, 2024

The correct way to do it is defining alias on Field as you mentioned. There is a dirty way by creating a custom env settings source which I am not suggesting because you will lose the nested and complex model functionality.

BTW, here is the code if you want to use it:

import os
from typing import Any


from pydantic_settings import BaseSettings, EnvSettingsSource, PydanticBaseSettingsSource, SettingsConfigDict
from pydantic.fields import FieldInfo


class CustomEnvSettingsSource(EnvSettingsSource):
    def get_field_value(self, field: FieldInfo, field_name: str) -> tuple[Any, str, bool]:
        if field_name in KubectlSecrets.model_fields:
            env_name = (KubectlSecrets.model_config['env_prefix'] + field_name).lower()
            return self.env_vars.get(env_name), field_name, False
        else:
            return super().get_field_value(field, field_name)


class KubectlSecrets(BaseSettings):
    credentials: str
    google_auth_key: str

    model_config = SettingsConfigDict(env_prefix = "K8S_SECRET_")
        
    @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, CustomEnvSettingsSource(settings_cls), dotenv_settings, file_secret_settings


class Settings(KubectlSecrets):
    environment: str = "development"
    redis_db: str = "0"

    model_config = SettingsConfigDict(env_prefix = "")




os.environ["K8S_SECRET_CREDENTIALS"] = "dummy"
os.environ["K8S_SECRET_GOOGLE_AUTH_KEY"] = "dummy_key"
os.environ["ENVIRONMENT"] = "prod"
os.environ["REDIS_DB"] = "1"

print(Settings())

from pydantic-settings.

alexdashkov avatar alexdashkov commented on June 19, 2024

Thanks for your answer. Indeed it doesn't look like a very scalable code as I'll need to hardcode class name there so with a big chance it will require to add as much code as to put an alias everywhere. Could you also precise what kind of "the nested and complex model functionality" I can lose by using this loader?

from pydantic-settings.

hramezani avatar hramezani commented on June 19, 2024

Thanks for your answer. Indeed it doesn't look like a very scalable code as I'll need to hardcode class name there so with a big chance it will require to add as much code as to put an alias everywhere.

It was just an example, you can implement get_field_value in a clever way to not hardcode the class names.

Could you also precise what kind of "the nested and complex model functionality" I can lose by using this loader?

settings models that have a field with the type of another BaseModel. take a look at the examples on doc

Another simple way is to include kubectl_secrets as a field in the Settings model and do not inherit from KubectlSecrets

import os

from pydantic_settings import BaseSettings, SettingsConfigDict

os.environ["K8S_SECRET_CREDENTIALS"] = "dummy"
os.environ["K8S_SECRET_GOOGLE_AUTH_KEY"] = "dummy_key"
os.environ["ENVIRONMENT"] = "prod"
os.environ["REDIS_DB"] = "1"

class KubectlSecrets(BaseSettings):
    credentials: str
    google_auth_key: str

    model_config = SettingsConfigDict(env_prefix = "K8S_SECRET_")


class Settings(BaseSettings):
    kubectl_secrets: KubectlSecrets = KubectlSecrets()
    environment: str = "development"
    redis_db: str = "0"

    model_config = SettingsConfigDict(env_prefix = "")

print(Settings())

from pydantic-settings.

alexdashkov avatar alexdashkov commented on June 19, 2024

Yup, I was thinking about this implementation, but in my context is not acceptable because it initiates nested classes during the class declaration not the initialisation. In my case I'm passing multiple env files during the initialisation of the settings class.

Anyway, I see a few possible ways to implement the functionality. Thanks for you help!

from pydantic-settings.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.