Skip to content

Instantly share code, notes, and snippets.

@fladd
Last active November 10, 2020 22:43
Show Gist options
  • Save fladd/caeb1106b5a803c215a85dbdf74fdba0 to your computer and use it in GitHub Desktop.
Save fladd/caeb1106b5a803c215a85dbdf74fdba0 to your computer and use it in GitHub Desktop.
Get licencing information of packages and their dependencies from pip
from email import message_from_string
from pkg_resources import get_distribution
def get_pkg_info(package, extras=False):
"""Get information about an installed package.
This function will also attempt to get the licence text from a bundled
licence file, if available.
Parameters
----------
package : str
the package to get information about
extras : bool, optional
whether to consider 'extras' required packages (default=False)
Returns
-------
metadata : dict
package metadata
required : list
required packages
"""
d = get_distribution(package)
m = message_from_string(d.get_metadata(d.PKG_INFO))
if "Requires-Dist" in m.keys():
deps = m.get_all("Requires-Dist")
if extras:
required = [x.split()[0] for x in deps]
else:
required = [x.split()[0] for x in deps if not "extra == " in x]
else:
required = []
metadata = {}
for key in m.keys():
if m.keys().count(key) == 1:
metadata[key] = m.get(key)
else:
metadata[key] = m.get_all(key)
metadata["License-text"] = ""
for l in ["LICENSE*", "LICENCE*", "COPYING*", "NOTICE*"]:
for licence_file in glob.glob(os.path.join(d.egg_info, l)):
with open(licence_file) as f:
metadata["License-text"] += f.read()
return metadata, required
def get_licensing_info(packages, extras=False):
"""Get licensing information of a list of package and their dependencies.
Parameters
----------
packages : list
the packages to get licensing information from
extras : bool, optional
whether to consider 'extras' required packages (default=False)
Returns
-------
licensing_info : list
the licensing information for each package
"""
licensing_info = []
for package in packages:
try:
metadata, required = get_pkg_info(package, extras)
packages.extend([x for x in required if x not in packages])
except:
continue
for package in packages:
try:
metadata, required = get_pkg_info(package, extras)
if not metadata in licensing_info:
licensing_info.append(metadata)
except:
continue
return sorted(licensing_info, key=lambda x: x["Name"])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment