Skip to main content

Faceberg

Faceberg

Bridge HuggingFace datasets with Apache Iceberg tables — no data copying, just metadata.

Faceberg maps HuggingFace datasets to Apache Iceberg tables. Your catalog metadata lives on HuggingFace Spaces (or Buckets) with an auto-deployed REST API, and any Iceberg-compatible query engine can access the data.

Installation

pip install faceberg

Requires Python 3.10+. The REST catalog server (faceberg serve) is included by default.

Prerequisites

Get a token from HuggingFace Settings and export it:

export HF_TOKEN=your_huggingface_token

The token is only required for remote catalogs (user/repo, hf://...). Local catalogs (plain paths) don't need one.

Quick Start

# Create a catalog on HuggingFace Hub (deploys a Space with a REST API)
faceberg user/mycatalog init

# Add datasets — table identifier is inferred (org.repo) unless --table is given
faceberg user/mycatalog add stanfordnlp/imdb
faceberg user/mycatalog add openai/gsm8k --config main

# List what's in the catalog
faceberg user/mycatalog list

# Query with interactive DuckDB shell
faceberg user/mycatalog quack
SELECT label, substr(text, 1, 100) as preview
FROM faceberg.stanfordnlp.imdb
LIMIT 10;

CLI Reference

Every command follows the same shape: faceberg <catalog-uri> <command> [args], where <catalog-uri> is one of:

URI form Backend
org/repo or hf://datasets/org/repo HuggingFace dataset repo (Space auto-deployed)
hf://spaces/org/repo HuggingFace Space
hf://buckets/org/repo HuggingFace Bucket (S3-like, no git history)
./path or /abs/path Local filesystem catalog
Command Description
init [config.yml] Create the catalog. Auto-discovers ./faceberg.yml if no path is given; --sync populates tables immediately.
add <dataset> Add a HuggingFace dataset as a table. --table ns.table sets an explicit identifier, --config selects a dataset config.
sync [table] Re-check datasets for new revisions and update Iceberg metadata. Omit table to sync everything; --tree-view shows progress as a tree.
list List all namespaces/tables in the catalog.
info <table> Show a table's schema, partitioning, and metadata location.
scan <table> Read and print sample rows. --limit/-n controls row count (default 5).
remove <identifier> Drop a table (ns.table) or an empty namespace. --yes skips the confirmation prompt.
serve Start an Iceberg REST catalog server. --host, --port (default 8181), --reload, --prefix.
quack Open an interactive DuckDB shell with the catalog pre-attached. --endpoint overrides auto-detection.

Run faceberg <uri> <command> --help for full flag details and examples on any command.

faceberg.yml

Catalogs are described by a faceberg.yml config that tracks dataset-to-table mappings:

default:
  imdb:
    type: dataset
    repo: stanfordnlp/imdb
    config: plain_text
  gsm8k:
    type: dataset
    repo: openai/gsm8k
    config: main

faceberg init tables.yml bootstraps a catalog from a file like this in one shot; faceberg sync re-reads it and updates any table whose source dataset revision changed.

Local Catalogs

For development, testing, or CI, point the CLI at a filesystem path instead of a HuggingFace URI — no token needed:

faceberg ./mycatalog init
faceberg ./mycatalog add stanfordnlp/imdb --config plain_text
faceberg ./mycatalog serve --port 8181   # in one terminal
faceberg ./mycatalog quack               # in another

See Local Catalogs for the on-disk layout and testing patterns.

HuggingFace Buckets

Catalog metadata can also live in a HuggingFace Bucket (hf://buckets/org/name) instead of a Space — an S3-like storage backend with no git history, useful for catalogs that don't need a hosted REST endpoint:

faceberg hf://buckets/user/mycatalog init
faceberg hf://buckets/user/mycatalog add stanfordnlp/imdb

How It Works

HuggingFace Hub
┌─────────────────────────────────────────────────────────┐
│                                                         │
│  ┌─────────────────────┐    ┌─────────────────────────┐ │
│  │  HF Datasets        │    │  HF Spaces (Catalog)    │ │
│  │  (Original Parquet) │◄───│  • Iceberg metadata     │ │
│  │                     │    │  • REST API endpoint    │ │
│  │  stanfordnlp/imdb/  │    │  • faceberg.yml         │ │
│  │   └── *.parquet     │    │                         │ │
│  └─────────────────────┘    └───────────┬─────────────┘ │
│                                         │               │
└─────────────────────────────────────────┼───────────────┘
                                          │ Iceberg REST API
                                          ▼
                              ┌─────────────────────────┐
                              │     Query Engines       │
                              │  DuckDB, Pandas, Spark  │
                              └─────────────────────────┘

No data is copied — only metadata is created. Query with DuckDB, PyIceberg, Spark, or any Iceberg-compatible tool.

Python API

import os
from faceberg import catalog

cat = catalog("user/mycatalog", hf_token=os.environ.get("HF_TOKEN"))
table = cat.load_table("stanfordnlp.imdb")
df = table.scan(limit=100).to_pandas()

The catalog object exposes the usual Iceberg operations:

Method Description
init(config) Initialize catalog storage, optionally with a Config
config() Load the catalog's faceberg.yml configuration
add_dataset(identifier, repo, config) Add a HuggingFace dataset as an Iceberg table
sync_dataset(identifier) / sync_datasets() Sync one or all datasets (update if source changed)
load_table(identifier) Load a table for querying
list_tables(namespace) / list_namespaces() Enumerate tables / namespaces
drop_table(identifier) / drop_namespace(identifier) Remove a table or empty namespace
table_exists(identifier) Check if a table exists

Pandas integration

import pandas as pd

df = pd.read_iceberg(
    table_identifier="stanfordnlp.imdb",
    catalog_name="faceberg",
    catalog_properties={"type": "rest", "uri": "https://user-mycatalog.hf.space"},
    columns=["text", "label"],
    limit=10,
)

See Pandas Integration for the local-catalog variant and more examples.

Share Your Catalog

Your catalog is accessible to anyone via the REST API:

import duckdb

conn = duckdb.connect()
conn.execute("INSTALL iceberg; LOAD iceberg")
conn.execute("""
    ATTACH 'https://user-mycatalog.hf.space' AS cat (
        TYPE ICEBERG,
        ENDPOINT 'https://user-mycatalog.hf.space',
        AUTHORIZATION_TYPE 'none'
    )
""")

result = conn.execute("SELECT * FROM cat.stanfordnlp.imdb LIMIT 5").fetchdf()

To make your catalog private, set the underlying HuggingFace Space/dataset/Bucket to private.

Documentation

Read the docs →

Development

git clone https://github.com/kszucs/faceberg
cd faceberg
pip install -e '.[dev]'

Common tasks are wired up via just (see the justfile):

just test     # run the test suite (pytest faceberg/tests/)
just cov      # run tests with coverage
just format   # format code with ruff
just check    # lint + format check
just build    # build distribution packages

Docs are written in Quarto (docs/*.qmd) and published to https://faceberg.kszucs.dev/.

License

Apache 2.0

Release files for faceberg 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for faceberg 0.4.0
File Size Uploaded
faceberg-0.4.0.tar.gz 88.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for faceberg 0.4.0
File Interpreter ABI Platform
faceberg-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 185.7 kB

Release files / faceberg-0.4.0.tar.gz

Download URL faceberg-0.4.0.tar.gz
Size 88.8 kB
Tags Source
SHA-256 checksum
How to use checksums
9c0c6ceabb6079e17a978f8958830e570891fe8d48927b0ecd62583983d10462
BLAKE2b-256 checksum
How to use checksums
5bd108eae9998241fb949cc36b5f4ff7d90382dd9301ee886d694cb893a640b2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 10, 2026.

Transparency log

Release files / faceberg-0.4.0-py3-none-any.whl

Download URL faceberg-0.4.0-py3-none-any.whl
Size 96.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
edccf897f4b221c014285f200cda9e608b0704c47adac8bbc7de48e4d4c2bd00
BLAKE2b-256 checksum
How to use checksums
96da1d840a379e57f491c48678e04e861244791f4659a91511bdc072644cabea
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 10, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page