-
Notifications
You must be signed in to change notification settings - Fork 765
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
uv pip install resulting in 401 Unauthorized with private index url #1709
uv pip install resulting in 401 Unauthorized with private index url #1709
Comments
Are you able to share the hosting provider (or similar) for the private repository? E.g., is it on Azure? |
Thanks for the (extremely quick!!!) response! I'm sorry, but I can't share more details about the private index. If it might be helpful, I explicitly mentioned the @ character because some of our developers had problems in the past due to '@' being converted into '%40' at some point depending on the setup, and I see this happening during the |
I have the same problem. I'm using a jfrog repo. The index url looks like:
|
Are you able to share the full output of running with |
I ran
and got:
Running the above command with |
Same issue for me with a private gitlab index > uv pip compile --index-url='https://__token__:[email protected]/api/v4/projects/$ID/packages/pypi/simple' --output-file=requirements/linux-uv.txt pyproject.toml
error: Failed to download: my-pkg==0.4.0
Caused by: HTTP status client error (401 Unauthorized) for url (https://gitlab.com/api/v4/projects/$ID/packages/pypi/files/.../my_pkg-0.4.0-py3-none-any.whl#sha256=...) |
Same error here on an GCP Arctifact Registry: > uv pip install my-pkg --extra-index-url "https://_json_key_base64:***@europe-west1-python.pkg.dev/project/repo/simple/"
uv_client::flat_index::from_entries
uv_resolver::resolver::solve
uv_resolver::resolver::choose_version package=root
uv_resolver::resolver::get_dependencies package=root, version=0a0.dev0
0.046054s 0ms INFO pubgrub::internal::partial_solution add_decision: root @ 0a0.dev0
uv_resolver::resolver::choose_version package=my-pkg
uv_resolver::resolver::package_wait package_name=my-pkg
uv_resolver::resolver::process_request request=Versions my-pkg
uv_client::registry_client::simple_api package=my-pkg
uv_client::cached_client::get_cacheable
uv_client::cached_client::read_and_parse_cache file=/root/.cache/uv/simple-v1/pypi/my-pkg.rkyv
uv_resolver::resolver::process_request request=Prefetch my-pkg *
0.046664s 0ms WARN uv_client::cached_client Broken cache entry at /root/.cache/uv/simple-v1/pypi/my-pkg.rkyv, removing: failed to open file `/root/.cache/uv/simple-v1/pypi/my-pkg.rkyv`
uv_client::cached_client::fresh_request url="https://pypi.org/simple/my-pkg/"
uv_client::cached_client::get_cacheable
uv_client::cached_client::read_and_parse_cache file=/root/.cache/uv/simple-v1/0c1fe98321190311/my-pkg.rkyv
uv_client::cached_client::revalidation_request url="https://europe-west1-python.pkg.dev/project/repo/simple/my-pkg/"
uv_client::cached_client::new_cache file=/root/.cache/uv/simple-v1/0c1fe98321190311/my-pkg.rkyv
uv_client::registry_client::parse_simple_api package=my-pkg
uv_client::html::parse url=https://_json_key_base64:***@europe-west1-python.pkg.dev/project/repo/simple/my-pkg/
uv_resolver::version_map::from_metadata
uv_distribution::distribution_database::get_or_build_wheel_metadata dist=my-pkg==0.0.1
uv_client::registry_client::wheel_metadata built_dist=my-pkg==0.0.1
uv_client::cached_client::get_serde
uv_client::cached_client::get_cacheable
uv_client::cached_client::read_and_parse_cache file=/root/.cache/uv/wheels-v0/index/0c1fe98321190311/my-pkg/my-pkg-0.0.1-py3-none-any.msgpack
uv_resolver::resolver::get_dependencies package=my-pkg, version=0.0.1
uv_resolver::resolver::distributions_wait package_id=my-pkg-0.0.1
0.187447s 0ms WARN uv_client::cached_client Broken cache entry at /root/.cache/uv/wheels-v0/index/0c1fe98321190311/my-pkg/my-pkg-0.0.1-py3-none-any.msgpack, removing: failed to open file `/root/.cache/uv/wheels-v0/index/0c1fe98321190311/my-pkg/my-pkg-0.0.1-py3-none-any.msgpack`
uv_client::cached_client::fresh_request url="https://europe-west1-python.pkg.dev/project/repo/my-pkg/my-pkg-0.0.1-py3-none-any.whl#sha256=5741581bb410a9b09a69871cad4783f7aa84fed6e05e68cb58060ea8d3c994d1"
error: Failed to download: my-pkg==0.0.1
Caused by: HTTP status client error (401 Unauthorized) for url (https://europe-west1-python.pkg.dev/project/repo/my-pkg/my-pkg-0.0.1-py3-none-any.whl#sha256=5741581bb410a9b09a69871cad4783f7aa84fed6e05e68cb58060ea8d3c994d1) |
Same problem here. Using a private azure index with This is a redacted version of the verbose output
|
We're continuing to investigate this. Unfortunately I had no problems authenticating with an access token with a private AWS CodeArtifact repository and haven't set up alternative private registries for testing yet. |
@zanieb Here a standalone setup to reproduce with simple PEP 503 index and Basic Authentication. In some folder create, index.html <!DOCTYPE html>
<html>
<body>
<a href="/non-existing-package/">non-existing-package</a>
</body>
</html> /non-existing-package/index.html <html><head>
<meta name="pypi:repository-version" content="1.1">
</head>
<body>
<h1>Links for non-existing-package</h1>
<a href="http://127.0.0.1:8080/non-existing-package/non-existing-package-0.1.0.tar.gz#sha256=fb1aa1f8d35a2e3b7bbc2ce632ece9571bb8093dec79826a54be075f15b11ecd">non-existing-package-0.1.0.tar.gz</a><br>
</body></html> and create this fake package with
then run with node,
to get a server with basic auth. Running uv,
fails with,
So the problem is that this simple API returns absolute URLs for package versions, and the access token is no longer part of the URL hence the 401 error. It works if the URLs are relative. I'm not sure for other hosting services but Gitlab packages, does return such absolute URLs and consequently fail. |
Thank you! Will report back soon. |
Unless I'm mistaken, the corresponding logic in pip is here https://github.com/pypa/pip/blob/b647ed5782e1fc5627e5e18a036130fea0b413e6/src/pip/_internal/network/auth.py#L404 to account for the fact that the package URL for a private index may not contain credentials. |
These are some high-quality comments, thanks @rth. |
A draft fix is up at #1886 — thanks again for the reproduction! |
…les (#1886) Closes #1709 Closes #1371 Tested with the reproduction provided in #1709 which gets past the HTTP 401. Reuses the same copying logic we introduced in #1874 to ensure authentication is attached to file URLs with a realm that matches that of the index. I had to move the authentication logic into a new crate so it could be used in `distribution-types`. We will want to something more robust in the future, like track all realms with authentication in a central store and perform lookups there. That's what `pip` does and it allows consolidation of logic like netrc lookups. That refactor feels significant though, and I'd like to get this fixed ASAP so this is a minimal fix.
Thanks for the push! I installed the package from commit 8a12b2e and it still isn't working for me, same error. After failure, I created a new env and pip installed uv in editable mode, checked |
I am on 0.1.9 and I continue to get a 401. |
@hwong557 - Do you still see missing credentials on |
Can you also confirm that you cleared the cache beforehand? ( |
Yes, I cleared the cache, and I get the same missing credentials error. |
@hwong557 - If you open a page like https://xxx.jfrog.io/yyy/simple/my_private_package, are the distribution URLs relative or absolute? |
Sorry for being unhelpful but the page asks for credentials and then refuses my creds. I'll have to talk to someone at my company, but I can confirm that
|
Trial JFrog account here I come |
We've identified this as a problem preserving authorization headers in streamed range requests. #1902 should resolve this. |
fingers crossed! FWIW same issue on gitlab pypi registry (at uv 0.1.9, after cleaning the cache). |
Was also still getting 401, compiled from zb/fix-range-auth and can confirm that it fixed the issue, thanks a lot @zanieb, can finally see how fast uv is, impressive! |
This comment was marked as outdated.
This comment was marked as outdated.
I just checked out #1902 and I can confirm it now works for GitLab for me |
I confirm #1902 fixes the issue for JFrog! |
Thanks for testing it everyone! |
After having installed [EDIT] My bad, #1902 is not part of |
Thanks for fixing it so fast ! Nice to see this projet moving forward as swiftly as it does ! |
awesome, works now for me as well! Your speed is super impressive, thank you so much! |
I am trying to use
uv pip install
with a private repository, and I am getting (401 Unauthorized errors). The same URL works completely fine with native pip, i.e. if I just remove the "uv".I cannot share the real URL, but there might be characters which might be raising some issues (like '@'), so here is a pseudo-example:
uv pip install privatepackage --index-url https://[email protected]:[email protected]/path1/path2/path3/path4/path5
My current uv version is
0.1.5
, and the Python env is3.8
.The text was updated successfully, but these errors were encountered: