Skip to content

Single trusted publisher for many packages causes slow API token creation #18514

@pnacht

Description

@pnacht

Describe the bug
If a single identity is registered as the "trusted publisher" for many packages (200+), the API token exchange can sometimes take a long time (over 5 seconds). This in conjunction with twine's built-in 5-second timeout causes the publication to fail.

Expected behavior
API token exchange should be consistently fast, at least fast enough for twine's timeout.

To Reproduce
Add an account as trusted publisher for many different packages. I'm not sure how many would be necessary to make it consistent, though... with 200+ packages, the exchange only times out occasionally (10% of the time, maybe?).

My Platform
Uploading with twine 6.10, from a Google Compute Engine instance running a Debian (bookworm) image.

Additional context
This was originally reported in pypa/twine#1261, but I was asked to instead see if something could be diagnosed in Warehouse first.

See below the output from the last time we had this timeout. It may be worth mentioning that other publications (a few hours before and after) succeeded.

Publishing packages in '[...]' using twine:
[...].tar.gz
[...].whl
Uploading distributions to https://upload.pypi.org/legacy/
INFO     [...].whl (51.0 KB)                                                 
INFO     [...].tar.gz (44.6 KB)                                                           
INFO     username set by command options                                        
INFO     Querying keyring for password                                          
Traceback (most recent call last):
  File ".venv/lib/python3.12/site-packages/urllib3/connectionpool.py", line 534, in _make_request
    response = conn.getresponse()
               ^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.12/site-packages/urllib3/connection.py", line 516, in getresponse
    httplib_response = super().getresponse()
                       ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/http/client.py", line 1428, in getresponse
    response.begin()
  File "/usr/lib/python3.12/http/client.py", line 331, in begin
    version, status, reason = self._read_status()
                              ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/http/client.py", line 292, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/socket.py", line 707, in readinto
    return self._sock.recv_into(b)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/ssl.py", line 1252, in recv_into
    return self.read(nbytes, buffer)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/ssl.py", line 1104, in read
    return self._sslobj.read(len, buffer)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TimeoutError: The read operation timed out

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File ".venv/lib/python3.12/site-packages/requests/adapters.py", line 667, in send
    resp = conn.urlopen(
           ^^^^^^^^^^^^^
  File ".venv/lib/python3.12/site-packages/urllib3/connectionpool.py", line 841, in urlopen
    retries = retries.increment(
              ^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.12/site-packages/urllib3/util/retry.py", line 474, in increment
    raise reraise(type(error), error, _stacktrace)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.12/site-packages/urllib3/util/util.py", line 39, in reraise
    raise value
  File ".venv/lib/python3.12/site-packages/urllib3/connectionpool.py", line 787, in urlopen
    response = self._make_request(
               ^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.12/site-packages/urllib3/connectionpool.py", line 536, in _make_request
    self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
  File ".venv/lib/python3.12/site-packages/urllib3/connectionpool.py", line 367, in _raise_timeout
    raise ReadTimeoutError(
urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='upload.pypi.org', port=443): Read timed out. (read timeout=5)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File ".venv/bin/twine", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File ".venv/lib/python3.12/site-packages/twine/__main__.py", line 33, in main
    error = cli.dispatch(sys.argv[1:])
            ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.12/site-packages/twine/cli.py", line 139, in dispatch
    return main(args.args)
           ^^^^^^^^^^^^^^^
  File ".venv/lib/python3.12/site-packages/twine/commands/upload.py", line 258, in main
    return upload(upload_settings, parsed_args.dists)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.12/site-packages/twine/commands/upload.py", line 181, in upload
    repository = upload_settings.create_repository()
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.12/site-packages/twine/settings.py", line 336, in create_repository
    self.password,
    ^^^^^^^^^^^^^
  File ".venv/lib/python3.12/site-packages/twine/settings.py", line 140, in password
    return self.auth.password
           ^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.12/site-packages/twine/auth.py", line 68, in password
    return utils.get_userpass_value(
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.12/site-packages/twine/utils.py", line 282, in get_userpass_value
    value = prompt_strategy()
            ^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.12/site-packages/twine/auth.py", line 185, in password_from_keyring_or_trusted_publishing_or_prompt
    if (token := self.make_trusted_publishing_token()) is not None:
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.12/site-packages/twine/auth.py", line 106, in make_trusted_publishing_token
    mint_token_resp = session.post(
                      ^^^^^^^^^^^^^
  File ".venv/lib/python3.12/site-packages/requests/sessions.py", line 637, in post
    return self.request("POST", url, data=data, json=json, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.12/site-packages/requests/sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.12/site-packages/requests/sessions.py", line 703, in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.12/site-packages/requests/adapters.py", line 713, in send
    raise ReadTimeout(e, request=request)
requests.exceptions.ReadTimeout: HTTPSConnectionPool(host='upload.pypi.org', port=443): Read timed out. (read timeout=5)

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions