question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItΒ collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Unauthorized publish/add using keyring with GCP Artifact Registry

See original GitHub issue
  • I am on the latest Poetry version.
  • I have searched the issues of this repo and believe that this is not a duplicate.
  • If an exception occurs when executing a command, I executed it again in debug mode (-vvv option).

Issue

When trying to publish a package to or add a package from a private GCP Artifact Registry using keyring, I get a 401 unauthorized error. I have followed this guide as closely as possible in an attempt to adapt it to the poetry use case. I am able to publish using twine and pull using pip. In poetry’s documentation it talks about supporting keyring. However, it seems this may only be in regards to storing and retrieving username and password. I am prompted for a username only when publishing. I have hit enter at this prompt as I’m trying to use the Google stored credentials in the keyring.

Poetry publish

poetry publish -r example-gcp-registry -vvv

Username:
Publishing example_package (0.1.0) to example-gcp-registry
 - Uploading example_package-0.1.0.tar.gz 100%

  Stack trace:

  7  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/clikit/console_application.py:131 in run
      129β”‚             parsed_args = resolved_command.args
      130β”‚
    β†’ 131β”‚             status_code = command.handle(parsed_args, io)
      132β”‚         except KeyboardInterrupt:
      133β”‚             status_code = 1

  6  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/clikit/api/command/command.py:120 in handle
      118β”‚     def handle(self, args, io):  # type: (Args, IO) -> int
      119β”‚         try:
    β†’ 120β”‚             status_code = self._do_handle(args, io)
      121β”‚         except KeyboardInterrupt:
      122β”‚             if io.is_debug():

  5  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/clikit/api/command/command.py:171 in _do_handle
      169β”‚         handler_method = self._config.handler_method
      170β”‚
    β†’ 171β”‚         return getattr(handler, handler_method)(args, io, self)
      172β”‚
      173β”‚     def __repr__(self):  # type: () -> str

  4  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/cleo/commands/command.py:92 in wrap_handle
       90β”‚         self._command = command
       91β”‚
    β†’  92β”‚         return self.handle()
       93β”‚
       94β”‚     def handle(self):  # type: () -> Optional[int]

  3  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/console/commands/publish.py:77 in handle
      75β”‚         )
      76β”‚
    β†’ 77β”‚         publisher.publish(
      78β”‚             self.option("repository"),
      79β”‚             self.option("username"),

  2  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/publishing/publisher.py:93 in publish
      91β”‚         )
      92β”‚
    β†’ 93β”‚         self._uploader.upload(
      94β”‚             url,
      95β”‚             cert=cert or get_cert(self._poetry.config, repository_name),

  1  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/publishing/uploader.py:119 in upload
      117β”‚
      118β”‚         try:
    β†’ 119β”‚             self._upload(session, url, dry_run)
      120β”‚         finally:
      121β”‚             session.close()

  UploadError

  HTTP Error 401: Unauthorized

  at ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/publishing/uploader.py:216 in _upload
      212β”‚                     self._register(session, url)
      213β”‚                 except HTTPError as e:
      214β”‚                     raise UploadError(e)
      215β”‚
    β†’ 216β”‚             raise UploadError(e)
      217β”‚
      218β”‚     def _do_upload(
      219β”‚         self, session, url, dry_run=False
      220β”‚     ):  # type: (requests.Session, str, Optional[bool]) -> None

Poetry add

poetry add --source example-gcp-registry example_package -vvv
Using virtualenv: /Users/user/Library/Caches/pypoetry/virtualenvs/example_package-LmoIvwng-py3.9

  Stack trace:

  10  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/clikit/console_application.py:131 in run
       129β”‚             parsed_args = resolved_command.args
       130β”‚
     β†’ 131β”‚             status_code = command.handle(parsed_args, io)
       132β”‚         except KeyboardInterrupt:
       133β”‚             status_code = 1

   9  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/clikit/api/command/command.py:120 in handle
       118β”‚     def handle(self, args, io):  # type: (Args, IO) -> int
       119β”‚         try:
     β†’ 120β”‚             status_code = self._do_handle(args, io)
       121β”‚         except KeyboardInterrupt:
       122β”‚             if io.is_debug():

   8  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/clikit/api/command/command.py:171 in _do_handle
       169β”‚         handler_method = self._config.handler_method
       170β”‚
     β†’ 171β”‚         return getattr(handler, handler_method)(args, io, self)
       172β”‚
       173β”‚     def __repr__(self):  # type: () -> str

   7  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/cleo/commands/command.py:92 in wrap_handle
        90β”‚         self._command = command
        91β”‚
     β†’  92β”‚         return self.handle()
        93β”‚
        94β”‚     def handle(self):  # type: () -> Optional[int]

   6  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/console/commands/add.py:106 in handle
       104β”‚             return 0
       105β”‚
     β†’ 106β”‚         requirements = self._determine_requirements(
       107β”‚             packages,
       108β”‚             allow_prereleases=self.option("allow-prereleases"),

   5  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/console/commands/init.py:328 in _determine_requirements
       326β”‚             elif "version" not in requirement:
       327β”‚                 # determine the best version automatically
     β†’ 328β”‚                 name, version = self._find_best_version_for_package(
       329β”‚                     requirement["name"],
       330β”‚                     allow_prereleases=allow_prereleases,

   4  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/console/commands/init.py:361 in _find_best_version_for_package
       359β”‚
       360β”‚         selector = VersionSelector(self._get_pool())
     β†’ 361β”‚         package = selector.find_best_candidate(
       362β”‚             name, required_version, allow_prereleases=allow_prereleases, source=source
       363β”‚         )

   3  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/version/version_selector.py:32 in find_best_candidate
       30β”‚             },
       31β”‚         )
     β†’ 32β”‚         candidates = self._pool.find_packages(dependency)
       33β”‚         only_prereleases = all([c.version.is_prerelease() for c in candidates])
       34β”‚

   2  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/repositories/pool.py:166 in find_packages
       164β”‚
       165β”‚         if repository is not None and not self._ignore_repository_names:
     β†’ 166β”‚             return self.repository(repository).find_packages(dependency)
       167β”‚
       168β”‚         packages = []

   1  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/repositories/legacy_repository.py:264 in find_packages
       262β”‚             versions = self._cache.store("matches").get(key)
       263β”‚         else:
     β†’ 264β”‚             page = self._get("/{}/".format(dependency.name.replace(".", "-")))
       265β”‚             if page is None:
       266β”‚                 return []

  RepositoryError

  401 Client Error: Unauthorized for url: https://us-east1-python.pkg.dev/example_project/example-gcp-registry/simple/example_package/

  at ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/repositories/legacy_repository.py:393 in _get
      389β”‚             if response.status_code == 404:
      390β”‚                 return
      391β”‚             response.raise_for_status()
      392β”‚         except requests.HTTPError as e:
    β†’ 393β”‚             raise RepositoryError(e)
      394β”‚
      395β”‚         if response.status_code in (401, 403):
      396β”‚             self._log(
      397β”‚                 "Authorization error accessing {url}".format(url=response.url),

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
caseydialpadcommented, Sep 13, 2021

@boweevil

Keyring authentication is handled with the following PR https://github.com/python-poetry/poetry/pull/4086 (slated for release with version 1.2.0).

As for the 401 error to pull, you would use the GCP URL url = "https://us-east1-python.pkg.dev/example_project/example_gcp_registry/simple" and to push you would use url = "https://us-east1-python.pkg.dev/example_project/example_gcp_registry/".

Let me know if that helps. I am unaware a technique beyond defining two separate repositories for supporting publish and pull on different URLs to the same repository. If you have a solution, I am all ears.

0reactions
neersightedcommented, Oct 5, 2022

Closed as #4086 is merged.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Keyring authentication to Artifact Repository not working (GCP)
Ultimately, I wanted to publish a package using Poetry, and that still fails (it does still prompt for credentials there). I think I...
Read more >
Set up authentication to Python package repositories | Artifact ...
Artifact Registry provides a keyring backend to store the credentials for connecting to Artifact Registry repositories. Password authentication: Use this optionΒ ...
Read more >
Support for Poetry Β· Issue #17 - GitHub
Any basic guidance on the steps needed to publish to a GCP artifacts registry would be greatly appreciated.
Read more >
Avoid Public PyPI Using Google Cloud Artifact Registry
It's easy for people with bad intent to publish packages with very similar names ... If you're on Google Cloud, you use Artifact...
Read more >
GCP Artifact Registry repositories are anonymously or publicly ...
Fix - Runtime. GCP Console. To remove anonymous or public access for your Artifact Registry repository: Log in toΒ ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found