1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
//! # hf-hub
//!
//! Async Rust client for the [Hugging Face Hub API](https://huggingface.co/docs/hub/api) —
//! the Rust counterpart to the Python [`huggingface_hub`](https://github.com/huggingface/huggingface_hub) library.
//!
//! The crate exposes a high-level, ergonomic API built around a single entry point,
//! [`HFClient`], and a family of typed handles ([`HFRepository<T>`](HFRepository),
//! [`HFBucket`]) that scope operations to a specific resource. The repo kind lives in
//! the type system via the [`RepoType`] trait and its four marker structs
//! ([`RepoTypeModel`], [`RepoTypeDataset`], [`RepoTypeSpace`], [`RepoTypeKernel`]).
//! All network I/O is async and driven by the [`reqwest`](https://docs.rs/reqwest)
//! HTTP client with built-in retries on transient failures.
//!
//! ## Quick start
//!
//! ```rust,no_run
//! use hf_hub::HFClient;
//!
//! #[tokio::main]
//! async fn main() -> hf_hub::HFResult<()> {
//! let client = HFClient::new()?;
//! let info = client.model("openai-community", "gpt2").info().send().await?;
//! println!("Repo: {:?}", info);
//! Ok(())
//! }
//! ```
//!
//! ## Feature overview
//!
//! - **Repositories** — read info, list contents, create, delete, move, and update settings for models, datasets, and
//! Spaces.
//! - **Files** — list, download (with optional local cache or `local_dir`), upload single files or whole folders, and
//! build multi-operation commits.
//! - **Commits & refs** — paginate commit history, compute diffs between revisions, and manage branches and tags.
//! - **Users & orgs** — `whoami`, authentication checks, profile lookup, and follower/following lists.
//! - **Spaces** — runtime, hardware, secrets, variables, pause/restart.
//! - **Buckets** — namespaced storage buckets, tree listings, and bucket sync plans.
//! - **Xet transfers** — high-performance chunk-deduplicated uploads and downloads integrated transparently into the
//! file APIs.
//! - **Optional blocking API** — synchronous counterparts to every async handle when the `blocking` feature is enabled.
//!
//! ## Creating a client
//!
//! [`HFClient::new()`] resolves configuration from the environment:
//!
//! | Variable | Purpose |
//! |---|---|
//! | `HF_TOKEN` | Authentication token (preferred source) |
//! | `HF_TOKEN_PATH` | Path to a file containing the token |
//! | `HF_ENDPOINT` | Override the Hub base URL |
//! | `HF_HOME` | Root for Hugging Face state (defaults to `~/.cache/huggingface`) |
//! | `HF_HUB_CACHE` | Cache directory for downloaded files |
//! | `HF_HUB_DISABLE_IMPLICIT_TOKEN` | Ignore the ambient `HF_TOKEN`/token file |
//!
//! For explicit configuration use [`HFClient::builder()`]:
//!
//! ```rust,no_run
//! use hf_hub::HFClient;
//!
//! let client = HFClient::builder()
//! .token("hf_xxx")
//! .endpoint("https://huggingface.co")
//! .cache_dir("/tmp/hf-cache")
//! .build()?;
//! # Ok::<(), hf_hub::HFError>(())
//! ```
//!
//! [`HFClient`] wraps an `Arc<…>` internally, so cloning it is cheap and all clones
//! share the same connection pool, token, and cache configuration.
//!
//! ## Repository handles
//!
//! Rather than passing `(repo_type, owner, name)` to every method, bind them once
//! with a typed handle. The repo kind is encoded in the type via a marker
//! ([`RepoTypeModel`], [`RepoTypeDataset`], [`RepoTypeSpace`], [`RepoTypeKernel`]):
//!
//! ```rust,no_run
//! use hf_hub::HFClient;
//!
//! # #[tokio::main] async fn main() -> hf_hub::HFResult<()> {
//! let client = HFClient::new()?;
//!
//! let model = client.model("openai-community", "gpt2");
//! let dataset = client.dataset("HuggingFaceFW", "fineweb");
//! let space = client.space("huggingface", "diffusers-gallery");
//! let kernel = client.kernel("kernels-community", "cutlass-mla");
//!
//! let exists = model.exists().send().await?;
//! # let _ = (dataset, space, kernel, exists); Ok(()) }
//! ```
//!
//! Space-specific methods like `runtime`, `add_secret`, and `pause` live as `impl`
//! blocks on `HFRepository<RepoTypeSpace>` — there is no separate `HFSpace` wrapper.
//!
//! When you start from a single `"owner/name"` string, [`split_id`] turns it into
//! the `(owner, name)` pair these constructors take (short-form ids like `"gpt2"`
//! yield an empty owner):
//!
//! ```rust,no_run
//! use hf_hub::{HFClient, split_id};
//!
//! # #[tokio::main] async fn main() -> hf_hub::HFResult<()> {
//! let client = HFClient::new()?;
//! let (owner, name) = split_id("openai-community/gpt2");
//! let model = client.model(owner, name);
//! # let _ = model; Ok(()) }
//! ```
//!
//! ## File operations
//!
//! File APIs live on the repository handle. Downloads go through the local cache
//! by default, producing a path that is safe to read from even across concurrent
//! calls:
//!
//! ```rust,no_run
//! use hf_hub::HFClient;
//!
//! # #[tokio::main] async fn main() -> hf_hub::HFResult<()> {
//! let client = HFClient::new()?;
//! let path = client
//! .model("openai-community", "gpt2")
//! .download_file()
//! .filename("config.json")
//! .send()
//! .await?;
//! println!("cached at {}", path.display());
//! # Ok(()) }
//! ```
//!
//! Uploads accept bytes, files, or entire folders, and can be batched into a single
//! commit via [`HFRepository::create_commit`] with [`repository::CommitOperation`]s.
//!
//! ## Pagination
//!
//! Endpoints that return a stream of results — commit history, repo listings,
//! recursive tree walks — return `impl Stream<Item = Result<T>>`. Use the
//! [`futures::StreamExt`](https://docs.rs/futures) adapters to iterate:
//!
//! ```rust,no_run
//! use futures::StreamExt;
//! use hf_hub::HFClient;
//!
//! # #[tokio::main] async fn main() -> hf_hub::HFResult<()> {
//! let client = HFClient::new()?;
//! let model = client.model("openai-community", "gpt2");
//! let stream = model.list_tree().recursive(true).send()?;
//! futures::pin_mut!(stream);
//! while let Some(entry) = stream.next().await {
//! println!("{:?}", entry?);
//! }
//! # Ok(()) }
//! ```
//!
//! ## Blocking API
//!
//! Enable the `blocking` feature for synchronous wrappers that manage a dedicated
//! tokio runtime internally. The runtime lives on a background thread, so the
//! blocking methods are safe to call even from inside another tokio runtime:
//!
//! ```toml
//! [dependencies]
//! hf-hub = { version = "1", features = ["blocking"] }
//! ```
//!
//! ```rust,no_run
//! #[cfg(feature = "blocking")]
//! fn main() -> Result<(), hf_hub::HFError> {
//! use hf_hub::HFClientSync;
//!
//! let client = HFClientSync::new()?;
//! let _info = client.model("openai-community", "gpt2").info().send()?;
//! Ok(())
//! }
//!
//! #[cfg(not(feature = "blocking"))]
//! fn main() {}
//! ```
//!
//! The blocking handles ([`HFClientSync`], [`HFRepositorySync`], [`HFBucketSync`])
//! mirror their async counterparts method-for-method.
//!
//! ## Errors
//!
//! All fallible operations return [`Result<T>`][Result] = `Result<T, `[`HFError`]`>`.
//! `HFError` distinguishes common Hub conditions — [`RepoNotFound`][HFError::RepoNotFound],
//! [`EntryNotFound`][HFError::EntryNotFound], [`RevisionNotFound`][HFError::RevisionNotFound],
//! [`AuthRequired`][HFError::AuthRequired], [`Forbidden`][HFError::Forbidden], and
//! [`RateLimited`][HFError::RateLimited] — so you can match on them directly without
//! parsing HTTP status codes or response bodies.
//!
//! ## Caching
//!
//! Downloads are content-addressed under `HF_HUB_CACHE`, with on-disk locking so
//! concurrent fetches of the same file deduplicate. Disable caching with
//! [`HFClientBuilder::cache_enabled(false)`][HFClientBuilder::cache_enabled], or
//! bypass it per-request by setting `.local_dir(...)` on the download builder.
//! Use [`HFClient::scan_cache`][crate::HFClient::scan_cache] to inspect what's
//! cached on disk.
//!
//! ## Cargo features
//!
//! - `blocking` — enables the synchronous `*Sync` handles.
//! - `socks` — enables SOCKS proxy support in the underlying HTTP client (forwards to `reqwest/socks`).
// With the fs/tokio-dependent modules cfg-gated out on wasm, many shared
// helpers are reachable only from native call sites and would each warn as
// `dead_code`; allow them wholesale.
pub
// Modules needing the filesystem or the multi-threaded tokio runtime are
// native-only; pure-HTTP modules are exposed on wasm too. See `verify_wasm.sh`.
pub
pub use ;
pub use HFBucket;
pub use ;
pub use ;
pub use ;
pub use ;