3

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.

sinoroc
  • 18,409
  • 2
  • 39
  • 70
pgossa
  • 171
  • 9
  • 1
    Does this answer your question? [What's the purpose of the "\_\_package\_\_" attribute in Python?](https://stackoverflow.com/questions/21233229/whats-the-purpose-of-the-package-attribute-in-python) – CryptoFool Jan 12 '23 at 17:28
  • Beyond your question about the meaning of `__package__` there are suspicious things in your question. -- You should not have a `__init__.py` right next to `pyproject.toml`, typically you would want to put all Python code in a sub-directory named after what you want your top-level import package to be. – sinoroc Jan 12 '23 at 18:37
  • @sinoroc Should I put my main file a the top or should I create a subfolder like "src" or something and put my main file inside? – pgossa Jan 13 '23 at 07:50
  • 1
    @pgossa I recommend the so-called `src`-layout, but you do not have to. It's best if you let `poetry` create the project template with [`poetry new --src name-of-your-new-project`](https://python-poetry.org/docs/cli/#new). – sinoroc Jan 13 '23 at 09:27

4 Answers4

9

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), and this is not what importlib.metadata.version() expects. This function expects the name of the distribution package (the thing that you pip-install), which is the one you write in pyproject.toml as name = "???".

So if the application or library whose version string you want to get is named Foo, then you only need to call the following

import importlib.metadata

version_string_of_foo = importlib.metadata.version('Foo')
sinoroc
  • 18,409
  • 2
  • 39
  • 70
-1

You can extract version from pyproject.toml using toml package to read toml file and then display it in a webpage.

Jurakin
  • 832
  • 1
  • 5
  • 19
-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.

General Grievance
  • 4,555
  • 31
  • 31
  • 45
  • This does not really answer the question. If you have a different question, you can ask it by clicking [Ask Question](https://stackoverflow.com/questions/ask). To get notified when this question gets new answers, you can [follow this question](https://meta.stackexchange.com/q/345661). Once you have enough [reputation](https://stackoverflow.com/help/whats-reputation), you can also [add a bounty](https://stackoverflow.com/help/privileges/set-bounties) to draw more attention to this question. - [From Review](/review/late-answers/34618319) – doneforaiur Jul 04 '23 at 16:27
  • Bad idea. Just use `importlib.metadata.version('TheNameOfTheAppOrLibrary')`. – sinoroc Aug 10 '23 at 20:24
-1

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.

Joe B
  • 692
  • 8
  • 18
  • Why so complex when there are solutions available in Python's standard library already that are way more robust? Just use `importlib.metadata.version('myApp')`. – sinoroc Aug 10 '23 at 20:24