Top-level CLI alias for nested model
maxnoe opened this issue · comments
We are looking to replace traitlets.config with pydantic_settings and one feature we are missing that is important to us is the ability to define short, top-level command line options for things that are defined deeper in the hierarchy.
E.g. consider:
from pydantic_settings import BaseSettings, CliApp
class SubSettings(BaseSettings):
option: str = "foo"
class Settings(BaseSettings):
sub: SubSettings
def cli_cmd(self) -> None:
print(self.model_dump())
CliApp.run(Settings)In this example, I'd like to expose --sub.option just as --option, e.g. by defining an alias mapping.
Looking at the code, maybe adding a field cli_aliases to the SettingsConfigDict would be a way here?
So that the code would look like this:
from pydantic_settings import BaseSettings, CliApp, SettingsConfigDict
class SubSettings(BaseSettings):
option: str = "foo"
class Settings(BaseSettings):
sub: SubSettings = SubSettings()
model_config = SettingsConfigDict(
cli_aliases={
"alias": "sub.option",
},
)
def cli_cmd(self) -> None:
print(self.model_dump())
CliApp.run(Settings)And then python example.py --alias="bar" would set sub.option="bar"
It should rather be:
model_config = SettingsConfigDict(
cli_aliases={
"sub.option": "alias",
},
)What is the expected behavior in the following case?
from pydantic_settings import BaseSettings, CliApp, SettingsConfigDict
from pydantic import Field
class SubSettings(BaseSettings):
option: str = "foo"
class Settings(BaseSettings):
sub: SubSettings = SubSettings()
option: str = "bar"
option2: str = Field("foobar", alias="option")
model_config = SettingsConfigDict(
cli_aliases={
"sub.option": "option",
},
)Making the mapping from the alias to the options trivially prevents duplicated alias definitions, so I found that the more natural mapping.
Concerning your example, I'd say raise an error like "Settings.option conflicts with cli_alias definition option: sub.optoin".
Fixed in 180e74e