Cyclopts
raw JSON → 4.10.1 verified Tue May 12 auth: no python install: verified
Cyclopts is a modern, easy-to-use command-line interface (CLI) framework built on Python type hints, offering an intuitive and efficient developer experience. It provides advanced type hinting support, rich help page generation from docstrings, and extensive customization options for parsing and launching. The library is actively maintained, currently at version 4.10.1, with frequent updates and ongoing development towards version 5.0.
pip install cyclopts Common errors
error Invalid value "200" for "AGE". You are too old to be using this application. ↓
cause The input value provided for a command-line argument failed a custom or built-in validation rule, even after successful type coercion. Cyclopts re-interprets `ValueError`, `TypeError`, or `AssertionError` into a user-friendly `ValidationError` message.
fix
Adjust the input value to comply with the expected validation criteria or modify the validator function if the criteria are incorrect. For example, if using
cyclopts.validators.Number.range(), ensure the input falls within the specified range. error Unknown command "this-is-not-a-registered-command" ↓
cause The command-line input specified a command name that has not been registered with the Cyclopts `App` instance using `@app.command` or `@app.default`.
fix
Ensure the command name provided on the command line exactly matches a registered command or check for typos. If the command should be available, verify it has been correctly registered with
@app.command or that it is the default command using @app.default. error Parameter "--values" was specified multiple times. ↓
cause A command-line parameter was provided more than once, and its definition (e.g., in `Parameter(allow_repeating=False)`) does not permit multiple occurrences.
fix
Modify the command-line input to specify the parameter only once, or adjust the
Parameter definition in your code to allow_repeating=True if the argument is intended to accept multiple values that form a list or similar collection. error ImportError: Cannot import module 'nonexistent.module'. ↓
cause When using Cyclopts's lazy loading feature for commands (e.g., `app.command("module.path:function")`), the specified Python module or attribute could not be found or imported at the time the command was executed.
fix
Verify that the import path (e.g.,
nonexistent.module and func) is correct and that the module is accessible within your Python environment. Ensure there are no typos in the module path or the function/App name specified after the colon. Warnings
breaking Major version 5.x (currently in alpha) is expected to introduce breaking changes. While specific details are not yet fully documented, major version bumps typically involve API alterations. Always review the official migration guide when upgrading to a new major version. ↓
fix Consult the official Cyclopts v5 migration guide (when available) and update code to reflect new API patterns and behaviors.
gotcha Migrating from Typer: `Argument` and `Option` from `typer` are replaced by `cyclopts.Parameter`. The handling of default actions, callbacks, `Enum` lookups, and `Union` types differs. Cyclopts natively supports `Union` types, unlike Typer. ↓
fix Replace `typer.Argument`/`typer.Option` with `cyclopts.Parameter`. Re-evaluate default command logic and how `Enum`/`Union` types are handled.
gotcha Parameter Resolution Order: When multiple `Parameter` annotations are applied (e.g., at the function, group, or app level), explicitly set attributes in `Annotated[..., Parameter()]` for a specific function parameter have the highest priority. ↓
fix Be aware of the resolution hierarchy: function-level annotations > group `default_parameter` > app `default_parameter`. Override specific behaviors at the highest-priority level needed.
gotcha Implicit Type Coercion: If a function parameter lacks an explicit type hint, Cyclopts will attempt to infer its type from a non-None default value. If no default is provided, it defaults to `str`. This can lead to unexpected parsing if not explicitly hinted. ↓
fix Always provide explicit type hints (e.g., `value: int`) for function parameters to ensure correct type coercion and prevent unexpected `str` parsing.
gotcha Lazy Loading `--help` Behavior (pre-v4.8.0): Prior to version 4.8.0, running `--help` on a parent command would eagerly import and resolve *all* lazy child commands. This negated the startup-time benefits of lazy loading. ↓
fix Upgrade to Cyclopts v4.8.0 or later. For lazy commands, provide the `help=` argument at registration time (e.g., `app.command('module:command_func', help='Description')`) to display descriptions without triggering imports.
gotcha Required parameters without default values must always be provided with an argument during command invocation. Not supplying a value for a required parameter will result in a runtime error. ↓
fix Ensure all required parameters are supplied with their corresponding argument values when invoking a command. Define a default value for parameters if they should be optional.
Install compatibility verified last tested: 2026-05-12
python os / libc status wheel install import disk
3.10 alpine (musl) wheel - 0.17s 37.3M
3.10 alpine (musl) - - 0.20s 37.4M
3.10 slim (glibc) wheel 3.3s 0.12s 38M
3.10 slim (glibc) - - 0.12s 38M
3.11 alpine (musl) wheel - 0.25s 41.1M
3.11 alpine (musl) - - 0.30s 41.2M
3.11 slim (glibc) wheel 3.2s 0.22s 42M
3.11 slim (glibc) - - 0.25s 42M
3.12 alpine (musl) wheel - 0.21s 32.5M
3.12 alpine (musl) - - 0.23s 32.7M
3.12 slim (glibc) wheel 3.1s 0.21s 33M
3.12 slim (glibc) - - 0.26s 33M
3.13 alpine (musl) wheel - 0.21s 32.3M
3.13 alpine (musl) - - 0.23s 32.3M
3.13 slim (glibc) wheel 3.0s 0.21s 33M
3.13 slim (glibc) - - 0.24s 33M
3.9 alpine (musl) wheel - 0.19s 35.3M
3.9 alpine (musl) - - 0.22s 35.5M
3.9 slim (glibc) wheel 3.6s 0.16s 36M
3.9 slim (glibc) - - 0.17s 36M
Imports
- App
from cyclopts import App - Parameter
from cyclopts import Parameter - run
from cyclopts import run
Quickstart last tested: 2026-04-24
from cyclopts import App
app = App()
@app.default
def main(name: str, count: int = 1):
"""Greets the given name(s).
Parameters
----------
name: str
The name to greet.
count: int
Number of times to greet.
"""
for _ in range(count):
print(f"Hello, {name}!")
if __name__ == "__main__":
# Example usage: python your_script.py World --count 3
# Or: python your_script.py --help
app()