Skip to content

Commit

Permalink
feat: cast single required field in model to click argument
Browse files Browse the repository at this point in the history
  • Loading branch information
A.Shpak committed Nov 15, 2022
1 parent 005464a commit 6e78b40
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 23 deletions.
76 changes: 55 additions & 21 deletions makeqr/cli_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import click
from click.decorators import FC
from pydantic import BaseModel, ValidationError
from pydantic.fields import ModelField

from makeqr import (
VERSION,
Expand Down Expand Up @@ -40,7 +41,10 @@
)


class FieldExtraClickOptionsModel(BaseModel, arbitrary_types_allowed=True):
class FieldExtraClickOptionsModel(
BaseModel,
arbitrary_types_allowed=True,
):
click_option_type: click.types.ParamType = click.types.STRING
click_option_multiple: bool = False

Expand All @@ -52,6 +56,22 @@ def _make_command_name(
return command_name.lower().split("qr")[1]


def _get_from_model_argument_name(
model_cls: Type[QRDataModelType],
) -> Any:
argument_name = None
for name, model_field in model_cls.__fields__.items():
click_extras = FieldExtraClickOptionsModel.parse_obj(
model_field.field_info.extra
)
model_field: ModelField
if model_field.required is True and click_extras.click_option_multiple is False:
if argument_name is not None:
return None
argument_name = name
return argument_name


def _echo_qr(
verbose: bool,
qr: MakeQR,
Expand All @@ -66,36 +86,50 @@ def _echo_qr(
click.echo(nl=True)


def _make_click_argument(
name: str,
model_field: ModelField,
) -> Callable:
click_extras = FieldExtraClickOptionsModel.parse_obj(
model_field.field_info.extra
)
return click.argument(
name,
type=click_extras.click_option_type,
default=model_field.default,
required=model_field.required,
)


def _make_click_options_from_model(
model_cls: Type[QRDataModelType],
) -> List[Callable[[FC], FC]]:
options = []
fields = model_cls.__fields__
params = []
argument_name = _get_from_model_argument_name(model_cls)

if len(fields) == 1:
name = list(fields.keys())[0]
model_field = fields[name]
click_extras = FieldExtraClickOptionsModel.parse_obj(
model_field.field_info.extra
)
options.append(
click.argument(
name,
type=click_extras.click_option_type,
default=model_field.default,
required=model_field.required,
for name, model_field in model_cls.__fields__.items():

if argument_name == name:
click_extras = FieldExtraClickOptionsModel.parse_obj(
model_field.field_info.extra
)
)
return options
params.append(
click.argument(
name,
type=click_extras.click_option_type,
default=model_field.default,
required=model_field.required,
)
)
continue

for name, model_field in model_cls.__fields__.items():
click_extras = FieldExtraClickOptionsModel.parse_obj(
model_field.field_info.extra
)
option_help = (
model_field.field_info.description or model_field.name.capitalize()
)
options.append(
params.append(
click.option(
f"-{model_field.alias}",
f"--{name}",
Expand All @@ -107,8 +141,8 @@ def _make_click_options_from_model(
multiple=click_extras.click_option_multiple,
)
)
options.reverse()
return options
params.reverse()
return params


def _echo(
Expand Down
2 changes: 0 additions & 2 deletions makeqr/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ class QRSMSModel(
_QRDataBaseModel,
):
recipients: Tuple[str, ...] = Field(
[],
alias="r",
click_option_multiple=True,
)
Expand All @@ -145,7 +144,6 @@ class QRTelModel(
_QRDataBaseModel,
):
tel: str = Field(
False,
description="Telephone number",
alias="t",
)
Expand Down

0 comments on commit 6e78b40

Please sign in to comment.