Making Packages Compatible
Developing for pipx
If you are a developer and want to be able to run
pipx install MY_PACKAGE
make sure you include scripts in your main table1 in pyproject.toml or its legacy equivalents for setup.cfg and
setup.py. pipx also exposes gui-scripts entry points, which are useful for GUI applications on Windows (they launch
without opening a console window).
[project.scripts]
foo = "my_package.some_module:main_func"
bar = "other_module:some_func"
[project.gui-scripts]
baz = "my_package_gui:start_func"
[options.entry_points]
console_scripts =
foo = my_package.some_module:main_func
bar = other_module:some_func
gui_scripts =
baz = my_package_gui:start_func
setup(
# other arguments here...
entry_points={
'console_scripts': [
'foo = my_package.some_module:main_func',
'bar = other_module:some_func',
],
'gui_scripts': [
'baz = my_package_gui:start_func',
]
},
)
In this case foo and bar (and baz on Windows) would be available as "applications" to pipx after installing the
above example package, invoking their corresponding entry point functions.
flowchart LR
TOML["pyproject.toml<br/>[project.scripts]"] --> |"defines"| EP["entry points<br/>foo, bar"]
EP --> |"pipx install"| VENV["isolated venv"]
VENV --> |"symlinks"| BIN["~/.local/bin/<br/>foo, bar"]
BIN --> |"invokes"| FUNC["my_package:<br/>main_func()"]
style TOML fill:#3f72af,color:#fff
style EP fill:#2a9d8f,color:#fff
style VENV fill:#7c4dff,color:#fff
style BIN fill:#388e3c,color:#fff
style FUNC fill:#c78c20,color:#fff
The pipx.run entry point group
When a user runs pipx run PACKAGE, pipx looks for a console script matching the package name. If the package name and
script name differ, the user has to write pipx run --spec PACKAGE SCRIPT, which is less convenient.
Package authors can declare a pipx.run entry point group to tell pipx which function to invoke for pipx run. This
entry point takes priority over console scripts when present.
[project.entry-points."pipx.run"]
my-package = "my_package.cli:main"
[options.entry_points]
pipx.run =
my-package = my_package.cli:main
With this declaration, pipx run my-package invokes my_package.cli:main even if no console script named my-package
exists. The build package uses this pattern so that pipx run build works even though
build's console script is named pyproject-build.
Manual pages
If you wish to provide documentation via man pages on UNIX-like systems then these can be added as data files:
[tool.setuptools.data-files]
"share/man/man1" = [
"manpage.1",
]
[options.data_files]
share/man/man1 =
manpage.1
setup(
# other arguments here...
data_files=[('share/man/man1', ['manpage.1'])]
)
Warning
The data-files keyword is "discouraged" in the
setuptools documentation
but there is no alternative if man pages are a requirement.
[tool.pdm.build]
source-includes = ["share"]
[tool.pdm.build.wheel-data]
data = [
{ path = "share/man/man1/*", relative-to = "." },
]
In this case the manual page manpage.1 could be accessed by the user after installing the above example package.
For a real-world example, see pycowsay's setup.py source
code.
You can read more about entry points here.