Why pypi redirects to "content" for one repository?

I have two “python” repositories:

❯ pulp python repository list                  
[
  {
    "pulp_href": "/pulp/api/v3/repositories/python/python/01978da5-3cc8-7519-bdc2-aa3ca3616e24/",
    "prn": "prn:python.pythonrepository:01978da5-3cc8-7519-bdc2-aa3ca3616e24",
    "pulp_created": "2025-06-20T14:01:45.932321Z",
    "pulp_last_updated": "2025-06-20T15:39:44.163043Z",
    "versions_href": "/pulp/api/v3/repositories/python/python/01978da5-3cc8-7519-bdc2-aa3ca3616e24/versions/",
    "pulp_labels": {},
    "latest_version_href": "/pulp/api/v3/repositories/python/python/01978da5-3cc8-7519-bdc2-aa3ca3616e24/versions/2/",
    "name": "ai",
    "description": "AI related packages",
    "retain_repo_versions": null,
    "remote": null,
    "autopublish": true
  },
  {
    "pulp_href": "/pulp/api/v3/repositories/python/python/019735b7-8a2b-7fc5-8bba-a9618ba9fad7/",
    "prn": "prn:python.pythonrepository:019735b7-8a2b-7fc5-8bba-a9618ba9fad7",
    "pulp_created": "2025-06-03T12:15:10.380337Z",
    "pulp_last_updated": "2025-06-20T11:25:46.395791Z",
    "versions_href": "/pulp/api/v3/repositories/python/python/019735b7-8a2b-7fc5-8bba-a9618ba9fad7/versions/",
    "pulp_labels": {},
    "latest_version_href": "/pulp/api/v3/repositories/python/python/019735b7-8a2b-7fc5-8bba-a9618ba9fad7/versions/7/",
    "name": "repo2",
    "description": null,
    "retain_repo_versions": null,
    "remote": null,
    "autopublish": false
  }
]

If I visit the “repo2”, it doesn’t redirect to “content”

❯ curl -I https://repo.example.org/pypi/repo2/simple/
HTTP/2 200 
server: nginx/1.28.0
date: Mon, 23 Jun 2025 07:53:01 GMT
content-type: text/html; charset=utf-8
vary: Accept, Cookie
allow: GET, POST, HEAD, OPTIONS
x-frame-options: DENY
x-content-type-options: nosniff
referrer-policy: same-origin
cross-origin-opener-policy: same-origin
correlation-id: b3da3440b9e94ace905519126225b511
access-control-expose-headers: Correlation-ID

but in case of “ai” repo redirect happens

❯ curl -I https://repo.example.org/pypi/ai/simple/       
HTTP/2 302 
server: nginx/1.28.0
date: Mon, 23 Jun 2025 07:53:08 GMT
content-type: text/html; charset=utf-8
content-length: 0
location: https://repo.example.org/pulp/content/ai/simple/
vary: Accept, Cookie
allow: GET, POST, HEAD, OPTIONS
x-frame-options: DENY
x-content-type-options: nosniff
referrer-policy: same-origin
cross-origin-opener-policy: same-origin
correlation-id: 628b7e1570e24d74990245c8b3e24adc
access-control-expose-headers: Correlation-ID

why it’s like this? is it documented somewhere?

The second repository is using publications as indicated by the autopublish=True. The difference between distributing a repository using publications versus one that doesn’t is partly performance based and mostly historical. Originally pulp_python was solely a publication plugin meaning everytime you created a new repository version a new publication needed to be created to serve the metadata. When we released pulp_python 3.4 a couple years ago to add twine upload support I added a new location (/pypi/{base_path}/) to serve the PyPI APIs and changed the default behavior to create the metadata at request time, removing the need for publications. To keep backwards compatibility I kept publications around and had the new API redirect to the old location (the content app) if publications were present. Since publications create the metadata ahead of time they are the more performant option, but the on-demand generation overhead usually isn’t that big so you typically don’t need publications unless your repository is really large or you want extra performance.

On that note I should document this behavior, if you want you can file a docs issue here: https://github.com/pulp/pulp_python/issues

1 Like

I see, thanks for the explanation. I tried to set "autopublish": false as “repo2” has, but it still redirects. Furthermore, I also pulled the latest all-in-one docker image, still redirects. Should the repo be recreated to disable redirect?

To disable the redirects either recreate the repo or delete all of the repo’s publications. The current logic checks to see if there is any publications available and redirects if there is.

2 Likes