Getting Started

Cyclopts relies heavily on function parameter type hints. If you are new to type hints or need a refresher, checkout the mypy cheatsheet.

A Basic Cyclopts Application

The most basic Cyclopts application is as follows:

import cyclopts

app = cyclopts.App()


@app.default
def main():
    print("Hello World!")


if __name__ == "__main__":
    app()

Save this as main.py and execute it to see:

$ python main.py
Hello World!

The App class offers various configuration options that we'll investigate in future guides. The app object has a decorator method, default, which registers a function as the default action. An application can have only a single default action. In this example, the main function is our default, and is executed when no CLI command is provided.

Function Arguments

Let's add some arguments to make this program a little more exciting.

import cyclopts

app = cyclopts.App()


@app.default
def main(name):
    print(f"Hello {name}!")


if __name__ == "__main__":
    app()

Execute it with an argument:

$ python main.py Alice
Hello Alice!

Here's what's happening:

  1. The function main was registered to app as the default action.

  2. Calling app() triggers Cyclopts to parse CLI inputs.

  3. Cyclopts identifies "Alice" as a positional argument, matching it to the parameter name. In the absence of an explicit type hint, Cyclopts defaults to str.

  4. Cyclopts calls the registered default main("Alice"), and the greeting is printed.

Multiple Arguments

Extending the example, lets add more arguments and type hints:

import cyclopts

app = cyclopts.App()


@app.default
def main(name: str, count: int):
    for _ in range(count):
        print(f"Hello {name}!")


if __name__ == "__main__":
    app()
$ python main.py Alice 3
Hello Alice!
Hello Alice!
Hello Alice!

The command line input "3" is converted to an integer because of count's type hint int. Cyclopts natively handles all python builtin types, see Coercion Rules for more details. Cyclopts adheres to Python's argument binding rules, allowing both positional and keyword arguments. Therefore, all these commands are equivalent:

$ python main.py Alice 3
$ python main.py --name Alice --count 3
$ python main.py --name=Alice --count=3
$ python main.py --count 3 --name=Alice
$ python main.py Alice --count 3
$ python main.py --count 3 Alice
$ python main.py --name=Alice 3
$ python main.py 3 --name=Alice

Cyclopts parses keyword arguments first, then fills in the gaps with positional arguments.

Adding Help

We can add application-level help documentation when creating our app:

app = cyclopts.App(help="Help string for this demo application.")
app()
$ my-script --help
Usage: my-script COMMAND

Help string for this demo application.

╭─ Commands ──────────────────────────────────────────────────────────╮
│ --help,-h  Display this message and exit.                           │
│ --version  Display application version.                             │
╰─────────────────────────────────────────────────────────────────────╯

By default, Cyclopts adds --help and --version commands to your CLI. If App.help is not set, Cyclopts will fallback to the first line (short description) of the registered @app.default function's docstring.