Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create default templates (feature request) #287

Open
A-Telfer opened this issue May 11, 2024 · 6 comments
Open

Create default templates (feature request) #287

A-Telfer opened this issue May 11, 2024 · 6 comments
Assignees

Comments

@A-Telfer
Copy link

A-Telfer commented May 11, 2024

Since a big part of pydantic-settings is accepting options from different sources (secrets, env, dotenv, json, yaml...) it would be nice if there were a way to also generate template files for them

Use example

There should be a way to separate Secret, SecretStr, and SecretBytes

from pydantic import Field, SecretStr, BaseModel
from pydantic_settings import BaseSettings
from typing import List

# Using a nested BaseSettings as there's no way to pass env variables to list items with BaseModels
class NestedSetting(BaseSettings):
    url: str
    password: SecretStr

class NestedModel(BaseModel):
    password: SecretStr 

class Sources(BaseSettings):
    whatever: int
    nested_settings: List[NestedSetting] = Field(default_factory=list)
    nested_model: NestedModel

config = Sources(
    whatever=1, 
    nested_settings =[
        {'url': 'a', 'password': 'b'}, 
        {'url': 'c', 'password': 'd'}
    ],
    nested_model = {'password': 'abc'}
)

then

config.template(secrets=False, format='dict')
{'whatever': 1, 'nested_settings': [{'url': 'a'}, {'url': 'a'}]

For secrets

config.template(only_secrets=True, format='env')
{"password": "*********", "nested_model__pasword": "***********"}
@hramezani
Copy link
Member

Thanks @A-Telfer for this feature request. Agree, this would be a great addition. I am thinking about implementing a method on each sources like get_template, and the method returns data structure for that specific source.

@sotte
Copy link

sotte commented May 26, 2024

I just closed #292 as duplicate of this ticket.

Knowing the name of a field (in #292 I was mostly interested in the representation as env var, but the same holds for any other representation) is quite useful. No more reading all the models and options to mentally compile / reconstruct the name of the field I'm interested in.

(I personal don't think of this feature as "templates", but naming is hard 🤷 )

Thinking out loud: template() should probably be a class method so that I don't need an instance of a config but can just get the structure/template based on the root class.

@A-Telfer
Copy link
Author

A-Telfer commented Jul 15, 2024

Just curious any updates on this @hramezani ? I might take a crack at the get_template idea

@hramezani
Copy link
Member

@A-Telfer it would be great!

@MarcBresson
Copy link

For format that supports it, we could have comments that include the type and the docstring

from pydantic import Field, SecretStr, BaseModel
from pydantic_settings import BaseSettings, SettingsConfigDict
from typing import List

class NestedSetting(BaseSettings):
    model_config = SettingsConfigDict(env_prefix="foo_")

    url: str
    """the nested setting URL."""

    password: SecretStr

# I think a class method would make more sense
template = NestedSetting.template(format="env")
print(template)
# FOO_URL: str
# the nested setting URL.
FOO_URL=

# FOO_PASSWORD: secret str
FOO_PASSWORD=

@braindevices
Copy link

braindevices commented Dec 4, 2024

At least for dot env or markdown document, there are existing project:
related project https://github.com/radeklat/settings-doc

I don't think there is well defined template for every config format we support, if we consider the env_prefix, alias, etc.

As long as there is no required field, for json, toml, yaml, one can simply do Settings().model_dump(...) then serialize to the format one wanted.

for json, there is no comment, for toml and yaml we can add some help message in the comment.

  • However, pyYAML does not allow us serialize with comment. One have to use ruamel.yaml.
  • the stdlib toml does not allow us add comment to toml file neither. one have to use tomlkit

If we decide to move to ruamel.yaml and tomlkit. Then one possible way is to mimic the CliSettingsSource._help_format() in all the Source, then create the comment per field during serialization.

if there is required field, then there is no real good way to generate valid template unless one provide some valid and meaningful values for them.

I don't think it is a good idea to make this repo depends on ruamel.yaml and tomlkit. So I really doubt this will be something we want to deal with in this repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants