Skip to content

Python Packaging Standards ​

The RepoForge.io Python index complies with the following Python Packaging Authority (PyPA) standards.

Repository API ​

StandardSpecification
PEP 503Simple Repository API
PEP 592Adding "Yank" Support to the Simple API
PEP 629Versioning PyPI's Simple API
PEP 658Serve Distribution Metadata in the Simple Repository API
PEP 691JSON-based Simple API for Python Package Indexes
PEP 700Additional Fields for the Simple API for Package Indexes
PEP 714Rename dist-info-metadata in the Simple API
PEP 792Project Status Markers in the Simple Index

The index serves Simple API version 1.4. The full specification is maintained at Simple repository API.

Distributions ​

StandardSpecification
PEP 427The Wheel Binary Package Format
PEP 440Version Identification and Dependency Specification
PEP 625Filename of a Source Distribution
PEP 643Metadata for Package Source Distributions

Upload Checks ​

When you upload with uv publish, twine or poetry publish, RepoForge.io also:

  • checks the sha256_digest your client sends against the file it receives, and rejects the upload with a 400 error if they differ
  • returns 409 Conflict if the same file has already been uploaded

Yank a Release ​

Yank a release when it is broken but other projects may depend on it. Yanking applies to every file of the version. After yanking, pip install my-package and uv add my-package pick the newest release that isn't yanked, while pip install my-package==1.0.0 still installs the yanked release.

From the Dashboard ​

  1. Open Python in the dashboard and select the package.
  2. In the row of the version you want to yank, click the Yank version button, between Download and Delete.
  3. Optionally, enter a reason. pip and uv show it to anyone who installs the version.
  4. Click Yank version.

The yank dialog, listing the files of the version and an optional reason

Yanked versions are struck through and marked Yanked, with the reason underneath. The Versions tile shows how many versions are yanked.

A package page with a yanked version

To undo it, click the Un-yank version button in the version's row, then click Un-yank version.

With the REST API ​

  1. Create an access token with the API access role and a role that can upload to the package (for example, Python - Full access). The REST API is available on paid plans.

  2. Yank the version, optionally with a reason:

    bash
    curl -X POST https://api.repoforge.io/rest/v1/python/my-package/versions/1.0.0/yank \
      -H "Authorization: Bearer $REPOFORGE_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"reason": "Broken on Windows, use 1.0.1"}'
  3. To undo it, un-yank the version:

    bash
    curl -X POST https://api.repoforge.io/rest/v1/python/my-package/versions/1.0.0/unyank \
      -H "Authorization: Bearer $REPOFORGE_TOKEN"

Set a Project's Status ​

A project can have one of these statuses:

  • active: the default.
  • deprecated: the project still accepts uploads, but users should move away from it.
  • archived: the project no longer accepts uploads. Existing releases can still be installed.
  • quarantined: the project serves no files and accepts no uploads, for example while you deal with a compromised release. Set the status back to active to lift it.

From the Dashboard ​

  1. Open Python in the dashboard and select the package.
  2. In the Status tile, click the current status.
  3. Choose Active, Deprecated or Archived. For Deprecated or Archived, you can enter a reason that installers show alongside the status.
  4. Click Save status.

The status dialog with Archived selected

Archived and deprecated packages show a notice at the top of the package page, and a label next to their name in the package list.

An archived package's page

To quarantine a project, use the REST API.

With the REST API ​

Use an access token with the same roles as for yanking:

bash
curl -X PUT https://api.repoforge.io/rest/v1/python/my-package/status \
  -H "Authorization: Bearer $REPOFORGE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"status": "archived", "reason": "Replaced by my-new-package"}'

Set "status": "active" to clear it.

Upstream Mirroring and Deleted Packages ​

If upstream mirroring is on, a name that isn't in your account is fetched from your mirror. Names that exist in your account, or existed and were deleted, are never fetched from the mirror: RepoForge.io returns 404 Not Found instead. A deleted private package therefore can't silently resolve to a package of the same name on PyPI, which is a common route for dependency confusion attacks.

Built with care by the RepoForge.io team.