Skip to content

Instantly share code, notes, and snippets.

@izikeros
Last active March 15, 2024 19:53
Show Gist options
  • Select an option

  • Save izikeros/7b7496b0a71fda35156b5231859b9a72 to your computer and use it in GitHub Desktop.

Select an option

Save izikeros/7b7496b0a71fda35156b5231859b9a72 to your computer and use it in GitHub Desktop.
[License reports] License reporting with liccheck #python #project #qa

License reporting with liccheck

This script rely on liccheck python package and contains some parts of code extracted and modified to fullfil my needs.

Requirements

  • liccheck installed: pip install liccheck
  • added configuration file or content in pyproject.tom, e.g.
[tool.liccheck]
authorized_licenses = [
  "bsd",
  "new bsd",
  "bsd license"
]
unauthorized_licenses = [
  "gpl v3"
]

[tool.liccheck.authorized_packages]
uuid = "<=1.30"

running the license_check.py script produces CSV output which can be later read into Excel

(...)
pyasn1-modules;0.2.8;BSD
pycparser;2.21;BSD
pydantic;1.9.0;MIT
(...)
pyparsing;3.0.8;MIT
import functools
from dataclasses import dataclass
from liccheck.command_line import check_package
from liccheck.command_line import generate_requirements_file_from_pyproject
from liccheck.command_line import get_packages_info
from liccheck.command_line import group_by
from liccheck.command_line import merge_args
from liccheck.command_line import read_strategy
from liccheck.command_line import Level
@dataclass
class Args:
strategy_ini_file: str
requirement_txt_file: str
level: Level
reporting_txt_file: str
no_deps: bool
def my_process(
requirement_file, strategy, level=Level.STANDARD, reporting_file=None, no_deps=False
):
print("gathering licenses...")
pkg_info = get_packages_info(requirement_file, no_deps)
deps_mention = "" if no_deps else " and dependencies"
print(f'{len(pkg_info)} package{"" if len(pkg_info) <= 1 else "s"}{deps_mention}.')
groups = group_by(pkg_info, functools.partial(check_package, strategy, level=level))
if reporting_file:
packages = []
for r, ps in groups.items():
packages.extend(
{
"name": p["name"],
"version": p["version"],
"license": (p["licenses"] or ["UNKNOWN"])[0],
"status": r,
}
for p in ps
)
return packages
def my_run(args):
args = merge_args(
{
"strategy_ini_file": args.strategy_ini_file,
"requirement_txt_file": args.requirement_txt_file,
"level": args.level,
"reporting_txt_file": args.reporting_txt_file,
"no_deps": args.no_deps,
"dependencies": False,
"optional_dependencies": [],
}
)
strategy = read_strategy(args["strategy_ini_file"])
if args["dependencies"] is True or len(args["optional_dependencies"]) > 0:
args["requirement_txt_file"] = generate_requirements_file_from_pyproject(
args["dependencies"], args["optional_dependencies"]
)
return my_process(
args["requirement_txt_file"],
strategy,
args["level"],
args["reporting_txt_file"],
args["no_deps"],
)
def get_package_license_file_url(pypi_package_name):
import requests
import json
url = f"https://pypi.org/pypi/{pypi_package_name}/json"
r = requests.get(url)
data = json.loads(r.text)
return data["info"]["license_file"]
if __name__ == "__main__":
args = Args(
strategy_ini_file="pyproject.toml",
requirement_txt_file="requirements.txt",
level=Level.STANDARD,
reporting_txt_file="reporting.txt",
no_deps=False,
)
packages = my_run(args)
res = "".join(
f'{p["name"]};{p["version"]};{p["license"]}\n'
for p in sorted(packages, key=lambda i: i["name"])
)
print(res)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment