mirror of https://github.com/astral-sh/uv
Add support for `HF_TOKEN` (#14797)
## Summary If `HF_TOKEN` is set, we'll automatically wire it up to authenticate requests when hitting private `huggingface.co` URLs in `uv run`. ## Test Plan An unauthenticated request: ``` > cargo run -- run https://huggingface.co/datasets/cmarsh/test/resolve/main/main.py File "/var/folders/nt/6gf2v7_s3k13zq_t3944rwz40000gn/T/mainYadr5M.py", line 1 Invalid username or password. ^^^^^^^^ SyntaxError: invalid syntax ``` An authenticated request: ``` > HF_TOKEN=hf_... cargo run run https://huggingface.co/datasets/cmarsh/test/resolve/main/main.py Hello from main.py! ```
This commit is contained in:
parent
7a56950bab
commit
a3ea1b69f2
|
|
@ -15,6 +15,7 @@ mod credentials;
|
|||
mod index;
|
||||
mod keyring;
|
||||
mod middleware;
|
||||
mod providers;
|
||||
mod realm;
|
||||
|
||||
// TODO(zanieb): Consider passing a cache explicitly throughout
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use reqwest::{Request, Response};
|
|||
use reqwest_middleware::{Error, Middleware, Next};
|
||||
use tracing::{debug, trace, warn};
|
||||
|
||||
use crate::providers::HuggingFaceProvider;
|
||||
use crate::{
|
||||
CREDENTIALS_CACHE, CredentialsCache, KeyringProvider,
|
||||
cache::FetchUrl,
|
||||
|
|
@ -457,9 +458,8 @@ impl AuthMiddleware {
|
|||
Some(credentials)
|
||||
};
|
||||
|
||||
return self
|
||||
.complete_request(credentials, request, extensions, next, auth_policy)
|
||||
.await;
|
||||
self.complete_request(credentials, request, extensions, next, auth_policy)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Fetch credentials for a URL.
|
||||
|
|
@ -503,6 +503,13 @@ impl AuthMiddleware {
|
|||
return credentials;
|
||||
}
|
||||
|
||||
// Support for known providers, like Hugging Face.
|
||||
if let Some(credentials) = HuggingFaceProvider::credentials_for(url).map(Arc::new) {
|
||||
debug!("Found Hugging Face credentials for {url}");
|
||||
self.cache().fetches.done(key, Some(credentials.clone()));
|
||||
return Some(credentials);
|
||||
}
|
||||
|
||||
// Netrc support based on: <https://github.com/gribouille/netrc>.
|
||||
let credentials = if let Some(credentials) = self.netrc.get().and_then(|netrc| {
|
||||
debug!("Checking netrc for credentials for {url}");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
use std::sync::LazyLock;
|
||||
use tracing::debug;
|
||||
use url::Url;
|
||||
|
||||
use uv_static::EnvVars;
|
||||
|
||||
use crate::Credentials;
|
||||
use crate::realm::Realm;
|
||||
|
||||
/// The [`Realm`] for the Hugging Face platform.
|
||||
static HUGGING_FACE_REALM: LazyLock<Realm> = LazyLock::new(|| {
|
||||
let url = Url::parse("https://huggingface.co").expect("Failed to parse Hugging Face URL");
|
||||
Realm::from(&url)
|
||||
});
|
||||
|
||||
/// The authentication token for the Hugging Face platform, if set.
|
||||
static HUGGING_FACE_TOKEN: LazyLock<Option<Vec<u8>>> = LazyLock::new(|| {
|
||||
// Extract the Hugging Face token from the environment variable, if it exists.
|
||||
let hf_token = std::env::var(EnvVars::HF_TOKEN)
|
||||
.ok()
|
||||
.map(String::into_bytes)
|
||||
.filter(|token| !token.is_empty())?;
|
||||
|
||||
if std::env::var_os(EnvVars::UV_NO_HF_TOKEN).is_some() {
|
||||
debug!("Ignoring Hugging Face token from environment due to `UV_NO_HF_TOKEN`");
|
||||
return None;
|
||||
}
|
||||
|
||||
debug!("Found Hugging Face token in environment");
|
||||
Some(hf_token)
|
||||
});
|
||||
|
||||
/// A provider for authentication credentials for the Hugging Face platform.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub(crate) struct HuggingFaceProvider;
|
||||
|
||||
impl HuggingFaceProvider {
|
||||
/// Returns the credentials for the Hugging Face platform, if available.
|
||||
pub(crate) fn credentials_for(url: &Url) -> Option<Credentials> {
|
||||
if Realm::from(url) == *HUGGING_FACE_REALM {
|
||||
if let Some(token) = HUGGING_FACE_TOKEN.as_ref() {
|
||||
return Some(Credentials::Bearer {
|
||||
token: token.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
@ -765,4 +765,11 @@ impl EnvVars {
|
|||
|
||||
/// Disable GitHub-specific requests that allow uv to skip `git fetch` in some circumstances.
|
||||
pub const UV_NO_GITHUB_FAST_PATH: &'static str = "UV_NO_GITHUB_FAST_PATH";
|
||||
|
||||
/// Authentication token for Hugging Face requests. When set, uv will use this token
|
||||
/// when making requests to `https://huggingface.co/` and any subdomains.
|
||||
pub const HF_TOKEN: &'static str = "HF_TOKEN";
|
||||
|
||||
/// Disable Hugging Face authentication, even if `HF_TOKEN` is set.
|
||||
pub const UV_NO_HF_TOKEN: &'static str = "UV_NO_HF_TOKEN";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -151,3 +151,18 @@ insecure.
|
|||
|
||||
Use `allow-insecure-host` with caution and only in trusted environments, as it can expose you to
|
||||
security risks due to the lack of certificate verification.
|
||||
|
||||
## Hugging Face support
|
||||
|
||||
uv supports automatic authentication for the Hugging Face Hub. Specifically, if the `HF_TOKEN`
|
||||
environment variable is set, uv will propagate it to requests to `huggingface.co`.
|
||||
|
||||
This is particularly useful for accessing private scripts in Hugging Face Datasets. For example, you
|
||||
can run the following command to execute the script `main.py` script from a private dataset:
|
||||
|
||||
```console
|
||||
$ HF_TOKEN=hf_... uv run https://huggingface.co/datasets/<user>/<name>/resolve/<branch>/main.py
|
||||
```
|
||||
|
||||
You can disable automatic Hugging Face authentication by setting the `UV_NO_HF_TOKEN=1` environment
|
||||
variable.
|
||||
|
|
|
|||
|
|
@ -252,6 +252,10 @@ Ignore `.env` files when executing `uv run` commands.
|
|||
|
||||
Disable GitHub-specific requests that allow uv to skip `git fetch` in some circumstances.
|
||||
|
||||
### `UV_NO_HF_TOKEN`
|
||||
|
||||
Disable Hugging Face authentication, even if `HF_TOKEN` is set.
|
||||
|
||||
### `UV_NO_INSTALLER_METADATA`
|
||||
|
||||
Skip writing `uv` installer metadata files (e.g., `INSTALLER`, `REQUESTED`, and `direct_url.json`) to site-packages `.dist-info` directories.
|
||||
|
|
@ -528,6 +532,11 @@ See [force-color.org](https://force-color.org).
|
|||
|
||||
Used for trusted publishing via `uv publish`.
|
||||
|
||||
### `HF_TOKEN`
|
||||
|
||||
Authentication token for Hugging Face requests. When set, uv will use this token
|
||||
when making requests to `https://huggingface.co/` and any subdomains.
|
||||
|
||||
### `HOME`
|
||||
|
||||
The standard `HOME` env var.
|
||||
|
|
|
|||
Loading…
Reference in New Issue