Skip to main content

A simple CLI to help determine whether a package has copyleft dependencies

Project description

PyPI version Supported Python versions Build status

amigpl is a small CLI that reads the license metadata of every distribution in your active Python environment and tells you whether any of them are licensed under the GPL or another copyleft license you’ve asked it to flag.

It is purely a discovery tool. It takes no position on whether copyleft licenses are good or bad — it just helps package authors who, for whatever reason, need to know whether their dependency tree contains them.

Installation

$ uv tool install amigpl     # or: pipx install amigpl

Quickstart

Run amigpl inside (or against) an environment with your project installed:

$ amigpl
No disallowed copyleft licenses found.

The bare invocation is shorthand for amigpl check. It scans every installed distribution and exits:

  • 0 if nothing in the disallow set was found,

  • 1 if any disallowed license was found,

  • 2 if any package had no parseable license metadata (suppress with --ignore-unknown).

To see what’s installed and the license each package claims, use list:

$ amigpl list
attrs              25.4.0  ok          MIT
click              8.2.1   ok          BSD-3-Clause
requests           2.32.5  ok          Apache-2.0
some-copyleft-pkg  1.0     disallowed  GPL-3.0-only

Scanning a lockfile

Pre-install audits work against uv.lock or PEP 751’s pylock.toml:

$ amigpl lockfile check uv.lock
$ amigpl lockfile list pylock.toml

Lockfiles don’t themselves carry license metadata, so amigpl fetches each package’s record from PyPI on demand. Responses are cached on disk ($XDG_CACHE_HOME/amigpl or ~/.cache/amigpl) so subsequent runs are fast; pass --no-pypi-cache to opt out.

The lockfile check and lockfile list commands accept every option the env-scanning check and list do, including --disallow-license, --allow-license, --ignore, and --format.

What counts as “disallowed”

By default amigpl flags packages licensed under the GPL, AGPL, or EUPL families — the strong copyleft licenses which typically require a project depending on them to adopt the same license.

Other copyleft-flavored licenses are not flagged by default:

  • LGPL packages can usually be depended on from a non-LGPL project, since Python import is treated as dynamic linking.

  • MPL, EPL, and CDDL are file-level copyleft; only modifications to those files inherit the license.

If you want to flag any of them, opt in:

$ amigpl --disallow-license LGPL          # add a whole family
$ amigpl --disallow-license LGPL-3.0-only # or a specific SPDX id

The argument accepts either a family alias (GPL, LGPL, AGPL, EUPL, MPL, EPL, CDDL) or any SPDX identifier. --allow-license does the inverse — removing a license from the disallow list — and is applied after --disallow-license, so you can subtract individual variants from a family you’ve opted into.

Configuration

A project’s policy lives in its pyproject.toml:

[tool.amigpl]
disallow-license = ["LGPL"]
allow-license = ["LGPL-2.1-or-later"]
ignore = ["some-package"]
ignore-unknown = true

ignore skips specific packages by name — useful when a transitive dependency has an unusual or unparseable license you’ve already vetted by hand and don’t want failing CI. Names are matched canonically, so hyphens, underscores, and case don’t matter.

CLI flags combine additively with config: --disallow-license, --allow-license, and --ignore each add to whatever the config already specified. --ignore-unknown (a boolean) overrides the config value when given.

CI integration

--format json and --format markdown exist for scripting and CI use. The markdown table is convenient for GITHUB_STEP_SUMMARY:

- name: License audit
  run: amigpl --format markdown >> "$GITHUB_STEP_SUMMARY"

The exit code is meaningful to CI regardless of format: 0 means clean, 1 means a disallowed license was found, 2 means a package’s license could not be determined.

How licenses are detected

amigpl reads PEP 639 License-Expression metadata when available — this is the modern, unambiguous form — and falls back to legacy Trove Classifier entries and the free-text License field for older packages.

The text reported for each package is exactly what the package itself claims. A package whose only license metadata is the Trove classifier License :: OSI Approved :: BSD License is reported as BSD-licensed, verbatim; amigpl never invents precision the package didn’t supply (it won’t decide for you that it’s BSD-2-Clause rather than BSD-3-Clause).

That ambiguity only matters when your disallow set is more specific than the package’s claim. With the default disallow set — GPL, AGPL, EUPL — no BSD variant is disallowed regardless of which one was meant, so the package is reported ok. If you --disallow-license BSD-3-Clause specifically, a package that only claims “BSD License” via the Trove classifier becomes unknown: it might or might not be the variant you disallowed, and amigpl won’t guess.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

amigpl-2026.5.2.tar.gz (34.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

amigpl-2026.5.2-py3-none-any.whl (32.0 kB view details)

Uploaded Python 3

File details

Details for the file amigpl-2026.5.2.tar.gz.

File metadata

  • Download URL: amigpl-2026.5.2.tar.gz
  • Upload date:
  • Size: 34.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for amigpl-2026.5.2.tar.gz
Algorithm Hash digest
SHA256 22ec2d88836e0f9d4d2df111e6083129d500c30b9e51004e7bb38094a38749fa
MD5 aa75b36441d04a07972f6df7c745b0cc
BLAKE2b-256 11050c389ad6c7eb2de2d8d6e2b2e62e5e7a424a4d8c525574fa6e01dd03d926

See more details on using hashes here.

Provenance

The following attestation bundles were made for amigpl-2026.5.2.tar.gz:

Publisher: ci.yml on Julian/AmIGPL

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file amigpl-2026.5.2-py3-none-any.whl.

File metadata

  • Download URL: amigpl-2026.5.2-py3-none-any.whl
  • Upload date:
  • Size: 32.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for amigpl-2026.5.2-py3-none-any.whl
Algorithm Hash digest
SHA256 e6100ffb7de19484065d9f1b16b20f76b8bf4581416b25ee8aa244a0d4ee6e7a
MD5 30a3643a4acce7378590389acfa43314
BLAKE2b-256 7e17716240f4d4de52547fdb07b1c6e5f9ba8860f4ed3d327812fbffdb6c3c81

See more details on using hashes here.

Provenance

The following attestation bundles were made for amigpl-2026.5.2-py3-none-any.whl:

Publisher: ci.yml on Julian/AmIGPL

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page