Repository navigation
Description
- 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 (
-vvvoption).
- OS version and name: Fedora 32
- Poetry version: Poetry 1.1.0
- Link of a Gist with the contents of your pyproject.toml file: https://gist.github.com/MasterNayru/0014ec89ae05d8f7651d18d8a107ec90
Issue
We have been using Poetry to pull down packages from a private PyPi repository and everything has been working fine until Poetry 1.1.0. We are configuring poetry to talk to our private PyPi installation by HTTP basic auth, and that auth works perfectly fine to resolve which versions of a package to install. The problem seems to be that that same auth is then used in the requests to download wheels from PyPi, which causes the following error to occur:
$ poetry config http-basic.myprivaterepo <username> <password>
$ poetry update -vvv
<snip>
2 ~/.pyenv/versions/3.8.5/lib/python3.8/site-packages/poetry/repositories/pypi_repository.py:454 in _download
452│
453│ def _download(self, url, dest): # type: (str, str) -> None
→ 454│ return download_file(url, dest, session=self.session)
455│
456│ def _log(self, msg, level="info"):
1 ~/.pyenv/versions/3.8.5/lib/python3.8/site-packages/poetry/utils/helpers.py:98 in download_file
96│
97│ with get(url, stream=True) as response:
→ 98│ response.raise_for_status()
99│
100│ with open(dest, "wb") as f:
HTTPError
400 Client Error: Bad Request for url: https://deckard-pip.s3.amazonaws.com/1234/my_broken_dependency/my_broken_dependency-0.1.3-py3-none-any.whl?AWSAccessKeyId=<key>&Signature=kz30gf304b%2F%2F93pQeUSPrto5MiE%3D&x-amz-security-token=<token>&Expires=1601690152
at ~/.pyenv/versions/3.8.5/lib/python3.8/site-packages/requests/models.py:941 in raise_for_status
937│ elif 500 <= self.status_code < 600:
938│ http_error_msg = u'%s Server Error: %s for url: %s' % (self.status_code, reason, self.url)
939│
940│ if http_error_msg:
→ 941│ raise HTTPError(http_error_msg, response=self)
942│
943│ def close(self):
944│
945│ called the underlying ``raw`` object must not be accessed again.
If I change the following lines in the poetry code:
2 ~/.pyenv/versions/3.8.5/lib/python3.8/site-packages/poetry/repositories/pypi_repository.py:454 in _download
453│ def _download(self, url, dest): # type: (str, str) -> None
→ 454│ return download_file(url, dest, session=self.session)
changes to:
2 ~/.pyenv/versions/3.8.5/lib/python3.8/site-packages/poetry/repositories/pypi_repository.py:454 in _download
453│ def _download(self, url, dest): # type: (str, str) -> None
→ 454│ return download_file(url, dest)
and re-run, everything works:
$ poetry update
Skipping virtualenv creation, as specified in config file.
Updating dependencies
Resolving dependencies... (41.8s)
No dependencies to install or update
It seems like the auth is needed to talk to the API for package version resolution but causes issues when it is also used for package downloads. If it makes any difference, I am using pypicloud as the backend for my private PyPi installation.
I am trying to be as brief as possible with my output as possible without dumping any keys or stuff like that. Please let me know if you need any more information or suggestions on what I should be changing in my configuration to get my stuff working again.
Activity
abn commentedon Oct 2, 2020
@MasterNayru interesting. We recently identified that in
1.0.10we did not apply authentication correctly for source specified in the pyproject toml. In typical circumstances we expect authentication to be used for both api queries as well as file downloads.Am I correct in understanding that in your case; authentication is used to retrieve wheel direct links (ie. incl. tokens) but the expectation is that we do not send basic auth when downloading these wheels? If so, this is a bit tricky, as this would mean there are 2 use cases that are not necessarily compatible with each other.
MasterNayru commentedon Oct 2, 2020
@abn I am expecting that if I am trying to download packages from S3 that, since pypicloud returns a URL with the necessary auth parameters in the download URL from the API requests, and since S3 seems to error out when the username/password auth parameters are provided, that they will somehow not be used as part of the requests for the downloads, which seemed to fit in line pretty well with the behaviour in the older versions.
MasterNayru commentedon Oct 2, 2020
@abn I am going to close this issue as it would appear that pypicloud have, since I last looked at it, defaulted to the behaviour which poetry is enforcing with regards to auth for package downloads. Rather than try to support the old behaviour which pip works with, I will update my pypicloud installation and make use of the new behaviour. Cheers for bearing with us.
[-]Cannot download packages from private PyPi repository using HTTP basic auth with Poetry 1.1.0 [/-][+]Cannot download packages from private PyPi repository using HTTP basic auth with Poetry 1.1.0 + old v1.0.x PypiCloud w/ default settings [/+]pepastach commentedon Oct 6, 2020
We hit exactly the same problem with poetry 1.1.1 and pypicloud 1.0.10.
The way I understand it, this can't be solved by pypicloud upgrade. Here's my reasoning:
Authorizationheader. This makes the request invalid. We verified it manually using curl.Since it's poetry/requests who adds the authorization header, I don't see how this can be fixed on pypicloud side.
Please correct me (or reopen the issue 😉 ).
pepastach commentedon Oct 6, 2020
pypicloud 1.0.11 introduced the ability to stream files through pypicloud. By briefly looking at the diff, it seems like we can configure pypicloud with
pypi.stream_files = True. pypicloud should then return the package file directly instead of redirecting to S3.We'll try pypicloud bump and report back.
Katafalkas commentedon Oct 23, 2020
Hi. Ran into the same issue.
pypicloud==1.1.5poetry==1.1.3Tried both with and without
pypi.stream_files = True- same issue.Error is because of the headers being sent. The same url is downloadable using
curl.Katafalkas commentedon Oct 23, 2020
@MasterNayru I would suggest that this issue should be considered as poetry issue. The reason being - same
pypicloudserver is working just fine withpip, and does not withpoetry.We run number of repositories and python packages, only one of them is with poetry and currently it does not work. We should either wait or help with fixing poetry or migrate to pip.
abn commentedon Nov 2, 2020
@Katafalkas one aspect to note here is that
pipandpoetryhave different uses for these URLs. One such case is thatpoetrystores these URLs in the lock file. Considering that the tokens used for these URLs are short-lived, it is not ideal to be used within a lock file. As far as I can tell the use of short-lived authorised URLs are not a defined behaviour. The use case inpipmost likely works because search and retrival are treated seperately, this in-effect might allow this to work as expected.Considering that
pypicloudis a common component these days, we might need to look at how we can better support it. On the other hand however, PEP 503 does not define a mechanism for independent authentication for the file URLs. Typically, the authentication for the host domain is re-used.Out of curiosity, are the domains different for the index and the file?
Qu4tro commentedon Nov 2, 2020
They are for us (also using
pypicloud), as the files are hosted onamazonaws.comand the index is on our domain.Katafalkas commentedon Nov 13, 2020
The url of pypi-cloud server and the file served from S3 are different by default, but there is an option to passthrough url. Which makes both of those URLs the same.
cereblanco commentedon Dec 12, 2020
This is how I setup private pypi
At terminal, add poetry config credentials for private_pypi
poetry config http-basic.myprivate_pypi <username> <password>Update lock with --no-update
poetry lock --no-updateAdd your library that is found at private pypi or
poetry installpoetry add <my-packate-found-at-private>@MeanderingCode let me know if this one works for you
7 remaining items
jensgustafsson commentedon Jan 28, 2021
This was very interesting news! We're running pypi cloud
1.1.17(The latest version) and runningpoetry lockdoes not work in any release after1.0.10of poetry. Would you mind sharing you pypi cloud config file?Which version of pypi cloud are you using btw?
Our config looks like this:
jensgustafsson commentedon Jan 28, 2021
UPDATE: Things actually works! We were indeed running an old version of pypi cloud. After updating to 1.1.17 things actually started to work! 🌟
MasterNayru commentedon Jan 28, 2021
Great to hear that it is working for you. The setting you would have needed to set was
storage.redirect_urls, notredirect_urlsas you had it in the config you postedjensgustafsson commentedon Jan 28, 2021
Thanks! Yes I actually figured that out after your previous reply 🙏 Thanks a lot!
voney commentedon Apr 29, 2022
I'm getting the exact same issue but using myget.org instead. The "solution" here is specific to pypicloud but the underlying issue of a package download being redirected to a different URL with auth baked in remains. I imagnee this issue will only grow as services use managed S3 style storage more and more.
Can this be re-opened and fixed "properly"?
improve http request handling for sources
abn commentedon Apr 29, 2022
@voney can you try the fix at #5518? That should "in theory" handle this better. If not, please create a new issue.
improve http request handling for sources
improve http request handling for sources
improve http request handling for sources
improve http request handling for sources
improve http request handling for sources
github-actions commentedon Mar 2, 2024
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.