> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mirage.strukto.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# HF Spaces

> Mount a Hugging Face Space repository as a filesystem and read its application files with shell commands.

The HF Spaces VFS mounts a [Hugging Face Space](https://huggingface.co/spaces)
repo (app code, README, config, requirements) at some prefix such as `/s/`.

For credential setup, see [HF Spaces Setup](/home/setup/hf_spaces).

## Install

```bash theme={null}
# No extra needed: the Hub API is reached over aiohttp, a core dependency.
uv add mirage-ai
```

## Config

```python theme={null}
import os

from mirage import MountMode, Workspace
from mirage.vfs.hf_spaces import HfSpacesConfig, HfSpacesVFS

config = HfSpacesConfig(
    repo_id=os.environ["HF_SPACE_REPO"],   # "namespace/space-name"
    token=os.environ.get("HF_TOKEN"),
    # Optional:
    # endpoint="https://huggingface.co",
    # revision="main",
)
vfs = HfSpacesVFS(config)
ws = Workspace({"/s": vfs}, mode=MountMode.READ)
```

## Reading, not writing

This mount is read-only, the way a [`github`](/python/vfs/github) mount is. A Hub write is
a **commit**, and a POSIX write cannot say where a commit ends, so `echo >`,
`rm`, `cp` and `mv` are refused here rather than silently making one commit
per file. The [`hf` CLI](/python/cli/hf) is the write half: `hf download --local-dir`
puts a copy on a ram or disk mount, which is an ordinary writable filesystem,
and `hf upload` sends it back as a single commit.

## Filesystem Layout

For example, `HuggingFaceBio/carbon-demo` mounted at `/s/` might expose:

```text theme={null}
/s/
  README.md
  app.py
  requirements.txt
  Dockerfile
```

## Example

```python theme={null}
import asyncio

from mirage import MountMode, Workspace
from mirage.vfs.hf_spaces import HfSpacesConfig, HfSpacesVFS


async def main() -> None:
    vfs = HfSpacesVFS(
        HfSpacesConfig(repo_id="HuggingFaceBio/carbon-demo"))
    ws = Workspace({"/s": vfs}, mode=MountMode.READ)

    r = await ws.execute("ls /s/")
    print(await r.stdout_str())

    r = await ws.execute("cat /s/README.md | head -n 20")
    print(await r.stdout_str())

    r = await ws.execute("grep -l import /s/*.py 2>/dev/null")
    print(await r.stdout_str())


if __name__ == "__main__":
    asyncio.run(main())
```

## Shell Commands

Every read command in [HF Buckets'](/python/vfs/hf_buckets#read-commands) set works here, as
do the text processing and path utilities, which only read. What does not is
the [File Operations](/python/vfs/hf_buckets#file-operations) group: this mount is read-only,
so `rm` and `touch` are refused, as is any command asked to write into it.

## Use Cases

* **Space introspection**: Browse an app's structure, requirements, and
  config before forking/cloning
* **App code review**: `grep` / `find` across a Space's Python without
  cloning the repo
