Reference

django_typer

    ___ _                           _____
   /   (_) __ _ _ __   __ _  ___   /__   \_   _ _ __   ___ _ __
  / /\ / |/ _` | '_ \ / _` |/ _ \    / /\/ | | | '_ \ / _ \ '__|
 / /_//| | (_| | | | | (_| | (_) |  / /  | |_| | |_) |  __/ |
/___,'_/ |\__,_|_| |_|\__, |\___/   \/    \__, | .__/ \___|_|
     |__/             |___/               |___/|_|

django-typer provides an extension class, TyperCommand, to the BaseCommand class that melds the Typer/click infrastructure with the Django infrastructure. The result is all the ease of specifying commands, groups and options and arguments using Typer and click in a way that feels like and is interface compatible with Django’s BaseCommand This should enable a smooth transition for existing Django commands and an intuitive feel for implementing new commands.

django-typer also supports shell completion for bash, zsh, fish and powershell and extends that support to native Django management commands as well.

The goal of django-typer is to provide full Typer style functionality while maintaining compatibility with the Django management command system. This means that the BaseCommand interface is preserved and the Typer interface is added on top of it. This means that this code base is more robust to changes in the Django management command system - because most of the base class functionality is preserved but many Typer and click internals are used directly to achieve this. We rely on robust CI to catch breaking changes upstream and keep a tight version lock on Typer.

class django_typer.management.BoundProxy(command: TyperCommand, proxied: Typer[P, R] | CommandInfo | TyperInfo | Callable[[...], Any])

Bases: Generic[P, R]

A helper class that proxies the Typer or command objects and binds them to the django command instance.

class django_typer.management.DTCommand(*args, callback: Callable[[...], Any] | None, params: List[Parameter] | None = None, **kwargs: Any)

Bases: DjangoTyperMixin, TyperCommand

This class extends the TyperCommand class to work with the django-typer interfaces. If you need to add functionality to the command class - you should inherit from this class. You can then pass your custom class to the command() decorators using the cls parameter.

from django_typer import TyperCommand, DTCommand, command

class CustomCommand(DTCommand):
    ...

class Command(TyperCommand):

    @command(cls=CustomCommand)
    def handle(self):
        ...

See click commands api for more information.

class django_typer.management.DTGroup(*args, **kwargs)

Bases: DjangoTyperMixin, TyperGroup

This class extends the TyperGroup class to work with the django-typer interfaces. If you need to add functionality to the group class you should inherit from this class. You can then pass your custom class to the command() decorators using the cls parameter.

from django_typer import TyperCommand, DTGroup, group

class CustomGroup(DTGroup):
    ...

class Command(TyperCommand):

    @group(cls=CustomGroup)
    def grp(self):
        ...

See click docs on custom groups and advanced patterns for more information.

list_commands(ctx: Context) List[str]

Do our best to list commands in definition order.

property name: str | None
class django_typer.management.DjangoTyperMixin(*args, callback: Callable[[...], Any] | None, params: List[Parameter] | None = None, **kwargs: Any)

Bases: object

A mixin we use to add additional needed contextual awareness to click Commands and Groups.

class Converter

Bases: object

Because of the way the BaseCommand forces parsing to be done in a separate first step, type casting of input strings to the correct types will have sometimes happened already. We use this class to avoid double type casting.

An alternative approach might be to flag converted values - but there does not seem to be a good approach to do this given how deep in the click infrastructure the conversion happens.

common_params() Sequence[Argument | Option]

Add the common parameters to this group only if this group is the root command’s user specified initialize callback.

context_class

alias of Context

get_params(ctx: Context) List[Parameter]

We override get_params to check to make sure that prompt_required is not set for parameters that have already been prompted for during the initial parse phase. We have to do this because of we’re stuffing the click infrastructure into the django infrastructure and the django infrastructure forces a two step parse process whereas click does not easily support separating these.

There may be a more sound approach than this?

property no_callback: bool

Returns false if no callback was registered at the root django command.

shell_complete(ctx: Context, incomplete: str) List[CompletionItem]

By default if the incomplete string is a space and there are no completions the click infrastructure will return _files. We’d rather return parameters for the command if there are any available.

django_typer.management.callback(name: str | None = <typer.models.DefaultPlaceholder object>, *, cls: ~typing.Type[~django_typer.management.DTGroup] = <class 'django_typer.management.DTGroup'>, invoke_without_command: bool = <typer.models.DefaultPlaceholder object>, no_args_is_help: bool = <typer.models.DefaultPlaceholder object>, subcommand_metavar: str | None = <typer.models.DefaultPlaceholder object>, chain: bool = <typer.models.DefaultPlaceholder object>, result_callback: ~typing.Callable[[...], ~typing.Any] | None = <typer.models.DefaultPlaceholder object>, context_settings: ~typing.Dict[~typing.Any, ~typing.Any] | None = <typer.models.DefaultPlaceholder object>, help: str | ~django.utils.functional.Promise | None = <typer.models.DefaultPlaceholder object>, epilog: str | None = <typer.models.DefaultPlaceholder object>, short_help: str | ~django.utils.functional.Promise | None = <typer.models.DefaultPlaceholder object>, options_metavar: str = <typer.models.DefaultPlaceholder object>, add_help_option: bool = <typer.models.DefaultPlaceholder object>, hidden: bool = <typer.models.DefaultPlaceholder object>, deprecated: bool = <typer.models.DefaultPlaceholder object>, rich_help_panel: str | None = <typer.models.DefaultPlaceholder object>, **kwargs: ~typing.Any) Callable[[Callable[[P2], R2]], Callable[[P2], R2]]

A function decorator that creates a Typer callback. This decorator wraps the Typer.callback() functionality. We’ve renamed it to initialize() because callback() is to general and not intuitive. Callbacks in Typer are functions that are invoked before a command is invoked and that can accept their own arguments. When an initialize() function is supplied to a django TyperCommand the default Django options will be added as parameters. You can specify these parameters (see django_typer.types) as arguments on the wrapped function if you wish to receive them - otherwise they will be intercepted by the base class infrastructure and used to their purpose.

The parameters are passed through to Typer.callback()

For example the below command defines two subcommands that both have a common initializer that accepts a –precision parameter option:

management/commands/math.py
 1import typing as t
 2from typer import Argument, Option
 3from django_typer import TyperCommand, initialize, command
 4
 5
 6class Command(TyperCommand):
 7
 8    precision = 2
 9
10    @initialize(help="Do some math at the given precision.")
11    def init(
12        self,
13        precision: t.Annotated[
14            int, Option(help="The number of decimal places to output.")
15        ] = precision,
16    ):
17        self.precision = precision
18
19    @command(help="Multiply the given numbers.")
20    def multiply(
21        self,
22        numbers: t.Annotated[
23            t.List[float], Argument(help="The numbers to multiply")
24        ],
25    ):
26        ...
27
28    @command()
29    def divide(
30        self,
31        numerator: t.Annotated[float, Argument(help="The numerator")],
32        denominator: t.Annotated[float, Argument(help="The denominator")]
33    ):
34        ...

When we run, the command we should provide the –precision option before the subcommand:

$ ./manage.py math --precision 5 multiply 2 2.333
4.66600
Parameters:
  • name – the name of the callback (defaults to the name of the decorated function)

  • cls – the command class to use - (the initialize() function is technically the root command group)

  • invoke_without_command – whether to invoke the callback if no command was specified.

  • no_args_is_help – whether to show the help if no arguments are provided

  • subcommand_metavar – the metavar to use for subcommands in the help output

  • chain – whether to chain commands, this allows multiple commands from the group to be specified and run in order sequentially in one call from the command line.

  • result_callback – a callback to invoke with the result of the command

  • context_settings – the click context settings to use - see click docs.

  • help – the help string to use, defaults to the function docstring, if you need to translate the help you should use the help kwarg instead because docstrings will not be translated.

  • epilog – the epilog to use in the help output

  • short_help – the short help to use in the help output

  • options_metavar – the metavar to use for options in the help output

  • add_help_option – whether to add the help option to the command

  • hidden – whether to hide this group from the help output

  • deprecated – show a deprecation warning

  • rich_help_panel – the rich help panel to use - if rich is installed this can be used to group commands into panels in the help output.

django_typer.management.command(name: str | None = None, *, cls: ~typing.Type[~django_typer.management.DTCommand] = <class 'django_typer.management.DTCommand'>, context_settings: ~typing.Dict[~typing.Any, ~typing.Any] | None = None, help: str | ~django.utils.functional.Promise | None = None, epilog: str | None = None, short_help: str | ~django.utils.functional.Promise | None = None, options_metavar: str = '[OPTIONS]', add_help_option: bool = True, no_args_is_help: bool = False, hidden: bool = False, deprecated: bool = False, rich_help_panel: str | None = <typer.models.DefaultPlaceholder object>, **kwargs: ~typing.Any) Callable[[Callable[[P], R]], Callable[[P], R]]

A function decorator that creates a new command and attaches it to the root command group. This is a passthrough to Typer.command() and the options are the same, except we swap the default command class for our wrapper.

We do not need to decorate handle() functions with this decorator, but if we want to pass options upstream to typer we can:

class Command(TyperCommand):

    @command(epilog="This is the epilog for the command.")
    def handle(self):
        ...

We can also use the command decorator to define multiple subcommands:

class Command(TyperCommand):

    @command()
    def command1(self):
        # execute command1 logic here

    @command(name='command2')
    def other_command(self):
        # arguments passed to the decorator are passed to typer and control
        # various aspects of the command, for instance here we've changed the
        # name of the command to 'command2' from 'other_command'

The decorated function is the command function. It may also be invoked directly as a method from an instance of the TyperCommand class, see get_command().

Parameters:
  • name – the name of the command (defaults to the name of the decorated function)

  • cls – the command class to use

  • context_settings

    the context settings to use - see click docs.

  • help – the help string to use, defaults to the function docstring, if you need the help to be translated you should use the help kwarg instead because docstrings will not be translated.

  • epilog – the epilog to use in the help output

  • short_help – the short help to use in the help output

  • options_metavar – the metavar to use for options in the help output

  • add_help_option – whether to add the help option to the command

  • no_args_is_help – whether to show the help if no arguments are provided

  • hidden – whether to hide the command from help output

  • deprecated – show a deprecation warning

  • rich_help_panel – the rich help panel to use - if rich is installed this can be used to group commands into panels in the help output.

django_typer.management.get_command(command_name: str, stdout: IO[str] | None = None, stderr: IO[str] | None = None, no_color: bool = False, force_color: bool = False, **kwargs: Any) BaseCommand
django_typer.management.get_command(command_name: str, cmd_type: Type[C], stdout: IO[str] | None = None, stderr: IO[str] | None = None, no_color: bool = False, force_color: bool = False, **kwargs: Any) C
django_typer.management.get_command(command_name: str, path0: str, *path: str, stdout: IO[str] | None = None, stderr: IO[str] | None = None, no_color: bool = False, force_color: bool = False, **kwargs: Any) MethodType

Get a Django command by its name and instantiate it with the provided options. This will work for subclasses of BaseCommand as well as for TyperCommand subclasses. If subcommands are listed for a TyperCommand, the method that corresponds to the command name will be returned. This method may then be invoked directly. If no subcommands are listed the command instance will be returned.

Using get_command to fetch a command instance and then invoking the instance as a callable is the preferred way to execute TyperCommand commands from code. The arguments and options passed to the __call__ method of the command should be fully resolved to their expected parameter types before being passed to the command. The call_command interface also works, but arguments must be unparsed strings and options may be either strings or resolved parameter types. The following is more efficient than call_command.

basic = get_command('basic')
result = basic(
    arg1,
    arg2,
    arg3=0.5,
    arg4=1
)

Subcommands may be retrieved by passing the subcommand names as additional arguments:

divide = get_command('hierarchy', 'math', 'divide')
result = divide(10, 2)

When fetching an entire TyperCommand (i.e. no group or subcommand path), you may supply the type of the expected TyperCommand as the second argument. This will allow the type system to infer the correct return type:

from myapp.management.commands import Command as Hierarchy
hierarchy: Hierarchy = get_command('hierarchy', Hierarchy)

Note

If get_command fetches a BaseCommand that does not implement __call__ get_command will make the command callable by adding a __call__ method that calls the handle method of the BaseCommand. This allows you to call the command like get_command(“command”)() with confidence.

Parameters:
  • command_name – the name of the command to get

  • path – the path walking down the group/command tree

  • stdout – the stdout stream to use

  • stderr – the stderr stream to use

  • no_color – whether to disable color

  • force_color – whether to force color

  • kwargs – t.Any other parameters to pass through to the command constructor

Raises:
  • ModuleNotFoundError – if the command is not found

  • LookupError – if the subcommand is not found

django_typer.management.group(name: str | None = <typer.models.DefaultPlaceholder object>, cls: ~typing.Type[~django_typer.management.DTGroup] = <class 'django_typer.management.DTGroup'>, invoke_without_command: bool = <typer.models.DefaultPlaceholder object>, no_args_is_help: bool = <typer.models.DefaultPlaceholder object>, subcommand_metavar: str | None = <typer.models.DefaultPlaceholder object>, chain: bool = <typer.models.DefaultPlaceholder object>, result_callback: ~typing.Callable[[...], ~typing.Any] | None = <typer.models.DefaultPlaceholder object>, context_settings: ~typing.Dict[~typing.Any, ~typing.Any] | None = <typer.models.DefaultPlaceholder object>, help: str | ~django.utils.functional.Promise | None = <typer.models.DefaultPlaceholder object>, epilog: str | None = <typer.models.DefaultPlaceholder object>, short_help: str | ~django.utils.functional.Promise | None = <typer.models.DefaultPlaceholder object>, options_metavar: str = <typer.models.DefaultPlaceholder object>, add_help_option: bool = <typer.models.DefaultPlaceholder object>, hidden: bool = <typer.models.DefaultPlaceholder object>, deprecated: bool = <typer.models.DefaultPlaceholder object>, rich_help_panel: str | None = <typer.models.DefaultPlaceholder object>, **kwargs: ~typing.Any) Callable[[Callable[[P], R]], Typer[P, R]]

A function decorator that creates a new subgroup and attaches it to the root command group. This is like creating a new Typer app and adding it to a parent Typer app. The kwargs are passed through to the Typer() constructor. The group() functions work like initialize() functions for their command groups.

management/commands/example.py
from django_typer import TyperCommand, group

class Command(TyperCommand):

    @group()
    def group1(self, flag: bool = False):
        # do group init stuff here

    # to attach a command to the group, use the command() decorator
    # on the group function
    @group1.command()
    def command1(self):
        ...

    # you can also attach subgroups to groups!
    @group1.group()
    def subgroup(self):
        # do subgroup init stuff here

    @subgroup.command()
    def subcommand(self):
        ...

These groups and subcommands can be invoked from the command line like so:

$ ./manage.py example group1 --flag command1
$ ./manage.py example group1 --flag subgroup subcommand
Parameters:
  • name – the name of the group (defaults to the name of the decorated function)

  • cls – the group class to use

  • invoke_without_command – whether to invoke the group callback if no command was specified.

  • no_args_is_help – whether to show the help if no arguments are provided

  • subcommand_metavar – the metavar to use for subcommands in the help output

  • chain – whether to chain commands, this allows multiple commands from the group to be specified and run in order sequentially in one call from the command line.

  • result_callback – a callback to invoke with the result of the command

  • context_settings

    the click context settings to use - see click docs.

  • help – the help string to use, defaults to the function docstring, if you need to translate the help you should use the help kwarg instead because docstrings will not be translated.

  • epilog – the epilog to use in the help output

  • short_help – the short help to use in the help output

  • options_metavar – the metavar to use for options in the help output

  • add_help_option – whether to add the help option to the command

  • hidden – whether to hide this group from the help output

  • deprecated – show a deprecation warning

  • rich_help_panel – the rich help panel to use - if rich is installed this can be used to group commands into panels in the help output.

django_typer.management.initialize(name: str | None = <typer.models.DefaultPlaceholder object>, *, cls: ~typing.Type[~django_typer.management.DTGroup] = <class 'django_typer.management.DTGroup'>, invoke_without_command: bool = <typer.models.DefaultPlaceholder object>, no_args_is_help: bool = <typer.models.DefaultPlaceholder object>, subcommand_metavar: str | None = <typer.models.DefaultPlaceholder object>, chain: bool = <typer.models.DefaultPlaceholder object>, result_callback: ~typing.Callable[[...], ~typing.Any] | None = <typer.models.DefaultPlaceholder object>, context_settings: ~typing.Dict[~typing.Any, ~typing.Any] | None = <typer.models.DefaultPlaceholder object>, help: str | ~django.utils.functional.Promise | None = <typer.models.DefaultPlaceholder object>, epilog: str | None = <typer.models.DefaultPlaceholder object>, short_help: str | ~django.utils.functional.Promise | None = <typer.models.DefaultPlaceholder object>, options_metavar: str = <typer.models.DefaultPlaceholder object>, add_help_option: bool = <typer.models.DefaultPlaceholder object>, hidden: bool = <typer.models.DefaultPlaceholder object>, deprecated: bool = <typer.models.DefaultPlaceholder object>, rich_help_panel: str | None = <typer.models.DefaultPlaceholder object>, **kwargs: ~typing.Any) Callable[[Callable[[P2], R2]], Callable[[P2], R2]]

A function decorator that creates a Typer callback. This decorator wraps the Typer.callback() functionality. We’ve renamed it to initialize() because callback() is to general and not intuitive. Callbacks in Typer are functions that are invoked before a command is invoked and that can accept their own arguments. When an initialize() function is supplied to a django TyperCommand the default Django options will be added as parameters. You can specify these parameters (see django_typer.types) as arguments on the wrapped function if you wish to receive them - otherwise they will be intercepted by the base class infrastructure and used to their purpose.

The parameters are passed through to Typer.callback()

For example the below command defines two subcommands that both have a common initializer that accepts a –precision parameter option:

management/commands/math.py
 1import typing as t
 2from typer import Argument, Option
 3from django_typer import TyperCommand, initialize, command
 4
 5
 6class Command(TyperCommand):
 7
 8    precision = 2
 9
