Registry / devops / cleo
library2.1.0pypypi✓ verified 30d ago

Cleo is a Python library designed to help developers create beautiful and testable command-line interfaces. It draws significant inspiration from the Symfony Console Component, providing a robust and familiar structure for building CLI applications. The library is actively maintained, with a release cadence that includes support for new Python versions and essential bug fixes, as demonstrated by the recent 2.1.0 update.

pip install cleo
INSTALL
IMPORT
SIG · CLEO
C
cleo
devopspythonv2.1.0
Install
2.7s avg
Import
157ms
Disk
31MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.9–3.13
musl
3.9–3.13
Install & Compatibility
Where this runs
tested against v2.1.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.160s · 34.7MB
glibc
py 3.10–3.95 runs
installs and imports cleanly · install 2.7s · import 0.154s · 31MB
31MB installed
● package 31MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Application
✓ from cleo.application import Application
✗ from cleo import Application
While 'from cleo import Application' might work in some contexts, the explicit path 'from cleo.application import Application' is recommended for clarity and directness, as shown in official examples.
Command
✓ from cleo.commands.command import Command
✗ from cleo import Command
Similar to Application, importing Command from its explicit module path 'cleo.commands.command' is the precise and recommended approach, as seen in the library's internal structure and modern examples.
argument
✓ from cleo.helpers import argument
✗ from cleo import InputArgument
Since Cleo v2.0.0 (and effectively v1.0.0), the recommended way to define command arguments is using the `argument` helper from `cleo.helpers`, replacing the older `InputArgument` class and docstring-based definitions.
option
✓ from cleo.helpers import option
✗ from cleo import InputOption
Corresponding to `argument`, the `option` helper from `cleo.helpers` is now the standard for defining command options, replacing `InputOption` and docstring-based methods in versions v2.0.0+.
CleoError
✓ from cleo.exceptions import CleoError
✗ from cleo.exceptions import CleoException
The exception hierarchy was refactored in Cleo v1.0.0 (effectively v2.0.0), with `CleoException` being replaced by `CleoError`.

This quickstart demonstrates how to create a basic command-line application with Cleo. It defines a `GreetCommand` that accepts an optional name argument and a 'yell' flag. The command uses `cleo.helpers.argument` and `cleo.helpers.option` for modern argument and option definitions. An `Application` instance registers the command, and a simulated `io` stream is used to run the command programmatically for demonstration purposes, mimicking command-line execution.

import os from cleo.application import Application from cleo.commands.command import Command from cleo.helpers import argument, option class GreetCommand(Command): name = "greet" description = "Greets someone" arguments = [ argument("name", description="Who do you want to greet?", optional=True) ] options = [ option("yell", "y", description="If set, the task will yell in uppercase letters", flag=True) ] def handle(self): name = self.argument("name") if name: text = f"Hello {name}" else: text = "Hello" if self.option("yell"): text = text.upper() self.line(text) application = Application("My CLI App", "1.0.0") application.add(GreetCommand()) if __name__ == "__main__": # Example of how to run, in a real app this would be called via command line # e.g., `python your_script.py greet John --yell` # For quickstart, we'll simulate it for programmatic execution and testing try: # Simulate a command-line call for demonstration # In a real scenario, this would be invoked via sys.argv from cleo.io.buffered_io import BufferedIO from cleo.io.inputs.string_input import StringInput from cleo.io.outputs.buffered_output import BufferedOutput # Example: running 'greet John --yell' input_stream = StringInput('greet John --yell') output_stream = BufferedOutput() error_stream = BufferedOutput() io = BufferedIO(input_stream, output_stream, error_stream) application.run(io) print("\n--- Output ---") print(output_stream.fetch()) print("--- Error ---") print(error_stream.fetch()) print("--------------") # Example: running 'greet' input_stream_no_args = StringInput('greet') output_stream_no_args = BufferedOutput() error_stream_no_args = BufferedOutput() io_no_args = BufferedIO(input_stream_no_args, output_stream_no_args, error_stream_no_args) application.run(io_no_args) print("\n--- Output (No Args) ---") print(output_stream_no_args.fetch()) print("--- Error (No Args) ---") print(error_stream_no_args.fetch()) print("------------------------") except Exception as e: print(f"An error occurred: {e}")
cleo --version
Debug
Known issues
breakingCleo versions 1.0.0 and 2.0.0 removed the `clikit` dependency, signifying a major internal refactoring. Code relying on `clikit` directly or specific `clikit`-based behaviors within Cleo will break.
fix
Review your code for direct or indirect `clikit` usage. Adapt to Cleo's native implementations for input/output handling, command definition, and other CLI functionalities. The library is now self-contained in this regard.
affects: >=1.0.0
breakingThe `Terminal` class was removed and replaced with `shutil.get_terminal_size()` from Python's standard library. Direct calls to `cleo.terminal.Terminal` will fail.
fix
Replace usages of `cleo.terminal.Terminal` with `shutil.get_terminal_size()` for terminal dimension retrieval.
affects: >=1.0.0
breakingThe exception hierarchy changed in versions 1.0.0 / 2.0.0. Specifically, `CleoException` was renamed or replaced by `CleoError`.
fix
Update exception handling blocks to catch `CleoError` instead of `CleoException` and adjust for any other related exception class changes.
affects: >=1.0.0
breakingDoc comment-based command configuration (where arguments and options were defined in the command's docstring) was removed in versions 1.0.0 / 2.0.0.
fix
Migrate command argument and option definitions to use the `arguments` and `options` class variables with `cleo.helpers.argument` and `cleo.helpers.option` decorators. Refer to the quickstart example for the new syntax.
affects: >=1.0.0
gotchaCleo version 1.0.0 was yanked shortly after its release due to compatibility issues with other projects (e.g., Poetry) that depended on its pre-release versions. Version 2.0.0 was released immediately after with no source code changes to effectively replace 1.0.0.
fix
Avoid using `cleo==1.0.0`. If targeting the feature set introduced in `1.0.0`, ensure you use `cleo>=2.0.0` (e.g., `pip install 'cleo>=2.0.0,<3.0.0'`).
affects: 1.0.0
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'cleo'
The 'cleo' library is not installed in the current Python environment or is not accessible to the Python interpreter being used.
fix
Install the library using pip: `pip install cleo`
Not enough arguments (missing: "<argument_name>")
When programmatically calling a command using `self.call()` from within another Cleo command, the arguments for the target command were not passed or parsed in the expected string format, leading to missing required arguments.
fix
Ensure arguments for the called command are passed as a single string to `self.call()`, often including the command name itself as the first part of the argument string, e.g., `self.call("target_command_name", "target_command_name arg_value --option")`.
The command "<command_name>" does not exist.
The command you are trying to execute or get help for has not been registered with the Cleo `Application` instance, or there's an issue with how nested commands are identified.
fix
Verify that your command class is properly added to the `Application` using `application.add(YourCommand())`. For nested commands, ensure the full command name (e.g., `namespace:command`) is correctly passed.
No such option: --<option_name>
An option was provided on the command line that has not been defined in the command's signature, or there is a typo in the option name.
fix
Define the expected option in the command's docstring using the `{--option_name}` or `{--option_name=default}` syntax, or correct any typos in the option name being passed.
Upgrade
Version history
2.1.0latest on PyPI · released Oct 30, 2023
Audit
Dependencies

No dependency data recorded yet.

Agent activity
34 hits · last 30 days
node
28
Amazon
1
OpenAI (training)
1
Resources
cleo — pip install cleo · libregistry