I think I'm missing something simple
I have a python poetry application:
name = "my-first-api"
version = "0.1.0"
description = ""
readme = "README.md"
packages = [{include = "application"}]
[tool.poetry.scripts]
start = "main:start"
[tool.poetry.dependencies]
python = ">=3.10,<3.12"
pip= "23.0.1"
setuptools="65.5.0"
fastapi="0.89.1"
uvicorn="0.20.0"
[tool.poetry.group.dev.dependencies]
pyinstaller = "^5.10.1"
pytest = "^7.3.1"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
I can run this and build this using Poetry, however, I would like to be able to create the executable with a poetry script as well.
Now I build it like this:
poetry run pyinstaller main.py --collect-submodules application --onefile --name myapi
I would like something like
poetry package
to automatically create this executable as well. How do I hook that up?
Btw. ths does not work :(
[tool.poetry.scripts]
start = "main:start"
builddist = "poetry run pyinstaller main.py --collect-submodules application --onefile --name myapi"
I have found a solution using the pyinstaller API.
As you may know already, Poetry will only let you run 'scripts' if they are functions inside your package. Just like in your pyproject.toml
, you map the start
command to main:start
, which is the start()
function of your main.py
module.
Similarly, you can create a function in a module that triggers Pyinstaller and map that to a command that you can run as poetry run <commmand>
.
Assuming you have a module structure like this:
my_package
├── my_package
│ ├── __init__.py
│ ├── pyinstaller.py
│ └── main.py
└── pyproject.toml
pyinstaller.py
to call the Pyinstaller APIThe file should be inside your package structure, as shown in the diagram above. This is adapted from the Pyinstaller docs
import PyInstaller.__main__
from pathlib import Path
HERE = Path(__file__).parent.absolute()
path_to_main = str(HERE / "main.py")
def install():
PyInstaller.__main__.run([
path_to_main,
'--onefile',
'--windowed',
# other pyinstaller options...
])
build
command in pyproject.toml
In the pyproject.toml
file, add this
[tool.poetry.scripts]
build = "my_package.pyinstaller:install"
build
commandYou must do so under the virtual environment that poetry creates:
poetry run build
🎉 Profit