Skip to content

Conversation

@cooperlees
Copy link
Contributor

@cooperlees cooperlees commented Nov 10, 2025

  • PEP691 introduced an alternative to the PyPI "xmlrpc" API to work out what packages to sync on a bandersnatch run
  • The xmlrpc calls are
    • list_packages_with_serial
    • changelog_since_serial
  • When api_method is set to simple in a banderstanch config we now
    • Pull down all the packages in a simple JSON fetch via aiohttp
    • Either return all packages or filter out ones that are newer than our last synced serial locally for each bandersnatch
      rather on PyPI server side ...

Test:

  • pre-commit run -a
  • Fix unitests and run
    • python3.13 -m venv --upgrade-deps .venv
    • .venv/bin/pip install tox
    • .venv/bin/tox -e py313
  • Set config and run the integration tests and see still pass
cooper@cooper-fedora-MJ0J8QHP:~/repos/bandersnatch$ export TOXENV=INTEGRATION
(.venv) cooper@cooper-fedora-MJ0J8QHP:~/repos/bandersnatch$ git diff
diff --git a/src/bandersnatch/tests/ci.conf b/src/bandersnatch/tests/ci.conf
index fa3a4a5..4b98db9 100644
--- a/src/bandersnatch/tests/ci.conf
+++ b/src/bandersnatch/tests/ci.conf
@@ -1,4 +1,4 @@
-; Config for the Travis CI Integration Test that hits PyPI
+; Config for the GitHub CI Integration Test that hits PyPI
 
 [mirror]
 directory = /tmp/pypi
@@ -14,6 +14,7 @@ storage-backend = filesystem
 verifiers = 3
 keep_index_versions = 2
 compare-method = hash
+api-method = simple
 
 [plugins]
 enabled =
cooper@cooper-fedora-MJ0J8QHP:~/repos/bandersnatch$ .venv/bin/pip install -e .
cooper@cooper-fedora-MJ0J8QHP:~/repos/bandersnatch$ source .venv/bin/activate
(.venv) cooper@cooper-fedora-MJ0J8QHP:~/repos/bandersnatch$ python test_runner.py
Running Ingtegration tests due to TOXENV set to INTEGRATION
Setting CI directory=/tmp/pypi
Starting CI bandersnatch mirror ...
...
2025-11-10 10:09:47,521 INFO: Syncing all packages. (mirror.py:291)
2025-11-10 10:09:47,521 INFO: Fetching all packages via Simple (PEP 691 v1) API (master.py:217)
2025-11-10 10:09:47,522 DEBUG: Fetching simple JSON index from https://pypi.org/simple w/headers {'User-Agent': 'bandersnatch 6.7.0.dev0 aiohttp XML-RPC client (Python: 3.13.9.final.0, version: 1.5.0)', 'Accept': 'application/vnd.pypi.simple.v1+json'} (master.py:190)
2025-11-10 10:09:48,125 DEBUG: Fetched #698083 from simple JSON index (master.py:225)
...
Bandersnatch PyPI CI finished successfully!
  • TODO: Add dedicated simple API CI - Will do in a dedicated follow up PR

Replace #1898 as a partial move controlled via config.

- PEP691 introduced an alternative to the PyPI "xmlrpc" API
  to work out what packages to sync on a bandersnatch run
- The xmlrpc calls are
  - `list_packages_with_serial`
  - `changelog_since_serial`
- When api_method is set to simple in a banderstanch config we now
  - TBA

Test:
- `pre-commit run -a`
- Fix unitests and run
  - `python3.13 -m venv --upgrade-deps .venv`
  - `.venv/bin/pip install tox`
  - `.venv/bin/tox -e py313`