10    @initialize(help="Do some math at the given precision.")
11    def init(
12        self,
13        precision: t.Annotated[
14            int, Option(help="The number of decimal places to output.")
15        ] = precision,
16    ):
17        self.precision = precision
18
19    @command(help="Multiply the given numbers.")
20    def multiply(
21        self,
22        numbers: t.Annotated[
23            t.List[float], Argument(help="The numbers to multiply")
24        ],
25    ):
26        ...
27
28    @command()
29    def divide(
30        self,
31        numerator: t.Annotated[float, Argument(help="The numerator")],
32        denominator: t.Annotated[float, Argument(help="The denominator")]
33    ):
34        ...

When we run, the command we should provide the –precision option before the subcommand:

$ ./manage.py math --precision 5 multiply 2 2.333
4.66600
Parameters:
  • name – the name of the callback (defaults to the name of the decorated function)

  • cls – the command class to use - (the initialize() function is technically the root command group)

  • invoke_without_command – whether to invoke the callback if no command was specified.

  • no_args_is_help – whether to show the help if no arguments are provided

  • subcommand_metavar – the metavar to use for subcommands in the help output

  • chain – whether to chain commands, this allows multiple commands from the group to be specified and run in order sequentially in one call from the command line.

  • result_callback – a callback to invoke with the result of the command

  • context_settings

    the click context settings to use - see click docs.

  • help – the help string to use, defaults to the function docstring, if you need to translate the help you should use the help kwarg instead because docstrings will not be translated.

  • epilog – the epilog to use in the help output

  • short_help – the short help to use in the help output

  • options_metavar – the metavar to use for options in the help output

  • add_help_option – whether to add the help option to the command

  • hidden – whether to hide this group from the help output

  • deprecated – show a deprecation warning

  • rich_help_panel – the rich help panel to use - if rich is installed this can be used to group commands into panels in the help output.

django_typer.management.model_parser_completer(model_or_qry: Type[Model] | QuerySet, lookup_field: str | None = None, case_insensitive: bool = False, help_field: str | None = None, query: Callable[[ModelObjectCompleter, Context, Parameter, str], Q] | None = None, limit: int | None = 50, distinct: bool = True, on_error: Callable[[Type[Model], str, Exception], None] | None = None) Dict[str, Any]

A factory function that returns a dictionary that can be used to specify a parser and completer for a typer.Option or typer.Argument. This is a convenience function that can be used to specify the parser and completer for a model object in one go.

def handle(
    self,
    obj: t.Annotated[
        ModelClass,
        typer.Argument(
            **model_parser_completer(ModelClass, 'field_name'),
            help=_("Fetch objects by their field_names.")
        ),
    ]
):
    ...
Parameters:
  • model_or_qry – the model class or QuerySet to use for lookup

  • lookup_field – the field to use for lookup, by default the primary key

  • case_insensitive – whether to perform case insensitive lookups and completions, default: False

  • help_field – the field to use for help output in completion suggestions, by default no help will be provided

  • query – a callable that will be used to build the query for completions, by default the query will be reasonably determined by the field type

  • limit – the maximum number of completions to return, default: 50

  • distinct – whether to filter out already provided parameters in the completion suggestions, True by default

  • on_error – a callable that will be called if the parser lookup fails to produce a matching object - by default a CommandError will be raised

class django_typer.management.Typer(*args, **kwargs: Any)

Typer adds additional groups of commands by adding Typer apps to parent Typer apps. This class extends the typer.Typer class so that we can add the additional information necessary to attach this app to the root app and other groups specified on the django command.

Parameters:
  • name – the name of the class being created

  • bases – the base classes of the class being created

  • attrs – the attributes of the class being created

  • cls – The class to use as the core typer group wrapper

  • invoke_without_command – whether to invoke the group callback if no command was specified.

  • no_args_is_help – whether to show the help if no arguments are provided

  • subcommand_metavar – the metavar to use for subcommands in the help output

  • chain – whether to chain commands, this allows multiple commands from the group to be specified and run in order sequentially in one call from the command line.

  • result_callback – a callback to invoke with the result of the command

  • context_settings

    the click context settings to use - see click docs.

  • help – the help string to use, defaults to the function docstring, if you need to translate the help you should use the help kwarg instead because docstrings will not be translated.

  • epilog – the epilog to use in the help output

  • short_help – the short help to use in the help output

  • options_metavar – the metavar to use for options in the help output

  • add_help_option – whether to add the help option to the command

  • hidden – whether to hide this group from the help output

  • deprecated – show a deprecation warning

  • rich_markup_mode – the rich markup mode to use - if rich is installed this can be used to enable rich markup or Markdown in the help output. Can be “markdown”, “rich” or None to disable markup rendering.

  • rich_help_panel – the rich help panel to use - if rich is installed this can be used to group commands into panels in the help output.

  • pretty_exceptions_enable – whether to enable pretty exceptions - if rich is installed this can be used to enable pretty exception rendering. This will default to on if the traceback configuration settings installs the rich traceback handler. This allows tracebacks to be configured by the user on a per deployment basis in the settings file. We therefore do not advise hardcoding this value.

  • pretty_exceptions_show_locals – whether to show local variables in pretty exceptions - if rich is installed. This will default to the ‘show_locals’ setting in the traceback configuration setting (on by default). This allows tracebacks to be configured by the user on a per deployment basis in the settings file. We therefore do not advise hardcoding this value.

  • pretty_exceptions_short – whether to show short tracebacks in pretty exceptions - if rich is installed. This will default to the ‘short’ setting in the traceback configuration setting (off by default). This allows tracebacks to be configured by the user on a per deployment basis in the settings file. We therefore do not advise hardcoding this value.

command(name: str | None = None, *, cls: ~typing.Type[~django_typer.management.DTCommand] = <class 'django_typer.management.DTCommand'>, context_settings: ~typing.Dict[~typing.Any, ~typing.Any] | None = None, help: str | ~django.utils.functional.Promise | None = None, epilog: str | None = None, short_help: str | ~django.utils.functional.Promise | None = None, options_metavar: str = '[OPTIONS]', add_help_option: bool = True, no_args_is_help: bool = False, hidden: bool = False, deprecated: bool = False, rich_help_panel: str | None = <typer.models.DefaultPlaceholder object>, **kwargs: ~typing.Any) Callable[[Callable[[P2], R2]], Callable[[P2], R2]]

A function decorator that creates a new command and attaches it to this group. This is a passthrough to Typer.command() and the options are the same, except we swap the default command class for our wrapper.

The decorated function is the command function. It may also be invoked directly as a method from an instance of the django command class.

class Command(TyperCommand):

    @group()
    def group1(self):
        pass

    @group1.command()
    def command1(self):
        # do stuff here

Note

If you need to use a different command class you will need to either inherit from django-typer or make sure yours is interface compatible with our extensions. You shouldn’t need to do this though - if the library does not do something you need it to please submit an issue.

Parameters:
  • name – the name of the command (defaults to the name of the decorated function)

  • cls – the command class to use

  • context_settings

    the context settings to use - see click docs.

  • help – the help string to use, defaults to the function docstring, if you need the help to be translated you should use the help kwarg instead because docstrings will not be translated.

  • epilog – the epilog to use in the help output

  • short_help – the short help to use in the help output

  • options_metavar – the metavar to use for options in the help output

  • add_help_option – whether to add the help option to the command

  • no_args_is_help – whether to show the help if no arguments are provided

  • hidden – whether to hide the command from help output

  • deprecated – show a deprecation warning

  • rich_help_panel – the rich help panel to use - if rich is installed this can be used to group commands into panels in the help output.

group(name: str | None = <typer.models.DefaultPlaceholder object>, cls: ~typing.Type[~django_typer.management.DTGroup] = <class 'django_typer.management.DTGroup'>, invoke_without_command: bool = <typer.models.DefaultPlaceholder object>, no_args_is_help: bool = <typer.models.DefaultPlaceholder object>, subcommand_metavar: str | None = <typer.models.DefaultPlaceholder object>, chain: bool = <typer.models.DefaultPlaceholder object>, result_callback: ~typing.Callable[[...], ~typing.Any] | None = <typer.models.DefaultPlaceholder object>, context_settings: ~typing.Dict[~typing.Any, ~typing.Any] | None = <typer.models.DefaultPlaceholder object>, help: str | ~django.utils.functional.Promise | None = <typer.models.DefaultPlaceholder object>, epilog: str | None = <typer.models.DefaultPlaceholder object>, short_help: str | ~django.utils.functional.Promise | None = <typer.models.DefaultPlaceholder object>, options_metavar: str = <typer.models.DefaultPlaceholder object>, add_help_option: bool = <typer.models.DefaultPlaceholder object>, hidden: bool = <typer.models.DefaultPlaceholder object>, deprecated: bool = <typer.models.DefaultPlaceholder object>, rich_help_panel: str | None = <typer.models.DefaultPlaceholder object>, **kwargs: ~typing.Any) Callable[[Callable[[P2], R2]], Typer[P2, R2]]

Create a new subgroup and attach it to this group. This is like creating a new Typer app and adding it to a parent Typer app. The kwargs are passed through to the Typer() constructor.

class Command(TyperCommand):

    @group()
    def group1(self):
        pass

    @group1.group()
    def subgroup(self):
        # do common group init stuff here

    @subgroup.command(help=_('My command does good stuff!'))
    def subcommand(self):
        # do command stuff here
Parameters:
  • name – the name of the group

  • cls – the group class to use

  • invoke_without_command – whether to invoke the group callback if no command was specified.

  • no_args_is_help – whether to show the help if no arguments are provided

  • subcommand_metavar – the metavar to use for subcommands in the help output

  • chain – whether to chain commands, this allows multiple commands from the group to be specified and run in order sequentially in one call from the command line.

  • result_callback – a callback to invoke with the result of the command

  • context_settings

    the click context settings to use - see click docs.

  • help – the help string to use, defaults to the function docstring, if you need to translate the help you should use the help kwarg instead because docstrings will not be translated.

  • epilog – the epilog to use in the help output

  • short_help – the short help to use in the help output

  • options_metavar – the metavar to use for options in the help output

  • add_help_option – whether to add the help option to the command

  • hidden – whether to hide this group from the help output

  • deprecated – show a deprecation warning

  • rich_help_panel – the rich help panel to use - if rich is installed this can be used to group commands into panels in the help output.

class django_typer.management.TyperCommand(stdout: TextIO | None = None, stderr: TextIO | None = None, no_color: bool = False, force_color: bool = False, **kwargs: Any)

An extension of BaseCommand that uses the Typer library to parse arguments and options. This class adapts BaseCommand using a light touch that relies on most of the original BaseCommand implementation to handle default arguments and behaviors.

All of the documented BaseCommand functionality works as expected. call_command also works as expected. TyperCommands however add a few extra features:

  • We define arguments and options using concise and optionally annotated type hints.

  • Simple TyperCommands implemented only using handle() can be called directly by invoking the command as a callable.

  • We can define arbitrarily complex subcommand group hierarchies using the group() and command() decorators.

  • Commands and subcommands can be fetched and invoked directly as functions using get_command()

  • We can define common initialization logic for groups of commands using initialize()

  • TyperCommands may safely return non-string values from handle()

Defining a typer command is a lot like defining a BaseCommand except that we do not have an add_arguments() method. Instead we define the parameters using type hints directly on handle():

import typing as t
from django_typer import TyperCommand

class Command(TyperCommand):

    def handle(
        self,
        arg: str,
        option: t.Optional[str] = None
    ):
        # do command logic here

TyperCommands can be extremely simple like above, or we can create really complex command group hierarchies with subcommands and subgroups (see group() and command()).

Typer apps can be configured with a number of parameters to control behavior such as exception behavior, help output, help markup interpretation, result processing and execution flow. These parameters can be passed to typer as keyword arguments in your Command class inheritance:

management/commands/chain.py
 1import typing as t
 2from django_typer import TyperCommand, command
 3
 4
 5class Command(TyperCommand, rich_markup_mode='markdown', chain=True):
 6
 7    suppressed_base_arguments = [
 8        '--verbosity', '--traceback', '--no-color', '--force-color',
 9        '--skip_checks', '--settings', '--pythonpath', '--version'
10    ]
11
12    @command()
13    def command1(self, option: t.Optional[str] = None):
14        """This is a *markdown* help string"""
15        print('command1')
16        return option
17
18    @command()
19    def command2(self, option: t.Optional[str] = None):
20        """This is a *markdown* help string"""
21        print('command2')
22        return option

We’re doing a number of things here:

We can see that our help renders like so:

chain Usage: ./manage.py chain [OPTIONS] COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]... ╭─ Options ────────────────────────────────────────────────────────────────────╮ --helpShow this message and exit.                                  ╰──────────────────────────────────────────────────────────────────────────────╯ ╭─ Commands ───────────────────────────────────────────────────────────────────╮ command1 This is a markdown help string                                    command2 This is a markdown help string                                    ╰──────────────────────────────────────────────────────────────────────────────╯

And we can see the chain behavior by calling our command(s) like so:

$ ./manage.py chain command1 --option one command2 --option two
command1
command2
['one', 'two']

See TyperCommandMeta for the list of accepted parameters. Also refer to the Typer docs for more information on the behaviors expected for those parameters - they are passed through to the Typer class constructor. Not all parameters may make sense in the context of a django command.

Parameters:
  • stdout – the stdout stream to use

  • stderr – the stderr stream to use

  • no_color – whether to disable color output

  • force_color – whether to force color output even if the stream is not a tty

classmethod callback(name: str | None = <typer.models.DefaultPlaceholder object>, *, cls: ~typing.Type[~django_typer.management.DTGroup] = <class 'django_typer.management.DTGroup'>, invoke_without_command: bool = <typer.models.DefaultPlaceholder object>, no_args_is_help: bool = <typer.models.DefaultPlaceholder object>, subcommand_metavar: str | None = <typer.models.DefaultPlaceholder object>, chain: bool = <typer.models.DefaultPlaceholder object>, result_callback: ~typing.Callable[[...], ~typing.Any] | None = <typer.models.DefaultPlaceholder object>, context_settings: ~typing.Dict[~typing.Any, ~typing.Any] | None = <typer.models.DefaultPlaceholder object>, help: str | ~django.utils.functional.Promise | None = <typer.models.DefaultPlaceholder object>, epilog: str | None = <typer.models.DefaultPlaceholder object>, short_help: str | ~django.utils.functional.Promise | None = <typer.models.DefaultPlaceholder object>, options_metavar: str = <typer.models.DefaultPlaceholder object>, add_help_option: bool = <typer.models.DefaultPlaceholder object>, hidden: bool = <typer.models.DefaultPlaceholder object>, deprecated: bool = <typer.models.DefaultPlaceholder object>, rich_help_panel: str | None = <typer.models.DefaultPlaceholder object>, **kwargs: ~typing.Any) Callable[[Callable[[P], R]], Callable[[P], R]]

Override the initializer for this command class after it has been defined.

Note

See Tutorial: Inheritance & Plugins for details on when you might want to use this extension pattern.

from your_app.management.commands.your_command import Command as YourCommand

@YourCommand.initialize()
def init(self, ...):
    # implement your command initialization logic here
Parameters:
  • name – the name of the callback (defaults to the name of the decorated function)

  • cls – the command class to use - (the initialize() function is technically the root command group)

  • invoke_without_command – whether to invoke the callback if no command was specified.

  • no_args_is_help – whether to show the help if no arguments are provided

  • subcommand_metavar – the metavar to use for subcommands in the help output

  • chain – whether to chain commands, this allows multiple commands from the group to be specified and run in order sequentially in one call from the command line.

  • result_callback – a callback to invoke with the result of the command

  • context_settings

    the click context settings to use - see click docs.

  • help – the help string to use, defaults to the function docstring, if you need to translate the help you should use the help kwarg instead because docstrings will not be translated.

  • epilog – the epilog to use in the help output

  • short_help – the short help to use in the help output

  • options_metavar – the metavar to use for options in the help output

  • add_help_option – whether to add the help option to the command

  • hidden – whether to hide this group from the help output

  • deprecated – show a deprecation warning

  • rich_help_panel – the rich help panel to use - if rich is installed this can be used to group commands into panels in the help output.

classmethod command(name: str | None = None, *, cls: ~typing.Type[~django_typer.management.DTCommand] = <class 'django_typer.management.DTCommand'>, context_settings: ~typing.Dict[~typing.Any, ~typing.Any] | None = None, help: str | ~django.utils.functional.Promise | None = None, epilog: str | None = None, short_help: str | ~django.utils.functional.Promise | None = None, options_metavar: str = '[OPTIONS]', add_help_option: bool = True, no_args_is_help: bool = False, hidden: bool = False, deprecated: bool = False, rich_help_panel: str | None = <typer.models.DefaultPlaceholder object>, **kwargs: ~typing.Any) Callable[[Callable[[P], R]], Callable[[P], R]]

Add a command to this command class after it has been defined. You can use this decorator to add commands to a root command from other Django apps.

Note

See Tutorial: Inheritance & Plugins for details on when you might want to use this extension pattern.

from your_app.management.commands.your_command import Command as YourCommand

@YourCommand.command()
def new_command(self, ...):
    # implement your additional command here
Parameters:
  • name – the name of the command (defaults to the name of the decorated function)

  • cls – the command class to use

  • context_settings

    the context settings to use - see click docs.

  • help – the help string to use, defaults to the function docstring, if you need the help to be translated you should use the help kwarg instead because docstrings will not be translated.

  • epilog – the epilog to use in the help output

  • short_help – the short help to use in the help output

  • options_metavar – the metavar to use for options in the help output

  • add_help_option – whether to add the help option to the command

  • no_args_is_help – whether to show the help if no arguments are provided

  • hidden – whether to hide the command from help output

  • deprecated – show a deprecation warning

  • rich_help_panel – the rich help panel to use - if rich is installed this can be used to group commands into panels in the help output.

echo(message: Any | None = None, nl: bool = True, err: bool = False)

A wrapper for typer.echo() that response –no-color and –force-color flags, and writes to the command’s stdout.

