pub mod cache;
pub mod checksum;
mod chunked;
pub mod config;
pub mod discover;
pub mod download;
pub mod error;
pub mod plan;
pub mod progress;
pub mod repo;
mod retry;
pub use config::{compile_glob_patterns, file_matches, FetchConfig, FetchConfigBuilder, Filter};
pub use discover::{GateStatus, ModelCardMetadata, SearchResult};
pub use download::DownloadOutcome;
pub use error::{FetchError, FileFailure};
pub use plan::{download_plan, DownloadPlan, FilePlan};
pub use progress::ProgressEvent;
use std::collections::HashMap;
use std::path::PathBuf;
use hf_hub::{Repo, RepoType};
pub async fn download(repo_id: String) -> Result<DownloadOutcome<PathBuf>, FetchError> {
let config = FetchConfig::builder().build()?;
download_with_config(repo_id, &config).await
}
pub async fn download_with_config(
repo_id: String,
config: &FetchConfig,
) -> Result<DownloadOutcome<PathBuf>, FetchError> {
let mut builder = hf_hub::api::tokio::ApiBuilder::new().high();
if let Some(ref token) = config.token {
builder = builder.with_token(Some(token.clone()));
}
if let Some(ref dir) = config.output_dir {
builder = builder.with_cache_dir(dir.clone());
}
let api = builder.build().map_err(FetchError::Api)?;
let hf_repo = match config.revision {
Some(ref rev) => {
Repo::with_revision(repo_id.clone(), RepoType::Model, rev.clone())
}
None => Repo::new(repo_id.clone(), RepoType::Model),
};
let repo = api.repo(hf_repo);
download::download_all_files(repo, repo_id, Some(config)).await
}
pub fn download_blocking(repo_id: String) -> Result<DownloadOutcome<PathBuf>, FetchError> {
let rt = tokio::runtime::Runtime::new().map_err(|e| FetchError::Io {
path: PathBuf::from("<runtime>"),
source: e,
})?;
rt.block_on(download(repo_id))
}
pub fn download_with_config_blocking(
repo_id: String,
config: &FetchConfig,
) -> Result<DownloadOutcome<PathBuf>, FetchError> {
let rt = tokio::runtime::Runtime::new().map_err(|e| FetchError::Io {
path: PathBuf::from("<runtime>"),
source: e,
})?;
rt.block_on(download_with_config(repo_id, config))
}
pub async fn download_files(
repo_id: String,
) -> Result<DownloadOutcome<HashMap<String, PathBuf>>, FetchError> {
let config = FetchConfig::builder().build()?;
download_files_with_config(repo_id, &config).await
}
pub async fn download_files_with_config(
repo_id: String,
config: &FetchConfig,
) -> Result<DownloadOutcome<HashMap<String, PathBuf>>, FetchError> {
let mut builder = hf_hub::api::tokio::ApiBuilder::new().high();
if let Some(ref token) = config.token {
builder = builder.with_token(Some(token.clone()));
}
if let Some(ref dir) = config.output_dir {
builder = builder.with_cache_dir(dir.clone());
}
let api = builder.build().map_err(FetchError::Api)?;
let hf_repo = match config.revision {
Some(ref rev) => {
Repo::with_revision(repo_id.clone(), RepoType::Model, rev.clone())
}
None => Repo::new(repo_id.clone(), RepoType::Model),
};
let repo = api.repo(hf_repo);
download::download_all_files_map(repo, repo_id, Some(config)).await
}
pub fn download_files_blocking(
repo_id: String,
) -> Result<DownloadOutcome<HashMap<String, PathBuf>>, FetchError> {
let rt = tokio::runtime::Runtime::new().map_err(|e| FetchError::Io {
path: PathBuf::from("<runtime>"),
source: e,
})?;
rt.block_on(download_files(repo_id))
}
pub async fn download_file(
repo_id: String,
filename: &str,
config: &FetchConfig,
) -> Result<DownloadOutcome<PathBuf>, FetchError> {
let mut builder = hf_hub::api::tokio::ApiBuilder::new().high();
if let Some(ref token) = config.token {
builder = builder.with_token(Some(token.clone()));
}
if let Some(ref dir) = config.output_dir {
builder = builder.with_cache_dir(dir.clone());
}
let api = builder.build().map_err(FetchError::Api)?;
let hf_repo = match config.revision {
Some(ref rev) => {
Repo::with_revision(repo_id.clone(), RepoType::Model, rev.clone())
}
None => Repo::new(repo_id.clone(), RepoType::Model),
};
let repo = api.repo(hf_repo);
download::download_file_by_name(repo, repo_id, filename, config).await
}
pub fn download_file_blocking(
repo_id: String,
filename: &str,
config: &FetchConfig,
) -> Result<DownloadOutcome<PathBuf>, FetchError> {
let rt = tokio::runtime::Runtime::new().map_err(|e| FetchError::Io {
path: PathBuf::from("<runtime>"),
source: e,
})?;
rt.block_on(download_file(repo_id, filename, config))
}
pub fn download_files_with_config_blocking(
repo_id: String,
config: &FetchConfig,
) -> Result<DownloadOutcome<HashMap<String, PathBuf>>, FetchError> {
let rt = tokio::runtime::Runtime::new().map_err(|e| FetchError::Io {
path: PathBuf::from("<runtime>"),
source: e,
})?;
rt.block_on(download_files_with_config(repo_id, config))
}
pub async fn download_with_plan(
plan: &DownloadPlan,
config: &FetchConfig,
) -> Result<DownloadOutcome<PathBuf>, FetchError> {
if plan.fully_cached() {
let cache_dir = config
.output_dir
.clone()
.map_or_else(cache::hf_cache_dir, Ok)?;
let repo_folder = format!("models--{}", plan.repo_id.replace('/', "--"));
let snapshot_dir = cache_dir
.join(&repo_folder)
.join("snapshots")
.join(&plan.revision);
return Ok(DownloadOutcome::Cached(snapshot_dir));
}
download_with_config(plan.repo_id.clone(), config).await
}
pub fn download_with_plan_blocking(
plan: &DownloadPlan,
config: &FetchConfig,
) -> Result<DownloadOutcome<PathBuf>, FetchError> {
let rt = tokio::runtime::Runtime::new().map_err(|e| FetchError::Io {
path: PathBuf::from("<runtime>"),
source: e,
})?;
rt.block_on(download_with_plan(plan, config))
}