-vvv option).I am trying to publish a python package to my companies Azure DevOps Artifacts. I have built the package using poetry. A run the following at the command line:
❯ poetry --version
Poetry version 1.0.9
❯ poetry config repositories.azure https://pkgs.dev.azure.com/.../pypi/upload
❯ poetry install
Installing dependencies from lock file
No dependencies to install or update
- Installing pyia (0.1.0)
❯ poetry build
Building pyia (0.1.0)
- Building sdist
- Built pyia-0.1.0.tar.gz
- Building wheel
- Built pyia-0.1.0-py3-none-any.whl
❯ poetry publish -r azure --username <> --password <> -vvv
Publishing pyia (0.1.0) to azure
- Uploading pyia-0.1.0-py3-none-any.whl 0%
- Uploading pyia-0.1.0-py3-none-any.whl 100%
- Uploading pyia-0.1.0-py3-none-any.whl 100%
[UploadError]
HTTP Error 401: Unauthorized
Traceback (most recent call last):
File "C:\Users\sedwardes\Miniconda3\envs\ia_py\lib\site-packages\clikit\console_application.py", line 131, in run
status_code = command.handle(parsed_args, io)
File "C:\Users\sedwardes\Miniconda3\envs\ia_py\lib\site-packages\clikit\api\command\command.py", line 120, in handle
status_code = self._do_handle(args, io)
File "C:\Users\sedwardes\Miniconda3\envs\ia_py\lib\site-packages\clikit\api\command\command.py", line 171, in _do_handle
return getattr(handler, handler_method)(args, io, self)
File "C:\Users\sedwardes\Miniconda3\envs\ia_py\lib\site-packages\cleo\commands\command.py", line 92, in wrap_handle
return self.handle()
File "C:\Users\sedwardes\Miniconda3\envs\ia_py\lib\site-packages\poetry\console\commands\publish.py", line 81, in handle
client_cert,
File "C:\Users\sedwardes\Miniconda3\envs\ia_py\lib\site-packages\poetry\masonry\publishing\publisher.py", line 92, in publish
client_cert=resolved_client_cert,
File "C:\Users\sedwardes\Miniconda3\envs\ia_py\lib\site-packages\poetry\masonry\publishing\uploader.py", line 110, in upload
self._upload(session, url)
File "C:\Users\sedwardes\Miniconda3\envs\ia_py\lib\site-packages\poetry\masonry\publishing\uploader.py", line 205, in _upload
raise UploadError(e)
I have used Poetry to publish to public repos before. But not Azure or private repos. I have a hunch there may be an issue with Azure Artifacts keyring. The Azure documentation suggests to use twine, and you authenticate with the Azure keyring.
Lastly I tried to copy the code from https://www.nuomiphp.com/eplan/en/104789.html, but I was met with the same error when following this template.
Any ideas on how to publish to Azure Artifacts?
Quick update. I was able to find a work around. I proceeded with Poetry package development as I normally would. Instead of using Poetry to publish at the end though I used:
> poetry build
> twine upload -r azure dist/*
For this to work I just followed the instructions Azure Artifacts provides for using Twine.
Are there any risks to doing it this way? Seems like it worked for me.
I was able to upload it for our azsure devops server.
We use the upload tokens in the connect feed dialog ( the one under "Upload packages with twine")
Make sure they are in the auth.toml in $HOME/.config/pypoetry/auth.toml
[http-basic]
[http-basic.myfoorepo]
username= ...
password= ....
then poetry publish -r myfoorepo should work
Thanks for the feedback @maxab. Our of curiosity were you able to use Poetry with Azure Pipelines?
I'm still a bit confused by Microsofts naming of TFS, Devops and Azure Pipelines. But if you mean the hosted build things, this I haven't tried so only used it in the on-prem installation.
But in general don't you have some kind of secret store there which you then can interpolate during the run.
Something like:
poetry publish -u $(username) -p $(password) ...
Hi, original developer of artifacts-keyring and occasional keyring contributor here 👋
In short, artifacts-keyring wraps up a separate tool that is able to use locally cached Azure DevOps credentials (or pop up a login window) to get a temporary access token to Azure Artifacts. This token isn't tied to the user's username, but comes with the username. To support this in keyring, we added the get_credential API.
It looks like Poetry is currently only using the get_password API (here), which requires a known username. get_credential _may_ accept a username (it's optional), and returns an object that provides both username and password to use.
If the version of keyring you find has get_credential, that's the only one you need to call - backends that don't support it will automatically use the result from get_password. However, if you don't have a username, you can still call get_credential with the index URL to have it generate a valid credential. (It looks like Poetry currently creates its own entry names, which won't work with the artifacts-keyring backend - we need at least the https://dev.azure.com/<name> part of the URL, and fail quickly for any query that doesn't match this.)
There should be no harm in deferring the get_credential call until a 401 has been received, and it's fine to pass the target URL with an always empty username (to avoid looking up any stored credentials). There ought not be a need to specifically search for the presence of the keyring backend.
poetry publish works when used along with personal access token of Azure Artifacts.
export POETRY_REPOSITORIES_AZURE_URL="<FEED URL>"
export POETRY_HTTP_BASIC_AZURE_USERNAME="<Any Thing>"
export POETRY_HTTP_BASIC_AZURE_PASSWORD="<personal access token>"
Note: When using personal access token, username is not required and can be anything
Then, finally, you can upload to Artifacts using the publish command
poetry publish -r azure --build
Most helpful comment
poetry publishworks when used along with personal access token of Azure Artifacts.Note: When using personal access token,
usernameis not required and can be anythingThen, finally, you can upload to Artifacts using the
publishcommand