├── .env ├── .github ├── DISCUSSION_TEMPLATE │ └── questions.yml ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── config.yml │ └── privileged.yml ├── dependabot.yml ├── labeler.yml └── workflows │ ├── add-to-project.yml │ ├── build-docs.yml │ ├── deploy-docs.yml │ ├── issue-manager.yml │ ├── labeler.yml │ ├── latest-changes.yml │ ├── publish.yml │ ├── smokeshow.yml │ ├── test-redistribute.yml │ └── test.yml ├── .gitignore ├── .pre-commit-config.yaml ├── CITATION.cff ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── data └── members.yml ├── docs ├── about │ └── index.md ├── alternatives.md ├── contributing.md ├── css │ ├── custom.css │ └── termynal.css ├── environment-variables.md ├── features.md ├── help-typer.md ├── img │ ├── favicon.png │ ├── github-social-preview.png │ ├── github-social-preview.svg │ ├── icon-square.svg │ ├── icon.svg │ ├── logo-margin │ │ ├── logo-margin-vector.svg │ │ ├── logo-margin-white-vector.svg │ │ ├── logo-margin-white.svg │ │ └── logo-margin.svg │ ├── pycharm-completion.png │ └── vscode-completion.png ├── index.md ├── js │ ├── custom.js │ └── termynal.js ├── management-tasks.md ├── management.md ├── overrides │ └── main.html ├── release-notes.md ├── resources │ └── index.md ├── tutorial │ ├── app-dir.md │ ├── arguments │ │ ├── default.md │ │ ├── envvar.md │ │ ├── help.md │ │ ├── index.md │ │ ├── optional.md │ │ └── other-uses.md │ ├── commands │ │ ├── arguments.md │ │ ├── callback.md │ │ ├── context.md │ │ ├── help.md │ │ ├── index.md │ │ ├── name.md │ │ ├── one-or-multiple.md │ │ └── options.md │ ├── exceptions.md │ ├── first-steps.md │ ├── index.md │ ├── install.md │ ├── launch.md │ ├── multiple-values │ │ ├── arguments-with-multiple-values.md │ │ ├── index.md │ │ ├── multiple-options.md │ │ └── options-with-multiple-values.md │ ├── one-file-per-command.md │ ├── options-autocompletion.md │ ├── options │ │ ├── callback-and-context.md │ │ ├── help.md │ │ ├── index.md │ │ ├── name.md │ │ ├── password.md │ │ ├── prompt.md │ │ ├── required.md │ │ └── version.md │ ├── package.md │ ├── parameter-types │ │ ├── bool.md │ │ ├── custom-types.md │ │ ├── datetime.md │ │ ├── enum.md │ │ ├── file.md │ │ ├── index.md │ │ ├── number.md │ │ ├── path.md │ │ └── uuid.md │ ├── printing.md │ ├── progressbar.md │ ├── prompt.md │ ├── subcommands │ │ ├── add-typer.md │ │ ├── callback-override.md │ │ ├── index.md │ │ ├── name-and-help.md │ │ ├── nested-subcommands.md │ │ └── single-file.md │ ├── terminating.md │ ├── testing.md │ ├── typer-command.md │ └── using-click.md └── virtual-environments.md ├── docs_src ├── app_dir │ └── tutorial001.py ├── arguments │ ├── default │ │ ├── tutorial001.py │ │ ├── tutorial001_an.py │ │ ├── tutorial002.py │ │ └── tutorial002_an.py │ ├── envvar │ │ ├── tutorial001.py │ │ ├── tutorial001_an.py │ │ ├── tutorial002.py │ │ ├── tutorial002_an.py │ │ ├── tutorial003.py │ │ └── tutorial003_an.py │ ├── help │ │ ├── tutorial001.py │ │ ├── tutorial001_an.py │ │ ├── tutorial002.py │ │ ├── tutorial002_an.py │ │ ├── tutorial003.py │ │ ├── tutorial003_an.py │ │ ├── tutorial004.py │ │ ├── tutorial004_an.py │ │ ├── tutorial005.py │ │ ├── tutorial005_an.py │ │ ├── tutorial006.py │ │ ├── tutorial006_an.py │ │ ├── tutorial007.py │ │ ├── tutorial007_an.py │ │ ├── tutorial008.py │ │ └── tutorial008_an.py │ └── optional │ │ ├── tutorial001.py │ │ ├── tutorial001_an.py │ │ ├── tutorial002.py │ │ ├── tutorial002_an.py │ │ └── tutorial003.py ├── commands │ ├── arguments │ │ └── tutorial001.py │ ├── callback │ │ ├── tutorial001.py │ │ ├── tutorial002.py │ │ ├── tutorial003.py │ │ └── tutorial004.py │ ├── context │ │ ├── tutorial001.py │ │ ├── tutorial002.py │ │ ├── tutorial003.py │ │ └── tutorial004.py │ ├── help │ │ ├── tutorial001.py │ │ ├── tutorial001_an.py │ │ ├── tutorial002.py │ │ ├── tutorial003.py │ │ ├── tutorial004.py │ │ ├── tutorial004_an.py │ │ ├── tutorial005.py │ │ ├── tutorial005_an.py │ │ ├── tutorial006.py │ │ ├── tutorial007.py │ │ ├── tutorial007_an.py │ │ └── tutorial008.py │ ├── index │ │ ├── tutorial001.py │ │ ├── tutorial002.py │ │ ├── tutorial003.py │ │ └── tutorial004.py │ ├── name │ │ └── tutorial001.py │ ├── one_or_multiple │ │ ├── tutorial001.py │ │ └── tutorial002.py │ └── options │ │ ├── tutorial001.py │ │ └── tutorial001_an.py ├── exceptions │ ├── tutorial001.py │ ├── tutorial002.py │ ├── tutorial003.py │ └── tutorial004.py ├── first_steps │ ├── tutorial001.py │ ├── tutorial002.py │ ├── tutorial003.py │ ├── tutorial004.py │ ├── tutorial005.py │ └── tutorial006.py ├── launch │ ├── tutorial001.py │ └── tutorial002.py ├── multiple_values │ ├── arguments_with_multiple_values │ │ ├── tutorial001.py │ │ ├── tutorial002.py │ │ └── tutorial002_an.py │ ├── multiple_options │ │ ├── tutorial001.py │ │ ├── tutorial001_an.py │ │ ├── tutorial002.py │ │ └── tutorial002_an.py │ └── options_with_multiple_values │ │ ├── tutorial001.py │ │ └── tutorial001_an.py ├── one_file_per_command │ ├── __init__.py │ ├── main.py │ ├── users │ │ ├── __init__.py │ │ ├── add.py │ │ └── delete.py │ └── version.py ├── options │ ├── callback │ │ ├── tutorial001.py │ │ ├── tutorial001_an.py │ │ ├── tutorial002.py │ │ ├── tutorial002_an.py │ │ ├── tutorial003.py │ │ ├── tutorial003_an.py │ │ ├── tutorial004.py │ │ └── tutorial004_an.py │ ├── help │ │ ├── tutorial001.py │ │ ├── tutorial001_an.py │ │ ├── tutorial002.py │ │ ├── tutorial002_an.py │ │ ├── tutorial003.py │ │ ├── tutorial003_an.py │ │ ├── tutorial004.py │ │ └── tutorial004_an.py │ ├── name │ │ ├── tutorial001.py │ │ ├── tutorial001_an.py │ │ ├── tutorial002.py │ │ ├── tutorial002_an.py │ │ ├── tutorial003.py │ │ ├── tutorial003_an.py │ │ ├── tutorial004.py │ │ ├── tutorial004_an.py │ │ ├── tutorial005.py │ │ └── tutorial005_an.py │ ├── password │ │ ├── tutorial001.py │ │ ├── tutorial001_an.py │ │ ├── tutorial002.py │ │ └── tutorial002_an.py │ ├── prompt │ │ ├── tutorial001.py │ │ ├── tutorial001_an.py │ │ ├── tutorial002.py │ │ ├── tutorial002_an.py │ │ ├── tutorial003.py │ │ └── tutorial003_an.py │ ├── required │ │ ├── tutorial001.py │ │ ├── tutorial001_an.py │ │ └── tutorial002.py │ └── version │ │ ├── tutorial001.py │ │ ├── tutorial001_an.py │ │ ├── tutorial002.py │ │ ├── tutorial002_an.py │ │ ├── tutorial003.py │ │ └── tutorial003_an.py ├── options_autocompletion │ ├── tutorial001.py │ ├── tutorial001_an.py │ ├── tutorial002.py │ ├── tutorial002_an.py │ ├── tutorial003.py │ ├── tutorial003_an.py │ ├── tutorial004.py │ ├── tutorial004_an.py │ ├── tutorial005.py │ ├── tutorial005_an.py │ ├── tutorial006.py │ ├── tutorial006_an.py │ ├── tutorial007.py │ ├── tutorial007_an.py │ ├── tutorial008.py │ ├── tutorial008_an.py │ ├── tutorial009.py │ └── tutorial009_an.py ├── parameter_types │ ├── bool │ │ ├── __init__.py │ │ ├── tutorial001.py │ │ ├── tutorial001_an.py │ │ ├── tutorial002.py │ │ ├── tutorial002_an.py │ │ ├── tutorial003.py │ │ ├── tutorial003_an.py │ │ ├── tutorial004.py │ │ └── tutorial004_an.py │ ├── custom_types │ │ ├── __init__.py │ │ ├── tutorial001.py │ │ ├── tutorial001_an.py │ │ ├── tutorial002.py │ │ └── tutorial002_an.py │ ├── datetime │ │ ├── __init__.py │ │ ├── tutorial001.py │ │ ├── tutorial002.py │ │ └── tutorial002_an.py │ ├── enum │ │ ├── __init__.py │ │ ├── tutorial001.py │ │ ├── tutorial002.py │ │ ├── tutorial002_an.py │ │ ├── tutorial003.py │ │ └── tutorial003_an.py │ ├── file │ │ ├── __init__.py │ │ ├── tutorial001.py │ │ ├── tutorial001_an.py │ │ ├── tutorial002.py │ │ ├── tutorial002_an.py │ │ ├── tutorial003.py │ │ ├── tutorial003_an.py │ │ ├── tutorial004.py │ │ ├── tutorial004_an.py │ │ ├── tutorial005.py │ │ └── tutorial005_an.py │ ├── index │ │ ├── __init__.py │ │ └── tutorial001.py │ ├── number │ │ ├── __init__.py │ │ ├── tutorial001.py │ │ ├── tutorial001_an.py │ │ ├── tutorial002.py │ │ ├── tutorial002_an.py │ │ ├── tutorial003.py │ │ └── tutorial003_an.py │ ├── path │ │ ├── __init__.py │ │ ├── tutorial001.py │ │ ├── tutorial001_an.py │ │ ├── tutorial002.py │ │ └── tutorial002_an.py │ └── uuid │ │ ├── __init__.py │ │ └── tutorial001.py ├── printing │ ├── tutorial001.py │ ├── tutorial002.py │ ├── tutorial003.py │ ├── tutorial004.py │ ├── tutorial005.py │ └── tutorial006.py ├── progressbar │ ├── tutorial001.py │ ├── tutorial002.py │ ├── tutorial003.py │ ├── tutorial004.py │ ├── tutorial005.py │ └── tutorial006.py ├── prompt │ ├── tutorial001.py │ ├── tutorial002.py │ ├── tutorial003.py │ └── tutorial004.py ├── subcommands │ ├── callback_override │ │ ├── tutorial001.py │ │ ├── tutorial002.py │ │ ├── tutorial003.py │ │ └── tutorial004.py │ ├── name_help │ │ ├── tutorial001.py │ │ ├── tutorial002.py │ │ ├── tutorial003.py │ │ ├── tutorial004.py │ │ ├── tutorial005.py │ │ ├── tutorial006.py │ │ ├── tutorial007.py │ │ └── tutorial008.py │ ├── tutorial001 │ │ ├── __init__.py │ │ ├── items.py │ │ ├── main.py │ │ └── users.py │ ├── tutorial002 │ │ └── main.py │ └── tutorial003 │ │ ├── __init__.py │ │ ├── items.py │ │ ├── lands.py │ │ ├── main.py │ │ ├── reigns.py │ │ ├── towns.py │ │ └── users.py ├── terminating │ ├── tutorial001.py │ ├── tutorial002.py │ └── tutorial003.py ├── testing │ ├── app01 │ │ ├── __init__.py │ │ ├── main.py │ │ └── test_main.py │ ├── app02 │ │ ├── __init__.py │ │ ├── main.py │ │ └── test_main.py │ ├── app02_an │ │ ├── __init__.py │ │ ├── main.py │ │ └── test_main.py │ └── app03 │ │ ├── __init__.py │ │ ├── main.py │ │ └── test_main.py └── using_click │ ├── tutorial001.py │ ├── tutorial002.py │ ├── tutorial003.py │ └── tutorial004.py ├── mkdocs.insiders.yml ├── mkdocs.maybe-insiders.yml ├── mkdocs.no-insiders.yml ├── mkdocs.yml ├── pdm_build.py ├── pyproject.toml ├── requirements-docs-insiders.txt ├── requirements-docs.txt ├── requirements-github-actions.txt ├── requirements-tests.txt ├── requirements.txt ├── scripts ├── deploy_docs_status.py ├── docker │ ├── Dockerfile │ └── compose.yaml ├── docs.py ├── format.sh ├── get-pwsh-activate.sh ├── lint.sh ├── mkdocs_hooks.py ├── test-cov-html.sh ├── test-files.sh └── test.sh ├── tests ├── __init__.py ├── assets │ ├── __init__.py │ ├── cli │ │ ├── __init__.py │ │ ├── app_other_name.py │ │ ├── empty_script.py │ │ ├── extended_app_cli.py │ │ ├── extended_empty_app_cli.py │ │ ├── func_other_name.py │ │ ├── multi_app.py │ │ ├── multi_app_cli.py │ │ ├── multi_func.py │ │ ├── multiapp-docs-title.md │ │ ├── multiapp-docs.md │ │ ├── not_python.txt │ │ ├── rich_formatted_app.py │ │ ├── richformattedapp-docs.md │ │ └── sample.py │ ├── completion_argument.py │ ├── completion_no_types.py │ ├── completion_no_types_order.py │ ├── corner_cases.py │ ├── prog_name.py │ ├── type_error_no_rich.py │ ├── type_error_no_rich_short_disable.py │ └── type_error_normal_traceback.py ├── test_ambiguous_params.py ├── test_annotated.py ├── test_callback_warning.py ├── test_cli │ ├── __init__.py │ ├── test_app_other_name.py │ ├── test_completion_run.py │ ├── test_doc.py │ ├── test_empty_script.py │ ├── test_extending_app.py │ ├── test_extending_empty_app.py │ ├── test_func_other_name.py │ ├── test_help.py │ ├── test_multi_app.py │ ├── test_multi_app_cli.py │ ├── test_multi_app_sub.py │ ├── test_multi_func.py │ ├── test_not_python.py │ ├── test_sub.py │ ├── test_sub_completion.py │ ├── test_sub_help.py │ └── test_version.py ├── test_completion │ ├── __init__.py │ ├── colon_example.py │ ├── example_rich_tags.py │ ├── path_example.py │ ├── test_completion.py │ ├── test_completion_complete.py │ ├── test_completion_complete_no_help.py │ ├── test_completion_complete_rich.py │ ├── test_completion_install.py │ ├── test_completion_option_colon.py │ ├── test_completion_path.py │ ├── test_completion_show.py │ └── test_sanitization.py ├── test_corner_cases.py ├── test_deprecation.py ├── test_exit_errors.py ├── test_future_annotations.py ├── test_launch.py ├── test_others.py ├── test_param_meta_empty.py ├── test_prog_name.py ├── test_rich_markup_mode.py ├── test_rich_utils.py ├── test_tracebacks.py ├── test_tutorial │ ├── __init__.py │ ├── test_arguments │ │ ├── __init__.py │ │ ├── test_default │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial001_an.py │ │ │ ├── test_tutorial002.py │ │ │ └── test_tutorial002_an.py │ │ ├── test_envvar │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial001_an.py │ │ │ ├── test_tutorial002.py │ │ │ ├── test_tutorial002_an.py │ │ │ ├── test_tutorial003.py │ │ │ └── test_tutorial003_an.py │ │ ├── test_help │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial001_an.py │ │ │ ├── test_tutorial002.py │ │ │ ├── test_tutorial002_an.py │ │ │ ├── test_tutorial003.py │ │ │ ├── test_tutorial003_an.py │ │ │ ├── test_tutorial004.py │ │ │ ├── test_tutorial004_an.py │ │ │ ├── test_tutorial005.py │ │ │ ├── test_tutorial005_an.py │ │ │ ├── test_tutorial006.py │ │ │ ├── test_tutorial006_an.py │ │ │ ├── test_tutorial007.py │ │ │ ├── test_tutorial007_an.py │ │ │ ├── test_tutorial008.py │ │ │ └── test_tutorial008_an.py │ │ └── test_optional │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial001_an.py │ │ │ ├── test_tutorial002.py │ │ │ ├── test_tutorial002_an.py │ │ │ └── test_tutorial003.py │ ├── test_commands │ │ ├── __init__.py │ │ ├── test_arguments │ │ │ ├── __init__.py │ │ │ └── test_tutorial001.py │ │ ├── test_callback │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial002.py │ │ │ ├── test_tutorial003.py │ │ │ └── test_tutorial004.py │ │ ├── test_context │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial002.py │ │ │ ├── test_tutorial003.py │ │ │ └── test_tutorial004.py │ │ ├── test_help │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial001_an.py │ │ │ ├── test_tutorial002.py │ │ │ ├── test_tutorial003.py │ │ │ ├── test_tutorial004.py │ │ │ ├── test_tutorial004_an.py │ │ │ ├── test_tutorial005.py │ │ │ ├── test_tutorial005_an.py │ │ │ ├── test_tutorial006.py │ │ │ ├── test_tutorial007.py │ │ │ ├── test_tutorial007_an.py │ │ │ └── test_tutorial008.py │ │ ├── test_index │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial002.py │ │ │ ├── test_tutorial003.py │ │ │ └── test_tutorial004.py │ │ ├── test_name │ │ │ ├── __init__.py │ │ │ └── test_tutorial001.py │ │ ├── test_one_or_multiple │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ └── test_tutorial002.py │ │ └── test_options │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ └── test_tutorial001_an.py │ ├── test_exceptions │ │ ├── __init__.py │ │ ├── test_tutorial001.py │ │ ├── test_tutorial002.py │ │ ├── test_tutorial003.py │ │ └── test_tutorial004.py │ ├── test_first_steps │ │ ├── __init__.py │ │ ├── test_tutorial001.py │ │ ├── test_tutorial002.py │ │ ├── test_tutorial003.py │ │ ├── test_tutorial004.py │ │ ├── test_tutorial005.py │ │ └── test_tutorial006.py │ ├── test_multiple_values │ │ ├── __init__.py │ │ ├── test_arguments_with_multiple_values │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial002.py │ │ │ └── test_tutorial002_an.py │ │ ├── test_multiple_options │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial001_an.py │ │ │ ├── test_tutorial002.py │ │ │ └── test_tutorial002_an.py │ │ └── test_options_with_multiple_values │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ └── test_tutorial001_an.py │ ├── test_one_file_per_command │ │ ├── __init__.py │ │ └── test_tutorial.py │ ├── test_options │ │ ├── __init__.py │ │ ├── test_callback │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial001_an.py │ │ │ ├── test_tutorial003.py │ │ │ ├── test_tutorial003_an.py │ │ │ ├── test_tutorial004.py │ │ │ └── test_tutorial004_an.py │ │ ├── test_help │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial001_an.py │ │ │ ├── test_tutorial002.py │ │ │ ├── test_tutorial002_an.py │ │ │ ├── test_tutorial003.py │ │ │ └── test_tutorial003_an.py │ │ ├── test_name │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial001_an.py │ │ │ ├── test_tutorial002.py │ │ │ ├── test_tutorial002_an.py │ │ │ ├── test_tutorial003.py │ │ │ ├── test_tutorial003_an.py │ │ │ ├── test_tutorial004.py │ │ │ ├── test_tutorial004_an.py │ │ │ ├── test_tutorial005.py │ │ │ └── test_tutorial005_an.py │ │ ├── test_prompt │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial001_an.py │ │ │ ├── test_tutorial002.py │ │ │ ├── test_tutorial002_an.py │ │ │ ├── test_tutorial003.py │ │ │ └── test_tutorial003_an.py │ │ ├── test_required │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ └── test_tutorial001_an.py │ │ └── test_version │ │ │ ├── __init__.py │ │ │ ├── test_tutorial003.py │ │ │ └── test_tutorial003_an.py │ ├── test_options_autocompletion │ │ ├── __init__.py │ │ ├── test_tutorial002.py │ │ ├── test_tutorial002_an.py │ │ ├── test_tutorial003.py │ │ ├── test_tutorial003_an.py │ │ ├── test_tutorial004.py │ │ ├── test_tutorial004_an.py │ │ ├── test_tutorial007.py │ │ ├── test_tutorial007_an.py │ │ ├── test_tutorial008.py │ │ ├── test_tutorial008_an.py │ │ ├── test_tutorial009.py │ │ └── test_tutorial009_an.py │ ├── test_parameter_types │ │ ├── __init__.py │ │ ├── test_bool │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial001_an.py │ │ │ ├── test_tutorial002.py │ │ │ ├── test_tutorial002_an.py │ │ │ ├── test_tutorial003.py │ │ │ ├── test_tutorial003_an.py │ │ │ ├── test_tutorial004.py │ │ │ └── test_tutorial004_an.py │ │ ├── test_custom_types │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial001_an.py │ │ │ ├── test_tutorial002.py │ │ │ └── test_tutorial002_an.py │ │ ├── test_datetime │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial002.py │ │ │ └── test_tutorial002_an.py │ │ ├── test_enum │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial002.py │ │ │ ├── test_tutorial002_an.py │ │ │ ├── test_tutorial003.py │ │ │ └── test_tutorial003_an.py │ │ ├── test_file │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial001_an.py │ │ │ ├── test_tutorial002.py │ │ │ ├── test_tutorial002_an.py │ │ │ ├── test_tutorial003.py │ │ │ ├── test_tutorial003_an.py │ │ │ ├── test_tutorial004.py │ │ │ ├── test_tutorial004_an.py │ │ │ ├── test_tutorial005.py │ │ │ └── test_tutorial005_an.py │ │ ├── test_index │ │ │ ├── __init__.py │ │ │ └── test_tutorial001.py │ │ ├── test_number │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial001_an.py │ │ │ ├── test_tutorial002.py │ │ │ ├── test_tutorial002_an.py │ │ │ ├── test_tutorial003.py │ │ │ └── test_tutorial003_an.py │ │ ├── test_path │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial001_an.py │ │ │ ├── test_tutorial002.py │ │ │ └── test_tutorial002_an.py │ │ └── test_uuid │ │ │ ├── __init__.py │ │ │ └── test_tutorial001.py │ ├── test_prompt │ │ ├── __init__.py │ │ ├── test_tutorial001.py │ │ ├── test_tutorial002.py │ │ └── test_tutorial003.py │ ├── test_subcommands │ │ ├── __init__.py │ │ ├── test_callback_override │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial002.py │ │ │ ├── test_tutorial003.py │ │ │ └── test_tutorial004.py │ │ ├── test_name_help │ │ │ ├── __init__.py │ │ │ ├── test_tutorial001.py │ │ │ ├── test_tutorial002.py │ │ │ ├── test_tutorial003.py │ │ │ ├── test_tutorial004.py │ │ │ ├── test_tutorial005.py │ │ │ ├── test_tutorial006.py │ │ │ ├── test_tutorial007.py │ │ │ └── test_tutorial008.py │ │ ├── test_tutorial001.py │ │ ├── test_tutorial002.py │ │ └── test_tutorial003.py │ ├── test_terminating │ │ ├── __init__.py │ │ ├── test_tutorial001.py │ │ ├── test_tutorial002.py │ │ └── test_tutorial003.py │ ├── test_testing │ │ ├── __init__.py │ │ ├── test_app01.py │ │ ├── test_app02.py │ │ ├── test_app02_an.py │ │ └── test_app03.py │ └── test_using_click │ │ ├── __init__.py │ │ ├── test_tutorial003.py │ │ └── test_tutorial004.py ├── test_type_conversion.py ├── test_types.py └── utils.py ├── typer-cli └── README.md └── typer ├── __init__.py ├── __main__.py ├── _completion_classes.py ├── _completion_shared.py ├── _types.py ├── _typing.py ├── cli.py ├── colors.py ├── completion.py ├── core.py ├── main.py ├── models.py ├── params.py ├── py.typed ├── rich_utils.py ├── testing.py └── utils.py /.env: -------------------------------------------------------------------------------- 1 | # Environment variables automatically read by VS Code, e.g. running tests 2 | 3 | # For tests, a large terminal width 4 | TERMINAL_WIDTH=3000 5 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [tiangolo] 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Security Contact 4 | about: Please report security vulnerabilities to security@tiangolo.com 5 | - name: Question or Problem 6 | about: Ask a question or ask about a problem in GitHub Discussions. 7 | url: https://github.com/fastapi/typer/discussions/categories/questions 8 | - name: Feature Request 9 | about: To suggest an idea or ask about a feature, please start with a question saying what you would like to achieve. There might be a way to do it already. 10 | url: https://github.com/fastapi/typer/discussions/categories/questions 11 | - name: Show and tell 12 | about: Show what you built with Typer or to be used with Typer. 13 | url: https://github.com/fastapi/typer/discussions/categories/show-and-tell 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/privileged.yml: -------------------------------------------------------------------------------- 1 | name: Privileged 2 | description: You are @tiangolo or he asked you directly to create an issue here. If not, check the other options. 👇 3 | body: 4 | - type: markdown 5 | attributes: 6 | value: | 7 | Thanks for your interest in Typer! 🚀 8 | 9 | If you are not @tiangolo or he didn't ask you directly to create an issue here, please start the conversation in a [Question in GitHub Discussions](https://github.com/fastapi/typer/discussions/categories/questions) instead. 10 | - type: checkboxes 11 | id: privileged 12 | attributes: 13 | label: Privileged issue 14 | description: Confirm that you are allowed to create an issue here. 15 | options: 16 | - label: I'm @tiangolo or he asked me directly to create an issue here. 17 | required: true 18 | - type: textarea 19 | id: content 20 | attributes: 21 | label: Issue Content 22 | description: Add the content of the issue here. 23 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # GitHub Actions 4 | - package-ecosystem: "github-actions" 5 | directory: "/" 6 | schedule: 7 | interval: "daily" 8 | commit-message: 9 | prefix: ⬆ 10 | # Python 11 | - package-ecosystem: "pip" 12 | directory: "/" 13 | schedule: 14 | interval: "daily" 15 | commit-message: 16 | prefix: ⬆ 17 | -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | docs: 2 | - all: 3 | - changed-files: 4 | - any-glob-to-any-file: 5 | - docs/** 6 | - docs_src/** 7 | - all-globs-to-all-files: 8 | - '!typer/**' 9 | - '!pyproject.toml' 10 | 11 | internal: 12 | - all: 13 | - changed-files: 14 | - any-glob-to-any-file: 15 | - .github/** 16 | - scripts/** 17 | - .gitignore 18 | - .pre-commit-config.yaml 19 | - pdm_build.py 20 | - requirements*.txt 21 | - all-globs-to-all-files: 22 | - '!docs/**' 23 | - '!typer/**' 24 | - '!pyproject.toml' 25 | -------------------------------------------------------------------------------- /.github/workflows/add-to-project.yml: -------------------------------------------------------------------------------- 1 | name: Add to Project 2 | 3 | on: 4 | pull_request_target: 5 | issues: 6 | types: 7 | - opened 8 | - reopened 9 | 10 | jobs: 11 | add-to-project: 12 | name: Add to project 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/add-to-project@v1.0.2 16 | with: 17 | project-url: https://github.com/orgs/fastapi/projects/2 18 | github-token: ${{ secrets.PROJECTS_TOKEN }} 19 | -------------------------------------------------------------------------------- /.github/workflows/labeler.yml: -------------------------------------------------------------------------------- 1 | name: Labels 2 | on: 3 | pull_request_target: 4 | types: 5 | - opened 6 | - synchronize 7 | - reopened 8 | # For label-checker 9 | - labeled 10 | - unlabeled 11 | 12 | jobs: 13 | labeler: 14 | permissions: 15 | contents: read 16 | pull-requests: write 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/labeler@v5 20 | if: ${{ github.event.action != 'labeled' && github.event.action != 'unlabeled' }} 21 | - run: echo "Done adding labels" 22 | # Run this after labeler applied labels 23 | check-labels: 24 | needs: 25 | - labeler 26 | permissions: 27 | pull-requests: read 28 | runs-on: ubuntu-latest 29 | steps: 30 | - uses: docker://agilepathway/pull-request-label-checker:latest 31 | with: 32 | one_of: breaking,security,feature,bug,refactor,upgrade,docs,lang-all,internal 33 | repo_token: ${{ secrets.GITHUB_TOKEN }} 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | *.pyc 3 | __pycache__ 4 | .venv* 5 | env 6 | dist 7 | .mypy_cache 8 | .idea 9 | site 10 | htmlcov 11 | .pytest_cache 12 | coverage.xml 13 | .coverage* 14 | .cache 15 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # See https://pre-commit.com for more information 2 | # See https://pre-commit.com/hooks.html for more hooks 3 | default_language_version: 4 | python: python3.10 5 | repos: 6 | - repo: https://github.com/pre-commit/pre-commit-hooks 7 | rev: v5.0.0 8 | hooks: 9 | - id: check-added-large-files 10 | - id: check-toml 11 | - id: check-yaml 12 | args: 13 | - --unsafe 14 | - id: end-of-file-fixer 15 | - id: trailing-whitespace 16 | - repo: https://github.com/astral-sh/ruff-pre-commit 17 | rev: v0.11.6 18 | hooks: 19 | - id: ruff 20 | args: 21 | - --fix 22 | - id: ruff-format 23 | ci: 24 | autofix_commit_msg: 🎨 [pre-commit.ci] Auto format from pre-commit.com hooks 25 | autoupdate_commit_msg: ⬆ [pre-commit.ci] pre-commit autoupdate 26 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | # This CITATION.cff file was generated with cffinit. 2 | # Visit https://bit.ly/cffinit to generate yours today! 3 | 4 | cff-version: 1.2.0 5 | title: Typer 6 | message: >- 7 | If you use this software, please cite it using the 8 | metadata from this file. 9 | type: software 10 | authors: 11 | - given-names: Sebastián 12 | family-names: Ramírez 13 | email: tiangolo@gmail.com 14 | identifiers: 15 | repository-code: 'https://github.com/fastapi/typer' 16 | url: 'https://typer.tiangolo.com' 17 | abstract: >- 18 | Typer, build great CLIs. Easy to code. Based on Python type hints. 19 | keywords: 20 | - typer 21 | - click 22 | license: MIT 23 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Please read the [Development - Contributing](https://typer.tiangolo.com/contributing/) guidelines in the documentation site. 2 | -------------------------------------------------------------------------------- /data/members.yml: -------------------------------------------------------------------------------- 1 | members: 2 | - login: tiangolo 3 | - login: svlandeg 4 | - login: patrick91 5 | -------------------------------------------------------------------------------- /docs/about/index.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | About **Typer**, its design, inspiration, and more. 🤓 4 | -------------------------------------------------------------------------------- /docs/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/docs/img/favicon.png -------------------------------------------------------------------------------- /docs/img/github-social-preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/docs/img/github-social-preview.png -------------------------------------------------------------------------------- /docs/img/pycharm-completion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/docs/img/pycharm-completion.png -------------------------------------------------------------------------------- /docs/img/vscode-completion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/docs/img/vscode-completion.png -------------------------------------------------------------------------------- /docs/overrides/main.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | -------------------------------------------------------------------------------- /docs/resources/index.md: -------------------------------------------------------------------------------- 1 | # Resources 2 | 3 | Additional resources, how to **help** and get help, how to **contribute**, and more. ✈️ 4 | -------------------------------------------------------------------------------- /docs/tutorial/arguments/index.md: -------------------------------------------------------------------------------- 1 | # CLI Arguments 2 | 3 | In the next few sections we'll see some ways to modify how *CLI arguments* work. 4 | 5 | We'll create optional *CLI arguments*, we'll add integrated help for *CLI arguments*, etc. 6 | -------------------------------------------------------------------------------- /docs/tutorial/arguments/other-uses.md: -------------------------------------------------------------------------------- 1 | # Other uses 2 | 3 | `typer.Argument()` has several other use cases. Such as for data validation, to enable other features, etc. 4 | 5 | You will see about these use cases later in the docs. 6 | -------------------------------------------------------------------------------- /docs/tutorial/install.md: -------------------------------------------------------------------------------- 1 | # Install **Typer** 2 | 3 | The first step is to install **Typer**. 4 | 5 | First, make sure you create your [virtual environment](../virtual-environments.md){.internal-link target=_blank}, activate it, and then install it, for example with: 6 | 7 |
8 | 9 | ```console 10 | $ pip install typer 11 | ---> 100% 12 | Successfully installed typer click shellingham rich 13 | ``` 14 | 15 |
16 | 17 | By default, `typer` comes with `rich` and `shellingham`. 18 | 19 | /// note 20 | 21 | If you are an advanced user and want to opt out of these default extra dependencies, you can instead install `typer-slim`. 22 | 23 | ```bash 24 | pip install typer 25 | ``` 26 | 27 | ...includes the same optional dependencies as: 28 | 29 | ```bash 30 | pip install "typer-slim[standard]" 31 | ``` 32 | 33 | /// 34 | -------------------------------------------------------------------------------- /docs/tutorial/multiple-values/index.md: -------------------------------------------------------------------------------- 1 | # Multiple Values 2 | 3 | There are several ways to declare multiple values for *CLI options* and *CLI arguments*. 4 | 5 | We'll see them in the next short sections. 6 | -------------------------------------------------------------------------------- /docs/tutorial/options/index.md: -------------------------------------------------------------------------------- 1 | # CLI Options 2 | 3 | In the next short sections we will see how to modify *CLI options* using `typer.Option()`. 4 | 5 | `typer.Option()` works very similarly to `typer.Argument()`, but has some extra features that we'll see next. 6 | -------------------------------------------------------------------------------- /docs_src/app_dir/tutorial001.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | import typer 4 | 5 | APP_NAME = "my-super-cli-app" 6 | 7 | 8 | def main(): 9 | app_dir = typer.get_app_dir(APP_NAME) 10 | config_path: Path = Path(app_dir) / "config.json" 11 | if not config_path.is_file(): 12 | print("Config file doesn't exist yet") 13 | 14 | 15 | if __name__ == "__main__": 16 | typer.run(main) 17 | -------------------------------------------------------------------------------- /docs_src/arguments/default/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str = typer.Argument("Wade Wilson")): 5 | print(f"Hello {name}") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/arguments/default/tutorial001_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(name: Annotated[str, typer.Argument()] = "Wade Wilson"): 6 | print(f"Hello {name}") 7 | 8 | 9 | if __name__ == "__main__": 10 | typer.run(main) 11 | -------------------------------------------------------------------------------- /docs_src/arguments/default/tutorial002.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | import typer 4 | 5 | 6 | def get_name(): 7 | return random.choice(["Deadpool", "Rick", "Morty", "Hiro"]) 8 | 9 | 10 | def main(name: str = typer.Argument(default_factory=get_name)): 11 | print(f"Hello {name}") 12 | 13 | 14 | if __name__ == "__main__": 15 | typer.run(main) 16 | -------------------------------------------------------------------------------- /docs_src/arguments/default/tutorial002_an.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | import typer 4 | from typing_extensions import Annotated 5 | 6 | 7 | def get_name(): 8 | return random.choice(["Deadpool", "Rick", "Morty", "Hiro"]) 9 | 10 | 11 | def main(name: Annotated[str, typer.Argument(default_factory=get_name)]): 12 | print(f"Hello {name}") 13 | 14 | 15 | if __name__ == "__main__": 16 | typer.run(main) 17 | -------------------------------------------------------------------------------- /docs_src/arguments/envvar/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str = typer.Argument("World", envvar="AWESOME_NAME")): 5 | print(f"Hello Mr. {name}") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/arguments/envvar/tutorial001_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(name: Annotated[str, typer.Argument(envvar="AWESOME_NAME")] = "World"): 6 | print(f"Hello Mr. {name}") 7 | 8 | 9 | if __name__ == "__main__": 10 | typer.run(main) 11 | -------------------------------------------------------------------------------- /docs_src/arguments/envvar/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str = typer.Argument("World", envvar=["AWESOME_NAME", "GOD_NAME"])): 5 | print(f"Hello Mr. {name}") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/arguments/envvar/tutorial002_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main( 6 | name: Annotated[str, typer.Argument(envvar=["AWESOME_NAME", "GOD_NAME"])] = "World", 7 | ): 8 | print(f"Hello Mr. {name}") 9 | 10 | 11 | if __name__ == "__main__": 12 | typer.run(main) 13 | -------------------------------------------------------------------------------- /docs_src/arguments/envvar/tutorial003.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str = typer.Argument("World", envvar="AWESOME_NAME", show_envvar=False)): 5 | print(f"Hello Mr. {name}") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/arguments/envvar/tutorial003_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main( 6 | name: Annotated[ 7 | str, typer.Argument(envvar="AWESOME_NAME", show_envvar=False) 8 | ] = "World", 9 | ): 10 | print(f"Hello Mr. {name}") 11 | 12 | 13 | if __name__ == "__main__": 14 | typer.run(main) 15 | -------------------------------------------------------------------------------- /docs_src/arguments/help/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str = typer.Argument(..., help="The name of the user to greet")): 5 | print(f"Hello {name}") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/arguments/help/tutorial001_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(name: Annotated[str, typer.Argument(help="The name of the user to greet")]): 6 | print(f"Hello {name}") 7 | 8 | 9 | if __name__ == "__main__": 10 | typer.run(main) 11 | -------------------------------------------------------------------------------- /docs_src/arguments/help/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str = typer.Argument(..., help="The name of the user to greet")): 5 | """ 6 | Say hi to NAME very gently, like Dirk. 7 | """ 8 | print(f"Hello {name}") 9 | 10 | 11 | if __name__ == "__main__": 12 | typer.run(main) 13 | -------------------------------------------------------------------------------- /docs_src/arguments/help/tutorial002_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(name: Annotated[str, typer.Argument(help="The name of the user to greet")]): 6 | """ 7 | Say hi to NAME very gently, like Dirk. 8 | """ 9 | print(f"Hello {name}") 10 | 11 | 12 | if __name__ == "__main__": 13 | typer.run(main) 14 | -------------------------------------------------------------------------------- /docs_src/arguments/help/tutorial003.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str = typer.Argument("World", help="Who to greet")): 5 | """ 6 | Say hi to NAME very gently, like Dirk. 7 | """ 8 | print(f"Hello {name}") 9 | 10 | 11 | if __name__ == "__main__": 12 | typer.run(main) 13 | -------------------------------------------------------------------------------- /docs_src/arguments/help/tutorial003_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(name: Annotated[str, typer.Argument(help="Who to greet")] = "World"): 6 | """ 7 | Say hi to NAME very gently, like Dirk. 8 | """ 9 | print(f"Hello {name}") 10 | 11 | 12 | if __name__ == "__main__": 13 | typer.run(main) 14 | -------------------------------------------------------------------------------- /docs_src/arguments/help/tutorial004.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str = typer.Argument("World", help="Who to greet", show_default=False)): 5 | """ 6 | Say hi to NAME very gently, like Dirk. 7 | """ 8 | print(f"Hello {name}") 9 | 10 | 11 | if __name__ == "__main__": 12 | typer.run(main) 13 | -------------------------------------------------------------------------------- /docs_src/arguments/help/tutorial004_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main( 6 | name: Annotated[ 7 | str, typer.Argument(help="Who to greet", show_default=False) 8 | ] = "World", 9 | ): 10 | """ 11 | Say hi to NAME very gently, like Dirk. 12 | """ 13 | print(f"Hello {name}") 14 | 15 | 16 | if __name__ == "__main__": 17 | typer.run(main) 18 | -------------------------------------------------------------------------------- /docs_src/arguments/help/tutorial005.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main( 5 | name: str = typer.Argument( 6 | "Wade Wilson", help="Who to greet", show_default="Deadpoolio the amazing's name" 7 | ), 8 | ): 9 | print(f"Hello {name}") 10 | 11 | 12 | if __name__ == "__main__": 13 | typer.run(main) 14 | -------------------------------------------------------------------------------- /docs_src/arguments/help/tutorial005_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main( 6 | name: Annotated[ 7 | str, 8 | typer.Argument( 9 | help="Who to greet", show_default="Deadpoolio the amazing's name" 10 | ), 11 | ] = "Wade Wilson", 12 | ): 13 | print(f"Hello {name}") 14 | 15 | 16 | if __name__ == "__main__": 17 | typer.run(main) 18 | -------------------------------------------------------------------------------- /docs_src/arguments/help/tutorial006.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str = typer.Argument("World", metavar="✨username✨")): 5 | print(f"Hello {name}") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/arguments/help/tutorial006_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(name: Annotated[str, typer.Argument(metavar="✨username✨")] = "World"): 6 | print(f"Hello {name}") 7 | 8 | 9 | if __name__ == "__main__": 10 | typer.run(main) 11 | -------------------------------------------------------------------------------- /docs_src/arguments/help/tutorial007.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main( 5 | name: str = typer.Argument(..., help="Who to greet"), 6 | lastname: str = typer.Argument( 7 | "", help="The last name", rich_help_panel="Secondary Arguments" 8 | ), 9 | age: str = typer.Argument( 10 | "", help="The user's age", rich_help_panel="Secondary Arguments" 11 | ), 12 | ): 13 | """ 14 | Say hi to NAME very gently, like Dirk. 15 | """ 16 | print(f"Hello {name}") 17 | 18 | 19 | if __name__ == "__main__": 20 | typer.run(main) 21 | -------------------------------------------------------------------------------- /docs_src/arguments/help/tutorial007_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main( 6 | name: Annotated[str, typer.Argument(help="Who to greet")], 7 | lastname: Annotated[ 8 | str, typer.Argument(help="The last name", rich_help_panel="Secondary Arguments") 9 | ] = "", 10 | age: Annotated[ 11 | str, 12 | typer.Argument(help="The user's age", rich_help_panel="Secondary Arguments"), 13 | ] = "", 14 | ): 15 | """ 16 | Say hi to NAME very gently, like Dirk. 17 | """ 18 | print(f"Hello {name}") 19 | 20 | 21 | if __name__ == "__main__": 22 | typer.run(main) 23 | -------------------------------------------------------------------------------- /docs_src/arguments/help/tutorial008.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str = typer.Argument("World", hidden=True)): 5 | """ 6 | Say hi to NAME very gently, like Dirk. 7 | """ 8 | print(f"Hello {name}") 9 | 10 | 11 | if __name__ == "__main__": 12 | typer.run(main) 13 | -------------------------------------------------------------------------------- /docs_src/arguments/help/tutorial008_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(name: Annotated[str, typer.Argument(hidden=True)] = "World"): 6 | """ 7 | Say hi to NAME very gently, like Dirk. 8 | """ 9 | print(f"Hello {name}") 10 | 11 | 12 | if __name__ == "__main__": 13 | typer.run(main) 14 | -------------------------------------------------------------------------------- /docs_src/arguments/optional/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str = typer.Argument()): 5 | print(f"Hello {name}") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/arguments/optional/tutorial001_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(name: Annotated[str, typer.Argument()]): 6 | print(f"Hello {name}") 7 | 8 | 9 | if __name__ == "__main__": 10 | typer.run(main) 11 | -------------------------------------------------------------------------------- /docs_src/arguments/optional/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str = typer.Argument(default="World")): 5 | print(f"Hello {name}!") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/arguments/optional/tutorial002_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(name: Annotated[str, typer.Argument()] = "World"): 6 | print(f"Hello {name}!") 7 | 8 | 9 | if __name__ == "__main__": 10 | typer.run(main) 11 | -------------------------------------------------------------------------------- /docs_src/arguments/optional/tutorial003.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str = typer.Argument(default=...)): 5 | print(f"Hello {name}") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/commands/arguments/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def create(username: str): 8 | print(f"Creating user: {username}") 9 | 10 | 11 | @app.command() 12 | def delete(username: str): 13 | print(f"Deleting user: {username}") 14 | 15 | 16 | if __name__ == "__main__": 17 | app() 18 | -------------------------------------------------------------------------------- /docs_src/commands/callback/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | state = {"verbose": False} 5 | 6 | 7 | @app.command() 8 | def create(username: str): 9 | if state["verbose"]: 10 | print("About to create a user") 11 | print(f"Creating user: {username}") 12 | if state["verbose"]: 13 | print("Just created a user") 14 | 15 | 16 | @app.command() 17 | def delete(username: str): 18 | if state["verbose"]: 19 | print("About to delete a user") 20 | print(f"Deleting user: {username}") 21 | if state["verbose"]: 22 | print("Just deleted a user") 23 | 24 | 25 | @app.callback() 26 | def main(verbose: bool = False): 27 | """ 28 | Manage users in the awesome CLI app. 29 | """ 30 | if verbose: 31 | print("Will write verbose output") 32 | state["verbose"] = True 33 | 34 | 35 | if __name__ == "__main__": 36 | app() 37 | -------------------------------------------------------------------------------- /docs_src/commands/callback/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def callback(): 5 | print("Running a command") 6 | 7 | 8 | app = typer.Typer(callback=callback) 9 | 10 | 11 | @app.command() 12 | def create(name: str): 13 | print(f"Creating user: {name}") 14 | 15 | 16 | if __name__ == "__main__": 17 | app() 18 | -------------------------------------------------------------------------------- /docs_src/commands/callback/tutorial003.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def callback(): 5 | print("Running a command") 6 | 7 | 8 | app = typer.Typer(callback=callback) 9 | 10 | 11 | @app.callback() 12 | def new_callback(): 13 | print("Override callback, running a command") 14 | 15 | 16 | @app.command() 17 | def create(name: str): 18 | print(f"Creating user: {name}") 19 | 20 | 21 | if __name__ == "__main__": 22 | app() 23 | -------------------------------------------------------------------------------- /docs_src/commands/callback/tutorial004.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.callback() 7 | def callback(): 8 | """ 9 | Manage users CLI app. 10 | 11 | Use it with the create command. 12 | 13 | A new user with the given NAME will be created. 14 | """ 15 | 16 | 17 | @app.command() 18 | def create(name: str): 19 | print(f"Creating user: {name}") 20 | 21 | 22 | if __name__ == "__main__": 23 | app() 24 | -------------------------------------------------------------------------------- /docs_src/commands/context/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def create(username: str): 8 | print(f"Creating user: {username}") 9 | 10 | 11 | @app.command() 12 | def delete(username: str): 13 | print(f"Deleting user: {username}") 14 | 15 | 16 | @app.callback() 17 | def main(ctx: typer.Context): 18 | """ 19 | Manage users in the awesome CLI app. 20 | """ 21 | print(f"About to execute command: {ctx.invoked_subcommand}") 22 | 23 | 24 | if __name__ == "__main__": 25 | app() 26 | -------------------------------------------------------------------------------- /docs_src/commands/context/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def create(username: str): 8 | print(f"Creating user: {username}") 9 | 10 | 11 | @app.command() 12 | def delete(username: str): 13 | print(f"Deleting user: {username}") 14 | 15 | 16 | @app.callback(invoke_without_command=True) 17 | def main(): 18 | """ 19 | Manage users in the awesome CLI app. 20 | """ 21 | print("Initializing database") 22 | 23 | 24 | if __name__ == "__main__": 25 | app() 26 | -------------------------------------------------------------------------------- /docs_src/commands/context/tutorial003.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def create(username: str): 8 | print(f"Creating user: {username}") 9 | 10 | 11 | @app.command() 12 | def delete(username: str): 13 | print(f"Deleting user: {username}") 14 | 15 | 16 | @app.callback(invoke_without_command=True) 17 | def main(ctx: typer.Context): 18 | """ 19 | Manage users in the awesome CLI app. 20 | """ 21 | if ctx.invoked_subcommand is None: 22 | print("Initializing database") 23 | 24 | 25 | if __name__ == "__main__": 26 | app() 27 | -------------------------------------------------------------------------------- /docs_src/commands/context/tutorial004.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command( 7 | context_settings={"allow_extra_args": True, "ignore_unknown_options": True} 8 | ) 9 | def main(ctx: typer.Context): 10 | for extra_arg in ctx.args: 11 | print(f"Got extra arg: {extra_arg}") 12 | 13 | 14 | if __name__ == "__main__": 15 | app() 16 | -------------------------------------------------------------------------------- /docs_src/commands/help/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command(help="Create a new user with USERNAME.") 7 | def create(username: str): 8 | """ 9 | Some internal utility function to create. 10 | """ 11 | print(f"Creating user: {username}") 12 | 13 | 14 | @app.command(help="Delete a user with USERNAME.") 15 | def delete(username: str): 16 | """ 17 | Some internal utility function to delete. 18 | """ 19 | print(f"Deleting user: {username}") 20 | 21 | 22 | if __name__ == "__main__": 23 | app() 24 | -------------------------------------------------------------------------------- /docs_src/commands/help/tutorial003.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def create(username: str): 8 | """ 9 | Create a user. 10 | """ 11 | print(f"Creating user: {username}") 12 | 13 | 14 | @app.command(deprecated=True) 15 | def delete(username: str): 16 | """ 17 | Delete a user. 18 | 19 | This is deprecated and will stop being supported soon. 20 | """ 21 | print(f"Deleting user: {username}") 22 | 23 | 24 | if __name__ == "__main__": 25 | app() 26 | -------------------------------------------------------------------------------- /docs_src/commands/help/tutorial005.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer(rich_markup_mode="markdown") 4 | 5 | 6 | @app.command() 7 | def create(username: str = typer.Argument(..., help="The username to be **created**")): 8 | """ 9 | **Create** a new *shiny* user. :sparkles: 10 | 11 | * Create a username 12 | 13 | * Show that the username is created 14 | 15 | --- 16 | 17 | Learn more at the [Typer docs website](https://typer.tiangolo.com) 18 | """ 19 | print(f"Creating user: {username}") 20 | 21 | 22 | @app.command(help="**Delete** a user with *USERNAME*.") 23 | def delete( 24 | username: str = typer.Argument(..., help="The username to be **deleted**"), 25 | force: bool = typer.Option(False, help="Force the **deletion** :boom:"), 26 | ): 27 | """ 28 | Some internal utility function to delete. 29 | """ 30 | print(f"Deleting user: {username}") 31 | 32 | 33 | if __name__ == "__main__": 34 | app() 35 | -------------------------------------------------------------------------------- /docs_src/commands/help/tutorial008.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer(rich_markup_mode="rich") 4 | 5 | 6 | @app.command(epilog="Made with :heart: in [blue]Venus[/blue]") 7 | def create(username: str): 8 | """ 9 | [green]Create[/green] a new user. :sparkles: 10 | """ 11 | print(f"Creating user: {username}") 12 | 13 | 14 | if __name__ == "__main__": 15 | app() 16 | -------------------------------------------------------------------------------- /docs_src/commands/index/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def main(name: str): 8 | print(f"Hello {name}") 9 | 10 | 11 | if __name__ == "__main__": 12 | app() 13 | -------------------------------------------------------------------------------- /docs_src/commands/index/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def create(): 8 | print("Creating user: Hiro Hamada") 9 | 10 | 11 | @app.command() 12 | def delete(): 13 | print("Deleting user: Hiro Hamada") 14 | 15 | 16 | if __name__ == "__main__": 17 | app() 18 | -------------------------------------------------------------------------------- /docs_src/commands/index/tutorial003.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer(no_args_is_help=True) 4 | 5 | 6 | @app.command() 7 | def create(): 8 | print("Creating user: Hiro Hamada") 9 | 10 | 11 | @app.command() 12 | def delete(): 13 | print("Deleting user: Hiro Hamada") 14 | 15 | 16 | if __name__ == "__main__": 17 | app() 18 | -------------------------------------------------------------------------------- /docs_src/commands/index/tutorial004.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def delete(): 8 | print("Deleting user: Hiro Hamada") 9 | 10 | 11 | @app.command() 12 | def create(): 13 | print("Creating user: Hiro Hamada") 14 | 15 | 16 | if __name__ == "__main__": 17 | app() 18 | -------------------------------------------------------------------------------- /docs_src/commands/name/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command("create") 7 | def cli_create_user(username: str): 8 | print(f"Creating user: {username}") 9 | 10 | 11 | @app.command("delete") 12 | def cli_delete_user(username: str): 13 | print(f"Deleting user: {username}") 14 | 15 | 16 | if __name__ == "__main__": 17 | app() 18 | -------------------------------------------------------------------------------- /docs_src/commands/one_or_multiple/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def create(): 8 | print("Creating user: Hiro Hamada") 9 | 10 | 11 | @app.callback() 12 | def callback(): 13 | pass 14 | 15 | 16 | if __name__ == "__main__": 17 | app() 18 | -------------------------------------------------------------------------------- /docs_src/commands/one_or_multiple/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def create(): 8 | print("Creating user: Hiro Hamada") 9 | 10 | 11 | @app.callback() 12 | def callback(): 13 | """ 14 | Creates a single user Hiro Hamada. 15 | 16 | In the next version it will create 5 more users. 17 | """ 18 | 19 | 20 | if __name__ == "__main__": 21 | app() 22 | -------------------------------------------------------------------------------- /docs_src/commands/options/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def create(username: str): 8 | print(f"Creating user: {username}") 9 | 10 | 11 | @app.command() 12 | def delete( 13 | username: str, 14 | force: bool = typer.Option(..., prompt="Are you sure you want to delete the user?"), 15 | ): 16 | if force: 17 | print(f"Deleting user: {username}") 18 | else: 19 | print("Operation cancelled") 20 | 21 | 22 | @app.command() 23 | def delete_all( 24 | force: bool = typer.Option( 25 | ..., prompt="Are you sure you want to delete ALL users?" 26 | ), 27 | ): 28 | if force: 29 | print("Deleting all users") 30 | else: 31 | print("Operation cancelled") 32 | 33 | 34 | @app.command() 35 | def init(): 36 | print("Initializing user database") 37 | 38 | 39 | if __name__ == "__main__": 40 | app() 41 | -------------------------------------------------------------------------------- /docs_src/commands/options/tutorial001_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | app = typer.Typer() 5 | 6 | 7 | @app.command() 8 | def create(username: str): 9 | print(f"Creating user: {username}") 10 | 11 | 12 | @app.command() 13 | def delete( 14 | username: str, 15 | force: Annotated[ 16 | bool, typer.Option(prompt="Are you sure you want to delete the user?") 17 | ], 18 | ): 19 | if force: 20 | print(f"Deleting user: {username}") 21 | else: 22 | print("Operation cancelled") 23 | 24 | 25 | @app.command() 26 | def delete_all( 27 | force: Annotated[ 28 | bool, typer.Option(prompt="Are you sure you want to delete ALL users?") 29 | ], 30 | ): 31 | if force: 32 | print("Deleting all users") 33 | else: 34 | print("Operation cancelled") 35 | 36 | 37 | @app.command() 38 | def init(): 39 | print("Initializing user database") 40 | 41 | 42 | if __name__ == "__main__": 43 | app() 44 | -------------------------------------------------------------------------------- /docs_src/exceptions/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str = "morty"): 5 | print(name + 3) 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/exceptions/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer(pretty_exceptions_show_locals=False) 4 | 5 | 6 | @app.command() 7 | def main(password: str): 8 | print(password + 3) 9 | 10 | 11 | if __name__ == "__main__": 12 | app() 13 | -------------------------------------------------------------------------------- /docs_src/exceptions/tutorial003.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer(pretty_exceptions_short=False) 4 | 5 | 6 | @app.command() 7 | def main(name: str = "morty"): 8 | print(name + 3) 9 | 10 | 11 | if __name__ == "__main__": 12 | app() 13 | -------------------------------------------------------------------------------- /docs_src/exceptions/tutorial004.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer(pretty_exceptions_enable=False) 4 | 5 | 6 | @app.command() 7 | def main(name: str = "morty"): 8 | print(name + 3) 9 | 10 | 11 | if __name__ == "__main__": 12 | app() 13 | -------------------------------------------------------------------------------- /docs_src/first_steps/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(): 5 | print("Hello World") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/first_steps/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str): 5 | print(f"Hello {name}") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/first_steps/tutorial003.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str, lastname: str): 5 | print(f"Hello {name} {lastname}") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/first_steps/tutorial004.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str, lastname: str, formal: bool = False): 5 | if formal: 6 | print(f"Good day Ms. {name} {lastname}.") 7 | else: 8 | print(f"Hello {name} {lastname}") 9 | 10 | 11 | if __name__ == "__main__": 12 | typer.run(main) 13 | -------------------------------------------------------------------------------- /docs_src/first_steps/tutorial005.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str, lastname: str = "", formal: bool = False): 5 | if formal: 6 | print(f"Good day Ms. {name} {lastname}.") 7 | else: 8 | print(f"Hello {name} {lastname}") 9 | 10 | 11 | if __name__ == "__main__": 12 | typer.run(main) 13 | -------------------------------------------------------------------------------- /docs_src/first_steps/tutorial006.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str, lastname: str = "", formal: bool = False): 5 | """ 6 | Say hi to NAME, optionally with a --lastname. 7 | 8 | If --formal is used, say hi very formally. 9 | """ 10 | if formal: 11 | print(f"Good day Ms. {name} {lastname}.") 12 | else: 13 | print(f"Hello {name} {lastname}") 14 | 15 | 16 | if __name__ == "__main__": 17 | typer.run(main) 18 | -------------------------------------------------------------------------------- /docs_src/launch/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(): 5 | print("Opening Typer's docs") 6 | typer.launch("https://typer.tiangolo.com") 7 | 8 | 9 | if __name__ == "__main__": 10 | typer.run(main) 11 | -------------------------------------------------------------------------------- /docs_src/launch/tutorial002.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | import typer 4 | 5 | APP_NAME = "my-super-cli-app" 6 | 7 | 8 | def main(): 9 | app_dir = typer.get_app_dir(APP_NAME) 10 | app_dir_path = Path(app_dir) 11 | app_dir_path.mkdir(parents=True, exist_ok=True) 12 | config_path: Path = Path(app_dir) / "config.json" 13 | if not config_path.is_file(): 14 | config_path.write_text('{"version": "1.0.0"}') 15 | config_file_str = str(config_path) 16 | print("Opening config directory") 17 | typer.launch(config_file_str, locate=True) 18 | 19 | 20 | if __name__ == "__main__": 21 | typer.run(main) 22 | -------------------------------------------------------------------------------- /docs_src/multiple_values/arguments_with_multiple_values/tutorial001.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | from typing import List 3 | 4 | import typer 5 | 6 | 7 | def main(files: List[Path], celebration: str): 8 | for path in files: 9 | if path.is_file(): 10 | print(f"This file exists: {path.name}") 11 | print(celebration) 12 | 13 | 14 | if __name__ == "__main__": 15 | typer.run(main) 16 | -------------------------------------------------------------------------------- /docs_src/multiple_values/arguments_with_multiple_values/tutorial002.py: -------------------------------------------------------------------------------- 1 | from typing import Tuple 2 | 3 | import typer 4 | 5 | 6 | def main( 7 | names: Tuple[str, str, str] = typer.Argument( 8 | ("Harry", "Hermione", "Ron"), help="Select 3 characters to play with" 9 | ), 10 | ): 11 | for name in names: 12 | print(f"Hello {name}") 13 | 14 | 15 | if __name__ == "__main__": 16 | typer.run(main) 17 | -------------------------------------------------------------------------------- /docs_src/multiple_values/arguments_with_multiple_values/tutorial002_an.py: -------------------------------------------------------------------------------- 1 | from typing import Tuple 2 | 3 | import typer 4 | from typing_extensions import Annotated 5 | 6 | 7 | def main( 8 | names: Annotated[ 9 | Tuple[str, str, str], typer.Argument(help="Select 3 characters to play with") 10 | ] = ("Harry", "Hermione", "Ron"), 11 | ): 12 | for name in names: 13 | print(f"Hello {name}") 14 | 15 | 16 | if __name__ == "__main__": 17 | typer.run(main) 18 | -------------------------------------------------------------------------------- /docs_src/multiple_values/multiple_options/tutorial001.py: -------------------------------------------------------------------------------- 1 | from typing import List, Optional 2 | 3 | import typer 4 | 5 | 6 | def main(user: Optional[List[str]] = typer.Option(None)): 7 | if not user: 8 | print(f"No provided users (raw input = {user})") 9 | raise typer.Abort() 10 | for u in user: 11 | print(f"Processing user: {u}") 12 | 13 | 14 | if __name__ == "__main__": 15 | typer.run(main) 16 | -------------------------------------------------------------------------------- /docs_src/multiple_values/multiple_options/tutorial001_an.py: -------------------------------------------------------------------------------- 1 | from typing import List, Optional 2 | 3 | import typer 4 | from typing_extensions import Annotated 5 | 6 | 7 | def main(user: Annotated[Optional[List[str]], typer.Option()] = None): 8 | if not user: 9 | print(f"No provided users (raw input = {user})") 10 | raise typer.Abort() 11 | for u in user: 12 | print(f"Processing user: {u}") 13 | 14 | 15 | if __name__ == "__main__": 16 | typer.run(main) 17 | -------------------------------------------------------------------------------- /docs_src/multiple_values/multiple_options/tutorial002.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | import typer 4 | 5 | 6 | def main(number: List[float] = typer.Option([])): 7 | print(f"The sum is {sum(number)}") 8 | 9 | 10 | if __name__ == "__main__": 11 | typer.run(main) 12 | -------------------------------------------------------------------------------- /docs_src/multiple_values/multiple_options/tutorial002_an.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | import typer 4 | from typing_extensions import Annotated 5 | 6 | 7 | def main(number: Annotated[List[float], typer.Option()] = []): 8 | print(f"The sum is {sum(number)}") 9 | 10 | 11 | if __name__ == "__main__": 12 | typer.run(main) 13 | -------------------------------------------------------------------------------- /docs_src/multiple_values/options_with_multiple_values/tutorial001.py: -------------------------------------------------------------------------------- 1 | from typing import Tuple 2 | 3 | import typer 4 | 5 | 6 | def main(user: Tuple[str, int, bool] = typer.Option((None, None, None))): 7 | username, coins, is_wizard = user 8 | if not username: 9 | print("No user provided") 10 | raise typer.Abort() 11 | print(f"The username {username} has {coins} coins") 12 | if is_wizard: 13 | print("And this user is a wizard!") 14 | 15 | 16 | if __name__ == "__main__": 17 | typer.run(main) 18 | -------------------------------------------------------------------------------- /docs_src/multiple_values/options_with_multiple_values/tutorial001_an.py: -------------------------------------------------------------------------------- 1 | from typing import Tuple 2 | 3 | import typer 4 | from typing_extensions import Annotated 5 | 6 | 7 | def main(user: Annotated[Tuple[str, int, bool], typer.Option()] = (None, None, None)): 8 | username, coins, is_wizard = user 9 | if not username: 10 | print("No user provided") 11 | raise typer.Abort() 12 | print(f"The username {username} has {coins} coins") 13 | if is_wizard: 14 | print("And this user is a wizard!") 15 | 16 | 17 | if __name__ == "__main__": 18 | typer.run(main) 19 | -------------------------------------------------------------------------------- /docs_src/one_file_per_command/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/docs_src/one_file_per_command/__init__.py -------------------------------------------------------------------------------- /docs_src/one_file_per_command/main.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | from .users import app as users_app 4 | from .version import app as version_app 5 | 6 | app = typer.Typer() 7 | 8 | app.add_typer(version_app) 9 | app.add_typer(users_app, name="users") 10 | 11 | 12 | if __name__ == "__main__": 13 | app() 14 | -------------------------------------------------------------------------------- /docs_src/one_file_per_command/users/__init__.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | from .add import app as add_app 4 | from .delete import app as delete_app 5 | 6 | app = typer.Typer() 7 | 8 | app.add_typer(add_app) 9 | app.add_typer(delete_app) 10 | -------------------------------------------------------------------------------- /docs_src/one_file_per_command/users/add.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def add(name: str): 8 | print(f"Adding user: {name}") 9 | -------------------------------------------------------------------------------- /docs_src/one_file_per_command/users/delete.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def delete(name: str): 8 | print(f"Deleting user: {name}") 9 | -------------------------------------------------------------------------------- /docs_src/one_file_per_command/version.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def version(): 8 | print("My CLI Version 1.0") 9 | -------------------------------------------------------------------------------- /docs_src/options/callback/tutorial001.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | import typer 4 | 5 | 6 | def name_callback(value: str): 7 | if value != "Camila": 8 | raise typer.BadParameter("Only Camila is allowed") 9 | return value 10 | 11 | 12 | def main(name: Optional[str] = typer.Option(default=None, callback=name_callback)): 13 | print(f"Hello {name}") 14 | 15 | 16 | if __name__ == "__main__": 17 | typer.run(main) 18 | -------------------------------------------------------------------------------- /docs_src/options/callback/tutorial001_an.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | import typer 4 | from typing_extensions import Annotated 5 | 6 | 7 | def name_callback(value: str): 8 | if value != "Camila": 9 | raise typer.BadParameter("Only Camila is allowed") 10 | return value 11 | 12 | 13 | def main(name: Annotated[Optional[str], typer.Option(callback=name_callback)] = None): 14 | print(f"Hello {name}") 15 | 16 | 17 | if __name__ == "__main__": 18 | typer.run(main) 19 | -------------------------------------------------------------------------------- /docs_src/options/callback/tutorial002.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | import typer 4 | 5 | 6 | def name_callback(value: str): 7 | print("Validating name") 8 | if value != "Camila": 9 | raise typer.BadParameter("Only Camila is allowed") 10 | return value 11 | 12 | 13 | def main(name: Optional[str] = typer.Option(default=None, callback=name_callback)): 14 | print(f"Hello {name}") 15 | 16 | 17 | if __name__ == "__main__": 18 | typer.run(main) 19 | -------------------------------------------------------------------------------- /docs_src/options/callback/tutorial002_an.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | import typer 4 | from typing_extensions import Annotated 5 | 6 | 7 | def name_callback(value: str): 8 | print("Validating name") 9 | if value != "Camila": 10 | raise typer.BadParameter("Only Camila is allowed") 11 | return value 12 | 13 | 14 | def main(name: Annotated[Optional[str], typer.Option(callback=name_callback)] = None): 15 | print(f"Hello {name}") 16 | 17 | 18 | if __name__ == "__main__": 19 | typer.run(main) 20 | -------------------------------------------------------------------------------- /docs_src/options/callback/tutorial003.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | import typer 4 | 5 | 6 | def name_callback(ctx: typer.Context, value: str): 7 | if ctx.resilient_parsing: 8 | return 9 | print("Validating name") 10 | if value != "Camila": 11 | raise typer.BadParameter("Only Camila is allowed") 12 | return value 13 | 14 | 15 | def main(name: Optional[str] = typer.Option(default=None, callback=name_callback)): 16 | print(f"Hello {name}") 17 | 18 | 19 | if __name__ == "__main__": 20 | typer.run(main) 21 | -------------------------------------------------------------------------------- /docs_src/options/callback/tutorial003_an.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | import typer 4 | from typing_extensions import Annotated 5 | 6 | 7 | def name_callback(ctx: typer.Context, value: str): 8 | if ctx.resilient_parsing: 9 | return 10 | print("Validating name") 11 | if value != "Camila": 12 | raise typer.BadParameter("Only Camila is allowed") 13 | return value 14 | 15 | 16 | def main(name: Annotated[Optional[str], typer.Option(callback=name_callback)] = None): 17 | print(f"Hello {name}") 18 | 19 | 20 | if __name__ == "__main__": 21 | typer.run(main) 22 | -------------------------------------------------------------------------------- /docs_src/options/callback/tutorial004.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | import typer 4 | 5 | 6 | def name_callback(ctx: typer.Context, param: typer.CallbackParam, value: str): 7 | if ctx.resilient_parsing: 8 | return 9 | print(f"Validating param: {param.name}") 10 | if value != "Camila": 11 | raise typer.BadParameter("Only Camila is allowed") 12 | return value 13 | 14 | 15 | def main(name: Optional[str] = typer.Option(default=None, callback=name_callback)): 16 | print(f"Hello {name}") 17 | 18 | 19 | if __name__ == "__main__": 20 | typer.run(main) 21 | -------------------------------------------------------------------------------- /docs_src/options/callback/tutorial004_an.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | import typer 4 | from typing_extensions import Annotated 5 | 6 | 7 | def name_callback(ctx: typer.Context, param: typer.CallbackParam, value: str): 8 | if ctx.resilient_parsing: 9 | return 10 | print(f"Validating param: {param.name}") 11 | if value != "Camila": 12 | raise typer.BadParameter("Only Camila is allowed") 13 | return value 14 | 15 | 16 | def main(name: Annotated[Optional[str], typer.Option(callback=name_callback)] = None): 17 | print(f"Hello {name}") 18 | 19 | 20 | if __name__ == "__main__": 21 | typer.run(main) 22 | -------------------------------------------------------------------------------- /docs_src/options/help/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main( 5 | name: str, 6 | lastname: str = typer.Option("", help="Last name of person to greet."), 7 | formal: bool = typer.Option(False, help="Say hi formally."), 8 | ): 9 | """ 10 | Say hi to NAME, optionally with a --lastname. 11 | 12 | If --formal is used, say hi very formally. 13 | """ 14 | if formal: 15 | print(f"Good day Ms. {name} {lastname}.") 16 | else: 17 | print(f"Hello {name} {lastname}") 18 | 19 | 20 | if __name__ == "__main__": 21 | typer.run(main) 22 | -------------------------------------------------------------------------------- /docs_src/options/help/tutorial001_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main( 6 | name: str, 7 | lastname: Annotated[str, typer.Option(help="Last name of person to greet.")] = "", 8 | formal: Annotated[bool, typer.Option(help="Say hi formally.")] = False, 9 | ): 10 | """ 11 | Say hi to NAME, optionally with a --lastname. 12 | 13 | If --formal is used, say hi very formally. 14 | """ 15 | if formal: 16 | print(f"Good day Ms. {name} {lastname}.") 17 | else: 18 | print(f"Hello {name} {lastname}") 19 | 20 | 21 | if __name__ == "__main__": 22 | typer.run(main) 23 | -------------------------------------------------------------------------------- /docs_src/options/help/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main( 5 | name: str, 6 | lastname: str = typer.Option("", help="Last name of person to greet."), 7 | formal: bool = typer.Option( 8 | False, help="Say hi formally.", rich_help_panel="Customization and Utils" 9 | ), 10 | debug: bool = typer.Option( 11 | False, help="Enable debugging.", rich_help_panel="Customization and Utils" 12 | ), 13 | ): 14 | """ 15 | Say hi to NAME, optionally with a --lastname. 16 | 17 | If --formal is used, say hi very formally. 18 | """ 19 | if formal: 20 | print(f"Good day Ms. {name} {lastname}.") 21 | else: 22 | print(f"Hello {name} {lastname}") 23 | 24 | 25 | if __name__ == "__main__": 26 | typer.run(main) 27 | -------------------------------------------------------------------------------- /docs_src/options/help/tutorial002_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main( 6 | name: str, 7 | lastname: Annotated[str, typer.Option(help="Last name of person to greet.")] = "", 8 | formal: Annotated[ 9 | bool, 10 | typer.Option( 11 | help="Say hi formally.", rich_help_panel="Customization and Utils" 12 | ), 13 | ] = False, 14 | debug: Annotated[ 15 | bool, 16 | typer.Option( 17 | help="Enable debugging.", rich_help_panel="Customization and Utils" 18 | ), 19 | ] = False, 20 | ): 21 | """ 22 | Say hi to NAME, optionally with a --lastname. 23 | 24 | If --formal is used, say hi very formally. 25 | """ 26 | if formal: 27 | print(f"Good day Ms. {name} {lastname}.") 28 | else: 29 | print(f"Hello {name} {lastname}") 30 | 31 | 32 | if __name__ == "__main__": 33 | typer.run(main) 34 | -------------------------------------------------------------------------------- /docs_src/options/help/tutorial003.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(fullname: str = typer.Option("Wade Wilson", show_default=False)): 5 | print(f"Hello {fullname}") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/options/help/tutorial003_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(fullname: Annotated[str, typer.Option(show_default=False)] = "Wade Wilson"): 6 | print(f"Hello {fullname}") 7 | 8 | 9 | if __name__ == "__main__": 10 | typer.run(main) 11 | -------------------------------------------------------------------------------- /docs_src/options/help/tutorial004.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main( 5 | fullname: str = typer.Option( 6 | "Wade Wilson", show_default="Deadpoolio the amazing's name" 7 | ), 8 | ): 9 | print(f"Hello {fullname}") 10 | 11 | 12 | if __name__ == "__main__": 13 | typer.run(main) 14 | -------------------------------------------------------------------------------- /docs_src/options/help/tutorial004_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main( 6 | fullname: Annotated[ 7 | str, typer.Option(show_default="Deadpoolio the amazing's name") 8 | ] = "Wade Wilson", 9 | ): 10 | print(f"Hello {fullname}") 11 | 12 | 13 | if __name__ == "__main__": 14 | typer.run(main) 15 | -------------------------------------------------------------------------------- /docs_src/options/name/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(user_name: str = typer.Option(..., "--name")): 5 | print(f"Hello {user_name}") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/options/name/tutorial001_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(user_name: Annotated[str, typer.Option("--name")]): 6 | print(f"Hello {user_name}") 7 | 8 | 9 | if __name__ == "__main__": 10 | typer.run(main) 11 | -------------------------------------------------------------------------------- /docs_src/options/name/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(user_name: str = typer.Option(..., "--name", "-n")): 5 | print(f"Hello {user_name}") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/options/name/tutorial002_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(user_name: Annotated[str, typer.Option("--name", "-n")]): 6 | print(f"Hello {user_name}") 7 | 8 | 9 | if __name__ == "__main__": 10 | typer.run(main) 11 | -------------------------------------------------------------------------------- /docs_src/options/name/tutorial003.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(user_name: str = typer.Option(..., "-n")): 5 | print(f"Hello {user_name}") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/options/name/tutorial003_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(user_name: Annotated[str, typer.Option("-n")]): 6 | print(f"Hello {user_name}") 7 | 8 | 9 | if __name__ == "__main__": 10 | typer.run(main) 11 | -------------------------------------------------------------------------------- /docs_src/options/name/tutorial004.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(user_name: str = typer.Option(..., "--user-name", "-n")): 5 | print(f"Hello {user_name}") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/options/name/tutorial004_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(user_name: Annotated[str, typer.Option("--user-name", "-n")]): 6 | print(f"Hello {user_name}") 7 | 8 | 9 | if __name__ == "__main__": 10 | typer.run(main) 11 | -------------------------------------------------------------------------------- /docs_src/options/name/tutorial005.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main( 5 | name: str = typer.Option(..., "--name", "-n"), 6 | formal: bool = typer.Option(False, "--formal", "-f"), 7 | ): 8 | if formal: 9 | print(f"Good day Ms. {name}.") 10 | else: 11 | print(f"Hello {name}") 12 | 13 | 14 | if __name__ == "__main__": 15 | typer.run(main) 16 | -------------------------------------------------------------------------------- /docs_src/options/name/tutorial005_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main( 6 | name: Annotated[str, typer.Option("--name", "-n")], 7 | formal: Annotated[bool, typer.Option("--formal", "-f")] = False, 8 | ): 9 | if formal: 10 | print(f"Good day Ms. {name}.") 11 | else: 12 | print(f"Hello {name}") 13 | 14 | 15 | if __name__ == "__main__": 16 | typer.run(main) 17 | -------------------------------------------------------------------------------- /docs_src/options/password/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main( 5 | name: str, email: str = typer.Option(..., prompt=True, confirmation_prompt=True) 6 | ): 7 | print(f"Hello {name}, your email is {email}") 8 | 9 | 10 | if __name__ == "__main__": 11 | typer.run(main) 12 | -------------------------------------------------------------------------------- /docs_src/options/password/tutorial001_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main( 6 | name: str, 7 | email: Annotated[str, typer.Option(prompt=True, confirmation_prompt=True)], 8 | ): 9 | print(f"Hello {name}, your email is {email}") 10 | 11 | 12 | if __name__ == "__main__": 13 | typer.run(main) 14 | -------------------------------------------------------------------------------- /docs_src/options/password/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main( 5 | name: str, 6 | password: str = typer.Option( 7 | ..., prompt=True, confirmation_prompt=True, hide_input=True 8 | ), 9 | ): 10 | print(f"Hello {name}. Doing something very secure with password.") 11 | print(f"...just kidding, here it is, very insecure: {password}") 12 | 13 | 14 | if __name__ == "__main__": 15 | typer.run(main) 16 | -------------------------------------------------------------------------------- /docs_src/options/password/tutorial002_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main( 6 | name: str, 7 | password: Annotated[ 8 | str, typer.Option(prompt=True, confirmation_prompt=True, hide_input=True) 9 | ], 10 | ): 11 | print(f"Hello {name}. Doing something very secure with password.") 12 | print(f"...just kidding, here it is, very insecure: {password}") 13 | 14 | 15 | if __name__ == "__main__": 16 | typer.run(main) 17 | -------------------------------------------------------------------------------- /docs_src/options/prompt/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str, lastname: str = typer.Option(..., prompt=True)): 5 | print(f"Hello {name} {lastname}") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/options/prompt/tutorial001_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(name: str, lastname: Annotated[str, typer.Option(prompt=True)]): 6 | print(f"Hello {name} {lastname}") 7 | 8 | 9 | if __name__ == "__main__": 10 | typer.run(main) 11 | -------------------------------------------------------------------------------- /docs_src/options/prompt/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main( 5 | name: str, lastname: str = typer.Option(..., prompt="Please tell me your last name") 6 | ): 7 | print(f"Hello {name} {lastname}") 8 | 9 | 10 | if __name__ == "__main__": 11 | typer.run(main) 12 | -------------------------------------------------------------------------------- /docs_src/options/prompt/tutorial002_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main( 6 | name: str, 7 | lastname: Annotated[str, typer.Option(prompt="Please tell me your last name")], 8 | ): 9 | print(f"Hello {name} {lastname}") 10 | 11 | 12 | if __name__ == "__main__": 13 | typer.run(main) 14 | -------------------------------------------------------------------------------- /docs_src/options/prompt/tutorial003.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(project_name: str = typer.Option(..., prompt=True, confirmation_prompt=True)): 5 | print(f"Deleting project {project_name}") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/options/prompt/tutorial003_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main( 6 | project_name: Annotated[str, typer.Option(prompt=True, confirmation_prompt=True)], 7 | ): 8 | print(f"Deleting project {project_name}") 9 | 10 | 11 | if __name__ == "__main__": 12 | typer.run(main) 13 | -------------------------------------------------------------------------------- /docs_src/options/required/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str, lastname: str = typer.Option()): 5 | print(f"Hello {name} {lastname}") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/options/required/tutorial001_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(name: str, lastname: Annotated[str, typer.Option()]): 6 | print(f"Hello {name} {lastname}") 7 | 8 | 9 | if __name__ == "__main__": 10 | typer.run(main) 11 | -------------------------------------------------------------------------------- /docs_src/options/required/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str, lastname: str = typer.Option(default=...)): 5 | print(f"Hello {name} {lastname}") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/options/version/tutorial001.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | import typer 4 | 5 | __version__ = "0.1.0" 6 | 7 | 8 | def version_callback(value: bool): 9 | if value: 10 | print(f"Awesome CLI Version: {__version__}") 11 | raise typer.Exit() 12 | 13 | 14 | def main( 15 | name: str = typer.Option("World"), 16 | version: Optional[bool] = typer.Option( 17 | None, "--version", callback=version_callback 18 | ), 19 | ): 20 | print(f"Hello {name}") 21 | 22 | 23 | if __name__ == "__main__": 24 | typer.run(main) 25 | -------------------------------------------------------------------------------- /docs_src/options/version/tutorial001_an.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | import typer 4 | from typing_extensions import Annotated 5 | 6 | __version__ = "0.1.0" 7 | 8 | 9 | def version_callback(value: bool): 10 | if value: 11 | print(f"Awesome CLI Version: {__version__}") 12 | raise typer.Exit() 13 | 14 | 15 | def main( 16 | name: Annotated[str, typer.Option()] = "World", 17 | version: Annotated[ 18 | Optional[bool], typer.Option("--version", callback=version_callback) 19 | ] = None, 20 | ): 21 | print(f"Hello {name}") 22 | 23 | 24 | if __name__ == "__main__": 25 | typer.run(main) 26 | -------------------------------------------------------------------------------- /docs_src/options/version/tutorial002.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | import typer 4 | 5 | __version__ = "0.1.0" 6 | 7 | 8 | def version_callback(value: bool): 9 | if value: 10 | print(f"Awesome CLI Version: {__version__}") 11 | raise typer.Exit() 12 | 13 | 14 | def name_callback(name: str): 15 | if name != "Camila": 16 | raise typer.BadParameter("Only Camila is allowed") 17 | 18 | 19 | def main( 20 | name: str = typer.Option(..., callback=name_callback), 21 | version: Optional[bool] = typer.Option( 22 | None, "--version", callback=version_callback 23 | ), 24 | ): 25 | print(f"Hello {name}") 26 | 27 | 28 | if __name__ == "__main__": 29 | typer.run(main) 30 | -------------------------------------------------------------------------------- /docs_src/options/version/tutorial002_an.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | import typer 4 | from typing_extensions import Annotated 5 | 6 | __version__ = "0.1.0" 7 | 8 | 9 | def version_callback(value: bool): 10 | if value: 11 | print(f"Awesome CLI Version: {__version__}") 12 | raise typer.Exit() 13 | 14 | 15 | def name_callback(name: str): 16 | if name != "Camila": 17 | raise typer.BadParameter("Only Camila is allowed") 18 | 19 | 20 | def main( 21 | name: Annotated[str, typer.Option(callback=name_callback)], 22 | version: Annotated[ 23 | Optional[bool], typer.Option("--version", callback=version_callback) 24 | ] = None, 25 | ): 26 | print(f"Hello {name}") 27 | 28 | 29 | if __name__ == "__main__": 30 | typer.run(main) 31 | -------------------------------------------------------------------------------- /docs_src/options/version/tutorial003.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | import typer 4 | 5 | __version__ = "0.1.0" 6 | 7 | 8 | def version_callback(value: bool): 9 | if value: 10 | print(f"Awesome CLI Version: {__version__}") 11 | raise typer.Exit() 12 | 13 | 14 | def name_callback(name: str): 15 | if name != "Camila": 16 | raise typer.BadParameter("Only Camila is allowed") 17 | return name 18 | 19 | 20 | def main( 21 | name: str = typer.Option(..., callback=name_callback), 22 | version: Optional[bool] = typer.Option( 23 | None, "--version", callback=version_callback, is_eager=True 24 | ), 25 | ): 26 | print(f"Hello {name}") 27 | 28 | 29 | if __name__ == "__main__": 30 | typer.run(main) 31 | -------------------------------------------------------------------------------- /docs_src/options/version/tutorial003_an.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | import typer 4 | from typing_extensions import Annotated 5 | 6 | __version__ = "0.1.0" 7 | 8 | 9 | def version_callback(value: bool): 10 | if value: 11 | print(f"Awesome CLI Version: {__version__}") 12 | raise typer.Exit() 13 | 14 | 15 | def name_callback(name: str): 16 | if name != "Camila": 17 | raise typer.BadParameter("Only Camila is allowed") 18 | return name 19 | 20 | 21 | def main( 22 | name: Annotated[str, typer.Option(callback=name_callback)], 23 | version: Annotated[ 24 | Optional[bool], 25 | typer.Option("--version", callback=version_callback, is_eager=True), 26 | ] = None, 27 | ): 28 | print(f"Hello {name}") 29 | 30 | 31 | if __name__ == "__main__": 32 | typer.run(main) 33 | -------------------------------------------------------------------------------- /docs_src/options_autocompletion/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def main(name: str = typer.Option("World", help="The name to say hi to.")): 8 | print(f"Hello {name}") 9 | 10 | 11 | if __name__ == "__main__": 12 | app() 13 | -------------------------------------------------------------------------------- /docs_src/options_autocompletion/tutorial001_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | app = typer.Typer() 5 | 6 | 7 | @app.command() 8 | def main(name: Annotated[str, typer.Option(help="The name to say hi to.")] = "World"): 9 | print(f"Hello {name}") 10 | 11 | 12 | if __name__ == "__main__": 13 | app() 14 | -------------------------------------------------------------------------------- /docs_src/options_autocompletion/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def complete_name(): 5 | return ["Camila", "Carlos", "Sebastian"] 6 | 7 | 8 | app = typer.Typer() 9 | 10 | 11 | @app.command() 12 | def main( 13 | name: str = typer.Option( 14 | "World", help="The name to say hi to.", autocompletion=complete_name 15 | ), 16 | ): 17 | print(f"Hello {name}") 18 | 19 | 20 | if __name__ == "__main__": 21 | app() 22 | -------------------------------------------------------------------------------- /docs_src/options_autocompletion/tutorial002_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def complete_name(): 6 | return ["Camila", "Carlos", "Sebastian"] 7 | 8 | 9 | app = typer.Typer() 10 | 11 | 12 | @app.command() 13 | def main( 14 | name: Annotated[ 15 | str, typer.Option(help="The name to say hi to.", autocompletion=complete_name) 16 | ] = "World", 17 | ): 18 | print(f"Hello {name}") 19 | 20 | 21 | if __name__ == "__main__": 22 | app() 23 | -------------------------------------------------------------------------------- /docs_src/options_autocompletion/tutorial003.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | valid_names = ["Camila", "Carlos", "Sebastian"] 4 | 5 | 6 | def complete_name(incomplete: str): 7 | completion = [] 8 | for name in valid_names: 9 | if name.startswith(incomplete): 10 | completion.append(name) 11 | return completion 12 | 13 | 14 | app = typer.Typer() 15 | 16 | 17 | @app.command() 18 | def main( 19 | name: str = typer.Option( 20 | "World", help="The name to say hi to.", autocompletion=complete_name 21 | ), 22 | ): 23 | print(f"Hello {name}") 24 | 25 | 26 | if __name__ == "__main__": 27 | app() 28 | -------------------------------------------------------------------------------- /docs_src/options_autocompletion/tutorial003_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | valid_names = ["Camila", "Carlos", "Sebastian"] 5 | 6 | 7 | def complete_name(incomplete: str): 8 | completion = [] 9 | for name in valid_names: 10 | if name.startswith(incomplete): 11 | completion.append(name) 12 | return completion 13 | 14 | 15 | app = typer.Typer() 16 | 17 | 18 | @app.command() 19 | def main( 20 | name: Annotated[ 21 | str, typer.Option(help="The name to say hi to.", autocompletion=complete_name) 22 | ] = "World", 23 | ): 24 | print(f"Hello {name}") 25 | 26 | 27 | if __name__ == "__main__": 28 | app() 29 | -------------------------------------------------------------------------------- /docs_src/options_autocompletion/tutorial004.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | valid_completion_items = [ 4 | ("Camila", "The reader of books."), 5 | ("Carlos", "The writer of scripts."), 6 | ("Sebastian", "The type hints guy."), 7 | ] 8 | 9 | 10 | def complete_name(incomplete: str): 11 | completion = [] 12 | for name, help_text in valid_completion_items: 13 | if name.startswith(incomplete): 14 | completion_item = (name, help_text) 15 | completion.append(completion_item) 16 | return completion 17 | 18 | 19 | app = typer.Typer() 20 | 21 | 22 | @app.command() 23 | def main( 24 | name: str = typer.Option( 25 | "World", help="The name to say hi to.", autocompletion=complete_name 26 | ), 27 | ): 28 | print(f"Hello {name}") 29 | 30 | 31 | if __name__ == "__main__": 32 | app() 33 | -------------------------------------------------------------------------------- /docs_src/options_autocompletion/tutorial004_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | valid_completion_items = [ 5 | ("Camila", "The reader of books."), 6 | ("Carlos", "The writer of scripts."), 7 | ("Sebastian", "The type hints guy."), 8 | ] 9 | 10 | 11 | def complete_name(incomplete: str): 12 | completion = [] 13 | for name, help_text in valid_completion_items: 14 | if name.startswith(incomplete): 15 | completion_item = (name, help_text) 16 | completion.append(completion_item) 17 | return completion 18 | 19 | 20 | app = typer.Typer() 21 | 22 | 23 | @app.command() 24 | def main( 25 | name: Annotated[ 26 | str, typer.Option(help="The name to say hi to.", autocompletion=complete_name) 27 | ] = "World", 28 | ): 29 | print(f"Hello {name}") 30 | 31 | 32 | if __name__ == "__main__": 33 | app() 34 | -------------------------------------------------------------------------------- /docs_src/options_autocompletion/tutorial005.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | valid_completion_items = [ 4 | ("Camila", "The reader of books."), 5 | ("Carlos", "The writer of scripts."), 6 | ("Sebastian", "The type hints guy."), 7 | ] 8 | 9 | 10 | def complete_name(incomplete: str): 11 | for name, help_text in valid_completion_items: 12 | if name.startswith(incomplete): 13 | yield (name, help_text) 14 | 15 | 16 | app = typer.Typer() 17 | 18 | 19 | @app.command() 20 | def main( 21 | name: str = typer.Option( 22 | "World", help="The name to say hi to.", autocompletion=complete_name 23 | ), 24 | ): 25 | print(f"Hello {name}") 26 | 27 | 28 | if __name__ == "__main__": 29 | app() 30 | -------------------------------------------------------------------------------- /docs_src/options_autocompletion/tutorial005_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | valid_completion_items = [ 5 | ("Camila", "The reader of books."), 6 | ("Carlos", "The writer of scripts."), 7 | ("Sebastian", "The type hints guy."), 8 | ] 9 | 10 | 11 | def complete_name(incomplete: str): 12 | for name, help_text in valid_completion_items: 13 | if name.startswith(incomplete): 14 | yield (name, help_text) 15 | 16 | 17 | app = typer.Typer() 18 | 19 | 20 | @app.command() 21 | def main( 22 | name: Annotated[ 23 | str, typer.Option(help="The name to say hi to.", autocompletion=complete_name) 24 | ] = "World", 25 | ): 26 | print(f"Hello {name}") 27 | 28 | 29 | if __name__ == "__main__": 30 | app() 31 | -------------------------------------------------------------------------------- /docs_src/options_autocompletion/tutorial006.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | import typer 4 | 5 | app = typer.Typer() 6 | 7 | 8 | @app.command() 9 | def main(name: List[str] = typer.Option(["World"], help="The name to say hi to.")): 10 | for each_name in name: 11 | print(f"Hello {each_name}") 12 | 13 | 14 | if __name__ == "__main__": 15 | app() 16 | -------------------------------------------------------------------------------- /docs_src/options_autocompletion/tutorial006_an.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | import typer 4 | from typing_extensions import Annotated 5 | 6 | app = typer.Typer() 7 | 8 | 9 | @app.command() 10 | def main( 11 | name: Annotated[List[str], typer.Option(help="The name to say hi to.")] = ["World"], 12 | ): 13 | for each_name in name: 14 | print(f"Hello {each_name}") 15 | 16 | 17 | if __name__ == "__main__": 18 | app() 19 | -------------------------------------------------------------------------------- /docs_src/options_autocompletion/tutorial007.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | import typer 4 | 5 | valid_completion_items = [ 6 | ("Camila", "The reader of books."), 7 | ("Carlos", "The writer of scripts."), 8 | ("Sebastian", "The type hints guy."), 9 | ] 10 | 11 | 12 | def complete_name(ctx: typer.Context, incomplete: str): 13 | names = ctx.params.get("name") or [] 14 | for name, help_text in valid_completion_items: 15 | if name.startswith(incomplete) and name not in names: 16 | yield (name, help_text) 17 | 18 | 19 | app = typer.Typer() 20 | 21 | 22 | @app.command() 23 | def main( 24 | name: List[str] = typer.Option( 25 | ["World"], help="The name to say hi to.", autocompletion=complete_name 26 | ), 27 | ): 28 | for n in name: 29 | print(f"Hello {n}") 30 | 31 | 32 | if __name__ == "__main__": 33 | app() 34 | -------------------------------------------------------------------------------- /docs_src/options_autocompletion/tutorial007_an.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | import typer 4 | from typing_extensions import Annotated 5 | 6 | valid_completion_items = [ 7 | ("Camila", "The reader of books."), 8 | ("Carlos", "The writer of scripts."), 9 | ("Sebastian", "The type hints guy."), 10 | ] 11 | 12 | 13 | def complete_name(ctx: typer.Context, incomplete: str): 14 | names = ctx.params.get("name") or [] 15 | for name, help_text in valid_completion_items: 16 | if name.startswith(incomplete) and name not in names: 17 | yield (name, help_text) 18 | 19 | 20 | app = typer.Typer() 21 | 22 | 23 | @app.command() 24 | def main( 25 | name: Annotated[ 26 | List[str], 27 | typer.Option(help="The name to say hi to.", autocompletion=complete_name), 28 | ] = ["World"], 29 | ): 30 | for n in name: 31 | print(f"Hello {n}") 32 | 33 | 34 | if __name__ == "__main__": 35 | app() 36 | -------------------------------------------------------------------------------- /docs_src/options_autocompletion/tutorial008.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | import typer 4 | from rich.console import Console 5 | 6 | valid_completion_items = [ 7 | ("Camila", "The reader of books."), 8 | ("Carlos", "The writer of scripts."), 9 | ("Sebastian", "The type hints guy."), 10 | ] 11 | 12 | err_console = Console(stderr=True) 13 | 14 | 15 | def complete_name(args: List[str], incomplete: str): 16 | err_console.print(f"{args}") 17 | for name, help_text in valid_completion_items: 18 | if name.startswith(incomplete): 19 | yield (name, help_text) 20 | 21 | 22 | app = typer.Typer() 23 | 24 | 25 | @app.command() 26 | def main( 27 | name: List[str] = typer.Option( 28 | ["World"], help="The name to say hi to.", autocompletion=complete_name 29 | ), 30 | ): 31 | for n in name: 32 | print(f"Hello {n}") 33 | 34 | 35 | if __name__ == "__main__": 36 | app() 37 | -------------------------------------------------------------------------------- /docs_src/parameter_types/bool/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/docs_src/parameter_types/bool/__init__.py -------------------------------------------------------------------------------- /docs_src/parameter_types/bool/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(force: bool = typer.Option(False, "--force")): 5 | if force: 6 | print("Forcing operation") 7 | else: 8 | print("Not forcing") 9 | 10 | 11 | if __name__ == "__main__": 12 | typer.run(main) 13 | -------------------------------------------------------------------------------- /docs_src/parameter_types/bool/tutorial001_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(force: Annotated[bool, typer.Option("--force")] = False): 6 | if force: 7 | print("Forcing operation") 8 | else: 9 | print("Not forcing") 10 | 11 | 12 | if __name__ == "__main__": 13 | typer.run(main) 14 | -------------------------------------------------------------------------------- /docs_src/parameter_types/bool/tutorial002.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | import typer 4 | 5 | 6 | def main(accept: Optional[bool] = typer.Option(None, "--accept/--reject")): 7 | if accept is None: 8 | print("I don't know what you want yet") 9 | elif accept: 10 | print("Accepting!") 11 | else: 12 | print("Rejecting!") 13 | 14 | 15 | if __name__ == "__main__": 16 | typer.run(main) 17 | -------------------------------------------------------------------------------- /docs_src/parameter_types/bool/tutorial002_an.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | import typer 4 | from typing_extensions import Annotated 5 | 6 | 7 | def main(accept: Annotated[Optional[bool], typer.Option("--accept/--reject")] = None): 8 | if accept is None: 9 | print("I don't know what you want yet") 10 | elif accept: 11 | print("Accepting!") 12 | else: 13 | print("Rejecting!") 14 | 15 | 16 | if __name__ == "__main__": 17 | typer.run(main) 18 | -------------------------------------------------------------------------------- /docs_src/parameter_types/bool/tutorial003.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(force: bool = typer.Option(False, "--force/--no-force", "-f/-F")): 5 | if force: 6 | print("Forcing operation") 7 | else: 8 | print("Not forcing") 9 | 10 | 11 | if __name__ == "__main__": 12 | typer.run(main) 13 | -------------------------------------------------------------------------------- /docs_src/parameter_types/bool/tutorial003_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(force: Annotated[bool, typer.Option("--force/--no-force", "-f/-F")] = False): 6 | if force: 7 | print("Forcing operation") 8 | else: 9 | print("Not forcing") 10 | 11 | 12 | if __name__ == "__main__": 13 | typer.run(main) 14 | -------------------------------------------------------------------------------- /docs_src/parameter_types/bool/tutorial004.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(in_prod: bool = typer.Option(True, " /--demo", " /-d")): 5 | if in_prod: 6 | print("Running in production") 7 | else: 8 | print("Running demo") 9 | 10 | 11 | if __name__ == "__main__": 12 | typer.run(main) 13 | -------------------------------------------------------------------------------- /docs_src/parameter_types/bool/tutorial004_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(in_prod: Annotated[bool, typer.Option(" /--demo", " /-d")] = True): 6 | if in_prod: 7 | print("Running in production") 8 | else: 9 | print("Running demo") 10 | 11 | 12 | if __name__ == "__main__": 13 | typer.run(main) 14 | -------------------------------------------------------------------------------- /docs_src/parameter_types/custom_types/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/docs_src/parameter_types/custom_types/__init__.py -------------------------------------------------------------------------------- /docs_src/parameter_types/custom_types/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | class CustomClass: 5 | def __init__(self, value: str): 6 | self.value = value 7 | 8 | def __str__(self): 9 | return f"" 10 | 11 | 12 | def parse_custom_class(value: str): 13 | return CustomClass(value * 2) 14 | 15 | 16 | def main( 17 | custom_arg: CustomClass = typer.Argument(parser=parse_custom_class), 18 | custom_opt: CustomClass = typer.Option("Foo", parser=parse_custom_class), 19 | ): 20 | print(f"custom_arg is {custom_arg}") 21 | print(f"--custom-opt is {custom_opt}") 22 | 23 | 24 | if __name__ == "__main__": 25 | typer.run(main) 26 | -------------------------------------------------------------------------------- /docs_src/parameter_types/custom_types/tutorial001_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | class CustomClass: 6 | def __init__(self, value: str): 7 | self.value = value 8 | 9 | def __str__(self): 10 | return f"" 11 | 12 | 13 | def parse_custom_class(value: str): 14 | return CustomClass(value * 2) 15 | 16 | 17 | def main( 18 | custom_arg: Annotated[CustomClass, typer.Argument(parser=parse_custom_class)], 19 | custom_opt: Annotated[CustomClass, typer.Option(parser=parse_custom_class)] = "Foo", 20 | ): 21 | print(f"custom_arg is {custom_arg}") 22 | print(f"--custom-opt is {custom_opt}") 23 | 24 | 25 | if __name__ == "__main__": 26 | typer.run(main) 27 | -------------------------------------------------------------------------------- /docs_src/parameter_types/custom_types/tutorial002.py: -------------------------------------------------------------------------------- 1 | import click 2 | import typer 3 | 4 | 5 | class CustomClass: 6 | def __init__(self, value: str): 7 | self.value = value 8 | 9 | def __repr__(self): 10 | return f"" 11 | 12 | 13 | class CustomClassParser(click.ParamType): 14 | name = "CustomClass" 15 | 16 | def convert(self, value, param, ctx): 17 | return CustomClass(value * 3) 18 | 19 | 20 | def main( 21 | custom_arg: CustomClass = typer.Argument(click_type=CustomClassParser()), 22 | custom_opt: CustomClass = typer.Option("Foo", click_type=CustomClassParser()), 23 | ): 24 | print(f"custom_arg is {custom_arg}") 25 | print(f"--custom-opt is {custom_opt}") 26 | 27 | 28 | if __name__ == "__main__": 29 | typer.run(main) 30 | -------------------------------------------------------------------------------- /docs_src/parameter_types/custom_types/tutorial002_an.py: -------------------------------------------------------------------------------- 1 | import click 2 | import typer 3 | from typing_extensions import Annotated 4 | 5 | 6 | class CustomClass: 7 | def __init__(self, value: str): 8 | self.value = value 9 | 10 | def __repr__(self): 11 | return f"" 12 | 13 | 14 | class CustomClassParser(click.ParamType): 15 | name = "CustomClass" 16 | 17 | def convert(self, value, param, ctx): 18 | return CustomClass(value * 3) 19 | 20 | 21 | def main( 22 | custom_arg: Annotated[CustomClass, typer.Argument(click_type=CustomClassParser())], 23 | custom_opt: Annotated[ 24 | CustomClass, typer.Option(click_type=CustomClassParser()) 25 | ] = "Foo", 26 | ): 27 | print(f"custom_arg is {custom_arg}") 28 | print(f"--custom-opt is {custom_opt}") 29 | 30 | 31 | if __name__ == "__main__": 32 | typer.run(main) 33 | -------------------------------------------------------------------------------- /docs_src/parameter_types/datetime/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/docs_src/parameter_types/datetime/__init__.py -------------------------------------------------------------------------------- /docs_src/parameter_types/datetime/tutorial001.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | 3 | import typer 4 | 5 | 6 | def main(birth: datetime): 7 | print(f"Interesting day to be born: {birth}") 8 | print(f"Birth hour: {birth.hour}") 9 | 10 | 11 | if __name__ == "__main__": 12 | typer.run(main) 13 | -------------------------------------------------------------------------------- /docs_src/parameter_types/datetime/tutorial002.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | 3 | import typer 4 | 5 | 6 | def main( 7 | launch_date: datetime = typer.Argument( 8 | ..., formats=["%Y-%m-%d", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d %H:%M:%S", "%m/%d/%Y"] 9 | ), 10 | ): 11 | print(f"Launch will be at: {launch_date}") 12 | 13 | 14 | if __name__ == "__main__": 15 | typer.run(main) 16 | -------------------------------------------------------------------------------- /docs_src/parameter_types/datetime/tutorial002_an.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | 3 | import typer 4 | from typing_extensions import Annotated 5 | 6 | 7 | def main( 8 | launch_date: Annotated[ 9 | datetime, 10 | typer.Argument( 11 | formats=["%Y-%m-%d", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d %H:%M:%S", "%m/%d/%Y"] 12 | ), 13 | ], 14 | ): 15 | print(f"Launch will be at: {launch_date}") 16 | 17 | 18 | if __name__ == "__main__": 19 | typer.run(main) 20 | -------------------------------------------------------------------------------- /docs_src/parameter_types/enum/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/docs_src/parameter_types/enum/__init__.py -------------------------------------------------------------------------------- /docs_src/parameter_types/enum/tutorial001.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | import typer 4 | 5 | 6 | class NeuralNetwork(str, Enum): 7 | simple = "simple" 8 | conv = "conv" 9 | lstm = "lstm" 10 | 11 | 12 | def main(network: NeuralNetwork = NeuralNetwork.simple): 13 | print(f"Training neural network of type: {network.value}") 14 | 15 | 16 | if __name__ == "__main__": 17 | typer.run(main) 18 | -------------------------------------------------------------------------------- /docs_src/parameter_types/enum/tutorial002.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | import typer 4 | 5 | 6 | class NeuralNetwork(str, Enum): 7 | simple = "simple" 8 | conv = "conv" 9 | lstm = "lstm" 10 | 11 | 12 | def main( 13 | network: NeuralNetwork = typer.Option(NeuralNetwork.simple, case_sensitive=False), 14 | ): 15 | print(f"Training neural network of type: {network.value}") 16 | 17 | 18 | if __name__ == "__main__": 19 | typer.run(main) 20 | -------------------------------------------------------------------------------- /docs_src/parameter_types/enum/tutorial002_an.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | import typer 4 | from typing_extensions import Annotated 5 | 6 | 7 | class NeuralNetwork(str, Enum): 8 | simple = "simple" 9 | conv = "conv" 10 | lstm = "lstm" 11 | 12 | 13 | def main( 14 | network: Annotated[ 15 | NeuralNetwork, typer.Option(case_sensitive=False) 16 | ] = NeuralNetwork.simple, 17 | ): 18 | print(f"Training neural network of type: {network.value}") 19 | 20 | 21 | if __name__ == "__main__": 22 | typer.run(main) 23 | -------------------------------------------------------------------------------- /docs_src/parameter_types/enum/tutorial003.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | from typing import List 3 | 4 | import typer 5 | 6 | 7 | class Food(str, Enum): 8 | food_1 = "Eggs" 9 | food_2 = "Bacon" 10 | food_3 = "Cheese" 11 | 12 | 13 | def main(groceries: List[Food] = typer.Option([Food.food_1, Food.food_3])): 14 | print(f"Buying groceries: {', '.join([f.value for f in groceries])}") 15 | 16 | 17 | if __name__ == "__main__": 18 | typer.run(main) 19 | -------------------------------------------------------------------------------- /docs_src/parameter_types/enum/tutorial003_an.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | from typing import List 3 | 4 | import typer 5 | from typing_extensions import Annotated 6 | 7 | 8 | class Food(str, Enum): 9 | food_1 = "Eggs" 10 | food_2 = "Bacon" 11 | food_3 = "Cheese" 12 | 13 | 14 | def main(groceries: Annotated[List[Food], typer.Option()] = [Food.food_1, Food.food_3]): 15 | print(f"Buying groceries: {', '.join([f.value for f in groceries])}") 16 | 17 | 18 | if __name__ == "__main__": 19 | typer.run(main) 20 | -------------------------------------------------------------------------------- /docs_src/parameter_types/file/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/docs_src/parameter_types/file/__init__.py -------------------------------------------------------------------------------- /docs_src/parameter_types/file/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(config: typer.FileText = typer.Option(...)): 5 | for line in config: 6 | print(f"Config line: {line}") 7 | 8 | 9 | if __name__ == "__main__": 10 | typer.run(main) 11 | -------------------------------------------------------------------------------- /docs_src/parameter_types/file/tutorial001_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(config: Annotated[typer.FileText, typer.Option()]): 6 | for line in config: 7 | print(f"Config line: {line}") 8 | 9 | 10 | if __name__ == "__main__": 11 | typer.run(main) 12 | -------------------------------------------------------------------------------- /docs_src/parameter_types/file/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(config: typer.FileTextWrite = typer.Option(...)): 5 | config.write("Some config written by the app") 6 | print("Config written") 7 | 8 | 9 | if __name__ == "__main__": 10 | typer.run(main) 11 | -------------------------------------------------------------------------------- /docs_src/parameter_types/file/tutorial002_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(config: Annotated[typer.FileTextWrite, typer.Option()]): 6 | config.write("Some config written by the app") 7 | print("Config written") 8 | 9 | 10 | if __name__ == "__main__": 11 | typer.run(main) 12 | -------------------------------------------------------------------------------- /docs_src/parameter_types/file/tutorial003.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(file: typer.FileBinaryRead = typer.Option(...)): 5 | processed_total = 0 6 | for bytes_chunk in file: 7 | # Process the bytes in bytes_chunk 8 | processed_total += len(bytes_chunk) 9 | print(f"Processed bytes total: {processed_total}") 10 | 11 | 12 | if __name__ == "__main__": 13 | typer.run(main) 14 | -------------------------------------------------------------------------------- /docs_src/parameter_types/file/tutorial003_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(file: Annotated[typer.FileBinaryRead, typer.Option()]): 6 | processed_total = 0 7 | for bytes_chunk in file: 8 | # Process the bytes in bytes_chunk 9 | processed_total += len(bytes_chunk) 10 | print(f"Processed bytes total: {processed_total}") 11 | 12 | 13 | if __name__ == "__main__": 14 | typer.run(main) 15 | -------------------------------------------------------------------------------- /docs_src/parameter_types/file/tutorial004.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(file: typer.FileBinaryWrite = typer.Option(...)): 5 | first_line_str = "some settings\n" 6 | # You cannot write str directly to a binary file, you have to encode it to get bytes 7 | first_line_bytes = first_line_str.encode("utf-8") 8 | # Then you can write the bytes 9 | file.write(first_line_bytes) 10 | # This is already bytes, it starts with b" 11 | second_line = b"la cig\xc3\xbce\xc3\xb1a trae al ni\xc3\xb1o" 12 | file.write(second_line) 13 | print("Binary file written") 14 | 15 | 16 | if __name__ == "__main__": 17 | typer.run(main) 18 | -------------------------------------------------------------------------------- /docs_src/parameter_types/file/tutorial004_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(file: Annotated[typer.FileBinaryWrite, typer.Option()]): 6 | first_line_str = "some settings\n" 7 | # You cannot write str directly to a binary file, you have to encode it to get bytes 8 | first_line_bytes = first_line_str.encode("utf-8") 9 | # Then you can write the bytes 10 | file.write(first_line_bytes) 11 | # This is already bytes, it starts with b" 12 | second_line = b"la cig\xc3\xbce\xc3\xb1a trae al ni\xc3\xb1o" 13 | file.write(second_line) 14 | print("Binary file written") 15 | 16 | 17 | if __name__ == "__main__": 18 | typer.run(main) 19 | -------------------------------------------------------------------------------- /docs_src/parameter_types/file/tutorial005.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(config: typer.FileText = typer.Option(..., mode="a")): 5 | config.write("This is a single line\n") 6 | print("Config line written") 7 | 8 | 9 | if __name__ == "__main__": 10 | typer.run(main) 11 | -------------------------------------------------------------------------------- /docs_src/parameter_types/file/tutorial005_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(config: Annotated[typer.FileText, typer.Option(mode="a")]): 6 | config.write("This is a single line\n") 7 | print("Config line written") 8 | 9 | 10 | if __name__ == "__main__": 11 | typer.run(main) 12 | -------------------------------------------------------------------------------- /docs_src/parameter_types/index/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/docs_src/parameter_types/index/__init__.py -------------------------------------------------------------------------------- /docs_src/parameter_types/index/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str, age: int = 20, height_meters: float = 1.89, female: bool = True): 5 | print(f"NAME is {name}, of type: {type(name)}") 6 | print(f"--age is {age}, of type: {type(age)}") 7 | print(f"--height-meters is {height_meters}, of type: {type(height_meters)}") 8 | print(f"--female is {female}, of type: {type(female)}") 9 | 10 | 11 | if __name__ == "__main__": 12 | typer.run(main) 13 | -------------------------------------------------------------------------------- /docs_src/parameter_types/number/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/docs_src/parameter_types/number/__init__.py -------------------------------------------------------------------------------- /docs_src/parameter_types/number/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main( 5 | id: int = typer.Argument(..., min=0, max=1000), 6 | age: int = typer.Option(20, min=18), 7 | score: float = typer.Option(0, max=100), 8 | ): 9 | print(f"ID is {id}") 10 | print(f"--age is {age}") 11 | print(f"--score is {score}") 12 | 13 | 14 | if __name__ == "__main__": 15 | typer.run(main) 16 | -------------------------------------------------------------------------------- /docs_src/parameter_types/number/tutorial001_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main( 6 | id: Annotated[int, typer.Argument(min=0, max=1000)], 7 | age: Annotated[int, typer.Option(min=18)] = 20, 8 | score: Annotated[float, typer.Option(max=100)] = 0, 9 | ): 10 | print(f"ID is {id}") 11 | print(f"--age is {age}") 12 | print(f"--score is {score}") 13 | 14 | 15 | if __name__ == "__main__": 16 | typer.run(main) 17 | -------------------------------------------------------------------------------- /docs_src/parameter_types/number/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main( 5 | id: int = typer.Argument(..., min=0, max=1000), 6 | rank: int = typer.Option(0, max=10, clamp=True), 7 | score: float = typer.Option(0, min=0, max=100, clamp=True), 8 | ): 9 | print(f"ID is {id}") 10 | print(f"--rank is {rank}") 11 | print(f"--score is {score}") 12 | 13 | 14 | if __name__ == "__main__": 15 | typer.run(main) 16 | -------------------------------------------------------------------------------- /docs_src/parameter_types/number/tutorial002_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main( 6 | id: Annotated[int, typer.Argument(min=0, max=1000)], 7 | rank: Annotated[int, typer.Option(max=10, clamp=True)] = 0, 8 | score: Annotated[float, typer.Option(min=0, max=100, clamp=True)] = 0, 9 | ): 10 | print(f"ID is {id}") 11 | print(f"--rank is {rank}") 12 | print(f"--score is {score}") 13 | 14 | 15 | if __name__ == "__main__": 16 | typer.run(main) 17 | -------------------------------------------------------------------------------- /docs_src/parameter_types/number/tutorial003.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(verbose: int = typer.Option(0, "--verbose", "-v", count=True)): 5 | print(f"Verbose level is {verbose}") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/parameter_types/number/tutorial003_an.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | 5 | def main(verbose: Annotated[int, typer.Option("--verbose", "-v", count=True)] = 0): 6 | print(f"Verbose level is {verbose}") 7 | 8 | 9 | if __name__ == "__main__": 10 | typer.run(main) 11 | -------------------------------------------------------------------------------- /docs_src/parameter_types/path/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/docs_src/parameter_types/path/__init__.py -------------------------------------------------------------------------------- /docs_src/parameter_types/path/tutorial001.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | from typing import Optional 3 | 4 | import typer 5 | 6 | 7 | def main(config: Optional[Path] = typer.Option(None)): 8 | if config is None: 9 | print("No config file") 10 | raise typer.Abort() 11 | if config.is_file(): 12 | text = config.read_text() 13 | print(f"Config file contents: {text}") 14 | elif config.is_dir(): 15 | print("Config is a directory, will use all its config files") 16 | elif not config.exists(): 17 | print("The config doesn't exist") 18 | 19 | 20 | if __name__ == "__main__": 21 | typer.run(main) 22 | -------------------------------------------------------------------------------- /docs_src/parameter_types/path/tutorial001_an.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | from typing import Optional 3 | 4 | import typer 5 | from typing_extensions import Annotated 6 | 7 | 8 | def main(config: Annotated[Optional[Path], typer.Option()] = None): 9 | if config is None: 10 | print("No config file") 11 | raise typer.Abort() 12 | if config.is_file(): 13 | text = config.read_text() 14 | print(f"Config file contents: {text}") 15 | elif config.is_dir(): 16 | print("Config is a directory, will use all its config files") 17 | elif not config.exists(): 18 | print("The config doesn't exist") 19 | 20 | 21 | if __name__ == "__main__": 22 | typer.run(main) 23 | -------------------------------------------------------------------------------- /docs_src/parameter_types/path/tutorial002.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | import typer 4 | 5 | 6 | def main( 7 | config: Path = typer.Option( 8 | ..., 9 | exists=True, 10 | file_okay=True, 11 | dir_okay=False, 12 | writable=False, 13 | readable=True, 14 | resolve_path=True, 15 | ), 16 | ): 17 | text = config.read_text() 18 | print(f"Config file contents: {text}") 19 | 20 | 21 | if __name__ == "__main__": 22 | typer.run(main) 23 | -------------------------------------------------------------------------------- /docs_src/parameter_types/path/tutorial002_an.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | import typer 4 | from typing_extensions import Annotated 5 | 6 | 7 | def main( 8 | config: Annotated[ 9 | Path, 10 | typer.Option( 11 | exists=True, 12 | file_okay=True, 13 | dir_okay=False, 14 | writable=False, 15 | readable=True, 16 | resolve_path=True, 17 | ), 18 | ], 19 | ): 20 | text = config.read_text() 21 | print(f"Config file contents: {text}") 22 | 23 | 24 | if __name__ == "__main__": 25 | typer.run(main) 26 | -------------------------------------------------------------------------------- /docs_src/parameter_types/uuid/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/docs_src/parameter_types/uuid/__init__.py -------------------------------------------------------------------------------- /docs_src/parameter_types/uuid/tutorial001.py: -------------------------------------------------------------------------------- 1 | from uuid import UUID 2 | 3 | import typer 4 | 5 | 6 | def main(user_id: UUID): 7 | print(f"USER_ID is {user_id}") 8 | print(f"UUID version is: {user_id.version}") 9 | 10 | 11 | if __name__ == "__main__": 12 | typer.run(main) 13 | -------------------------------------------------------------------------------- /docs_src/printing/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from rich import print 3 | 4 | data = { 5 | "name": "Rick", 6 | "age": 42, 7 | "items": [{"name": "Portal Gun"}, {"name": "Plumbus"}], 8 | "active": True, 9 | "affiliation": None, 10 | } 11 | 12 | 13 | def main(): 14 | print("Here's the data") 15 | print(data) 16 | 17 | 18 | if __name__ == "__main__": 19 | typer.run(main) 20 | -------------------------------------------------------------------------------- /docs_src/printing/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from rich import print 3 | 4 | 5 | def main(): 6 | print("[bold red]Alert![/bold red] [green]Portal gun[/green] shooting! :boom:") 7 | 8 | 9 | if __name__ == "__main__": 10 | typer.run(main) 11 | -------------------------------------------------------------------------------- /docs_src/printing/tutorial003.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from rich.console import Console 3 | from rich.table import Table 4 | 5 | console = Console() 6 | 7 | 8 | def main(): 9 | table = Table("Name", "Item") 10 | table.add_row("Rick", "Portal Gun") 11 | table.add_row("Morty", "Plumbus") 12 | console.print(table) 13 | 14 | 15 | if __name__ == "__main__": 16 | typer.run(main) 17 | -------------------------------------------------------------------------------- /docs_src/printing/tutorial004.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from rich.console import Console 3 | 4 | err_console = Console(stderr=True) 5 | 6 | 7 | def main(): 8 | err_console.print("Here is something written to standard error") 9 | 10 | 11 | if __name__ == "__main__": 12 | typer.run(main) 13 | -------------------------------------------------------------------------------- /docs_src/printing/tutorial005.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(good: bool = True): 5 | message_start = "everything is " 6 | if good: 7 | ending = typer.style("good", fg=typer.colors.GREEN, bold=True) 8 | else: 9 | ending = typer.style("bad", fg=typer.colors.WHITE, bg=typer.colors.RED) 10 | message = message_start + ending 11 | typer.echo(message) 12 | 13 | 14 | if __name__ == "__main__": 15 | typer.run(main) 16 | -------------------------------------------------------------------------------- /docs_src/printing/tutorial006.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str): 5 | typer.secho(f"Welcome here {name}", fg=typer.colors.MAGENTA) 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/progressbar/tutorial001.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | import typer 4 | from rich.progress import track 5 | 6 | 7 | def main(): 8 | total = 0 9 | for value in track(range(100), description="Processing..."): 10 | # Fake processing time 11 | time.sleep(0.01) 12 | total += 1 13 | print(f"Processed {total} things.") 14 | 15 | 16 | if __name__ == "__main__": 17 | typer.run(main) 18 | -------------------------------------------------------------------------------- /docs_src/progressbar/tutorial002.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | import typer 4 | from rich.progress import Progress, SpinnerColumn, TextColumn 5 | 6 | 7 | def main(): 8 | with Progress( 9 | SpinnerColumn(), 10 | TextColumn("[progress.description]{task.description}"), 11 | transient=True, 12 | ) as progress: 13 | progress.add_task(description="Processing...", total=None) 14 | progress.add_task(description="Preparing...", total=None) 15 | time.sleep(5) 16 | print("Done!") 17 | 18 | 19 | if __name__ == "__main__": 20 | typer.run(main) 21 | -------------------------------------------------------------------------------- /docs_src/progressbar/tutorial003.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | import typer 4 | 5 | 6 | def main(): 7 | total = 0 8 | with typer.progressbar(range(100)) as progress: 9 | for value in progress: 10 | # Fake processing time 11 | time.sleep(0.01) 12 | total += 1 13 | print(f"Processed {total} things.") 14 | 15 | 16 | if __name__ == "__main__": 17 | typer.run(main) 18 | -------------------------------------------------------------------------------- /docs_src/progressbar/tutorial004.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | import typer 4 | 5 | 6 | def iterate_user_ids(): 7 | # Let's imagine this is a web API, not a range() 8 | for i in range(100): 9 | yield i 10 | 11 | 12 | def main(): 13 | total = 0 14 | with typer.progressbar(iterate_user_ids(), length=100) as progress: 15 | for value in progress: 16 | # Fake processing time 17 | time.sleep(0.01) 18 | total += 1 19 | print(f"Processed {total} user IDs.") 20 | 21 | 22 | if __name__ == "__main__": 23 | typer.run(main) 24 | -------------------------------------------------------------------------------- /docs_src/progressbar/tutorial005.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | import typer 4 | 5 | 6 | def main(): 7 | total = 0 8 | with typer.progressbar(range(100), label="Processing") as progress: 9 | for value in progress: 10 | # Fake processing time 11 | time.sleep(0.01) 12 | total += 1 13 | print(f"Processed {total} things.") 14 | 15 | 16 | if __name__ == "__main__": 17 | typer.run(main) 18 | -------------------------------------------------------------------------------- /docs_src/progressbar/tutorial006.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | import typer 4 | 5 | 6 | def main(): 7 | total = 1000 8 | with typer.progressbar(length=total) as progress: 9 | for batch in range(4): 10 | # Fake processing time 11 | time.sleep(1) 12 | # Increment by 250 on each loop iteration 13 | # (it will take 4 seconds to reach 1000) 14 | progress.update(250) 15 | print(f"Processed {total} things in batches.") 16 | 17 | 18 | if __name__ == "__main__": 19 | typer.run(main) 20 | -------------------------------------------------------------------------------- /docs_src/prompt/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(): 5 | person_name = typer.prompt("What's your name?") 6 | print(f"Hello {person_name}") 7 | 8 | 9 | if __name__ == "__main__": 10 | typer.run(main) 11 | -------------------------------------------------------------------------------- /docs_src/prompt/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(): 5 | delete = typer.confirm("Are you sure you want to delete it?") 6 | if not delete: 7 | print("Not deleting") 8 | raise typer.Abort() 9 | print("Deleting it!") 10 | 11 | 12 | if __name__ == "__main__": 13 | typer.run(main) 14 | -------------------------------------------------------------------------------- /docs_src/prompt/tutorial003.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(): 5 | delete = typer.confirm("Are you sure you want to delete it?", abort=True) 6 | print("Deleting it!") 7 | 8 | 9 | if __name__ == "__main__": 10 | typer.run(main) 11 | -------------------------------------------------------------------------------- /docs_src/prompt/tutorial004.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from rich.prompt import Prompt 3 | 4 | 5 | def main(): 6 | name = Prompt.ask("Enter your name :sunglasses:") 7 | print(f"Hey there {name}!") 8 | 9 | 10 | if __name__ == "__main__": 11 | typer.run(main) 12 | -------------------------------------------------------------------------------- /docs_src/subcommands/callback_override/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | users_app = typer.Typer() 6 | app.add_typer(users_app, name="users") 7 | 8 | 9 | @users_app.callback() 10 | def users_callback(): 11 | print("Running a users command") 12 | 13 | 14 | @users_app.command() 15 | def create(name: str): 16 | print(f"Creating user: {name}") 17 | 18 | 19 | if __name__ == "__main__": 20 | app() 21 | -------------------------------------------------------------------------------- /docs_src/subcommands/callback_override/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | def users_callback(): 7 | print("Running a users command") 8 | 9 | 10 | users_app = typer.Typer(callback=users_callback) 11 | app.add_typer(users_app, name="users") 12 | 13 | 14 | @users_app.command() 15 | def create(name: str): 16 | print(f"Creating user: {name}") 17 | 18 | 19 | if __name__ == "__main__": 20 | app() 21 | -------------------------------------------------------------------------------- /docs_src/subcommands/callback_override/tutorial003.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | def default_callback(): 7 | print("Running a users command") 8 | 9 | 10 | users_app = typer.Typer(callback=default_callback) 11 | app.add_typer(users_app, name="users") 12 | 13 | 14 | @users_app.callback() 15 | def user_callback(): 16 | print("Callback override, running users command") 17 | 18 | 19 | @users_app.command() 20 | def create(name: str): 21 | print(f"Creating user: {name}") 22 | 23 | 24 | if __name__ == "__main__": 25 | app() 26 | -------------------------------------------------------------------------------- /docs_src/subcommands/callback_override/tutorial004.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | def default_callback(): 7 | print("Running a users command") 8 | 9 | 10 | users_app = typer.Typer(callback=default_callback) 11 | 12 | 13 | def callback_for_add_typer(): 14 | print("I have the high land! Running users command") 15 | 16 | 17 | app.add_typer(users_app, name="users", callback=callback_for_add_typer) 18 | 19 | 20 | @users_app.callback() 21 | def user_callback(): 22 | print("Callback override, running users command") 23 | 24 | 25 | @users_app.command() 26 | def create(name: str): 27 | print(f"Creating user: {name}") 28 | 29 | 30 | if __name__ == "__main__": 31 | app() 32 | -------------------------------------------------------------------------------- /docs_src/subcommands/name_help/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | users_app = typer.Typer() 6 | app.add_typer(users_app, name="users", help="Manage users in the app.") 7 | 8 | 9 | @users_app.command() 10 | def create(name: str): 11 | print(f"Creating user: {name}") 12 | 13 | 14 | if __name__ == "__main__": 15 | app() 16 | -------------------------------------------------------------------------------- /docs_src/subcommands/name_help/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | users_app = typer.Typer() 6 | app.add_typer(users_app, name="users") 7 | 8 | 9 | @users_app.callback() 10 | def users(): 11 | """ 12 | Manage users in the app. 13 | """ 14 | 15 | 16 | @users_app.command() 17 | def create(name: str): 18 | print(f"Creating user: {name}") 19 | 20 | 21 | if __name__ == "__main__": 22 | app() 23 | -------------------------------------------------------------------------------- /docs_src/subcommands/name_help/tutorial003.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | def users(): 7 | """ 8 | Manage users in the app. 9 | """ 10 | 11 | 12 | users_app = typer.Typer(callback=users, name="users") 13 | app.add_typer(users_app) 14 | 15 | 16 | @users_app.command() 17 | def create(name: str): 18 | print(f"Creating user: {name}") 19 | 20 | 21 | if __name__ == "__main__": 22 | app() 23 | -------------------------------------------------------------------------------- /docs_src/subcommands/name_help/tutorial004.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | def old_callback(): 7 | """ 8 | Old callback help. 9 | """ 10 | 11 | 12 | users_app = typer.Typer(callback=old_callback) 13 | app.add_typer(users_app, name="users") 14 | 15 | 16 | @users_app.callback() 17 | def users(): 18 | """ 19 | Manage users in the app. 20 | """ 21 | 22 | 23 | @users_app.command() 24 | def create(name: str): 25 | print(f"Creating user: {name}") 26 | 27 | 28 | if __name__ == "__main__": 29 | app() 30 | -------------------------------------------------------------------------------- /docs_src/subcommands/name_help/tutorial005.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | def old_callback(): 7 | """ 8 | Old callback help. 9 | """ 10 | 11 | 12 | users_app = typer.Typer(callback=old_callback, name="users") 13 | 14 | 15 | def new_users(): 16 | """ 17 | I have the highland! Create some users. 18 | """ 19 | 20 | 21 | app.add_typer(users_app, callback=new_users, name="new-users") 22 | 23 | 24 | @users_app.callback() 25 | def users(): 26 | """ 27 | Manage users in the app. 28 | """ 29 | 30 | 31 | @users_app.command() 32 | def create(name: str): 33 | print(f"Creating user: {name}") 34 | 35 | 36 | if __name__ == "__main__": 37 | app() 38 | -------------------------------------------------------------------------------- /docs_src/subcommands/name_help/tutorial006.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | def old_callback(): 7 | """ 8 | Old callback help. 9 | """ 10 | 11 | 12 | users_app = typer.Typer(callback=old_callback, name="exp-users", help="Explicit help.") 13 | 14 | 15 | def new_users(): 16 | """ 17 | I have the highland! Create some users. 18 | """ 19 | 20 | 21 | app.add_typer(users_app, callback=new_users) 22 | 23 | 24 | @users_app.callback() 25 | def users(): 26 | """ 27 | Manage users in the app. 28 | """ 29 | 30 | 31 | @users_app.command() 32 | def create(name: str): 33 | print(f"Creating user: {name}") 34 | 35 | 36 | if __name__ == "__main__": 37 | app() 38 | -------------------------------------------------------------------------------- /docs_src/subcommands/name_help/tutorial007.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | def old_callback(): 7 | """ 8 | Old callback help. 9 | """ 10 | 11 | 12 | users_app = typer.Typer(callback=old_callback, name="users", help="Explicit help.") 13 | 14 | 15 | def new_users(): 16 | """ 17 | I have the highland! Create some users. 18 | """ 19 | 20 | 21 | app.add_typer(users_app, callback=new_users) 22 | 23 | 24 | @users_app.callback(help="Help from callback for users.") 25 | def users(): 26 | """ 27 | Manage users in the app. 28 | """ 29 | 30 | 31 | @users_app.command() 32 | def create(name: str): 33 | print(f"Creating user: {name}") 34 | 35 | 36 | if __name__ == "__main__": 37 | app() 38 | -------------------------------------------------------------------------------- /docs_src/subcommands/name_help/tutorial008.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | def old_callback(): 7 | """ 8 | Old callback help. 9 | """ 10 | 11 | 12 | users_app = typer.Typer(callback=old_callback, name="exp-users", help="Explicit help.") 13 | 14 | 15 | def new_users(): 16 | """ 17 | I have the highland! Create some users. 18 | """ 19 | 20 | 21 | app.add_typer( 22 | users_app, 23 | callback=new_users, 24 | name="cake-sith-users", 25 | help="Unlimited powder! Eh, users.", 26 | ) 27 | 28 | 29 | @users_app.callback(help="Help from callback for users.") 30 | def users(): 31 | """ 32 | Manage users in the app. 33 | """ 34 | 35 | 36 | @users_app.command() 37 | def create(name: str): 38 | print(f"Creating user: {name}") 39 | 40 | 41 | if __name__ == "__main__": 42 | app() 43 | -------------------------------------------------------------------------------- /docs_src/subcommands/tutorial001/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/docs_src/subcommands/tutorial001/__init__.py -------------------------------------------------------------------------------- /docs_src/subcommands/tutorial001/items.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def create(item: str): 8 | print(f"Creating item: {item}") 9 | 10 | 11 | @app.command() 12 | def delete(item: str): 13 | print(f"Deleting item: {item}") 14 | 15 | 16 | @app.command() 17 | def sell(item: str): 18 | print(f"Selling item: {item}") 19 | 20 | 21 | if __name__ == "__main__": 22 | app() 23 | -------------------------------------------------------------------------------- /docs_src/subcommands/tutorial001/main.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | import items 4 | import users 5 | 6 | app = typer.Typer() 7 | app.add_typer(users.app, name="users") 8 | app.add_typer(items.app, name="items") 9 | 10 | if __name__ == "__main__": 11 | app() 12 | -------------------------------------------------------------------------------- /docs_src/subcommands/tutorial001/users.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def create(user_name: str): 8 | print(f"Creating user: {user_name}") 9 | 10 | 11 | @app.command() 12 | def delete(user_name: str): 13 | print(f"Deleting user: {user_name}") 14 | 15 | 16 | if __name__ == "__main__": 17 | app() 18 | -------------------------------------------------------------------------------- /docs_src/subcommands/tutorial002/main.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | items_app = typer.Typer() 5 | app.add_typer(items_app, name="items") 6 | users_app = typer.Typer() 7 | app.add_typer(users_app, name="users") 8 | 9 | 10 | @items_app.command("create") 11 | def items_create(item: str): 12 | print(f"Creating item: {item}") 13 | 14 | 15 | @items_app.command("delete") 16 | def items_delete(item: str): 17 | print(f"Deleting item: {item}") 18 | 19 | 20 | @items_app.command("sell") 21 | def items_sell(item: str): 22 | print(f"Selling item: {item}") 23 | 24 | 25 | @users_app.command("create") 26 | def users_create(user_name: str): 27 | print(f"Creating user: {user_name}") 28 | 29 | 30 | @users_app.command("delete") 31 | def users_delete(user_name: str): 32 | print(f"Deleting user: {user_name}") 33 | 34 | 35 | if __name__ == "__main__": 36 | app() 37 | -------------------------------------------------------------------------------- /docs_src/subcommands/tutorial003/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/docs_src/subcommands/tutorial003/__init__.py -------------------------------------------------------------------------------- /docs_src/subcommands/tutorial003/items.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def create(item: str): 8 | print(f"Creating item: {item}") 9 | 10 | 11 | @app.command() 12 | def delete(item: str): 13 | print(f"Deleting item: {item}") 14 | 15 | 16 | @app.command() 17 | def sell(item: str): 18 | print(f"Selling item: {item}") 19 | 20 | 21 | if __name__ == "__main__": 22 | app() 23 | -------------------------------------------------------------------------------- /docs_src/subcommands/tutorial003/lands.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | import reigns 4 | import towns 5 | 6 | app = typer.Typer() 7 | app.add_typer(reigns.app, name="reigns") 8 | app.add_typer(towns.app, name="towns") 9 | 10 | if __name__ == "__main__": 11 | app() 12 | -------------------------------------------------------------------------------- /docs_src/subcommands/tutorial003/main.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | import items 4 | import lands 5 | import users 6 | 7 | app = typer.Typer() 8 | app.add_typer(users.app, name="users") 9 | app.add_typer(items.app, name="items") 10 | app.add_typer(lands.app, name="lands") 11 | 12 | if __name__ == "__main__": 13 | app() 14 | -------------------------------------------------------------------------------- /docs_src/subcommands/tutorial003/reigns.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def conquer(name: str): 8 | print(f"Conquering reign: {name}") 9 | 10 | 11 | @app.command() 12 | def destroy(name: str): 13 | print(f"Destroying reign: {name}") 14 | 15 | 16 | if __name__ == "__main__": 17 | app() 18 | -------------------------------------------------------------------------------- /docs_src/subcommands/tutorial003/towns.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def found(name: str): 8 | print(f"Founding town: {name}") 9 | 10 | 11 | @app.command() 12 | def burn(name: str): 13 | print(f"Burning town: {name}") 14 | 15 | 16 | if __name__ == "__main__": 17 | app() 18 | -------------------------------------------------------------------------------- /docs_src/subcommands/tutorial003/users.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def create(user_name: str): 8 | print(f"Creating user: {user_name}") 9 | 10 | 11 | @app.command() 12 | def delete(user_name: str): 13 | print(f"Deleting user: {user_name}") 14 | 15 | 16 | if __name__ == "__main__": 17 | app() 18 | -------------------------------------------------------------------------------- /docs_src/terminating/tutorial001.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | existing_usernames = ["rick", "morty"] 4 | 5 | 6 | def maybe_create_user(username: str): 7 | if username in existing_usernames: 8 | print("The user already exists") 9 | raise typer.Exit() 10 | else: 11 | print(f"User created: {username}") 12 | 13 | 14 | def send_new_user_notification(username: str): 15 | # Somehow send a notification here for the new user, maybe an email 16 | print(f"Notification sent for new user: {username}") 17 | 18 | 19 | def main(username: str): 20 | maybe_create_user(username=username) 21 | send_new_user_notification(username=username) 22 | 23 | 24 | if __name__ == "__main__": 25 | typer.run(main) 26 | -------------------------------------------------------------------------------- /docs_src/terminating/tutorial002.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(username: str): 5 | if username == "root": 6 | print("The root user is reserved") 7 | raise typer.Exit(code=1) 8 | print(f"New user created: {username}") 9 | 10 | 11 | if __name__ == "__main__": 12 | typer.run(main) 13 | -------------------------------------------------------------------------------- /docs_src/terminating/tutorial003.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(username: str): 5 | if username == "root": 6 | print("The root user is reserved") 7 | raise typer.Abort() 8 | print(f"New user created: {username}") 9 | 10 | 11 | if __name__ == "__main__": 12 | typer.run(main) 13 | -------------------------------------------------------------------------------- /docs_src/testing/app01/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/docs_src/testing/app01/__init__.py -------------------------------------------------------------------------------- /docs_src/testing/app01/main.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | import typer 4 | 5 | app = typer.Typer() 6 | 7 | 8 | @app.command() 9 | def main(name: str, city: Optional[str] = None): 10 | print(f"Hello {name}") 11 | if city: 12 | print(f"Let's have a coffee in {city}") 13 | 14 | 15 | if __name__ == "__main__": 16 | app() 17 | -------------------------------------------------------------------------------- /docs_src/testing/app01/test_main.py: -------------------------------------------------------------------------------- 1 | from typer.testing import CliRunner 2 | 3 | from .main import app 4 | 5 | runner = CliRunner() 6 | 7 | 8 | def test_app(): 9 | result = runner.invoke(app, ["Camila", "--city", "Berlin"]) 10 | assert result.exit_code == 0 11 | assert "Hello Camila" in result.output 12 | assert "Let's have a coffee in Berlin" in result.output 13 | -------------------------------------------------------------------------------- /docs_src/testing/app02/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/docs_src/testing/app02/__init__.py -------------------------------------------------------------------------------- /docs_src/testing/app02/main.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def main(name: str, email: str = typer.Option(..., prompt=True)): 8 | print(f"Hello {name}, your email is: {email}") 9 | 10 | 11 | if __name__ == "__main__": 12 | app() 13 | -------------------------------------------------------------------------------- /docs_src/testing/app02/test_main.py: -------------------------------------------------------------------------------- 1 | from typer.testing import CliRunner 2 | 3 | from .main import app 4 | 5 | runner = CliRunner() 6 | 7 | 8 | def test_app(): 9 | result = runner.invoke(app, ["Camila"], input="camila@example.com\n") 10 | assert result.exit_code == 0 11 | assert "Hello Camila, your email is: camila@example.com" in result.output 12 | -------------------------------------------------------------------------------- /docs_src/testing/app02_an/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/docs_src/testing/app02_an/__init__.py -------------------------------------------------------------------------------- /docs_src/testing/app02_an/main.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | app = typer.Typer() 5 | 6 | 7 | @app.command() 8 | def main(name: str, email: Annotated[str, typer.Option(prompt=True)]): 9 | print(f"Hello {name}, your email is: {email}") 10 | 11 | 12 | if __name__ == "__main__": 13 | app() 14 | -------------------------------------------------------------------------------- /docs_src/testing/app02_an/test_main.py: -------------------------------------------------------------------------------- 1 | from typer.testing import CliRunner 2 | 3 | from .main import app 4 | 5 | runner = CliRunner() 6 | 7 | 8 | def test_app(): 9 | result = runner.invoke(app, ["Camila"], input="camila@example.com\n") 10 | assert result.exit_code == 0 11 | assert "Hello Camila, your email is: camila@example.com" in result.output 12 | -------------------------------------------------------------------------------- /docs_src/testing/app03/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/docs_src/testing/app03/__init__.py -------------------------------------------------------------------------------- /docs_src/testing/app03/main.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | 4 | def main(name: str = "World"): 5 | print(f"Hello {name}") 6 | 7 | 8 | if __name__ == "__main__": 9 | typer.run(main) 10 | -------------------------------------------------------------------------------- /docs_src/testing/app03/test_main.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typer.testing import CliRunner 3 | 4 | from .main import main 5 | 6 | app = typer.Typer() 7 | app.command()(main) 8 | 9 | runner = CliRunner() 10 | 11 | 12 | def test_app(): 13 | result = runner.invoke(app, ["--name", "Camila"]) 14 | assert result.exit_code == 0 15 | assert "Hello Camila" in result.output 16 | -------------------------------------------------------------------------------- /docs_src/using_click/tutorial001.py: -------------------------------------------------------------------------------- 1 | import click 2 | 3 | 4 | @click.command() 5 | @click.option("--count", default=1, help="Number of greetings.") 6 | @click.option("--name", prompt="Your name", help="The person to greet.") 7 | def hello(count, name): 8 | """Simple program that greets NAME for a total of COUNT times.""" 9 | for x in range(count): 10 | click.echo(f"Hello {name}!") 11 | 12 | 13 | if __name__ == "__main__": 14 | hello() 15 | -------------------------------------------------------------------------------- /docs_src/using_click/tutorial002.py: -------------------------------------------------------------------------------- 1 | import click 2 | 3 | 4 | @click.group() 5 | def cli(): 6 | pass 7 | 8 | 9 | @click.command() 10 | def initdb(): 11 | click.echo("Initialized the database") 12 | 13 | 14 | @click.command() 15 | def dropdb(): 16 | click.echo("Dropped the database") 17 | 18 | 19 | cli.add_command(initdb) 20 | cli.add_command(dropdb) 21 | 22 | 23 | if __name__ == "__main__": 24 | cli() 25 | -------------------------------------------------------------------------------- /docs_src/using_click/tutorial003.py: -------------------------------------------------------------------------------- 1 | import click 2 | import typer 3 | 4 | app = typer.Typer() 5 | 6 | 7 | @app.command() 8 | def top(): 9 | """ 10 | Top level command, form Typer 11 | """ 12 | print("The Typer app is at the top level") 13 | 14 | 15 | @app.callback() 16 | def callback(): 17 | """ 18 | Typer app, including Click subapp 19 | """ 20 | 21 | 22 | @click.command() 23 | @click.option("--name", prompt="Your name", help="The person to greet.") 24 | def hello(name): 25 | """Simple program that greets NAME for a total of COUNT times.""" 26 | click.echo(f"Hello {name}!") 27 | 28 | 29 | typer_click_object = typer.main.get_command(app) 30 | 31 | typer_click_object.add_command(hello, "hello") 32 | 33 | if __name__ == "__main__": 34 | typer_click_object() 35 | -------------------------------------------------------------------------------- /docs_src/using_click/tutorial004.py: -------------------------------------------------------------------------------- 1 | import click 2 | import typer 3 | 4 | 5 | @click.group() 6 | def cli(): 7 | pass 8 | 9 | 10 | @cli.command() 11 | def initdb(): 12 | click.echo("Initialized the database") 13 | 14 | 15 | @cli.command() 16 | def dropdb(): 17 | click.echo("Dropped the database") 18 | 19 | 20 | app = typer.Typer() 21 | 22 | 23 | @app.command() 24 | def sub(): 25 | """ 26 | A single-command Typer sub app 27 | """ 28 | print("Typer is now below Click, the Click app is the top level") 29 | 30 | 31 | typer_click_object = typer.main.get_command(app) 32 | 33 | cli.add_command(typer_click_object, "sub") 34 | 35 | if __name__ == "__main__": 36 | cli() 37 | -------------------------------------------------------------------------------- /mkdocs.insiders.yml: -------------------------------------------------------------------------------- 1 | plugins: 2 | typeset: 3 | markdown_extensions: 4 | material.extensions.preview: 5 | targets: 6 | include: 7 | - "*" 8 | -------------------------------------------------------------------------------- /mkdocs.maybe-insiders.yml: -------------------------------------------------------------------------------- 1 | # Define this here and not in the main mkdocs.yml file because that one could be auto 2 | # updated and written, and the script would remove the env var 3 | INHERIT: !ENV [INSIDERS_FILE, './mkdocs.no-insiders.yml'] 4 | markdown_extensions: 5 | pymdownx.highlight: 6 | linenums: !ENV [LINENUMS, false] 7 | -------------------------------------------------------------------------------- /mkdocs.no-insiders.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/mkdocs.no-insiders.yml -------------------------------------------------------------------------------- /requirements-docs-insiders.txt: -------------------------------------------------------------------------------- 1 | git+https://${TOKEN}@github.com/squidfunk/mkdocs-material-insiders.git@9.5.30-insiders-4.53.11 2 | git+https://${TOKEN}@github.com/pawamoy-insiders/griffe-typing-deprecated.git 3 | git+https://${TOKEN}@github.com/pawamoy-insiders/mkdocstrings-python.git 4 | -------------------------------------------------------------------------------- /requirements-docs.txt: -------------------------------------------------------------------------------- 1 | -e . 2 | 3 | mkdocs-material==9.5.50 4 | mdx-include >=1.4.1,<2.0.0 5 | mkdocs-redirects>=1.2.1,<1.3.0 6 | pyyaml >=5.3.1,<7.0.0 7 | # For Material for MkDocs, Chinese search 8 | # jieba==0.42.1 9 | # For image processing by Material for MkDocs 10 | pillow==11.1.0 11 | # For image processing by Material for MkDocs 12 | cairosvg==2.7.1 13 | # mkdocstrings[python]==0.25.1 14 | # Enable griffe-typingdoc once dropping Python 3.7 and upgrading typing-extensions 15 | # griffe-typingdoc==0.2.5 16 | # For griffe, it formats with black 17 | # black==24.3.0 18 | mkdocs-macros-plugin==1.3.7 19 | markdown-include-variants==0.0.4 20 | -------------------------------------------------------------------------------- /requirements-github-actions.txt: -------------------------------------------------------------------------------- 1 | PyGithub>=2.3.0,<3.0.0 2 | pydantic>=2.5.3,<3.0.0 3 | pydantic-settings>=2.1.0,<3.0.0 4 | httpx>=0.27.0,<0.29.0 5 | smokeshow 6 | -------------------------------------------------------------------------------- /requirements-tests.txt: -------------------------------------------------------------------------------- 1 | -e . 2 | 3 | pytest >=4.4.0,<9.0.0 4 | pytest-cov >=2.10.0,<7.0.0 5 | coverage[toml] >=6.2,<8.0 6 | pytest-xdist >=1.32.0,<4.0.0 7 | pytest-sugar >=0.9.4,<1.1.0 8 | mypy ==1.4.1 9 | ruff ==0.11.6 10 | # Needed explicitly by typer-slim 11 | rich >=10.11.0 12 | shellingham >=1.3.0 13 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | -e . 2 | 3 | -r requirements-tests.txt 4 | -r requirements-docs.txt 5 | 6 | pre-commit >=2.17.0,<5.0.0 7 | -------------------------------------------------------------------------------- /scripts/docker/compose.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | typer: 3 | build: 4 | context: ../../ 5 | dockerfile: scripts/docker/Dockerfile 6 | volumes: 7 | - ../../:/code 8 | command: sleep infinity 9 | -------------------------------------------------------------------------------- /scripts/format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | set -x 3 | set -e 4 | 5 | ruff check typer tests docs_src scripts --fix 6 | ruff format typer tests docs_src scripts 7 | -------------------------------------------------------------------------------- /scripts/get-pwsh-activate.sh: -------------------------------------------------------------------------------- 1 | curl https://raw.githubusercontent.com/python/cpython/main/Lib/venv/scripts/common/Activate.ps1 -o Activate.ps1 2 | -------------------------------------------------------------------------------- /scripts/lint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -x 5 | 6 | mypy typer 7 | ruff check typer tests docs_src scripts 8 | ruff format typer tests docs_src scripts --check 9 | -------------------------------------------------------------------------------- /scripts/test-cov-html.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -x 5 | 6 | bash scripts/test.sh --cov-report=html ${@} 7 | -------------------------------------------------------------------------------- /scripts/test-files.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -x 5 | 6 | # Check copy paste errors in tutorials 7 | if grep -r --include "*.md" "Usage: tutorial" ./docs ; then echo "Incorrect console demo"; exit 1 ; fi 8 | if grep -r --include "*.md" "python tutorial" ./docs ; then echo "Incorrect console demo"; exit 1 ; fi 9 | -------------------------------------------------------------------------------- /scripts/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -x 5 | 6 | # For tests, a large terminal width 7 | export TERMINAL_WIDTH=3000 8 | # Force disable terminal for tests inside of pytest, takes precedence over GITHUB_ACTIONS env var 9 | export _TYPER_FORCE_DISABLE_TERMINAL=1 10 | # Run autocompletion install tests in the CI 11 | export _TYPER_RUN_INSTALL_COMPLETION_TESTS=1 12 | # It seems xdist-pytest ensures modified sys.path to import relative modules in examples keeps working 13 | pytest --cov --cov-report=term-missing -o console_output_style=progress --numprocesses=auto ${@} 14 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/__init__.py -------------------------------------------------------------------------------- /tests/assets/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/assets/__init__.py -------------------------------------------------------------------------------- /tests/assets/cli/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/assets/cli/__init__.py -------------------------------------------------------------------------------- /tests/assets/cli/app_other_name.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | application = typer.Typer() 4 | 5 | 6 | @application.command() 7 | def callback(name: str = "World"): 8 | typer.echo(f"Hello {name}") 9 | -------------------------------------------------------------------------------- /tests/assets/cli/empty_script.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/assets/cli/empty_script.py -------------------------------------------------------------------------------- /tests/assets/cli/extended_app_cli.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | sub_sub_app = typer.Typer() 4 | 5 | 6 | @sub_sub_app.command() 7 | def sub_sub_command(): 8 | typer.echo("sub_sub_command") 9 | 10 | 11 | sub_app = typer.Typer() 12 | sub_app.add_typer(sub_sub_app, name="sub") 13 | 14 | 15 | @sub_app.command() 16 | def hello(): 17 | typer.echo("hello there") 18 | 19 | 20 | @sub_app.command() 21 | def bye(): 22 | typer.echo("bye bye") 23 | 24 | 25 | cli = typer.Typer() 26 | cli.add_typer(sub_app) 27 | 28 | 29 | @cli.command() 30 | def top(): 31 | typer.echo("top") 32 | -------------------------------------------------------------------------------- /tests/assets/cli/extended_empty_app_cli.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | cli = typer.Typer() 4 | sub_app = typer.Typer() 5 | cli.add_typer(sub_app) 6 | 7 | 8 | @sub_app.command() 9 | def hello(): 10 | typer.echo("hello there") 11 | 12 | 13 | @sub_app.command() 14 | def bye(): 15 | typer.echo("bye bye") 16 | -------------------------------------------------------------------------------- /tests/assets/cli/func_other_name.py: -------------------------------------------------------------------------------- 1 | def some_function(name: str = "World"): 2 | print(f"Hello {name}") 3 | -------------------------------------------------------------------------------- /tests/assets/cli/multi_app.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | sub_app = typer.Typer() 4 | 5 | variable = "Some text" 6 | 7 | 8 | @sub_app.command() 9 | def hello(name: str = "World", age: int = typer.Option(0, help="The age of the user")): 10 | """ 11 | Say Hello 12 | """ 13 | typer.echo(f"Hello {name}") 14 | 15 | 16 | @sub_app.command() 17 | def hi(user: str = typer.Argument("World", help="The name of the user to greet")): 18 | """ 19 | Say Hi 20 | """ 21 | 22 | 23 | @sub_app.command() 24 | def bye(): 25 | """ 26 | Say bye 27 | """ 28 | typer.echo("sub bye") 29 | 30 | 31 | app = typer.Typer(help="Demo App", epilog="The end") 32 | app.add_typer(sub_app, name="sub") 33 | 34 | 35 | @app.command() 36 | def top(): 37 | """ 38 | Top command 39 | """ 40 | typer.echo("top") 41 | -------------------------------------------------------------------------------- /tests/assets/cli/multi_app_cli.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | sub_app = typer.Typer() 4 | 5 | 6 | @sub_app.command() 7 | def hello(): 8 | typer.echo("sub hello") 9 | 10 | 11 | @sub_app.command() 12 | def bye(): 13 | typer.echo("sub bye") 14 | 15 | 16 | cli = typer.Typer() 17 | cli.add_typer(sub_app, name="sub") 18 | 19 | 20 | @cli.command() 21 | def top(): 22 | typer.echo("top") 23 | -------------------------------------------------------------------------------- /tests/assets/cli/multi_func.py: -------------------------------------------------------------------------------- 1 | message = "Stuff" 2 | 3 | 4 | def say_stuff(): 5 | print(message) 6 | 7 | 8 | def main(name: str = "World"): 9 | """ 10 | Say hi to someone, by default to the World. 11 | """ 12 | print(f"Hello {name}") 13 | -------------------------------------------------------------------------------- /tests/assets/cli/not_python.txt: -------------------------------------------------------------------------------- 1 | This is not Python 2 | -------------------------------------------------------------------------------- /tests/assets/cli/rich_formatted_app.py: -------------------------------------------------------------------------------- 1 | import typer 2 | from typing_extensions import Annotated 3 | 4 | app = typer.Typer(rich_markup_mode="rich") 5 | 6 | 7 | @app.command(help="Say [bold red]hello[/bold red] to the user.") 8 | def hello( 9 | user_1: Annotated[ 10 | str, 11 | typer.Argument(help="The [bold]cool[/bold] name of the [green]user[/green]"), 12 | ], 13 | user_2: Annotated[str, typer.Argument(help="The world")] = "The World", 14 | force: Annotated[ 15 | bool, typer.Option(help="Force the welcome [red]message[/red]") 16 | ] = False, 17 | ): 18 | print(f"Hello {user_1} and {user_2}") # pragma: no cover 19 | 20 | 21 | if __name__ == "__main__": 22 | app() 23 | -------------------------------------------------------------------------------- /tests/assets/cli/richformattedapp-docs.md: -------------------------------------------------------------------------------- 1 | # Awesome CLI 2 | 3 | Say hello to the user. 4 | 5 | **Usage**: 6 | 7 | ```console 8 | $ hello [OPTIONS] USER_1 [USER_2] 9 | ``` 10 | 11 | **Arguments**: 12 | 13 | * `USER_1`: The cool name of the user [required] 14 | * `[USER_2]`: The world [default: The World] 15 | 16 | **Options**: 17 | 18 | * `--force / --no-force`: Force the welcome message [default: no-force] 19 | * `--install-completion`: Install completion for the current shell. 20 | * `--show-completion`: Show completion for the current shell, to copy it or customize the installation. 21 | * `--help`: Show this message and exit. 22 | -------------------------------------------------------------------------------- /tests/assets/cli/sample.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def hello(name: str = "World", formal: bool = False): 8 | """ 9 | Say hi 10 | """ 11 | if formal: 12 | typer.echo(f"Good morning Ms. {name}") 13 | else: 14 | typer.echo(f"Hello {name}!") 15 | 16 | 17 | @app.command() 18 | def bye(friend: bool = False): 19 | """ 20 | Say bye 21 | """ 22 | if friend: 23 | typer.echo("Goodbye my friend") 24 | else: 25 | typer.echo("Goodbye") 26 | -------------------------------------------------------------------------------- /tests/assets/completion_argument.py: -------------------------------------------------------------------------------- 1 | import click 2 | import typer 3 | 4 | app = typer.Typer() 5 | 6 | 7 | def shell_complete(ctx: click.Context, param: click.Parameter, incomplete: str): 8 | typer.echo(f"ctx: {ctx.info_name}", err=True) 9 | typer.echo(f"arg is: {param.name}", err=True) 10 | typer.echo(f"incomplete is: {incomplete}", err=True) 11 | return ["Emma"] 12 | 13 | 14 | @app.command(context_settings={"auto_envvar_prefix": "TEST"}) 15 | def main(name: str = typer.Argument(shell_complete=shell_complete)): 16 | """ 17 | Say hello. 18 | """ 19 | 20 | 21 | if __name__ == "__main__": 22 | app() 23 | -------------------------------------------------------------------------------- /tests/assets/completion_no_types.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | def complete(ctx, args, incomplete): 7 | typer.echo(f"info name is: {ctx.info_name}", err=True) 8 | typer.echo(f"args is: {args}", err=True) 9 | typer.echo(f"incomplete is: {incomplete}", err=True) 10 | return [ 11 | ("Camila", "The reader of books."), 12 | ("Carlos", "The writer of scripts."), 13 | ("Sebastian", "The type hints guy."), 14 | ] 15 | 16 | 17 | @app.command() 18 | def main(name: str = typer.Option("World", autocompletion=complete)): 19 | print(f"Hello {name}") 20 | 21 | 22 | if __name__ == "__main__": 23 | app() 24 | -------------------------------------------------------------------------------- /tests/assets/completion_no_types_order.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | def complete(args, incomplete, ctx): 7 | typer.echo(f"info name is: {ctx.info_name}", err=True) 8 | typer.echo(f"args is: {args}", err=True) 9 | typer.echo(f"incomplete is: {incomplete}", err=True) 10 | return [ 11 | ("Camila", "The reader of books."), 12 | ("Carlos", "The writer of scripts."), 13 | ("Sebastian", "The type hints guy."), 14 | ] 15 | 16 | 17 | @app.command() 18 | def main(name: str = typer.Option("World", autocompletion=complete)): 19 | print(f"Hello {name}") 20 | 21 | 22 | if __name__ == "__main__": 23 | app() 24 | -------------------------------------------------------------------------------- /tests/assets/corner_cases.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command(context_settings={"auto_envvar_prefix": "TEST"}) 7 | def main( 8 | name: str = typer.Option("John", hidden=True), 9 | lastname: str = typer.Option("Doe", "/lastname", show_default="Mr. Doe"), 10 | age: int = typer.Option(lambda: 42, show_default=True), 11 | ): 12 | """ 13 | Say hello. 14 | """ 15 | print(f"Hello {name} {lastname}, it seems you have {age}") 16 | 17 | 18 | if __name__ == "__main__": 19 | app() 20 | -------------------------------------------------------------------------------- /tests/assets/prog_name.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def main(i: int): # pragma: no cover 8 | pass 9 | 10 | 11 | if __name__ == "__main__": 12 | app(prog_name="custom-name") 13 | -------------------------------------------------------------------------------- /tests/assets/type_error_no_rich.py: -------------------------------------------------------------------------------- 1 | import typer 2 | import typer.main 3 | 4 | typer.main.rich = None 5 | 6 | 7 | def main(name: str = "morty"): 8 | print(name + 3) 9 | 10 | 11 | if __name__ == "__main__": 12 | typer.run(main) 13 | -------------------------------------------------------------------------------- /tests/assets/type_error_no_rich_short_disable.py: -------------------------------------------------------------------------------- 1 | import typer 2 | import typer.main 3 | 4 | typer.main.rich = None 5 | 6 | 7 | app = typer.Typer(pretty_exceptions_short=False) 8 | 9 | 10 | @app.command() 11 | def main(name: str = "morty"): 12 | print(name + 3) 13 | 14 | 15 | if __name__ == "__main__": 16 | app() 17 | -------------------------------------------------------------------------------- /tests/assets/type_error_normal_traceback.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def main(name: str = "morty"): 8 | print(name) 9 | 10 | 11 | broken_app = typer.Typer() 12 | 13 | 14 | @broken_app.command() 15 | def broken(name: str = "morty"): 16 | print(name + 3) 17 | 18 | 19 | if __name__ == "__main__": 20 | app(standalone_mode=False) 21 | 22 | typer.main.get_command(broken_app)() 23 | -------------------------------------------------------------------------------- /tests/test_cli/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_cli/__init__.py -------------------------------------------------------------------------------- /tests/test_cli/test_completion_run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | import sys 4 | 5 | 6 | def test_script_completion_run(): 7 | result = subprocess.run( 8 | [sys.executable, "-m", "coverage", "run", "-m", "typer"], 9 | capture_output=True, 10 | encoding="utf-8", 11 | env={ 12 | **os.environ, 13 | "___MAIN__.PY_COMPLETE": "complete_bash", 14 | "_PYTHON _M TYPER_COMPLETE": "complete_bash", 15 | "COMP_WORDS": "typer tests/assets/cli/sample.py", 16 | "COMP_CWORD": "2", 17 | }, 18 | ) 19 | assert "run" in result.stdout 20 | -------------------------------------------------------------------------------- /tests/test_cli/test_empty_script.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | 5 | def test_script_help(): 6 | result = subprocess.run( 7 | [ 8 | sys.executable, 9 | "-m", 10 | "coverage", 11 | "run", 12 | "-m", 13 | "typer", 14 | "tests/assets/cli/empty_script.py", 15 | "--help", 16 | ], 17 | capture_output=True, 18 | encoding="utf-8", 19 | ) 20 | assert "run" not in result.stdout 21 | -------------------------------------------------------------------------------- /tests/test_cli/test_func_other_name.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | 5 | def test_script(): 6 | result = subprocess.run( 7 | [ 8 | sys.executable, 9 | "-m", 10 | "coverage", 11 | "run", 12 | "-m", 13 | "typer", 14 | "tests/assets/cli/func_other_name.py", 15 | "run", 16 | "--name", 17 | "Camila", 18 | ], 19 | capture_output=True, 20 | encoding="utf-8", 21 | ) 22 | assert "Hello Camila" in result.stdout 23 | -------------------------------------------------------------------------------- /tests/test_cli/test_help.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | 5 | def test_script_help(): 6 | result = subprocess.run( 7 | [ 8 | sys.executable, 9 | "-m", 10 | "coverage", 11 | "run", 12 | "-m", 13 | "typer", 14 | "tests/assets/cli/sample.py", 15 | "--help", 16 | ], 17 | capture_output=True, 18 | encoding="utf-8", 19 | ) 20 | assert "run" in result.stdout 21 | 22 | 23 | def test_not_python(): 24 | result = subprocess.run( 25 | [ 26 | sys.executable, 27 | "-m", 28 | "coverage", 29 | "run", 30 | "-m", 31 | "typer", 32 | "tests/assets/cli/not_python.txt", 33 | "run", 34 | ], 35 | capture_output=True, 36 | encoding="utf-8", 37 | ) 38 | assert "Could not import as Python file" in result.stderr 39 | -------------------------------------------------------------------------------- /tests/test_cli/test_not_python.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | 5 | def test_not_python(): 6 | result = subprocess.run( 7 | [ 8 | sys.executable, 9 | "-m", 10 | "coverage", 11 | "run", 12 | "-m", 13 | "typer", 14 | "tests/assets/cli/not_python.txt", 15 | "run", 16 | ], 17 | capture_output=True, 18 | encoding="utf-8", 19 | ) 20 | assert "Could not import as Python file" in result.stderr 21 | -------------------------------------------------------------------------------- /tests/test_cli/test_sub_completion.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | import sys 4 | 5 | 6 | def test_script_completion_run(): 7 | result = subprocess.run( 8 | [sys.executable, "-m", "coverage", "run", "-m", "typer"], 9 | capture_output=True, 10 | encoding="utf-8", 11 | env={ 12 | **os.environ, 13 | "___MAIN__.PY_COMPLETE": "complete_bash", 14 | "_PYTHON _M TYPER_COMPLETE": "complete_bash", 15 | "COMP_WORDS": "typer tests/assets/cli/sample.py run hello --", 16 | "COMP_CWORD": "4", 17 | }, 18 | ) 19 | assert "--name" in result.stdout 20 | -------------------------------------------------------------------------------- /tests/test_cli/test_sub_help.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | 5 | def test_script_help(): 6 | result = subprocess.run( 7 | [ 8 | sys.executable, 9 | "-m", 10 | "coverage", 11 | "run", 12 | "-m", 13 | "typer", 14 | "tests/assets/cli/sample.py", 15 | "run", 16 | "--help", 17 | ], 18 | capture_output=True, 19 | encoding="utf-8", 20 | ) 21 | assert "bye" in result.stdout 22 | assert "Say bye" in result.stdout 23 | assert "hello" in result.stdout 24 | assert "Say hi" in result.stdout 25 | -------------------------------------------------------------------------------- /tests/test_cli/test_version.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | 5 | def test_script_help(): 6 | result = subprocess.run( 7 | [sys.executable, "-m", "coverage", "run", "-m", "typer", "--version"], 8 | capture_output=True, 9 | encoding="utf-8", 10 | ) 11 | assert "Typer version:" in result.stdout 12 | -------------------------------------------------------------------------------- /tests/test_completion/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_completion/__init__.py -------------------------------------------------------------------------------- /tests/test_completion/colon_example.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | image_desc = [ 4 | ("alpine:latest", "latest alpine image"), 5 | ("alpine:hello", "fake image: for testing"), 6 | ("nvidia/cuda:10.0-devel-ubuntu18.04", ""), 7 | ] 8 | 9 | 10 | def _complete(incomplete: str) -> str: 11 | for image, desc in image_desc: 12 | if image.startswith(incomplete): 13 | yield image, desc 14 | 15 | 16 | app = typer.Typer() 17 | 18 | 19 | @app.command() 20 | def image(name: str = typer.Option(autocompletion=_complete)): 21 | typer.echo(name) 22 | 23 | 24 | if __name__ == "__main__": 25 | app() 26 | -------------------------------------------------------------------------------- /tests/test_completion/example_rich_tags.py: -------------------------------------------------------------------------------- 1 | import typer 2 | 3 | app = typer.Typer() 4 | 5 | 6 | @app.command() 7 | def create(username: str): 8 | """ 9 | Create a [green]new[green/] user with USERNAME. 10 | """ 11 | print(f"Creating user: {username}") 12 | 13 | 14 | @app.command() 15 | def delete(username: str): 16 | """ 17 | Delete a user with [bold]USERNAME[/]. 18 | """ 19 | print(f"Deleting user: {username}") 20 | 21 | 22 | @app.command() 23 | def delete_all(): 24 | """ 25 | [red]Delete ALL users[/red] in the database. 26 | """ 27 | print("Deleting all users") 28 | 29 | 30 | if __name__ == "__main__": 31 | app() 32 | -------------------------------------------------------------------------------- /tests/test_completion/path_example.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | import typer 4 | 5 | app = typer.Typer() 6 | 7 | 8 | @app.command() 9 | def f(p: Path): 10 | print(p) 11 | 12 | 13 | if __name__ == "__main__": 14 | app() 15 | -------------------------------------------------------------------------------- /tests/test_completion/test_completion_path.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | import sys 4 | 5 | from . import path_example as mod 6 | 7 | 8 | def test_script(): 9 | result = subprocess.run( 10 | [sys.executable, "-m", "coverage", "run", mod.__file__, "path/to/deadpool"], 11 | capture_output=True, 12 | encoding="utf-8", 13 | ) 14 | assert result.returncode == 0 15 | assert "deadpool" in result.stdout 16 | 17 | 18 | def test_completion_path_bash(): 19 | result = subprocess.run( 20 | [sys.executable, "-m", "coverage", "run", mod.__file__, " "], 21 | capture_output=True, 22 | encoding="utf-8", 23 | env={ 24 | **os.environ, 25 | "_PATH_EXAMPLE.PY_COMPLETE": "complete_bash", 26 | "COMP_WORDS": "path_example.py ", 27 | "COMP_CWORD": "2", 28 | }, 29 | ) 30 | assert result.returncode == 0 31 | -------------------------------------------------------------------------------- /tests/test_deprecation.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | import pytest 4 | import typer 5 | from typer.testing import CliRunner 6 | 7 | runner = CliRunner() 8 | 9 | 10 | def test_deprecation(): 11 | app = typer.Typer() 12 | 13 | def add_command(): 14 | @app.command() 15 | def cmd( 16 | opt: Optional[float] = typer.Option( 17 | 3.14, 18 | is_flag=True, 19 | flag_value="42", 20 | help="Some wonderful number", 21 | ), 22 | ): ... # pragma: no cover 23 | 24 | with pytest.warns( 25 | match="The 'is_flag' and 'flag_value' parameters are not supported by Typer" 26 | ): 27 | add_command() 28 | -------------------------------------------------------------------------------- /tests/test_future_annotations.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import typer 4 | from typer.testing import CliRunner 5 | from typing_extensions import Annotated 6 | 7 | runner = CliRunner() 8 | 9 | 10 | def test_annotated(): 11 | app = typer.Typer() 12 | 13 | @app.command() 14 | def cmd(force: Annotated[bool, typer.Option("--force")] = False): 15 | if force: 16 | print("Forcing operation") 17 | else: 18 | print("Not forcing") 19 | 20 | result = runner.invoke(app) 21 | assert result.exit_code == 0, result.output 22 | assert "Not forcing" in result.output 23 | 24 | result = runner.invoke(app, ["--force"]) 25 | assert result.exit_code == 0, result.output 26 | assert "Forcing operation" in result.output 27 | -------------------------------------------------------------------------------- /tests/test_prog_name.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | from pathlib import Path 4 | 5 | 6 | def test_custom_prog_name(): 7 | file_path = Path(__file__).parent / "assets/prog_name.py" 8 | result = subprocess.run( 9 | [sys.executable, "-m", "coverage", "run", str(file_path), "--help"], 10 | capture_output=True, 11 | encoding="utf-8", 12 | ) 13 | assert "Usage: custom-name [OPTIONS] I" in result.stdout 14 | -------------------------------------------------------------------------------- /tests/test_tutorial/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_arguments/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_arguments/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_arguments/test_default/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_arguments/test_default/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_arguments/test_envvar/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_arguments/test_envvar/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_arguments/test_help/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_arguments/test_help/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_arguments/test_optional/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_arguments/test_optional/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_commands/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_commands/test_arguments/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_commands/test_arguments/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_commands/test_callback/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_commands/test_callback/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_commands/test_callback/test_tutorial002.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | from typer.testing import CliRunner 5 | 6 | from docs_src.commands.callback import tutorial002 as mod 7 | 8 | app = mod.app 9 | 10 | runner = CliRunner() 11 | 12 | 13 | def test_app(): 14 | result = runner.invoke(app, ["create", "Camila"]) 15 | assert result.exit_code == 0 16 | assert "Running a command" in result.output 17 | assert "Creating user: Camila" in result.output 18 | 19 | 20 | def test_script(): 21 | result = subprocess.run( 22 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 23 | capture_output=True, 24 | encoding="utf-8", 25 | ) 26 | assert "Usage" in result.stdout 27 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_commands/test_callback/test_tutorial003.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | from typer.testing import CliRunner 5 | 6 | from docs_src.commands.callback import tutorial003 as mod 7 | 8 | app = mod.app 9 | 10 | runner = CliRunner() 11 | 12 | 13 | def test_app(): 14 | result = runner.invoke(app, ["create", "Camila"]) 15 | assert result.exit_code == 0 16 | assert "Override callback, running a command" in result.output 17 | assert "Running a command" not in result.output 18 | assert "Creating user: Camila" in result.output 19 | 20 | 21 | def test_for_coverage(): 22 | mod.callback() 23 | 24 | 25 | def test_script(): 26 | result = subprocess.run( 27 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 28 | capture_output=True, 29 | encoding="utf-8", 30 | ) 31 | assert "Usage" in result.stdout 32 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_commands/test_context/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_commands/test_context/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_commands/test_context/test_tutorial004.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | from typer.testing import CliRunner 5 | 6 | from docs_src.commands.context import tutorial004 as mod 7 | 8 | app = mod.app 9 | 10 | runner = CliRunner() 11 | 12 | 13 | def test_1(): 14 | result = runner.invoke(app, ["--name", "Camila", "--city", "Berlin"]) 15 | assert result.exit_code == 0 16 | assert "Got extra arg: --name" in result.output 17 | assert "Got extra arg: Camila" in result.output 18 | assert "Got extra arg: --city" in result.output 19 | assert "Got extra arg: Berlin" in result.output 20 | 21 | 22 | def test_script(): 23 | result = subprocess.run( 24 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 25 | capture_output=True, 26 | encoding="utf-8", 27 | ) 28 | assert "Usage" in result.stdout 29 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_commands/test_help/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_commands/test_help/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_commands/test_help/test_tutorial008.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | from typer.testing import CliRunner 5 | 6 | from docs_src.commands.help import tutorial008 as mod 7 | 8 | app = mod.app 9 | 10 | runner = CliRunner() 11 | 12 | 13 | def test_main_help(): 14 | result = runner.invoke(app, ["--help"]) 15 | assert result.exit_code == 0 16 | assert "Create a new user. ✨" in result.output 17 | assert "Made with ❤ in Venus" in result.output 18 | 19 | 20 | def test_call(): 21 | # Mainly for coverage 22 | result = runner.invoke(app, ["Morty"]) 23 | assert result.exit_code == 0 24 | 25 | 26 | def test_script(): 27 | result = subprocess.run( 28 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 29 | capture_output=True, 30 | encoding="utf-8", 31 | ) 32 | assert "Usage" in result.stdout 33 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_commands/test_index/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_commands/test_index/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_commands/test_index/test_tutorial001.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | from typer.testing import CliRunner 5 | 6 | from docs_src.commands.index import tutorial001 as mod 7 | 8 | app = mod.app 9 | 10 | runner = CliRunner() 11 | 12 | 13 | def test_no_arg(): 14 | result = runner.invoke(app) 15 | assert result.exit_code != 0 16 | assert "Missing argument 'NAME'." in result.output 17 | 18 | 19 | def test_arg(): 20 | result = runner.invoke(app, ["Camila"]) 21 | assert result.exit_code == 0 22 | assert "Hello Camila" in result.output 23 | 24 | 25 | def test_script(): 26 | result = subprocess.run( 27 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 28 | capture_output=True, 29 | encoding="utf-8", 30 | ) 31 | assert "Usage" in result.stdout 32 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_commands/test_name/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_commands/test_name/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_commands/test_one_or_multiple/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_commands/test_one_or_multiple/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_commands/test_one_or_multiple/test_tutorial001.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | from typer.testing import CliRunner 5 | 6 | from docs_src.commands.one_or_multiple import tutorial001 as mod 7 | 8 | app = mod.app 9 | 10 | runner = CliRunner() 11 | 12 | 13 | def test_help(): 14 | result = runner.invoke(app, ["--help"]) 15 | assert result.exit_code == 0 16 | assert "Commands" in result.output 17 | assert "create" in result.output 18 | 19 | 20 | def test_command(): 21 | result = runner.invoke(app, ["create"]) 22 | assert result.exit_code == 0 23 | assert "Creating user: Hiro Hamada" in result.output 24 | 25 | 26 | def test_script(): 27 | result = subprocess.run( 28 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 29 | capture_output=True, 30 | encoding="utf-8", 31 | ) 32 | assert "Usage" in result.stdout 33 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_commands/test_options/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_commands/test_options/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_exceptions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_exceptions/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_first_steps/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_first_steps/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_first_steps/test_tutorial001.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | import typer 5 | from typer.testing import CliRunner 6 | 7 | from docs_src.first_steps import tutorial001 as mod 8 | 9 | runner = CliRunner() 10 | 11 | 12 | def test_cli(): 13 | app = typer.Typer() 14 | app.command()(mod.main) 15 | result = runner.invoke(app, []) 16 | assert result.output == "Hello World\n" 17 | 18 | 19 | def test_script(): 20 | result = subprocess.run( 21 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 22 | capture_output=True, 23 | encoding="utf-8", 24 | ) 25 | assert "Usage" in result.stdout 26 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_first_steps/test_tutorial002.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | import typer 5 | from typer.testing import CliRunner 6 | 7 | from docs_src.first_steps import tutorial002 as mod 8 | 9 | runner = CliRunner() 10 | 11 | app = typer.Typer() 12 | app.command()(mod.main) 13 | 14 | 15 | def test_1(): 16 | result = runner.invoke(app, []) 17 | assert result.exit_code != 0 18 | assert "Missing argument 'NAME'" in result.output 19 | 20 | 21 | def test_2(): 22 | result = runner.invoke(app, ["Camila"]) 23 | assert result.exit_code == 0 24 | assert "Hello Camila" in result.output 25 | 26 | 27 | def test_script(): 28 | result = subprocess.run( 29 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 30 | capture_output=True, 31 | encoding="utf-8", 32 | ) 33 | assert "Usage" in result.stdout 34 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_first_steps/test_tutorial003.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | import typer 5 | from typer.testing import CliRunner 6 | 7 | from docs_src.first_steps import tutorial003 as mod 8 | 9 | runner = CliRunner() 10 | 11 | app = typer.Typer() 12 | app.command()(mod.main) 13 | 14 | 15 | def test_1(): 16 | result = runner.invoke(app, ["Camila"]) 17 | assert result.exit_code != 0 18 | assert "Missing argument 'LASTNAME'" in result.output 19 | 20 | 21 | def test_2(): 22 | result = runner.invoke(app, ["Camila", "Gutiérrez"]) 23 | assert result.exit_code == 0 24 | assert "Hello Camila Gutiérrez" in result.output 25 | 26 | 27 | def test_script(): 28 | result = subprocess.run( 29 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 30 | capture_output=True, 31 | encoding="utf-8", 32 | ) 33 | assert "Usage" in result.stdout 34 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_multiple_values/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_multiple_values/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_multiple_values/test_arguments_with_multiple_values/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_multiple_values/test_arguments_with_multiple_values/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_multiple_values/test_arguments_with_multiple_values/test_tutorial001.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | import typer 5 | from typer.testing import CliRunner 6 | 7 | from docs_src.multiple_values.arguments_with_multiple_values import tutorial001 as mod 8 | 9 | runner = CliRunner() 10 | app = typer.Typer() 11 | app.command()(mod.main) 12 | 13 | 14 | def test_main(): 15 | result = runner.invoke(app, ["README.md", "pyproject.toml", "woohoo!"]) 16 | assert result.exit_code == 0 17 | assert "This file exists: README.md\nwoohoo!" in result.output 18 | assert "This file exists: pyproject.toml\nwoohoo!" in result.output 19 | 20 | 21 | def test_script(): 22 | result = subprocess.run( 23 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 24 | capture_output=True, 25 | encoding="utf-8", 26 | ) 27 | assert "Usage" in result.stdout 28 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_multiple_values/test_multiple_options/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_multiple_values/test_multiple_options/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_multiple_values/test_options_with_multiple_values/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_multiple_values/test_options_with_multiple_values/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_one_file_per_command/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_one_file_per_command/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_options/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_options/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_options/test_callback/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_options/test_callback/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_options/test_callback/test_tutorial001.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | import typer 5 | from typer.testing import CliRunner 6 | 7 | from docs_src.options.callback import tutorial001 as mod 8 | 9 | runner = CliRunner() 10 | 11 | app = typer.Typer() 12 | app.command()(mod.main) 13 | 14 | 15 | def test_1(): 16 | result = runner.invoke(app, ["--name", "Camila"]) 17 | assert result.exit_code == 0 18 | assert "Hello Camila" in result.output 19 | 20 | 21 | def test_2(): 22 | result = runner.invoke(app, ["--name", "rick"]) 23 | assert result.exit_code != 0 24 | assert "Invalid value for '--name'" in result.output 25 | assert "Only Camila is allowed" in result.output 26 | 27 | 28 | def test_script(): 29 | result = subprocess.run( 30 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 31 | capture_output=True, 32 | encoding="utf-8", 33 | ) 34 | assert "Usage" in result.stdout 35 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_options/test_callback/test_tutorial001_an.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | import typer 5 | from typer.testing import CliRunner 6 | 7 | from docs_src.options.callback import tutorial001_an as mod 8 | 9 | runner = CliRunner() 10 | 11 | app = typer.Typer() 12 | app.command()(mod.main) 13 | 14 | 15 | def test_1(): 16 | result = runner.invoke(app, ["--name", "Camila"]) 17 | assert result.exit_code == 0 18 | assert "Hello Camila" in result.output 19 | 20 | 21 | def test_2(): 22 | result = runner.invoke(app, ["--name", "rick"]) 23 | assert result.exit_code != 0 24 | assert "Invalid value for '--name'" in result.output 25 | assert "Only Camila is allowed" in result.output 26 | 27 | 28 | def test_script(): 29 | result = subprocess.run( 30 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 31 | capture_output=True, 32 | encoding="utf-8", 33 | ) 34 | assert "Usage" in result.stdout 35 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_options/test_help/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_options/test_help/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_options/test_help/test_tutorial003.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | import typer 5 | from typer.testing import CliRunner 6 | 7 | from docs_src.options.help import tutorial003 as mod 8 | 9 | runner = CliRunner() 10 | 11 | app = typer.Typer() 12 | app.command()(mod.main) 13 | 14 | 15 | def test_call(): 16 | result = runner.invoke(app) 17 | assert result.exit_code == 0 18 | assert "Hello Wade Wilson" in result.output 19 | 20 | 21 | def test_help(): 22 | result = runner.invoke(app, ["--help"]) 23 | assert result.exit_code == 0 24 | assert "--fullname" in result.output 25 | assert "TEXT" in result.output 26 | assert "[default: Wade Wilson]" not in result.output 27 | 28 | 29 | def test_script(): 30 | result = subprocess.run( 31 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 32 | capture_output=True, 33 | encoding="utf-8", 34 | ) 35 | assert "Usage" in result.stdout 36 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_options/test_help/test_tutorial003_an.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | import typer 5 | from typer.testing import CliRunner 6 | 7 | from docs_src.options.help import tutorial003_an as mod 8 | 9 | runner = CliRunner() 10 | 11 | app = typer.Typer() 12 | app.command()(mod.main) 13 | 14 | 15 | def test_call(): 16 | result = runner.invoke(app) 17 | assert result.exit_code == 0 18 | assert "Hello Wade Wilson" in result.output 19 | 20 | 21 | def test_help(): 22 | result = runner.invoke(app, ["--help"]) 23 | assert result.exit_code == 0 24 | assert "--fullname" in result.output 25 | assert "TEXT" in result.output 26 | assert "[default: Wade Wilson]" not in result.output 27 | 28 | 29 | def test_script(): 30 | result = subprocess.run( 31 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 32 | capture_output=True, 33 | encoding="utf-8", 34 | ) 35 | assert "Usage" in result.stdout 36 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_options/test_name/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_options/test_name/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_options/test_prompt/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_options/test_prompt/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_options/test_required/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_options/test_required/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_options/test_version/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_options/test_version/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_options_autocompletion/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_options_autocompletion/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_parameter_types/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_parameter_types/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_parameter_types/test_bool/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_parameter_types/test_bool/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_parameter_types/test_custom_types/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_parameter_types/test_custom_types/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_parameter_types/test_datetime/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_parameter_types/test_datetime/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_parameter_types/test_datetime/test_tutorial002.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | import typer 5 | from typer.testing import CliRunner 6 | 7 | from docs_src.parameter_types.datetime import tutorial002 as mod 8 | 9 | runner = CliRunner() 10 | 11 | app = typer.Typer() 12 | app.command()(mod.main) 13 | 14 | 15 | def test_main(): 16 | result = runner.invoke(app, ["1969-10-29"]) 17 | assert result.exit_code == 0 18 | assert "Launch will be at: 1969-10-29 00:00:00" in result.output 19 | 20 | 21 | def test_usa_weird_date_format(): 22 | result = runner.invoke(app, ["10/29/1969"]) 23 | assert result.exit_code == 0 24 | assert "Launch will be at: 1969-10-29 00:00:00" in result.output 25 | 26 | 27 | def test_script(): 28 | result = subprocess.run( 29 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 30 | capture_output=True, 31 | encoding="utf-8", 32 | ) 33 | assert "Usage" in result.stdout 34 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_parameter_types/test_enum/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_parameter_types/test_enum/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_parameter_types/test_enum/test_tutorial002.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | import typer 5 | from typer.testing import CliRunner 6 | 7 | from docs_src.parameter_types.enum import tutorial002 as mod 8 | 9 | runner = CliRunner() 10 | 11 | app = typer.Typer() 12 | app.command()(mod.main) 13 | 14 | 15 | def test_upper(): 16 | result = runner.invoke(app, ["--network", "CONV"]) 17 | assert result.exit_code == 0 18 | assert "Training neural network of type: conv" in result.output 19 | 20 | 21 | def test_mix(): 22 | result = runner.invoke(app, ["--network", "LsTm"]) 23 | assert result.exit_code == 0 24 | assert "Training neural network of type: lstm" in result.output 25 | 26 | 27 | def test_script(): 28 | result = subprocess.run( 29 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 30 | capture_output=True, 31 | encoding="utf-8", 32 | ) 33 | assert "Usage" in result.stdout 34 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_parameter_types/test_enum/test_tutorial002_an.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | import typer 5 | from typer.testing import CliRunner 6 | 7 | from docs_src.parameter_types.enum import tutorial002_an as mod 8 | 9 | runner = CliRunner() 10 | 11 | app = typer.Typer() 12 | app.command()(mod.main) 13 | 14 | 15 | def test_upper(): 16 | result = runner.invoke(app, ["--network", "CONV"]) 17 | assert result.exit_code == 0 18 | assert "Training neural network of type: conv" in result.output 19 | 20 | 21 | def test_mix(): 22 | result = runner.invoke(app, ["--network", "LsTm"]) 23 | assert result.exit_code == 0 24 | assert "Training neural network of type: lstm" in result.output 25 | 26 | 27 | def test_script(): 28 | result = subprocess.run( 29 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 30 | capture_output=True, 31 | encoding="utf-8", 32 | ) 33 | assert "Usage" in result.stdout 34 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_parameter_types/test_file/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_parameter_types/test_file/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_parameter_types/test_file/test_tutorial003.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | from pathlib import Path 4 | 5 | import typer 6 | from typer.testing import CliRunner 7 | 8 | from docs_src.parameter_types.file import tutorial003 as mod 9 | 10 | runner = CliRunner() 11 | 12 | app = typer.Typer() 13 | app.command()(mod.main) 14 | 15 | 16 | def test_main(tmpdir): 17 | binary_file = Path(tmpdir) / "config.txt" 18 | binary_file.write_bytes(b"la cig\xc3\xbce\xc3\xb1a trae al ni\xc3\xb1o") 19 | result = runner.invoke(app, ["--file", f"{binary_file}"]) 20 | binary_file.unlink() 21 | assert result.exit_code == 0 22 | assert "Processed bytes total:" in result.output 23 | 24 | 25 | def test_script(): 26 | result = subprocess.run( 27 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 28 | capture_output=True, 29 | encoding="utf-8", 30 | ) 31 | assert "Usage" in result.stdout 32 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_parameter_types/test_file/test_tutorial003_an.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | from pathlib import Path 4 | 5 | import typer 6 | from typer.testing import CliRunner 7 | 8 | from docs_src.parameter_types.file import tutorial003_an as mod 9 | 10 | runner = CliRunner() 11 | 12 | app = typer.Typer() 13 | app.command()(mod.main) 14 | 15 | 16 | def test_main(tmpdir): 17 | binary_file = Path(tmpdir) / "config.txt" 18 | binary_file.write_bytes(b"la cig\xc3\xbce\xc3\xb1a trae al ni\xc3\xb1o") 19 | result = runner.invoke(app, ["--file", f"{binary_file}"]) 20 | binary_file.unlink() 21 | assert result.exit_code == 0 22 | assert "Processed bytes total:" in result.output 23 | 24 | 25 | def test_script(): 26 | result = subprocess.run( 27 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 28 | capture_output=True, 29 | encoding="utf-8", 30 | ) 31 | assert "Usage" in result.stdout 32 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_parameter_types/test_index/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_parameter_types/test_index/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_parameter_types/test_number/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_parameter_types/test_number/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_parameter_types/test_path/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_parameter_types/test_path/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_parameter_types/test_uuid/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_parameter_types/test_uuid/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_prompt/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_prompt/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_prompt/test_tutorial001.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | import typer 5 | from typer.testing import CliRunner 6 | 7 | from docs_src.prompt import tutorial001 as mod 8 | 9 | runner = CliRunner() 10 | 11 | app = typer.Typer() 12 | app.command()(mod.main) 13 | 14 | 15 | def test_cli(): 16 | result = runner.invoke(app, input="Camila\n") 17 | assert result.exit_code == 0 18 | assert "What's your name?:" in result.output 19 | assert "Hello Camila" in result.output 20 | 21 | 22 | def test_script(): 23 | result = subprocess.run( 24 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 25 | capture_output=True, 26 | encoding="utf-8", 27 | ) 28 | assert "Usage" in result.stdout 29 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_subcommands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_subcommands/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_subcommands/test_callback_override/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_subcommands/test_callback_override/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_subcommands/test_callback_override/test_tutorial001.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | from typer.testing import CliRunner 5 | 6 | from docs_src.subcommands.callback_override import tutorial001 as mod 7 | 8 | runner = CliRunner() 9 | 10 | app = mod.app 11 | 12 | 13 | def test_cli(): 14 | result = runner.invoke(app, ["users", "create", "Camila"]) 15 | assert result.exit_code == 0 16 | assert "Running a users command" in result.output 17 | assert "Creating user: Camila" in result.output 18 | 19 | 20 | def test_script(): 21 | result = subprocess.run( 22 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 23 | capture_output=True, 24 | encoding="utf-8", 25 | ) 26 | assert "Usage" in result.stdout 27 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_subcommands/test_callback_override/test_tutorial002.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | from typer.testing import CliRunner 5 | 6 | from docs_src.subcommands.callback_override import tutorial002 as mod 7 | 8 | runner = CliRunner() 9 | 10 | app = mod.app 11 | 12 | 13 | def test_cli(): 14 | result = runner.invoke(app, ["users", "create", "Camila"]) 15 | assert result.exit_code == 0 16 | assert "Running a users command" in result.output 17 | assert "Creating user: Camila" in result.output 18 | 19 | 20 | def test_script(): 21 | result = subprocess.run( 22 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 23 | capture_output=True, 24 | encoding="utf-8", 25 | ) 26 | assert "Usage" in result.stdout 27 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_subcommands/test_callback_override/test_tutorial003.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | from typer.testing import CliRunner 5 | 6 | from docs_src.subcommands.callback_override import tutorial003 as mod 7 | 8 | runner = CliRunner() 9 | 10 | app = mod.app 11 | 12 | 13 | def test_cli(): 14 | result = runner.invoke(app, ["users", "create", "Camila"]) 15 | assert result.exit_code == 0 16 | assert "Running a users command" not in result.output 17 | assert "Callback override, running users command" in result.output 18 | assert "Creating user: Camila" in result.output 19 | 20 | 21 | def test_for_coverage(): 22 | mod.default_callback() 23 | 24 | 25 | def test_script(): 26 | result = subprocess.run( 27 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 28 | capture_output=True, 29 | encoding="utf-8", 30 | ) 31 | assert "Usage" in result.stdout 32 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_subcommands/test_name_help/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_subcommands/test_name_help/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_terminating/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_terminating/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_terminating/test_tutorial002.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | import typer 5 | from typer.testing import CliRunner 6 | 7 | from docs_src.terminating import tutorial002 as mod 8 | 9 | runner = CliRunner() 10 | 11 | app = typer.Typer() 12 | app.command()(mod.main) 13 | 14 | 15 | def test_cli(): 16 | result = runner.invoke(app, ["Camila"]) 17 | assert result.exit_code == 0 18 | assert "New user created: Camila" in result.output 19 | 20 | 21 | def test_root(): 22 | result = runner.invoke(app, ["root"]) 23 | assert result.exit_code == 1 24 | assert "The root user is reserved" in result.output 25 | 26 | 27 | def test_script(): 28 | result = subprocess.run( 29 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 30 | capture_output=True, 31 | encoding="utf-8", 32 | ) 33 | assert "Usage" in result.stdout 34 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_testing/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_testing/__init__.py -------------------------------------------------------------------------------- /tests/test_tutorial/test_testing/test_app01.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | from docs_src.testing.app01 import main as mod 5 | from docs_src.testing.app01.test_main import test_app 6 | 7 | 8 | def test_app01(): 9 | test_app() 10 | 11 | 12 | def test_script(): 13 | result = subprocess.run( 14 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 15 | capture_output=True, 16 | encoding="utf-8", 17 | ) 18 | assert "Usage" in result.stdout 19 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_testing/test_app02.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | from docs_src.testing.app02 import main as mod 5 | from docs_src.testing.app02.test_main import test_app 6 | 7 | 8 | def test_app02(): 9 | test_app() 10 | 11 | 12 | def test_script(): 13 | result = subprocess.run( 14 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 15 | capture_output=True, 16 | encoding="utf-8", 17 | ) 18 | assert "Usage" in result.stdout 19 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_testing/test_app02_an.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | from docs_src.testing.app02_an import main as mod 5 | from docs_src.testing.app02_an.test_main import test_app 6 | 7 | 8 | def test_app02_an(): 9 | test_app() 10 | 11 | 12 | def test_script(): 13 | result = subprocess.run( 14 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 15 | capture_output=True, 16 | encoding="utf-8", 17 | ) 18 | assert "Usage" in result.stdout 19 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_testing/test_app03.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | 4 | from docs_src.testing.app03 import main as mod 5 | from docs_src.testing.app03.test_main import test_app 6 | 7 | 8 | def test_app03(): 9 | test_app() 10 | 11 | 12 | def test_script(): 13 | result = subprocess.run( 14 | [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], 15 | capture_output=True, 16 | encoding="utf-8", 17 | ) 18 | assert "Usage" in result.stdout 19 | -------------------------------------------------------------------------------- /tests/test_tutorial/test_using_click/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/tests/test_tutorial/test_using_click/__init__.py -------------------------------------------------------------------------------- /tests/utils.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from os import getenv 3 | 4 | import pytest 5 | 6 | try: 7 | import shellingham 8 | from shellingham import ShellDetectionFailure 9 | 10 | shell = shellingham.detect_shell()[0] 11 | except ImportError: # pragma: no cover 12 | shellingham = None 13 | shell = None 14 | except ShellDetectionFailure: # pragma: no cover 15 | shell = None 16 | 17 | 18 | needs_py310 = pytest.mark.skipif( 19 | sys.version_info < (3, 10), reason="requires python3.10+" 20 | ) 21 | 22 | needs_linux = pytest.mark.skipif( 23 | not sys.platform.startswith("linux"), reason="Test requires Linux" 24 | ) 25 | 26 | needs_bash = pytest.mark.skipif( 27 | not shellingham or not shell or "bash" not in shell, reason="Test requires Bash" 28 | ) 29 | 30 | requires_completion_permission = pytest.mark.skipif( 31 | not getenv("_TYPER_RUN_INSTALL_COMPLETION_TESTS", False), 32 | reason="Test requires permission to run completion installation tests", 33 | ) 34 | -------------------------------------------------------------------------------- /typer/__main__.py: -------------------------------------------------------------------------------- 1 | from .cli import main 2 | 3 | main() 4 | -------------------------------------------------------------------------------- /typer/colors.py: -------------------------------------------------------------------------------- 1 | # Variable names to colors, just for completion 2 | BLACK = "black" 3 | RED = "red" 4 | GREEN = "green" 5 | YELLOW = "yellow" 6 | BLUE = "blue" 7 | MAGENTA = "magenta" 8 | CYAN = "cyan" 9 | WHITE = "white" 10 | 11 | RESET = "reset" 12 | 13 | BRIGHT_BLACK = "bright_black" 14 | BRIGHT_RED = "bright_red" 15 | BRIGHT_GREEN = "bright_green" 16 | BRIGHT_YELLOW = "bright_yellow" 17 | BRIGHT_BLUE = "bright_blue" 18 | BRIGHT_MAGENTA = "bright_magenta" 19 | BRIGHT_CYAN = "bright_cyan" 20 | BRIGHT_WHITE = "bright_white" 21 | -------------------------------------------------------------------------------- /typer/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastapi/typer/9138340f90258c9ef42a5159fc6bebc7373dbdf8/typer/py.typed --------------------------------------------------------------------------------