Standards
peryx implements the Python index standards listed below. The
Simple Repository API consolidates most
of them. peryx serves meta.api-version 1.4 when the resolved page contains the required fields and 1.0 otherwise.
Installer request sequence
pip install requests sends this sequence to a standards-compliant index:
Every hop names a standard: the page format is PEP 503/691, its fields are PEP 700, the yank markers are PEP 592, the metadata shortcut is PEP 658/714, and the filename pip parsed to pick a wheel is PEP 427. peryx sits on both sides of this conversation, a server to your clients and a client to its upstreams, which is why the table below mixes "served" and "parsed".
| Standard | Role in peryx |
|---|---|
| PEP 503 | HTML Simple API and project-name normalization |
| PEP 691 | JSON Simple API and content negotiation |
| PEP 629 | Simple API version marker |
| PEP 700 | versions, size, and upload-time fields |
| PEP 592 | Yanked-file metadata |
| PEP 658 and PEP 714 | .metadata siblings for package metadata |
| PEP 740 | Index-hosted attestations |
| PEP 792 | Project status markers |
| PEP 440 | Version ordering and Requires-Python validation |
| PEP 427 and PEP 625 | Wheel and source-distribution validation |
| PEP 527 | Zip source distributions |
| Core metadata | METADATA, PKG-INFO, and import declarations |
| PEP 508 | Dependency specifiers |
| PEP 639 | SPDX license expressions and files |
| PEP 685 | Normalized extra names |
| PEP 643 | Dynamic metadata fields |
| PEP 753 | Canonical project URL labels |
| Legacy JSON API | Project and release compatibility responses |
| Legacy upload API | Multipart uploads used by twine and uv publish |
.pypirc | Upload and mirror authentication conventions |
Metadata validation on upload
peryx parses the core metadata of a hosted upload and rejects the whole upload when a field is malformed, so a broken
METADATA never reaches a resolver. It checks each field with the library that owns the grammar, as it does the wire
formats.
Requires-Dist,Provides-Dist, andObsoletes-Distmust parse as PEP 508 dependency specifiers.License-Expressionmust be a PEP 639 SPDX expression of known, non-deprecated identifiers, and may not accompany the legacyLicensefield.Provides-Extranames collide when they normalize equal under PEP 685.Dynamicmay name only a field PEP 643 lets vary, neverName,Version, orMetadata-Version.Classifiervalues must be known, non-deprecated trove classifiers, andAuthor-email/Maintainer-emailmust be RFC 822 address lists.- Every field must appear at or after the
Metadata-Versionthat introduced it; a 2.5-onlyImport-Nameon a 2.1 document is rejected.
The upload reference lists the accept and reject tables with the exact error strings.
PEP 714 and the core-metadata key
PEP 658 shipped with a bug in its dist-info-metadata key name, and PEP 714 renamed it to core-metadata. Indexes such
as pypi.org emit both keys for compatibility. peryx parses both spellings, prefers core-metadata when both are
present, and emits both spellings downstream for older clients.
Upstream compatibility
Some upstreams implement only part of the stack; Artifactory and GitLab may serve HTML
alone. peryx negotiates JSON first and parses PEP 503 HTML as the fallback. Missing fields lower the served API version
or remain absent. An upstream that advertises another Simple API major version receives a 502; peryx supports Simple
API 1.x.
The discovery documents at /+api and /{route}/+api report only capabilities peryx implements today. They advertise
Simple HTML/JSON, api-version 1.4, PEP 658 metadata siblings, project status, provenance, and legacy JSON. The legacy
JSON responses are derived from Simple detail pages, so fields outside that source, such as ownership and vulnerability
data, are empty.
Operational checks
- The machinery that serves these: architecture
- The endpoints they map to: HTTP endpoints
- How PEP 427/503/440 combine to match a wheel's
.dist-infoon upload: wheel .dist-info matching