C.W.K.
Stream
Lesson 02 of 06 · published

Repository Types: Models, Datasets, Spaces

~28 min · hub, repos

Level 0Scout
0 XP0/50 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

Three repo contracts, not three tabs

The Hub treats models, datasets, and Spaces as different repository contracts — different URL prefixes, different metadata schemas, different storage backends, different rate limits. The web UI puts them under tabs, which makes them look like the same thing. They aren't.

  • huggingface.co/{org}/{name}model repo. Holds weights (.safetensors / .bin), config, tokenizer, and a README.md with YAML front-matter (the model card).
  • huggingface.co/datasets/{org}/{name}dataset repo. Holds data files (Parquet, CSV, JSONL, audio, image), an optional loading script, and a dataset card.
  • huggingface.co/spaces/{org}/{name}Space repo. An app: Gradio / Streamlit / Docker / static. Has runtime config, secrets, and hardware tier.

Why the distinction matters

Every API call in huggingface_hub takes a repo_type. If you pass repo_type="model" when you mean dataset, the call returns 404 even if the repo exists — same Git infra, different namespace. The HfApi methods list_models(), list_datasets(), list_spaces() are not aliases of the same function; they hit different indices and accept different filters (e.g. task= only on models, language= on both models and datasets).

The repo type also dictates what shows up on the page: model repos get the inference widget and Use This Model button; dataset repos get the Data Studio viewer; Spaces get the running app iframe. None of that is configurable — it's bound to the repo type.

Code

Three repo types, three list endpoints·python
from huggingface_hub import HfApi

api = HfApi()

# Models — task filter is unique to this surface
llamas = api.list_models(search="llama", task="text-generation", sort="downloads", limit=5)
for m in llamas:
    print(f"MODEL  {m.id:<55} dl={m.downloads or 0:>8}")

# Datasets — language filter
korean_ds = api.list_datasets(language="ko", sort="downloads", limit=5)
for d in korean_ds:
    print(f"DATA   {d.id:<55} dl={d.downloads or 0:>8}")

# Spaces — sdk filter (gradio | streamlit | docker | static)
gradio_spaces = api.list_spaces(filter="gradio", sort="likes", limit=5)
for s in gradio_spaces:
    print(f"SPACE  {s.id:<55} likes={s.likes or 0}")
repo_type matters on every CRUD call·python
from huggingface_hub import HfApi

api = HfApi()
repo_id = "stanfordnlp/imdb"  # this is a DATASET, not a model

# Wrong: 404 even though the repo exists
try:
    api.repo_info(repo_id, repo_type="model")
except Exception as e:
    print("model lookup:", type(e).__name__)

# Right
info = api.repo_info(repo_id, repo_type="dataset")
print("dataset siblings:", [s.rfilename for s in info.siblings[:5]])

External links

Exercise

Pick three repos from the public Hub — one model, one dataset, one Space — that you'd actually use in a project. For each, call api.repo_info(repo_id, repo_type=...) and inspect: .sha, .last_modified, .siblings (list of files), .tags. Note which fields are unique per repo type. Save the result as a Python dict for the next exercise.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.