Skip to content

Support additional parameter names (single-dash, etc) #11

@gusutabopb

Description

@gusutabopb

It'd be great to be able to use single-dash parameter names (as well as alternative names) as natively supported by click/argparse. Here's an example from click's documentation:

@click.command()
@click.option('-s', '--string-to-echo', 'string')
def echo(string):
    click.echo(string)

In clidantic, this would mean being able to achieve something like:

Usage: mycli.py [OPTIONS]

Options:
  -n, --name, --old-name TEXT  [required]
  -c, --count INTEGER          [required]
  --help                       Show this message and exit.

Given a model such as:

class Config(BaseModel):
    name: str
    count: int

Implementation idea

I'm not sure this is an approach you'd like, but it can be achieved by exploiting pydantic's FieldInfo's extra attribute to attach arbitrary metadata to the field:

class Config(BaseModel):
    name: str = Field(cli={"names": ("-n", "--old-name")})
    count: int = Field(cli={"names": ("-c",)})

Besides some type annotation changes (Tuple[str, str] to Tuple[str, ...]), this can be achieved by changing just two lines in param_from_field

def param_from_field(
     # example.test-attribute
     base_option_name = delimiter.join(parent_path + (kebab_name,))
     full_option_name = f"--{base_option_name}"
+    extra_names = field.field_info.extra.get("cli", {}).get("names", ())
     # Early out of non-boolean fields
     if field.outer_type_ is bool:
         full_disable_flag = delimiter.join(parent_path + (f"no-{kebab_name}",))
         full_option_name += f"/--{full_disable_flag}"
     # example.test-attribute -> example__test_attribute
     identifier = base_option_name.replace(delimiter, internal_delimiter).replace("-", "_")
-    return identifier, full_option_name
+    return identifier, full_option_name, *extra_names

Here's a full working example: gusutabopb@67847df

Further extension

The cli dictionary in FieldInfo.extra can also be expanded in the future to allow users further customizing how to map Pydantic fields to CLI parameters (in ways not covered by Pydantic's native fields). In that case, it might be a good idea to make that a Pydantic model for validation purposes (but that's beyond the scope of this issue).

PS: Thanks for the great library!

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions