Reputation: 285
I am not very familiar with python, I only done automation with so I am a new with packages and everything.
I am creating an API with Flask, Gunicorn and Poetry.
I noticed that there is a version number inside the pyproject.toml and I would like to create a route /version which returns the version of my app.
My app structure look like this atm:
├── README.md
├── __init__.py
├── poetry.lock
├── pyproject.toml
├── tests
│ └── __init__.py
└── wsgi.py
Where wsgi.py
is my main file which run the app.
I saw peoples using importlib but I didn't find how to make it work as it is used with:
__version__ = importlib.metadata.version("__package__")
But I have no clue what this package mean.
Upvotes: 13
Views: 13715
Reputation: 22438
You should not use __package__
, which is the name of the "import package" (or maybe import module, depending on where this line of code is located), because this is not what is expected here.
importlib.metadata.version()
expects the name of the "distribution package" (the thing that you pip-install), which is the one you write in the [project]
table of pyproject.toml
as name = "my-distribution-package-name"
.
So if the application or library whose version string you want to get is named my-foo-lib
, then you only need to call the following
import importlib.metadata
version_string_of_foo = importlib.metadata.version('my-foo-lib')
Upvotes: 26
Reputation: 39930
If you are using Poetry to manage dependencies, you will have to specify package-mode = true
under [tool.poetry]
section in order for importlib.metadata
to be able to report the correct package version, as listed in the pyproject.toml
file.
Here's how your pyproject.toml
file should look like:
[tool.poetry]
name = "mypackage"
version = "0.44.0"
description = "My package"
package-mode = true
You can then use importlib.metadata
to infer the version programmatically:
import importlib.metadata
version_string_of_foo = importlib.metadata.version('mypackage')
print(version_string_of_foo)
# '0.44.0'
Upvotes: 1
Reputation: 5485
In the project.toml
you can specify version in different ways:
[tool.poetry]
:[tool.poetry]
name = "my-package"
version = "0.1.0"
[project]
section:[project]
name = "my-package"
version = "2020.0.0"
The next point is that you may want to see the version of installed packages (e.g. via pip
or poetry
) or your application. The next:
import importlib.metadata
version = importlib.metadata.version("my-package")
print(version)
This code works fine with installed packages. To make working it with your project, you should install it using pip install -e .
or something similar.
If you want to check version of your project without installing, then you can use the following snippet:
from pathlib import Path
import toml
version = "unknown"
# adopt path to your pyproject.toml
pyproject_toml_file = Path(__file__).parent / "pyproject.toml"
if pyproject_toml_file.exists() and pyproject_toml_file.is_file():
data = toml.load(pyproject_toml_file)
# check project.version
if "project" in data and "version" in data["project"]:
version = data["project"]["version"]
# check tool.poetry.version
elif "tool" in data and "poetry" in data["tool"] and "version" in data["tool"]["poetry"]:
version = data["tool"]["poetry"]["version"]
print(version)
To make it working you should install toml
package in advance.
Upvotes: 10
Reputation: 760
I am doing this:
from poetry.core.factory import Factory
def display_version():
__thisScript__ = os.path.realpath(__file__)
__thisFolder__ = os.path.dirname(__thisScript__)
factory = Factory()
this_project = factory.create_poetry(__thisFolder__)
print(f"{this_project.package.name} version {this_project.package.version}")
print(f"{this_project.package.description}")
sys.exit(0)
# end def
I also added the included statemetn the pyproject.toml file into my pyproject.toml file as mentioned by Haoqi Chen
[tool.poetry]
name = "myApp"
version = "0.1.5"
description = "A faster alternative to Windows `rmdir /s /q` for large directories."
authors = ["Joe B"]
readme = "README.md"
include = [{path = "./pyproject.toml"}]
I used a relative path to pyproject.toml as I always use poetry build from the same folder as pyproject.toml.
Upvotes: -2
Reputation: 1
I had the same question.
One of the solution I could come up is to ship the pyproject.toml file together with the project, as a data file. This can be done by putting pyproject.toml inside your_package/data
, and put include = [{path = "phuego/data/pyproject.toml"}]
under [tool.poetry]
in pyproject.toml. Then, you can use toml
package to access it.
But I'm not convinced by this solution. Perhaps there is a better idea out there.
Upvotes: -2