Building and distributing your CLIs¶
To build and distribute you own CLI I recommend you use uv..
In this quick walkthrough we'll be creating a CLI called zit
, a basic clone of git.
Creating a new CLI¶
First, you'll want to create a project. For that, follow uv's most up to date documentation about creating a new project.
A quick summary at the time of writing is:
-
Create a project directory:
mkdir zitcd zit -
Initialize a project:
uv init -
Install clypi:
uv add clypi -
Code your CLI.
uv
created amain.py
file but you should create your own python package inside a subdirectory calledzit
. Inside that subdirectory create an empty file called__init__.py
and a file calledmain.py
with the following content:tree.
├── README.md
├── pyproject.toml
├── uv.lock
└── zit
├── init.py
└── main.py# zit/main.py import clypi from clypi import Command, arg class Zit(Command): """ A git clone, but much slower ;) """ verbose: bool = arg(False, short="v") async def run(self): clypi.cprint("Sorry I don't know how to use git, it's too hard!", fg="yellow") if self.verbose: clypi.cprint("asdkjnbsvaeusbvkajhfnuehfvousadhvuashfqei" * 100) def main(): """ This will be the entrypoint for our CLI """ zit = Zit.parse() zit.start() if __name__ == "__main__": main()
-
Test out your new CLI. You can run it locally with:
uv run ./zit/main.py -
You'll need to add a build system so that
uv
understands this is a package you want to distribute and people to install. Add the following to yourpyproject.toml
-
Add an entrypoint to your Python package. This tells Python how to execute your program. Add the following lines to your
pyproject.toml
-
Install your package locally and run it
Building and distributing your CLI¶
I highly recommend you follow uv's guide on building an publishing packages.
The TLDR is uv build
then uv publish
, but you'll want to set up your project with the right metadata. The official packaging Python guide is really good to configure all you'll need for distributing a quality package.
[Advanced] Pre-built binaries (Shivs 🔪)¶
Shiv's provide an easy way to bundle Python code into an executable file. Shiv's are, essentially, an executable zip file with Python files inside.
To build a shiv with uv and clypi given the above zit
example, run:
You now have a binary (zit-bin
) that you can distribute and run like any other binary. You'll have to manually add it to a $PATH
location though (What is $PATH?).