Skip to content

Top-level CLI alias for nested model #623

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

Open
maxnoe opened this issue May 26, 2025 · 4 comments
Open

Top-level CLI alias for nested model #623

maxnoe opened this issue May 26, 2025 · 4 comments
Assignees

Comments

@maxnoe
Copy link

maxnoe commented May 26, 2025

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.

@hramezani
Copy link
Member

Thanks @maxnoe for this issue.

@kschwab Do you have time to check this issue?

@maxnoe
Copy link
Author

maxnoe commented May 28, 2025

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"

@karta9821
Copy link
Contributor

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",
        },
    )

@maxnoe
Copy link
Author

maxnoe commented May 28, 2025

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".

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

4 participants