PyPI now serves project status markers in its standardindex APIs. This allows downstream consumers (like Python package installers andindex mirrors) to retrieve project statuses programmatically and use them toinform users when a project is archived or quarantined.
See the project archival and project quarantine announcement postsfor additional information on PyPI’s implementation of those individual statuses.
Many Python regularly find themselves asking the samequestions again and again when evaluating a new dependency:
These questions (and many others in the domain of supply chain security)essentially boil down to a single question:what is the status of this project?
Before PEP 792, Python packaging had no less than three overlappingsolutions for determining a project’s status:
Individual releases of a project could include a Development Status trove classifier in their metadata, such as Development Status :: 7 - Inactive to indicate that the project is no longer actively maintained.
However, trove classifiers occur at the distribution level, leadingto two problems:
sampleproject==1.2.3 may fail to realize that sampleproject===1.2.4 signals that the entire project is now inactive.Indices can mark individual files (or entire releases) as “yanked,” per the file yanking specification. Yanked files are effectively soft-deleted, meaning that they’ll be skipped by complying installers during resolution but not if explicitly pinned by the user.
Yanking is a useful tool for mitigating accidental vulnerabilitiesor compatibility breakages in a release, but it has the same “scope”issue as classifiers: it applies at the file and release level,not at the project level.
Moreover, the semantics of yanking aren’t appropriate for all potentialstatuses: soft deletion is still disruptive, whereas statuses like”archived” and “deprecated” suggest that the project is stillsuitable for installation, so long as the user can be made aware ofits status.
PyPI itself has “project statuses,” which apply to the entire project. These statuses were not standardized, and therefore only appeared on user-facing HTML pages, not in the standard APIs. This made them difficult to retrieve programmatically, limiting their usefulness.
Beyond these partial solutions many downstreams also apply heuristicsto determine a project’s status, such as checking for recent project(or source repository) activity or using popularity metrics likeGitHub stars as a proxy for project health. However, these heuristicscan be manipulated or outright incorrect, such as when a project is featurecomplete and therefore has no recent activity.
Overall, these partial solutions and heuristics point to a need forsomething better.
That brings us to the new feature: project status markers.
Project status markers are a Python packaging standard derived from PyPI’sexisting project statuses. The standard defines four project statuses,which have both index-side and installer-side semantics:
Of these statuses, PyPI currently supports active, archived, andquarantined. PyPI doesn’t support deprecated yet, but we’ll be lookingat supporting it now that the MVP is complete.
Beyond the statuses themselves, the standard also defines an optional”status reason” that can be used to provide additional context about the status.PyPI doesn’t currently expose status reasons, but may do so in the future.
The standard is one thing, but let’s see how to actually get statusmarkers from PyPI’s index APIs.
Status markers are available in both the HTML and JSON index APIs.For the HTML API the <meta> fields are:
pypi:project-status for the project status itself (or active by default)pypi:project-status-reason for the project status reason (if present)For example:
curl --silent  -H "Accept: application/vnd.pypi.simple.v1+html"  https://pypi.org/simple/pepy/  | htmlq --pretty 'head meta[name="pypi:project-status"]'Yields:
<meta name="pypi:project-status" content="archived">Within the JSON API, the project status is available via thetop-level project-status object, which contains status and reasonfields corresponding to the HTML API fields above.
For example:
curl --silent  -H "Accept: application/vnd.pypi.simple.v1+json"  https://pypi.org/simple/pepy/  | jq '."project-status"'Yields:
{ "status": "archived",}Starting today, Python package installers and other index consumers canretrieve status markers from PyPI’s standard index APIs.
Our hope is that downstreams will consume these markers, and use themas suggested by the standard. In particular we hope that installers likepip and uv will signal relevant statuses to users, helping themform a better picture of the status of their dependencies as well as setpolicies controlling which statuses are acceptable for installation.
PEP 792 was authored by William Woodruff (Astral) andFacundo Tuesca (Trail of Bits). We’d like to thank Donald Stufft for beingthe PEP’s sponsor and PEP delegate. Additionally, we’d like to thankDustin Ingram and Mike Fiedler for their review and feedback on the PEPand the associated changes to PyPI.
The funding for this feature’s development comes in part fromAlpha-Omega. Alpha-Omega’s mission is to protect society by catalyzingsustainable security improvements to the most critical open-source softwareprojects and ecosystems.
This warning is technically moot, as PyPI itself will not offer any files from quarantined projects for installation. However, the warning can still help users understand why their installation has failed, and is therefore recommended by the standard. ↩
Digital signatures add another layer of security to your online transactions and communications. But how…
Unfortunately the string of phishing attacks using domain-confusionand legitimate-looking emails continues. This is the same…
SummaryI recently responded to an attack campaign where malicious actors injected code into GitHub Actions…
Internet security is leveling up with MPIC. While your organization likely won’t need to do…
Sept. 10: Get actionable insights from 20+ global experts as they discuss PQC readiness assessments,…
SummaryPyPI now checks for expired domains to prevent domain resurrection attacks,a type of supply-chain attack…
This website uses cookies.