Parameters:
  • message – The string or bytes to output. Other objects are converted to strings.

  • err – Write to stderr instead of stdout.

  • nl – Print a newline after the message. Enabled by default.

get_subcommand(*command_path: str) CommandNode

Retrieve a CommandNode at the given command path.

Parameters:

command_path – the path to the command to retrieve, where each argument is the string name in order of a group or command in the hierarchy.

Returns:

the command node at the given path

Raises:

LookupError – if no group or command exists at the given path

classmethod group(name: str | None = <typer.models.DefaultPlaceholder object>, cls: ~typing.Type[~django_typer.management.DTGroup] = <class 'django_typer.management.DTGroup'>, invoke_without_command: bool = <typer.models.DefaultPlaceholder object>, no_args_is_help: bool = <typer.models.DefaultPlaceholder object>, subcommand_metavar: str | None = <typer.models.DefaultPlaceholder object>, chain: bool = <typer.models.DefaultPlaceholder object>, result_callback: ~typing.Callable[[...], ~typing.Any] | None = <typer.models.DefaultPlaceholder object>, context_settings: ~typing.Dict[~typing.Any, ~typing.Any] | None = <typer.models.DefaultPlaceholder object>, help: str | ~django.utils.functional.Promise | None = <typer.models.DefaultPlaceholder object>, epilog: str | None = <typer.models.DefaultPlaceholder object>, short_help: str | ~django.utils.functional.Promise | None = <typer.models.DefaultPlaceholder object>, options_metavar: str = <typer.models.DefaultPlaceholder object>, add_help_option: bool = <typer.models.DefaultPlaceholder object>, hidden: bool = <typer.models.DefaultPlaceholder object>, deprecated: bool = <typer.models.DefaultPlaceholder object>, rich_help_panel: str | None = <typer.models.DefaultPlaceholder object>, **kwargs: ~typing.Any) Callable[[Callable[[P], R]], Typer[P, R]]

Add a group to this command class after it has been defined. You can use this decorator to add groups to a root command from other Django apps.

Note

See Tutorial: Inheritance & Plugins for details on when you might want to use this extension pattern.

from your_app.management.commands.your_command import Command as YourCommand

@YourCommand.group()
def new_group(self, ...):
    # implement your group initializer here

@new_group.command()
def grp_command(self, ...):
    # implement group subcommand here
Parameters:
  • name – the name of the group (defaults to the name of the decorated function)

  • cls – the group class to use

  • invoke_without_command – whether to invoke the group callback if no command was specified.

  • no_args_is_help – whether to show the help if no arguments are provided

  • subcommand_metavar – the metavar to use for subcommands in the help output

  • chain – whether to chain commands, this allows multiple commands from the group to be specified and run in order sequentially in one call from the command line.

  • result_callback – a callback to invoke with the result of the command

  • context_settings

    the click context settings to use - see click docs.

  • help – the help string to use, defaults to the function docstring, if you need to translate the help you should use the help kwarg instead because docstrings will not be translated.

  • epilog – the epilog to use in the help output

  • short_help – the short help to use in the help output

  • options_metavar – the metavar to use for options in the help output

  • add_help_option – whether to add the help option to the command

  • hidden – whether to hide this group from the help output

  • deprecated – show a deprecation warning

  • rich_help_panel – the rich help panel to use - if rich is installed this can be used to group commands into panels in the help output.

classmethod initialize(name: str | None = <typer.models.DefaultPlaceholder object>, *, cls: ~typing.Type[~django_typer.management.DTGroup] = <class 'django_typer.management.DTGroup'>, invoke_without_command: bool = <typer.models.DefaultPlaceholder object>, no_args_is_help: bool = <typer.models.DefaultPlaceholder object>, subcommand_metavar: str | None = <typer.models.DefaultPlaceholder object>, chain: bool = <typer.models.DefaultPlaceholder object>, result_callback: ~typing.Callable[[...], ~typing.Any] | None = <typer.models.DefaultPlaceholder object>, context_settings: ~typing.Dict[~typing.Any, ~typing.Any] | None = <typer.models.DefaultPlaceholder object>, help: str | ~django.utils.functional.Promise | None = <typer.models.DefaultPlaceholder object>, epilog: str | None = <typer.models.DefaultPlaceholder object>, short_help: str | ~django.utils.functional.Promise | None = <typer.models.DefaultPlaceholder object>, options_metavar: str = <typer.models.DefaultPlaceholder object>, add_help_option: bool = <typer.models.DefaultPlaceholder object>, hidden: bool = <typer.models.DefaultPlaceholder object>, deprecated: bool = <typer.models.DefaultPlaceholder object>, rich_help_panel: str | None = <typer.models.DefaultPlaceholder object>, **kwargs: ~typing.Any) Callable[[Callable[[P], R]], Callable[[P], R]]

Override the initializer for this command class after it has been defined.

Note

See Tutorial: Inheritance & Plugins for details on when you might want to use this extension pattern.

from your_app.management.commands.your_command import Command as YourCommand

@YourCommand.initialize()
def init(self, ...):
    # implement your command initialization logic here
Parameters:
  • name – the name of the callback (defaults to the name of the decorated function)

  • cls – the command class to use - (the initialize() function is technically the root command group)

  • invoke_without_command – whether to invoke the callback if no command was specified.

  • no_args_is_help – whether to show the help if no arguments are provided

  • subcommand_metavar – the metavar to use for subcommands in the help output

  • chain – whether to chain commands, this allows multiple commands from the group to be specified and run in order sequentially in one call from the command line.

  • result_callback – a callback to invoke with the result of the command

  • context_settings

    the click context settings to use - see click docs.

  • help – the help string to use, defaults to the function docstring, if you need to translate the help you should use the help kwarg instead because docstrings will not be translated.

  • epilog – the epilog to use in the help output

  • short_help – the short help to use in the help output

  • options_metavar – the metavar to use for options in the help output

  • add_help_option – whether to add the help option to the command

  • hidden – whether to hide this group from the help output

  • deprecated – show a deprecation warning

  • rich_help_panel – the rich help panel to use - if rich is installed this can be used to group commands into panels in the help output.

print_help(prog_name: str, subcommand: str, *cmd_path: str)

Print the help message for this command to stdout of the django command.

Parameters:
  • prog_name – the name of the manage script that invoked the command

  • subcommand – the name of the django command

  • cmd_path – the path to the command to print the help for. This is an extension to the pase class print_help() interface, required because typer/click have different helps for each subgroup or subcommand.

secho(message: Any | None = None, nl: bool = True, err: bool = False, **styles: Any)

A wrapper for typer.secho() that response –no-color and –force-color flags, and writes to the command’s stdout.

Parameters:
  • message – The string or bytes to output. Other objects are converted to strings.

  • err – Write to stderr instead of stdout.

  • nl – Print a newline after the message. Enabled by default.

  • styles – Styles to apply to the output

class django_typer.management.CommandNode(name: str, click_command: DjangoTyperMixin, django_command: TyperCommand, parent: Context | None = None)

A tree node that represents a command in the command tree. This is used to walk the click command hierarchy and produce helps and map command paths to command functions. The command tree is built on TyperCommand initialization.

Parameters:
  • name – the name of the command or subcommand

  • click_command – the click command object

  • context – the click context object

  • django_command – the django command instance

  • parent – the parent node or None if this is a root node

property children: Dict[str, CommandNode]

The child group and command nodes of this command node.

click_command: DjangoTyperMixin

The click command object that this node represents.

context: Context

The Typer context object used to run this command.

get_command(*command_path: str) CommandNode

Return the command node for the given command path at or below this node.

Parameters:

command_path – the parent group names followed by the name of the command or group to retrieve

Returns:

the command node at the given group/subcommand path

Raises:

LookupError – if the command path does not exist

name: str

The name of the group or command that this node represents.

print_help() str | None

Prints the help for this command to stdout of the django command.

class django_typer.management.TyperCommandMeta(cls_name, bases, attrs, name: str | None = <typer.models.DefaultPlaceholder object>, cls: ~typing.Type[~django_typer.management.DTGroup] | None = <class 'django_typer.management.DTGroup'>, invoke_without_command: bool = <typer.models.DefaultPlaceholder object>, no_args_is_help: bool = <typer.models.DefaultPlaceholder object>, subcommand_metavar: str | None = <typer.models.DefaultPlaceholder object>, chain: bool = <typer.models.DefaultPlaceholder object>, result_callback: ~typing.Callable[[...], ~typing.Any] | None = <typer.models.DefaultPlaceholder object>, context_settings: ~typing.Dict[~typing.Any, ~typing.Any] | None = <typer.models.DefaultPlaceholder object>, callback: ~typing.Callable[[...], ~typing.Any] | None = <typer.models.DefaultPlaceholder object>, help: str | ~django.utils.functional.Promise | None = <typer.models.DefaultPlaceholder object>, epilog: str | None = <typer.models.DefaultPlaceholder object>, short_help: str | ~django.utils.functional.Promise | None = <typer.models.DefaultPlaceholder object>, options_metavar: str = <typer.models.DefaultPlaceholder object>, add_help_option: bool = <typer.models.DefaultPlaceholder object>, hidden: bool = <typer.models.DefaultPlaceholder object>, deprecated: bool = <typer.models.DefaultPlaceholder object>, rich_markup_mode: ~typing.Literal['markdown', 'rich', None] = <typer.models.DefaultPlaceholder object>, rich_help_panel: str | None = <typer.models.DefaultPlaceholder object>, pretty_exceptions_enable: ~typer.models.DefaultPlaceholder | bool = <typer.models.DefaultPlaceholder object>, pretty_exceptions_show_locals: ~typer.models.DefaultPlaceholder | bool = <typer.models.DefaultPlaceholder object>, pretty_exceptions_short: ~typer.models.DefaultPlaceholder | bool = <typer.models.DefaultPlaceholder object>, **kwargs: ~typing.Any)

The metaclass used to build the TyperCommand class. This metaclass is responsible for building Typer app using the arguments supplied to the TyperCommand constructor. It also discovers if handle() was supplied as the single command implementation.

Warning

This metaclass is private because it may change substantially in the future to support changes in the upstream libraries. The TyperCommand interface should be considered the stable interface.

Parameters:
  • name – the name of the class being created

  • bases – the base classes of the class being created

  • attrs – the attributes of the class being created

  • cls – The class to use as the core typer group wrapper

  • invoke_without_command – whether to invoke the group callback if no command was specified.

  • no_args_is_help – whether to show the help if no arguments are provided

  • subcommand_metavar – the metavar to use for subcommands in the help output

  • chain – whether to chain commands, this allows multiple commands from the group to be specified and run in order sequentially in one call from the command line.

  • result_callback – a callback to invoke with the result of the command

  • context_settings

    the click context settings to use - see click docs.

  • help – the help string to use, defaults to the function docstring, if you need to translate the help you should use the help kwarg instead because docstrings will not be translated.

  • epilog – the epilog to use in the help output

  • short_help – the short help to use in the help output

  • options_metavar – the metavar to use for options in the help output

  • add_help_option – whether to add the help option to the command

  • hidden – whether to hide this group from the help output

  • deprecated – show a deprecation warning

  • rich_markup_mode – the rich markup mode to use - if rich is installed this can be used to enable rich markup or Markdown in the help output. Can be “markdown”, “rich” or None to disable markup rendering.

  • rich_help_panel – the rich help panel to use - if rich is installed this can be used to group commands into panels in the help output.

  • pretty_exceptions_enable – whether to enable pretty exceptions - if rich is installed this can be used to enable pretty exception rendering. This will default to on if the traceback configuration settings installs the rich traceback handler. This allows tracebacks to be configured by the user on a per deployment basis in the settings file. We therefore do not advise hardcoding this value.

  • pretty_exceptions_show_locals – whether to show local variables in pretty exceptions - if rich is installed. This will default to the ‘show_locals’ setting in the traceback configuration setting (on by default). This allows tracebacks to be configured by the user on a per deployment basis in the settings file. We therefore do not advise hardcoding this value.

  • pretty_exceptions_short – whether to show short tracebacks in pretty exceptions - if rich is installed. This will default to the ‘short’ setting in the traceback configuration setting (off by default). This allows tracebacks to be configured by the user on a per deployment basis in the settings file. We therefore do not advise hardcoding this value.

types

Common types for command line argument specification.

django_typer.types.ForceColor

The type hint for the Django –force-color option.

The –force-color option is included by default and behaves the same as on BaseCommand use it to force colorization of the command. You can check the supplied value of –force-color by checking the force_color attribute of the command instance.

alias of Annotated[bool, <typer.models.OptionInfo object at 0x7ff9369d2d20>]

django_typer.types.NoColor

The type hint for the Django –no-color option.

The –no-color option is included by default and behaves the same as on BaseCommand use it to force disable colorization of the command. You can check the supplied value of –no-color by checking the no_color attribute of the command instance.

alias of Annotated[bool, <typer.models.OptionInfo object at 0x7ff9369d2c60>]

django_typer.types.PythonPath

The type hint for the Django –pythonpath option.

The –pythonpath option is included by default and behaves the same as on BaseCommand use it to specify a directory to add to the Python sys path.

alias of Annotated[Path | None, <typer.models.OptionInfo object at 0x7ff9369d2ae0>]

django_typer.types.Settings

The type hint for the Django –settings option.

The –settings option is included by default and behaves the same as on BaseCommand use it to specify or override the settings module to use.

alias of Annotated[str, <typer.models.OptionInfo object at 0x7ff9369d2a20>]

django_typer.types.SkipChecks

The type hint for the Django –skip-checks option.

The –skip-checks option is included by default and behaves the same as on BaseCommand use it to skip system checks.

alias of Annotated[bool, <typer.models.OptionInfo object at 0x7ff9369d2ea0>]

django_typer.types.Traceback

The type hint for the Django –traceback option.

The –traceback option is included by default and behaves the same as on BaseCommand use it to allow CommandError exceptions to propagate out of the command and produce a stack trace.

alias of Annotated[bool, <typer.models.OptionInfo object at 0x7ff9369d2ba0>]

django_typer.types.Verbosity

The type hint for the Django –verbosity option. TyperCommand does not include the verbosity option by default, but it can be added to the command like so if needed.

from django_typer.types import Verbosity

def handle(self, verbosity: Verbosity = 1):
    ...

alias of Annotated[int, <typer.models.OptionInfo object at 0x7ff9369d2900>]

django_typer.types.Version

The type hint for the Django –version option.

The –version option is included by default and behaves the same as on BaseCommand.

alias of Annotated[bool, <typer.models.OptionInfo object at 0x7ff9369d2660>]

django_typer.types.print_version(context, _, value)

A callback to run the get_version() routine of the command when –version is specified.

django_typer.types.set_force_color(context, param, value)

If the value was provided set it on the command.

django_typer.types.set_no_color(context, param, value)

If the value was provided set it on the command.

parsers

Typer supports custom parsers for options and arguments. If you would like to type a parameter with a type that isn’t supported by Typer you can implement your own parser , or ParamType in click parlance.

This module contains a collection of parsers that turn strings into useful Django types. Pass these parsers to the parser argument of typer.Option and typer.Argument. Parsers are provided for:

Warning

If you implement a custom parser, please take care to ensure that it:
  • Handles the case where the value is already the expected type.

  • Returns None if the value is None (already implemented if subclassing ParamType).

  • Raises a CommandError if the value is invalid.

  • Handles the case where the param and context are None.

class django_typer.parsers.ModelObjectParser(model_cls: Type[Model], lookup_field: str | None = None, case_insensitive: bool = False, on_error: Callable[[Type[Model], str, Exception], None] | None = None)

A parser that will turn strings into model object instances based on the configured lookup field and model class.

from django_typer.parsers import ModelObjectParser

class Command(TyperCommand):
    def handle(
        self,
        django_apps: Annotated[
            t.List[MyModel],
            typer.Argument(
                parser=ModelObjectParser(MyModel, lookup_field="name"),
                help=_("One or more application labels."),
            ),
        ],
    ):

Note

Typer does not respect the shell_complete functions on ParamTypes passed as parsers. To add shell_completion see ModelObjectCompleter or the model_parser_completer() convenience function.

Parameters:
  • model_cls – The model class to use for lookup.

  • lookup_field – The field to use for lookup. Defaults to ‘pk’.

  • on_error – A callable that will be called if the lookup fails. The callable should accept three arguments: the model class, the value that failed to lookup, and the exception that was raised. If not provided, a CommandError will be raised.

convert(value: Any, param: Parameter | None, ctx: Context | None)

Invoke the parsing action on the given string. If the value is already a model instance of the expected type the value will be returned. Otherwise the value will be treated as a value to query against the lookup_field. If no model object is found the error handler is invoked if one was provided.

Parameters:
  • value – The value to parse.

  • param – The parameter that the value is associated with.

  • ctx – The context of the command.

Raises:

CommandError – If the lookup fails and no error handler is provided.

django_typer.parsers.parse_app_label(label: str | AppConfig)

A parser for app labels. If the label is already an AppConfig instance, the instance is returned. The label will be tried first, if that fails the label will be treated as the app name.

import typing as t
import typer
from django_typer.management import TyperCommand
from django_typer.parsers import parse_app_label

class Command(TyperCommand):

    def handle(
        self,
        django_apps: t.Annotated[
            t.List[AppConfig],
            typer.Argument(
                parser=parse_app_label,
                help=_("One or more application labels.")
            )
        ]
    ):
        ...
Parameters:

label – The label to map to an AppConfig instance.

Raises:

CommandError – If no matching app can be found.

completers

Typer and click provide tab-completion hooks for individual parameters. As with parsers custom completion logic can be implemented for custom parameter types and added to the annotation of the parameter. Previous versions of Typer supporting click 7 used the autocompletion argument to provide completion logic, Typer still supports this, but passing shell_complete to the annotation is the preferred way to do this.

This module provides some completer functions and classes that work with common Django types:

class django_typer.completers.ModelObjectCompleter(model_or_qry: Type[Model] | QuerySet, lookup_field: str | None = None, help_field: str | None = None, query: Callable[[ModelObjectCompleter, Context, Parameter, str], Q] | None = None, limit: int | None = 50, case_insensitive: bool = False, distinct: bool = True)

A completer for generic Django model objects. This completer will work for most Django core model field types where completion makes sense.

This completer currently supports the following field types and their subclasses:

The completer query logic is pluggable, but the defaults cover most use cases. The limit field is important. It defaults to 50 meaning if more than 50 potential completions are found only the first 50 will be returned and there will be no indication to the user that there are more. This is to prevent the shell from becoming unresponsive when offering completion for large tables.

To use this completer, pass an instance of this class to the shell_complete argument of a typer.Option or typer.Argument:

from django_typer.completers import ModelObjectCompleter

class Command(TyperCommand):

    def handle(
        self,
        model_obj: Annotated[
            MyModel,
            typer.Argument(
                shell_complete=ModelObjectCompleter(MyModel, lookup_field="name"),
                help=_("The model object to use.")
            )
        ]
    ):
        ...

Note

See also model_parser_completer() for a convenience function that returns a configured parser and completer for a model object and helps reduce boilerplate.

Parameters:
  • model_or_qry – The Django model class or a queryset to filter against.

  • lookup_field – The name of the model field to use for lookup.

  • help_field – The name of the model field to use for help text or None if no help text should be provided.

  • query – A callable that accepts the completer object instance, the click context, the click parameter, and the incomplete string and returns a Q object to use for filtering the queryset. The default query will use the relevant class methods depending on the lookup field class. See the query methods for details.

  • limit – The maximum number of completion items to return. If None, all matching items will be returned. When offering completion for large tables you’ll want to set this to a reasonable limit. Default: 50

  • case_insensitive – Whether or not to perform case insensitive matching when completing text-based fields. Defaults to False.

  • distinct – Whether or not to filter out duplicate values. Defaults to True. This is not the same as calling distinct() on the queryset - which will happen regardless - but rather whether or not to filter out values that are already given for the parameter on the command line.

float_query(context: Context, parameter: Parameter, incomplete: str) Q

The default completion query builder for float fields. This method will return a Q object that will match any value that starts with the incomplete string. For example, if the incomplete string is “1.1”, the query will match 1.1 <= float(incomplete) < 1.2

Parameters:
  • context – The click context.

  • parameter – The click parameter.

  • incomplete – The incomplete string.

Returns:

A Q object to use for filtering the queryset.

Raises:
  • ValueError – If the incomplete string is not a valid float.

  • TypeError – If the incomplete string is not a valid float.

int_query(context: Context, parameter: Parameter, incomplete: str) Q

The default completion query builder for integer fields. This method will return a Q object that will match any value that starts with the incomplete string. For example, if the incomplete string is “1”, the query will match 1, 10-19, 100-199, 1000-1999, etc.

Parameters:
  • context – The click context.

  • parameter – The click parameter.

  • incomplete – The incomplete string.

Returns:

A Q object to use for filtering the queryset.

Raises:
  • ValueError – If the incomplete string is not a valid integer.

  • TypeError – If the incomplete string is not a valid integer.

text_query(context: Context, parameter: Parameter, incomplete: str) Q

The default completion query builder for text-based fields. This method will return a Q object that will match any value that starts with the incomplete string. Case sensitivity is determined by the case_insensitive constructor parameter.

Parameters:
  • context – The click context.

  • parameter – The click parameter.

  • incomplete – The incomplete string.

Returns:

A Q object to use for filtering the queryset.

uuid_query(context: Context, parameter: Parameter, incomplete: str) Q

The default completion query builder for UUID fields. This method will return a Q object that will match any value that starts with the incomplete string. The incomplete string will be stripped of all non-alphanumeric characters and padded with zeros to 32 characters. For example, if the incomplete string is “a”, the query will match a0000000-0000-0000-0000-000000000000 to affffffff-ffff-ffff-ffff-ffffffffffff.

Parameters:
  • context – The click context.

  • parameter – The click parameter.

  • incomplete – The incomplete string.

Returns:

A Q object to use for filtering the queryset.

Raises:

ValueError – If the incomplete string is too long or contains invalid UUID characters. Anything other than (0-9a-fA-F).

django_typer.completers.chain(completer: Callable[[Context, Parameter, str], List[CompletionItem]], *completers: Callable[[Context, Parameter, str], List[CompletionItem]], first_match: bool = False, allow_duplicates: bool = False)

Run through the given completers and return the items from the first one, or all of them if first_match is False.

Note

This function is also useful for filtering out previously supplied duplicate values for completers that do not natively support that:

shell_complete=chain(
    complete_import_path,
    allow_duplicates=False
)
Parameters:
  • completer – The first completer to use (must be at least one!)

  • completers – The completers to use

  • first_match – If true, return only the matches from the first completer that finds completions. Default: False

  • allow_duplicates – If False (default) remove completions from previously provided values.

django_typer.completers.commands(allow_duplicates: bool = False)

A completer that completes management command names.

Parameters:

allow_duplicates – Whether or not to allow duplicate values. Defaults to False.

Returns:

A completer function.

django_typer.completers.complete_app_label(ctx: Context, param: Parameter, incomplete: str) List[CompletionItem]

A case-sensitive completer for Django app labels or names. The completer prefers labels but names will also work.

import typing as t
import typer
from django_typer.management import TyperCommand
from django_typer.parsers import parse_app_label
from django_typer.completers import complete_app_label

class Command(TyperCommand):

    def handle(
        self,
        django_apps: t.Annotated[
            t.List[AppConfig],
            typer.Argument(
                parser=parse_app_label,
                shell_complete=complete_app_label,
                help=_("One or more application labels.")
            )
        ]
    ):
        ...
Parameters:
  • ctx – The click context.

  • param – The click parameter.

  • incomplete – The incomplete string.

Returns:

A list of matching app labels or names. Labels already present for the parameter on the command line will be filtered out.

django_typer.completers.complete_directory(ctx: Context, param: Parameter, incomplete: str, *, dir_only: bool | None = True) List[CompletionItem]

A completer that completes a directory path (but not files). Relative incomplete paths are interpreted relative to the current working directory.

Parameters:
  • ctx – The click context.

  • param – The click parameter.

  • incomplete – The incomplete string.

Returns:

A list of available matching directories

django_typer.completers.complete_import_path(ctx: Context, param: Parameter, incomplete: str) List[CompletionItem]

A completer that completes a python dot import path string based on sys.path.

Parameters:
  • ctx – The click context.

  • param – The click parameter.

  • incomplete – The incomplete string.

Returns:

A list of available matching import paths

django_typer.completers.complete_path(ctx: Context, param: Parameter, incomplete: str, dir_only: bool | None = None) List[CompletionItem]

A completer that completes a path. Relative incomplete paths are interpreted relative to the current working directory.

Parameters:
  • ctx – The click context.

  • param – The click parameter.

  • incomplete – The incomplete string.

  • dir_only – Restrict completions to paths to directories only, otherwise complete directories or files.

Returns:

A list of available matching directories

django_typer.completers.databases(allow_duplicates: bool = False)

A completer that completes Django database aliases configured in settings.DATABASES.

Parameters:

allow_duplicates – Whether or not to allow duplicate values. Defaults to False.

Returns:

A completer function.

django_typer.completers.these_strings(strings: Callable[[], Sequence[str] | KeysView[str] | Generator[str, None, None]] | Sequence[str] | KeysView[str] | Generator[str, None, None], allow_duplicates: bool = False)

Get a completer that provides completion logic that matches the allowed strings.

Parameters:
  • strings – A sequence of allowed strings or a callable that generates a sequence of allowed strings.

  • allow_duplicates – Whether or not to allow duplicate values. Defaults to False.

Returns:

A completer function.

utils

A collection of useful utilities.

django_typer.utils.get_current_command() TyperCommand | None

Returns the current typer command. This can be used as a way to access the current command object from anywhere if we are executing inside of one from higher on the stack. We primarily need this because certain monkey patches are required in typer code - namely for enabling/disabling color based on configured parameters.

This function is thread safe.

This is analogous to click’s get_current_context but for command execution.

Returns:

The current typer command or None if there is no active command.

django_typer.utils.is_method(func_or_params: Callable[[...], Any] | List[str] | None) bool | None

This logic is used to to determine if a function should be bound as a method or not. Right now django-typer will treat module scope functions as methods when binding to command classes if they have a first argument named ‘self’.

Parameters:

func – The function to check or a list of parameter names, or None

Returns:

True if the function should be considered a method, False if not and None if undetermined.

django_typer.utils.register_command_plugins(package: ModuleType, commands: List[str] | None = None)

Register a command plugin for the given command within the given package.

For example, use this in your AppConfig’s ready() method:

from django.apps import AppConfig
from django_typer.utils import register_command_plugins


class MyAppConfig(AppConfig):
    name = "myapp"

    def ready(self):
        from .management import plugins

        register_command_plugins(plugins)
Parameters:
  • package – The package the command extension module resides in

  • commands – The names of the commands/modules, if not provided, all modules in the package will be registered as plugins

django_typer.utils.traceback_config() bool | Dict[str, Any]

Fetch the rich traceback installation parameters from our settings. By default rich tracebacks are on with show_locals = True. If the config is set to False or None rich tracebacks will not be installed even if the library is present.

This allows us to have a common traceback configuration for all commands. If rich tracebacks are managed separately this setting can also be switched off.

shellcompletion

The shellcompletion command is a Django management command that installs and removes shellcompletion scripts for supported shells (bash, fish, zsh, powershell). This command is also the entry point for running the completion logic and can be used to debug completer code.

shellcompletion Usage: manage.py shellcompletion [OPTIONS] COMMAND [ARGS]... This command installs autocompletion for the current shell. This command uses  the typer/click autocompletion scripts to generate the autocompletion items,  but monkey patches the scripts to invoke our bundled shell complete script  which fails over to the django autocomplete function when the command being  completed is not a :class:`~django_typer.TyperCommand`. When the django  autocomplete function is used we also wrap it so that it works for any  supported click/typer shell, not just bash. We also provide a remove command to easily remove the installed script. Great pains are taken to use the upstream dependency's shell completion logic. This is so advances and additional shell support implemented upstream should  just work. However, it would be possible to add support for new shells here  using the pluggable logic that click provides. It is probably a better idea  however to add support for new shells at the typer level. Shell autocompletion can be brittle with every shell having its own quirks and nuances. We make a good faith effort here to support all the shells that  typer/click support, but there can easily be system specific configuration  issues that prevent this from working. In those cases users should refer to  the online documentation for their specific shell to troubleshoot. ╭─ Options ────────────────────────────────────────────────────────────────────╮ --helpShow this message and exit. ╰──────────────────────────────────────────────────────────────────────────────╯ ╭─ Django ─────────────────────────────────────────────────────────────────────╮ --settingsTEXTThe Python path to a settings module, e.g.         "myproject.settings.main". If this isn't provided, the DJANGO_SETTINGS_MODULE environment variable    will be used.                                      --pythonpathPATHA directory to add to the Python path, e.g.        "/home/djangoprojects/myproject".                  [default: None]                                    --tracebackRaise on CommandError exceptions ╰──────────────────────────────────────────────────────────────────────────────╯ ╭─ Commands ───────────────────────────────────────────────────────────────────╮ install  Install autocompletion for the current or given shell.            remove   Remove autocompletion for the current or given shell.             complete Generate autocompletion for command string.                       ╰──────────────────────────────────────────────────────────────────────────────╯

install() invokes typer’s shell completion installation logic, but does have to patch the installed scripts. This is because there is only one installation for all Django management commands, not each individual command. The completion logic here will failover to Django’s builtin autocomplete if the command in question is not a TyperCommand. To promote compatibility with other management command libraries or custom completion logic, a fallback completion function can also be specified.

class django_typer.management.commands.shellcompletion.Command(stdout: TextIO | None = None, stderr: TextIO | None = None, no_color: bool = False, force_color: bool = False, **kwargs: Any)

This command installs autocompletion for the current shell. This command uses the typer/click autocompletion scripts to generate the autocompletion items, but monkey patches the scripts to invoke our bundled shell complete script which fails over to the django autocomplete function when the command being completed is not a TyperCommand. When the django autocomplete function is used we also wrap it so that it works for any supported click/typer shell, not just bash.

We also provide a remove command to easily remove the installed script.

Great pains are taken to use the upstream dependency’s shell completion logic. This is so advances and additional shell support implemented upstream should just work. However, it would be possible to add support for new shells here using the pluggable logic that click provides. It is probably a better idea however to add support for new shells at the typer level.

Shell autocompletion can be brittle with every shell having its own quirks and nuances. We make a good faith effort here to support all the shells that typer/click support, but there can easily be system specific configuration issues that prevent this from working. In those cases users should refer to the online documentation for their specific shell to troubleshoot.

complete(cmd_str: ~typing.Annotated[str | None, <typer.models.ArgumentInfo object at 0x7ff933079490>] = None, shell: ~typing.Annotated[~typer._completion_shared.Shells | None, <typer.models.OptionInfo object at 0x7ff933078410>] = None, fallback: ~typing.Annotated[str | None, <typer.models.OptionInfo object at 0x7ff933078c20>] = None)

We implement the shell complete generation script as a Django command because the Django environment needs to be bootstrapped for it to work. This also allows us to test completion logic in a platform agnostic way.

Tip

This command is super useful for debugging shell_complete logic. For example to enter into the debugger, we could set a breakpoint in our shell_complete function for the option parameter and then run the following command:

$ ./manage.py shellcompletion complete "./manage.py your_command --option "
 shellcompletion Usage: shellcompletion [OPTIONS] command Generate autocompletion for command string. ╭─ Arguments ──────────────────────────────────────────────────────────────────╮ cmd_strcommandThe command string to generate completion            suggestions for.                                     [default: None]                                      ╰──────────────────────────────────────────────────────────────────────────────╯ ╭─ Options ────────────────────────────────────────────────────────────────────╮ --shell[bash|zsh|fish|powershell|pSpecify the shell to fetch    wsh]completion for, default will  autodetect.                   [default: None]               --fallbackTEXT                       The python import path to a   fallback complete function to use when the completion       command is not a              TyperCommand. By default, the builtin django autocomplete   function is used.             [default: None]               --helpShow this message and exit. ╰──────────────────────────────────────────────────────────────────────────────╯
django_fallback()

Run django’s builtin bash autocomplete function. We wrap the click completion class to make it work for all supported shells, not just bash.

install(shell: ~typing.Annotated[~typer._completion_shared.Shells | None, <typer.models.ArgumentInfo object at 0x7ff93302d640>] = 'sh', manage_script: ~typing.Annotated[str | None, <typer.models.OptionInfo object at 0x7ff93302f740>] = None, fallback: ~typing.Annotated[str | None, <typer.models.OptionInfo object at 0x7ff93302f650>] = None)

Install autocompletion for the given shell. If the shell is not specified, it will try to detect the shell. If the shell is not detected, it will fail.

We run the upstream typer installation routines, with some augmentation.

shellcompletion install Usage: shellcompletion install [OPTIONS] [SHELL]:[bash|zsh|fish|powershell|pwsh] Install autocompletion for the current or given shell. ╭─ Arguments ───────────────────────────────────────────────────────────────────────╮ shell[SHELL]:[bash|zsh|fish|powershellSpecify the shell to install or   |pwsh]remove autocompletion for.        [default: sh]                     ╰───────────────────────────────────────────────────────────────────────────────────╯ ╭─ Options ─────────────────────────────────────────────────────────────────────────╮ --manage-scriptTEXTThe name of the django manage script to install      autocompletion for if different than the script used to invoke this command.                              [default: None]                                      --fallbackTEXTThe python import path to a fallback complete        function to use when the completion command is not a TyperCommand.                                        [default: None]                                      --helpShow this message and exit. ╰───────────────────────────────────────────────────────────────────────────────────╯
property manage_script: str | Path

Returns the name of the manage command as a string if it is available as a command on the user path. If it is a script that is not available as a command on the path it will return an absolute Path object to the script.

property manage_script_name: str

Get the name of the manage script as a command available from the shell’s path.

noop()

This is a no-op command that is used to bootstrap click Completion classes. It has no use other than to avoid any potential attribute access errors when we spoof completion logic

property noop_command

This is a no-op command that is used to bootstrap click Completion classes. It has no use other than to avoid any potential attribute errors when we emulate upstream completion logic

patch_script(shell: Shells | None = None, fallback: str | None = None) None

We have to monkey patch the typer completion scripts to point to our custom shell complete script. This is potentially brittle but thats why we have robust CI!

Parameters:
  • shell – The shell to patch the completion script for.

  • fallback – The python import path to a fallback autocomplete function to use when the completion command is not a TyperCommand. Defaults to None, which means the bundled complete script will fallback to the django autocomplete function, but wrap it so it works for all supported shells other than just bash.

remove(shell: ~typing.Annotated[~typer._completion_shared.Shells | None, <typer.models.ArgumentInfo object at 0x7ff933079d90>] = 'sh', manage_script: ~typing.Annotated[str | None, <typer.models.OptionInfo object at 0x7ff933079d60>] = None)

Remove the autocompletion for the given shell. If the shell is not specified, it will try to detect the shell. If the shell is not detected, it will fail.

Since the installation routine is upstream we first run install to determine where the completion script is installed and then we remove it.

 shellcompletion Usage: shellcompletion [OPTIONS] [SHELL]:[bash|zsh|fish|powershell|pwsh] Remove autocompletion for the current or given shell. ╭─ Arguments ──────────────────────────────────────────────────────────────────╮ shell[SHELL]:[bash|zsh|fish|powershSpecify the shell to install or ell|pwsh]remove shell completion for.    [default: sh]                   ╰──────────────────────────────────────────────────────────────────────────────╯ ╭─ Options ────────────────────────────────────────────────────────────────────╮ --manage-scriptTEXTThe name of the django manage script to remove  shell completion for if different than the      script used to invoke this command.             [default: None]                                 --helpShow this message and exit. ╰──────────────────────────────────────────────────────────────────────────────╯
property shell: Shells

Get the active shell. If not explicitly set, it first tries to find the shell in the environment variable shell complete scripts set and failing that it will try to autodetect the shell.