- Set config and run the integration tests and see still pass
```
cooper@cooper-fedora-MJ0J8QHP:~/repos/bandersnatch$ export TOXENV=INTEGRATION
cooper@cooper-fedora-MJ0J8QHP:~/repos/bandersnatch$ git diff
diff --git a/src/bandersnatch/unittest.conf b/src/bandersnatch/unittest.conf
index 209c106..cff279e 100644
--- a/src/bandersnatch/unittest.conf
+++ b/src/bandersnatch/unittest.conf
@@ -94,7 +94,7 @@ compare-method = hash

 ; API method to use for fetching package lists and changelogs
 ; Options: xmlrpc, simple
-api-method = xmlrpc
+api-method = simple

 ; Enable filtering plugins
 [plugins]
cooper@cooper-fedora-MJ0J8QHP:~/repos/bandersnatch$ .venv/bin/pip install -e .
cooper@cooper-fedora-MJ0J8QHP:~/repos/bandersnatch$ source .venv/bin/activate
(.venv) cooper@cooper-fedora-MJ0J8QHP:~/repos/bandersnatch$ python test_runner.py
Running Ingtegration tests due to TOXENV set to INTEGRATION
Setting CI directory=/tmp/pypi
Starting CI bandersnatch mirror ...
...
2025-11-10 09:52:43,444 INFO: Deleting path: /tmp/pypi/web/packages/ff/f3/9b11e001e84b4d1721f75e20b3c058854a748407e6fc1abe6da0aa22014f/black-25.9.0-cp39-cp39-win_amd64.whl (storage.py:227)
2025-11-10 09:52:43,444 INFO: Removing file: /tmp/pypi/web/packages/ff/f3/9b11e001e84b4d1721f75e20b3c058854a748407e6fc1abe6da0aa22014f/black-25.9.0-cp39-cp39-win_amd64.whl (filesystem.py:188)
2025-11-10 09:52:43,444 INFO: Deleting path: /tmp/pypi/web/packages/4b/43/20b5c90612d7bdb2bdbcceeb53d588acca3bb8f0e4c5d5c751a2c8fdd55a/black-25.9.0.tar.gz (storage.py:227)
2025-11-10 09:52:43,444 INFO: Removing file: /tmp/pypi/web/packages/4b/43/20b5c90612d7bdb2bdbcceeb53d588acca3bb8f0e4c5d5c751a2c8fdd55a/black-25.9.0.tar.gz (filesystem.py:188)
2025-11-10 09:52:43,444 DEBUG: Closing Master's aiohttp ClientSession and waiting 0.1 seconds (master.py:88)
Bandersnatch PyPI CI finished successfully!
```
- TODO: Add dedicated simple API CI - Will do in a dedicated follow up PR
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for using the PEP 691 Simple API (v1) as an alternative to the traditional XML-RPC API for fetching package lists and changelogs from PyPI. The implementation allows users to configure which API method to use via the api-method configuration option.

Key Changes:

  • Added api-method configuration option (defaults to xmlrpc, with simple as an alternative)
  • Implemented Simple API support with new methods _all_packages_simple() and _changed_packages_simple() in the Master class
  • Added comprehensive test coverage for both API methods and configuration validation

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/bandersnatch/configuration.py Added api_method field to SetConfigValues and validation logic to ensure only valid values (xmlrpc, simple) are accepted
src/bandersnatch/master.py Added api_method parameter to Master class, implemented Simple API methods (fetch_simple_index, _all_packages_simple, _changed_packages_simple), and refactored existing methods to route based on API method
src/bandersnatch/mirror.py Updated Master instantiation to pass api_method from config values
src/bandersnatch/main.py Updated delete operation to pass api_method when creating Master instance
src/bandersnatch/defaults.conf Added default api-method = xmlrpc configuration
src/bandersnatch/example.conf Added documentation and example for the new api-method configuration option
src/bandersnatch/unittest.conf Added api-method = xmlrpc to test configuration
src/bandersnatch/tests/test_master.py Added comprehensive tests for Simple API methods, XML-RPC methods, and default behavior
src/bandersnatch/tests/test_configuration.py Added tests for api_method validation including valid values, invalid values, and default behavior

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +190 to +202
async def fetch_simple_index(self) -> Any:
"""Return a mapping of all project data from the PyPI Index API"""
custom_headers = await self._gen_custom_headers()
custom_headers["Accept"] = "application/vnd.pypi.simple.v1+json"
logger.debug(
f"Fetching simple JSON index from {self.simple_url} "
f"w/headers {custom_headers}"
)
async with self.session.get(
self.simple_url, headers=custom_headers
) as response:
simple_index = await response.json()
return simple_index
Copy link

Copilot AI Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing error handling for the fetch_simple_index method. If the HTTP request fails or returns invalid JSON, the error will propagate uncaught. Consider adding try-except blocks similar to the rpc method (lines 181-188) to handle TimeoutError and other potential exceptions, and potentially raise SimpleRpcError for consistency with the XML-RPC error handling pattern.

Copilot uses AI. Check for mistakes.
@cooperlees
Copy link
Contributor Author

@pombredanne Please feel free to double check my (and AI's) copying of my logic :)

@cooperlees
Copy link
Contributor Author

Another TODO is docs explaining the 1 hour limitation of simple API ...

@cooperlees cooperlees merged commit 34980f3 into main Nov 15, 2025
11 of 12 checks passed
@cooperlees cooperlees deleted the pep691_xmlrpc_support branch November 15, 2025 04:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants