How can I get the author name, project description etc from a Distribution object in pkg_resources?
Asked Answered
T

2

8

pkg_resources api let's you get Distribution objects that represent egg distributions inside a directory. I can trivially get the project name and version of the distribution with dist.project_name and dist.version, however I'm lost on how I can get the other metadata that's usually specified in the setup script (like author, description, etc.)

Testy answered 12/5, 2012 at 20:29 Comment(0)
S
5

I was looking how to do the same thing. This is what I came up with. It is probably not the best solution, but seems to work.

# get the raw PKG-INFO data
from pkg_resources import get_distribution
pkgInfo = get_distribution('myapp').get_metadata('PKG-INFO')

# parse it using email.Parser
from email import message_from_string
msg = message_from_string(pkgInfo)
print(msg.items())

# optional: convert it to a MultiDict
from webob.multidict import MultiDict
metadata = MultiDict(msg)
print(metadata.get('Author'))
print(metadata.getall('Classifier'))
Startle answered 2/2, 2014 at 23:17 Comment(1)
Note: In Python these days, the metadata file will more likely be named METADATA rather than PKG-INFOBandy
L
-1

Same problem here. I solved it by creating a file package.py under mymodule with all the variables that would otherwise be hardcoded into setup.py. Then in setup.py:

pkg_info = get_package_info('mymodule')
setup(**pkg_info)

However in setup.py, I cannot directly import mymodule.package as pkg_info because that would cause setup.py to require the module it is defining. Therefore a custom import method get_package_info(module_name) is needed in setup.py:

def get_package_info(module_name):
    '''
    Read info about package version, author etc
    from <module_name>/package.py

    Return:
        dict {'version': '1.2.3', 'author': 'John Doe', ...}
    '''
    here = os.path.dirname(os.path.abspath(__file__))
    code_globals = {}
    code_locals = {}
    with open(os.path.join(here, module_name, 'package.py')) as f:
        code = compile(f.read(), "package.py", 'exec')
        exec(code, code_globals, code_locals)
    return code_locals

The mymodule/package.py:

# -*- coding: utf-8 -*-
name = 'mymodule'
version = '1.2.3'
description = 'My module for demonstration'
url = 'https://github.com/myorg/mymodule'
author = 'John Doe'
author_email = '[email protected]'

...

packages = ['mymodule']
install_requires = ['myotherpackage', 'somepackage']

...

With this method I can easily access the package info anywhere where I can access the module, e.g: from mymodule.package import version, author. Also, the info needs to be stored only in one place.

Limon answered 9/3, 2016 at 14:9 Comment(1)
For long_description I read README.rst file. To avoid reading the file each time mymodule is imported, in setup.py I have: pkg_info['long_description'] = read_long_description before setup(**pkg_info).Dispraise

© 2022 - 2024 — McMap. All rights reserved.