Skip to content

Add support for custom parameter types #77

Description

@ananis25

I want to extend the CLI app with custom data types not supported by Typer/Click. Right now, the Typer app raises an error on encountering an unsupported type.

The solution you would like

We could add a method to the Typer object to register custom data types along with a function to convert terminal input string to an object of the desired type.

A possible API could be:

app = typer.Typer()
app.register_custom_type(_type, _deserializer)

Here is the monkey-patched solution I use right now without providing a registration API. If this seems like a useful feature, I'll try refine this and submit a PR.

import datetime
from typing import Any, Callable, Optional

import typer
import click


_get_click_type = typer.main.get_click_type
REGISTERED_TYPES = {
    datetime.date: lambda string: datetime.datetime.strptime(string, '%Y-%m-%d').date()
}

class TyperCustomParam(click.ParamType):
    name = 'CustomParameter'
    def __init__(self, typ: type, deserializer: Optional[Callable] = None): 
        self.name = typ.__name__
        self._deserializer = typ if deserializer is None else deserializer

    def convert(self, value, param, ctx): 
        try:
            return self._deserializer(value)
        except Exception as E: 
            self.fail(
                f"couldn't serialize {value} to an instance of type {self.name}, error: {E}"
            )

def supersede_get_click_type(
    *, annotation: Any, parameter_info: typer.main.ParameterInfo
) -> click.ParamType:
    if annotation in REGISTERED_TYPES:
        return TyperCustomParam(annotation, REGISTERED_TYPES[annotation])
    else:
        return _get_click_type(annotation=annotation, parameter_info=parameter_info)

typer.main.get_click_type = supersede_get_click_type

Alternatives

Alternatives would be to either modify the original routine or create a wrapper function to accept a Click supported datatype and convert later. Letting users create custom types directly is preferred since that lets us create CLIs without touching existing code.

Thank you for looking into this. Similar to FastAPI, typer is a really nice library.

Metadata

Metadata

Assignees

No one assigned

    Labels

    answeredfeatureNew feature, enhancement or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions