Last modified: Aug 11, 2025 By Alexander Williams

Python Typer Enum Choices and Validation

Typer makes building CLI apps easy. Using Enum choices and validation ensures robust user input handling. This guide shows you how.

Why Use Enum Choices in Typer?

Enums provide predefined options for CLI parameters. They make your app more user-friendly and reduce errors.

With Enum, you can limit input to specific values. This prevents invalid data from reaching your application logic.

Basic Enum Usage in Typer

Here's how to create a simple Enum choice parameter:

 
from enum import Enum
import typer

class Color(str, Enum):
    RED = "red"
    GREEN = "green"
    BLUE = "blue"

app = typer.Typer()

@app.command()
def set_color(color: Color):
    typer.echo(f"You chose {color.value}")

if __name__ == "__main__":
    app()

When run, this only accepts "red", "green", or "blue":


$ python app.py red
You chose red

$ python app.py yellow
Error: Invalid value for 'COLOR': 'yellow' is not one of 'red', 'green', 'blue'

Advanced Validation Patterns

Beyond Enums, Typer offers other validation techniques. Combine them for maximum input safety.

Custom Validators

Create functions to validate complex conditions. Use them with Typer's callback feature.

 
def validate_age(value: int):
    if value < 18:
        raise typer.BadParameter("Age must be 18+")
    return value

@app.command()
def register(age: int = typer.Option(..., callback=validate_age)):
    typer.echo(f"Registered with age {age}")

Range Validation

For numeric values, specify acceptable ranges directly:

 
@app.command()
def set_temp(temp: int = typer.Option(..., min=10, max=30)):
    typer.echo(f"Temperature set to {temp}°C")

Combining Enum with Other Typer Features

Enums work well with other Typer capabilities. For example, you can use them with boolean flags or help text.

Here's an example with help text:

 
@app.command()
def set_mode(
    mode: Mode = typer.Option(
        Mode.NORMAL,
        help="Operation mode",
        case_sensitive=False
    )
):
    typer.echo(f"Running in {mode.value} mode")

Real-World Example: File Converter

Let's build a practical CLI tool that converts files between formats:

 
from enum import Enum
from pathlib import Path
import typer

class Format(str, Enum):
    JPEG = "jpg"
    PNG = "png"
    GIF = "gif"

def validate_input(file: Path):
    if not file.exists():
        raise typer.BadParameter("File doesn't exist")
    if not file.is_file():
        raise typer.BadParameter("Must be a regular file")
    return file

@app.command()
def convert(
    input: Path = typer.Argument(..., callback=validate_input),
    output: Path = typer.Argument(...),
    format: Format = typer.Option(Format.JPEG)
):
    # Conversion logic would go here
    typer.echo(f"Converting {input} to {output}.{format.value}")

Error Handling Best Practices

Always provide clear error messages. Typer's BadParameter exception helps with this.

For complex apps, consider using subcommands to organize functionality.

Conclusion

Enum choices and validation make your Typer apps more robust. They guide users and prevent invalid input.

Combine Enums with other Typer features for professional CLI tools. Remember to provide clear error messages.

For more on Typer, check our type hints guide.