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.
Release files for amigpl 2026.5.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| amigpl-2026.5.2.tar.gz | 34.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| amigpl-2026.5.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 66.0 kB
Release files / amigpl-2026.5.2.tar.gz
| Download URL | amigpl-2026.5.2.tar.gz |
|---|---|
| Size | 34.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
22ec2d88836e0f9d4d2df111e6083129d500c30b9e51004e7bb38094a38749fa
|
|
BLAKE2b-256 checksum How to use checksums |
11050c389ad6c7eb2de2d8d6e2b2e62e5e7a424a4d8c525574fa6e01dd03d926
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 17, 2026.
Transparency logRelease files / amigpl-2026.5.2-py3-none-any.whl
| Download URL | amigpl-2026.5.2-py3-none-any.whl |
|---|---|
| Size | 32.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e6100ffb7de19484065d9f1b16b20f76b8bf4581416b25ee8aa244a0d4ee6e7a
|
|
BLAKE2b-256 checksum How to use checksums |
7e17716240f4d4de52547fdb07b1c6e5f9ba8860f4ed3d327812fbffdb6c3c81
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 17, 2026.
Transparency log