Specifying command line scripts in pyproject.toml
Question:
I’m trying to add a pyproject.toml to a project that’s been using setup.py in order to enable support by pipx. I’d like to specify the command line scripts the project includes in pyproject.toml, but all the guides I can find give instructions for use with poetry, which I am not using.
I also don’t want to specify entry points to modules – I already have working command line scripts and just want to specify those.
Is there a proper place in pyproject.toml to specify command line scripts?
Not sure it matters, but the package in question is cutlet.
Answers:
Is there a proper place in pyproject.toml to specify command line scripts?
PEP566 (Metadata 2.1) only defines Core metadata specifications. Thus, the answer depends on your build system (Note: PEP518 defines build system concept).
If you use the existing build tools such as setuptools
, poetry
, and flit
, you only can consider adding such options in pyproject.toml if that tool supports command line scripts (console_scripts
) in pyproject.toml. Surely, if you have your own build tool, you need to implement a parser to parse the command line scripts in pyproject.toml.
Lastly, you can check below list to know which major build system supports command line scripts (console_scripts
) in pyproject.toml (2020/Oct):
- setuptools: not implemented yet according to PEP621
- poetry: yes, here’s part of the implementation.
- flit: yes.
Update July 2022: if your TOML file uses setuptools as its build system, setuptools will happily create and install a console script. For example, my pyproject.toml
file starts like this:
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
Extend your pyproject.toml
file with an entry like this, naming the package, module and entry-point function names:
[project.scripts]
my-client = "my_package.my_module:main_cli"
Then run the install sequence:
pip3 install .
And setuptools will install a shell script named my-client
somewhere appropriate, for me in my Py3.9 virtual environment ‘s bin directory (~/.virtualenvs/py39/bin).
I was doing a similar thing, upgrading a package that had a setup.py
, altho I had no existing scripts. With the rewrite to using pyproject.toml
I dropped the old setup.py
file entirely.
FWIW I realize the OP asked for a way to install existing scripts, which I didn’t provide. This answer tells setuptools to create and install new scripts.
Update Feb 2023: thanks for all the votes. If you’re cutting corners to meet arbitrary management deadlines, just copy-paste this short pyproject.toml
file and adjust:
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
[project]
name = "my_client"
version = "1.2.3"
authors = [{name="Ubr Programmer", email="[email protected]" }]
description = "Client for my awesome system"
readme = "README.md"
dependencies = ["cachetools","requests"]
requires-python = ">=3.9"
[project.scripts]
my-client = "my_package.my_module:main_cli"
[project.urls]
"Homepage" = "https://github.com/your_name_here/something"
"Bug Tracker" = "https://github.com/your_name_here/something/issues"
I’m trying to add a pyproject.toml to a project that’s been using setup.py in order to enable support by pipx. I’d like to specify the command line scripts the project includes in pyproject.toml, but all the guides I can find give instructions for use with poetry, which I am not using.
I also don’t want to specify entry points to modules – I already have working command line scripts and just want to specify those.
Is there a proper place in pyproject.toml to specify command line scripts?
Not sure it matters, but the package in question is cutlet.
Is there a proper place in pyproject.toml to specify command line scripts?
PEP566 (Metadata 2.1) only defines Core metadata specifications. Thus, the answer depends on your build system (Note: PEP518 defines build system concept).
If you use the existing build tools such as setuptools
, poetry
, and flit
, you only can consider adding such options in pyproject.toml if that tool supports command line scripts (console_scripts
) in pyproject.toml. Surely, if you have your own build tool, you need to implement a parser to parse the command line scripts in pyproject.toml.
Lastly, you can check below list to know which major build system supports command line scripts (console_scripts
) in pyproject.toml (2020/Oct):
- setuptools: not implemented yet according to PEP621
- poetry: yes, here’s part of the implementation.
- flit: yes.
Update July 2022: if your TOML file uses setuptools as its build system, setuptools will happily create and install a console script. For example, my pyproject.toml
file starts like this:
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
Extend your pyproject.toml
file with an entry like this, naming the package, module and entry-point function names:
[project.scripts]
my-client = "my_package.my_module:main_cli"
Then run the install sequence:
pip3 install .
And setuptools will install a shell script named my-client
somewhere appropriate, for me in my Py3.9 virtual environment ‘s bin directory (~/.virtualenvs/py39/bin).
I was doing a similar thing, upgrading a package that had a setup.py
, altho I had no existing scripts. With the rewrite to using pyproject.toml
I dropped the old setup.py
file entirely.
FWIW I realize the OP asked for a way to install existing scripts, which I didn’t provide. This answer tells setuptools to create and install new scripts.
Update Feb 2023: thanks for all the votes. If you’re cutting corners to meet arbitrary management deadlines, just copy-paste this short pyproject.toml
file and adjust:
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
[project]
name = "my_client"
version = "1.2.3"
authors = [{name="Ubr Programmer", email="[email protected]" }]
description = "Client for my awesome system"
readme = "README.md"
dependencies = ["cachetools","requests"]
requires-python = ">=3.9"
[project.scripts]
my-client = "my_package.my_module:main_cli"
[project.urls]
"Homepage" = "https://github.com/your_name_here/something"
"Bug Tracker" = "https://github.com/your_name_here/something/issues"