I'm writing a package in Python, and I want possible users to install a command to their system by installing with pip
. A package that I want to copy the installation behavior of is gdown
. When you install this, a gdown
python executable is put inside the environment's (whether it's global or a virtual environment) bin/
folder, so that gdown
can be called from the command line.
How do I replicate this behavior? I tried to look at the code in the repository but I can't seem to find the code that does this.
Assume we're working with pyproject.toml
, which is the standard by now.
Let's distinguish between two use-cases:
1. Making a Python script available as executable
You can use [project.scripts]
(official reference) to have an executable shortcut created to some python function (which is what gdown
does too):
[project.scripts]
spam-cli = "spam:main_cli"
This will create an executable spam-cli.exe
(on Windows, inside Scripts/
) or spam-cli
(on Linux, inside bin/
) that runs main_cli()
from the installed spam.py
file.
The Poetry backend has it's own syntax to it:
[tool.poetry.scripts]
my_package_cli = "my_package.console:run"
2. Installing an existing script or executable
Instead you might want to make a shell script or compiled binary available with your pip package. As far as I know, the pyproject.toml
standard doesn't support this. But, there are options for both the setuptools and Poetry backends:
[tool.setuptools]
script-files = [ "myscript" ]
(See https://stackoverflow.com/a/74955996/4784914. Note: script-files
is being discouraged though!)
[tool.poetry.scripts]
myscript = { reference = "some_binary.exe", type = "file" }
I cannot find any documentation to back this up, oddly enough, but it works.
This will copy the executable or script into the bin/
or Scripts/
directory, making them available directly from the CLI after installing the package.