-
Notifications
You must be signed in to change notification settings - Fork 901
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
Add documentation on using dependencies from private GitLab package indexes #9583
base: main
Are you sure you want to change the base?
Conversation
## GitLab | ||
|
||
If you want to add a dependency from a private GitLab package index, you need to force uv to pass credentials by adding the token name directly to the index's URL: | ||
|
||
```toml | ||
[[tool.uv.index]] | ||
url = "https://GITLAB_TOKEN@$gitlab.com/api/v4/{PROJECT-OR-GROUP}/-/packages/pypi/simple" | ||
``` | ||
|
||
Since the token name is hardcoded in the pyproject.toml file, all users must set up a personal access token with the same name (GITLAB_TOKEN in the example) before installing dependencies. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be preferred to suggest using UV_INDEX_{name}_USERNAME and UV_INDEX_{name}_PASSWORD for the credentialed pieces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that too. With credentials but without token name in URL, uv will first try unauthroized request, receive 404 and cry uncle. I'll reword it for better clarity. Any suggestions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uv/crates/uv-auth/src/middleware.rs
Lines 148 to 160 in 81569c4
/// We may or may not need authentication. We'll check for cached credentials for the URL, | |
/// which is relatively specific and can save us an expensive failed request. Otherwise, | |
/// we'll make the request and look for less-specific credentials on failure i.e. if the | |
/// server tells us authorization is needed. This pattern avoids attaching credentials to | |
/// requests that do not need them, which can cause some servers to deny the request. | |
/// | |
/// - Check the cache (url key) | |
/// - Perform the request | |
/// - On 401, 403, or 404 check for authentication if there was a cache miss | |
/// - Check the cache (realm key) for the username and password | |
/// - Check the netrc for a username and password | |
/// - Perform the request again if found | |
/// - Add the username and password to the cache if successful |
Are you sure the 404 is the problem? It is explicitly one of the status codes that UV will retry with auth for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I'm sure is that adding token name fixes the issue described in the linked report. Take a look at the logs I've linked there. @zanieb seems to know the underlying cause.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For what it is worth I ran into a very similar issue to the one that you had in terms of uv output, and determined that a strangely configured python package index was returning 200 with no auth, and not listing any versions unless auth was provided. I may try to implement one of the configuration options discussed in your issue and raise a PR, but I am hoping that I can get the creator of the index I need to use at work to simply fix the probable permissions issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding the token name fixes it because we skip trying an unauthenticated request.
My earlier comments were incorrect regarding the 404, thanks @Raymi306 for pointing that out — we will search for credentails on a 404. It looks like GitLab is actually returning an okay response? The relevant logs being:
TRACE No credentials in cache for URL https://gitlab.com/api/v4/groups/${ID}/-/packages/pypi/simple/livity-airtable/
TRACE Attempting unauthenticated request for https://gitlab.com/api/v4/groups/${ID}/-/packages/pypi/simple/livity-airtable/
TRACE cached request https://gitlab.com/api/v4/groups/${ID}/-/packages/pypi/simple/livity-airtable/ is storable because its response has a 'public' cache-control directive
TRACE Received package metadata for: livity-airtable
TRACE Selecting candidate for livity-airtable with range * with 0 remote versions
Sorry for misleading you there, I'm not sure why I thought we only retried on 401..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, thanks for clearing it out.
strangely configured python package index was returning 200
Hmm, the free gitlab.com offering has only one config option in the package registry - forwarding requests to PyPI. It actually might be the issue. I'll investigate it further.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @rafalkrupinski!
Doc change: adding a section on using dependncies from a GitLab package index.
Relates to #9331
Could mention using explicit source configuration as GitLab may be configured as a proxy to the official PyPI, but I see other sections don't include anything more than strictly necessary.