# How to Download Models from HuggingFace Directly in the oMLX Admin Dashboard

> Easily download HuggingFace models directly within the oMLX admin dashboard. Our FastAPI integration simplifies model management for your projects.

- Repository: [Jun Kim/omlx](https://github.com/jundot/omlx)
- Tags: how-to-guide
- Published: 2026-05-11

---

**The oMLX admin dashboard provides a web interface that communicates with FastAPI endpoints to search, download, and manage HuggingFace models through the `HFDownloader` class.**

The `jundot/omlx` repository implements a complete model management system that allows you to download models from HuggingFace directly in the oMLX admin dashboard without leaving your browser. The backend handles downloads asynchronously, offering real-time progress monitoring, cancellation, and retry capabilities through a RESTful API.

## Architecture of the Download System

The download functionality is implemented across several key files in the oMLX codebase.

### Core Components

**`HFDownloader`** ([`omlx/admin/hf_downloader.py`](https://github.com/jundot/omlx/blob/main/omlx/admin/hf_downloader.py)) is the central class that orchestrates model downloads. It creates ** `DownloadTask`** dataclass instances to track state and executes the actual download using `huggingface_hub.snapshot_download` within a background asyncio task.

The **FastAPI routes** in [`omlx/admin/routes.py`](https://github.com/jundot/omlx/blob/main/omlx/admin/routes.py) expose the HTTP interface. Key endpoints include:

- `POST /api/hf/download` – Initiates a new download
- `GET /api/hf/tasks` – Returns the status of all active and completed tasks
- `POST /api/hf/cancel/{task_id}` – Aborts a running download
- `POST /api/hf/retry/{task_id}` – Resumes failed or gated downloads
- `GET /api/hf/model-info` – Retrieves metadata before downloading

### Request Validation

Incoming requests are validated using Pydantic models defined in [`omlx/admin/models.py`](https://github.com/jundot/omlx/blob/main/omlx/admin/models.py) (referenced in [`routes.py`](https://github.com/jundot/omlx/blob/main/routes.py)). The **`HFDownloadRequest`** schema requires a `repo_id` and accepts an optional `hf_token`, while **`HFRetryRequest`** handles retry payloads with updated authentication tokens.

### Progress Tracking

Internally, `HFDownloader` spawns a background task that calls `_poll_progress` to update the `task.progress` and `task.downloaded_size` attributes. The UI polls `GET /api/hf/tasks` to retrieve current statistics, including percentage complete, bytes downloaded, and error states.

## Configuration

Custom HuggingFace endpoints are supported through the global settings in **[`omlx/settings.py`](https://github.com/jundot/omlx/blob/main/omlx/settings.py)**. The system checks for an `HF_ENDPOINT` environment variable; if unset, it defaults to `https://huggingface.co`. This allows the dashboard to work with private Hub instances or mirrors.

## Step-by-Step Download Workflow

1. **Verify model metadata** using `GET /api/hf/model-info?repo_id=<model>` to check size, parameters, and available files.
2. **Initiate the download** by posting to `/api/hf/download` with the repository ID and optional token.
3. **Monitor progress** by polling `/api/hf/tasks` every few seconds to track the `status`, `progress` percentage, and `downloaded_size`.
4. **Control execution** via the cancel or retry endpoints if network issues occur or authentication is required.

## Code Examples

### Starting a Download

Use `curl` to initiate a download for a public MLX model:

```bash
curl -X POST "http://localhost:8000/api/hf/download" \
     -H "Content-Type: application/json" \
     -d '{"repo_id":"mlx-community/Llama-3-8B-4bit","hf_token":""}'

```

The endpoint returns a serialized `DownloadTask`:

```json
{
  "success": true,
  "task": {
    "task_id": "7c9e4b2a‑…",
    "repo_id": "mlx-community/Llama-3-8B-4bit",
    "status": "pending",
    "progress": 0.0,
    "total_size": 0,
    "downloaded_size": 0,
    "error": "",
    "created_at": 1715598423.12,
    "started_at": 0,
    "completed_at": 0,
    "retry_count": 0
  }
}

```

### Polling Task Status

Check the current state of all downloads:

```bash
curl "http://localhost:8000/api/hf/tasks"

```

Example response showing active progress:

```json
{
  "tasks": [
    {
      "task_id": "7c9e4b2a‑…",
      "repo_id": "mlx-community/Llama-3-8B-4bit",
      "status": "downloading",
      "progress": 42.3,
      "total_size": 8423243520,
      "downloaded_size": 3567894322,
      "error": ""
    }
  ]
}

```

### Canceling a Download

Abort a specific task using its ID:

```bash
curl -X POST "http://localhost:8000/api/hf/cancel/7c9e4b2a-…"

```

Response:

```json
{ "success": true }

```

### Retrying Failed Downloads

For gated models or network failures, retry with a valid token:

```bash
curl -X POST "http://localhost:8000/api/hf/retry/7c9e4b2a-…" \
     -H "Content-Type: application/json" \
     -d '{"hf_token":"hf_YourToken"}'

```

### Fetching Model Metadata

Inspect model details before committing to a download:

```bash
curl "http://localhost:8000/api/hf/model-info?repo_id=mlx-community/Llama-3-8B-4bit"

```

Response includes formatted size and parameter counts:

```json
{
  "repo_id": "mlx-community/Llama-3-8B-4bit",
  "name": "Llama-3-8B-4bit",
  "model_card": "## Llama‑3 8‑B 4‑bit …",

  "size": 8423243520,
  "size_formatted": "7.8 GB",
  "params": 7300000000,
  "params_formatted": "7.3B",
  "files": [ ]
}

```

### Python Integration

Automate downloads using the `requests` library:

```python
import requests
import time

BASE = "http://localhost:8000"

# Start download

resp = requests.post(
    f"{BASE}/api/hf/download",
    json={"repo_id": "mlx-community/Llama-3-8B-4bit"},
)
task = resp.json()["task"]
print("Task ID:", task["task_id"])

# Poll until completion

while True:
    tasks = requests.get(f"{BASE}/api/hf/tasks").json()["tasks"]
    t = next(t for t in tasks if t["task_id"] == task["task_id"])
    print(f"{t['progress']:.1f}% – {t['status']}")
    if t["status"] in ("completed", "failed", "cancelled"):
        break
    time.sleep(2)

```

## Summary

- The **`HFDownloader`** class in [`omlx/admin/hf_downloader.py`](https://github.com/jundot/omlx/blob/main/omlx/admin/hf_downloader.py) manages all download operations using `huggingface_hub.snapshot_download` in background asyncio tasks.
- FastAPI routes in [`omlx/admin/routes.py`](https://github.com/jundot/omlx/blob/main/omlx/admin/routes.py) provide the REST API surface for the admin dashboard to start, monitor, cancel, and retry downloads.
- Real-time progress is tracked through the `DownloadTask` dataclass and exposed via the `GET /api/hf/tasks` endpoint.
- Configuration for custom HuggingFace endpoints is handled through `HF_ENDPOINT` in [`omlx/settings.py`](https://github.com/jundot/omlx/blob/main/omlx/settings.py), defaulting to the public hub.

## Frequently Asked Questions

### Do I need a HuggingFace token to download models?

Public models do not require authentication. However, gated or private repositories require a valid `hf_token` passed in the `POST /api/hf/download` request body or via the retry endpoint.

### Can I download multiple models simultaneously?

Yes. The `HFDownloader` creates independent `DownloadTask` instances for each request, executing them as separate asyncio background tasks without blocking the main server process.

### How do I configure a custom HuggingFace endpoint?

Set the `HF_ENDPOINT` environment variable or modify [`omlx/settings.py`](https://github.com/jundot/omlx/blob/main/omlx/settings.py) to point to your private Hub instance. If left unspecified, the system uses the default `https://huggingface.co` endpoint.

### What happens if a download fails?

Failed tasks retain their error state and partial progress. You can resume the download by calling `POST /api/hf/retry/{task_id}` with the appropriate task ID and, if needed, an updated HuggingFace token.