Hub Python Library documentation

Gérer votre Space

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v2.4.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Gérer votre Space

Dans ce guide, nous allons voir comment gérer le runtime de votre Space (secrets, hardware et volumes) à l'aide de huggingface_hub.

Rechercher des Spaces

Vous pouvez rechercher des Spaces sur le Hub en utilisant la recherche sémantique avec search_spaces(). Cette fonction utilise une recherche basée sur les embeddings pour les requêtes multi-mots et une recherche en texte intégral pour les requêtes à un seul mot.

>>> from huggingface_hub import search_spaces
>>> results = list(search_spaces("generate image"))
>>> results[0]
SpaceSearchResult(id='mrfakename/Z-Image-Turbo', title='Z Image Turbo', sdk='gradio', likes=2867, ...)

Vous pouvez filtrer les résultats par SDK ou par balises :

>>> results = search_spaces("chatbot", sdk="gradio", filter="mcp-server")

Ou via l'interface en ligne de commande :

>>> hf spaces search "generate image"
>>> hf spaces search "chatbot" --sdk gradio --limit 5

Un exemple simple : configurer les secrets et le matériel.

Voici un exemple de bout en bout pour créer et configurer un Space sur le Hub.

Créer un Space sur le Hub

>>> from huggingface_hub import HfApi
>>> repo_id = "Wauplin/my-cool-training-space"
>>> api = HfApi()

# For example with a Gradio SDK
>>> api.create_repo(repo_id=repo_id, repo_type="space", space_sdk="gradio")

Les Spaces statiques sont gratuits pour tous. Les Spaces Gradio et Docker fonctionnent sur du calcul : sur le matériel cpu-basic gratuit, ils nécessitent un abonnement (PRO pour les utilisateurs, Team ou Enterprise pour les organisations), tandis que le matériel payant n’exige que la facturation (un moyen de paiement et des crédits prépayés). Sans abonnement, la création, la duplication ou le déplacement d’un Space Gradio ou Docker sur cpu-basic échoue avec une erreur de paiement (HTTP 402). Consultez les tarifs pour plus de détails.

Créer un Space à partir d'un modèle

Au lieu de démarrer à partir d'un Space vide, vous pouvez initialiser un nouveau Space à partir de l'un des modèles officiels proposés sur le Hub (par exemple JupyterLab, un chatbot Gradio, une application Streamlit, etc.). Listez les modèles disponibles avec list_space_templates(), puis passez le repo_id d'un modèle (ou son name court) en tant que space_template à create_repo(). Notez que space_sdk reste obligatoire : le modèle initialise les fichiers tandis que le SDK définit les métadonnées de la carte.

>>> from huggingface_hub import HfApi
>>> api = HfApi()

# List available templates
>>> for template in api.list_space_templates():
...     print(f"{template.name} ({template.repo_id})")
Streamlit (streamlit/streamlit-template-space)
JupyterLab (SpacesExamples/jupyterlab)
chatbot (gradio-templates/chatbot)
...

# Create a Space from a template, by repo id or by short name
>>> api.create_repo(repo_id=repo_id, repo_type="space", space_template="SpacesExamples/jupyterlab")
>>> api.create_repo(repo_id=repo_id, repo_type="space", space_template="JupyterLab")

Certains modèles sont recommandés comme privés (par exemple JupyterLab). Si vous ne définissez pas explicitement la visibilité, ces Spaces sont créés en privé automatiquement.

Depuis l’interface en ligne de commande, la même fonctionnalité est disponible via hf spaces templates et hf repos create --template :

# List available templates
>>> hf spaces templates
NAME            REPO_ID                                        SDK    PREFERRED_PRIVATE
--------------- ---------------------------------------------- ------ -----------------
Streamlit       streamlit/streamlit-template-space             docker
JupyterLab      SpacesExamples/jupyterlab                      docker ✔
Argilla         argilla/argilla-template-space                 docker
Livebook        livebook-dev/livebook                          docker
...

# Create a Space from a template
>>> hf repos create my-jupyterlab --type space --template jupyterlab

Dupliquer un Space

Cela peut s’avérer utile si vous souhaitez construire à partir d’un Space existant plutôt que de repartir de zéro. C’est également utile si vous souhaitez contrôler la configuration/les paramètres d’un Space public. Consultez duplicate_repo() pour plus de détails.

>>> api.duplicate_repo("multimodalart/dreambooth-training", repo_type="space")

Téléversez votre code à l'aide de la solution de votre choix

Voici un exemple pour téléverser le dossier local src/ de votre machine vers votre Space :

>>> api.upload_folder(repo_id=repo_id, repo_type="space", folder_path="src/")

À cette étape, votre application devrait déjà être en cours d'exécution sur le Hub ! Toutefois, vous souhaiterez peut-être la configurer davantage avec des secrets et du matériel plus performant.

Configurer les secrets et les variables

Votre Space peut nécessiter des clés secrètes, des jetons ou des variables pour fonctionner. Consultez la documentation pour plus de détails. Par exemple, un jeton HF pour téléverser un jeu de données d'images sur le Hub une fois généré depuis votre Space.

>>> api.add_space_secret(repo_id=repo_id, key="HF_TOKEN", value="hf_api_***")
>>> api.add_space_variable(repo_id=repo_id, key="MODEL_REPO_ID", value="user/repo")

Vous pouvez lister les secrets et variables existants. Les valeurs des secrets sont en écriture seule, seules les clés, les descriptions et les horodatages de mise à jour sont donc retournés :

>>> api.get_space_secrets(repo_id=repo_id)
{'HF_TOKEN': SpaceSecret(key='HF_TOKEN', description=None, updated_at=datetime.datetime(...))}
>>> api.get_space_variables(repo_id=repo_id)
{'MODEL_REPO_ID': SpaceVariable(key='MODEL_REPO_ID', value='user/repo', description=None, updated_at=...)}

Les secrets et les variables peuvent également être supprimés :

>>> api.delete_space_secret(repo_id=repo_id, key="HF_TOKEN")
>>> api.delete_space_variable(repo_id=repo_id, key="MODEL_REPO_ID")

Depuis votre Space, les secrets sont disponibles sous forme de variables d’environnement (ou de Streamlit Secrets Management si vous utilisez Streamlit). Pas besoin de les récupérer via l’API !

Toute modification de la configuration de votre Space (secrets ou matériel) déclenchera un redémarrage de votre application.

Bonus : définissez les secrets et les variables lors de la création ou de la duplication du Space !

Les secrets et les variables peuvent être définis lors de la création ou de la duplication d'un espace :

>>> api.create_repo(
...     repo_id=repo_id,
...     repo_type="space",
...     space_sdk="gradio",
...     space_secrets=[{"key": "HF_TOKEN", "value": "hf_api_***"}, ...],
...     space_variables=[{"key": "MODEL_REPO_ID", "value": "user/repo"}, ...],
... )
>>> api.duplicate_repo(
...     from_id=repo_id,
...     repo_type="space",
...     space_secrets=[{"key": "HF_TOKEN", "value": "hf_api_***"}, ...],
...     space_variables=[{"key": "MODEL_REPO_ID", "value": "user/repo"}, ...],
... )

Configurer le matériel

Par défaut, votre Space s’exécute sur le matériel gratuit cpu-basic (ce qui nécessite un abonnement pour les Spaces Gradio et Docker, voir ci-dessus). Vous pouvez mettre à niveau le matériel pour l’exécuter sur des GPU. Une méthode de paiement et des crédits prépayés (ou une subvention communautaire) sont requis pour mettre à niveau votre Space. Consultez la documentation pour plus de détails.

# Use `SpaceHardware` enum
>>> from huggingface_hub import SpaceHardware
>>> api.request_space_hardware(repo_id=repo_id, hardware=SpaceHardware.T4_MEDIUM)

# Or simply pass a string value
>>> api.request_space_hardware(repo_id=repo_id, hardware="t4-medium")

Les mises à jour du matériel ne sont pas effectuées immédiatement, car votre Space doit être rechargé sur nos serveurs. À tout moment, vous pouvez vérifier sur quel matériel votre Space est exécuté pour voir si votre demande a été prise en compte.

>>> runtime = api.get_space_runtime(repo_id=repo_id)
>>> runtime.stage
"RUNNING_BUILDING"
>>> runtime.hardware
"cpu-basic"
>>> runtime.requested_hardware
"t4-medium"

Vous disposez désormais d'un Space entièrement configuré. Pensez à rétrograder votre Space vers cpu-basic une fois que vous avez terminé de l'utiliser.

Bonus : demandez du matériel lors de la création ou de la duplication de l'Espace !

Le matériel mis à niveau sera automatiquement affecté à votre Space une fois celui-ci construit.

>>> api.create_repo(
...     repo_id=repo_id,
...     repo_type="space",
...     space_sdk="gradio",
...     space_hardware="cpu-upgrade",
...     space_sleep_time="7200", # 2 hours in secs
... )
>>> api.duplicate_repo(
...     from_id=repo_id,
...     repo_type="space",
...     space_hardware="cpu-upgrade",
...     space_sleep_time="7200", # 2 hours in secs
... )

Suivre votre quota ZeroGPU

Les Spaces ZeroGPU s'exécutent sur des GPU partagés alloués à la demande. Chaque fois que vous utilisez un Space ZeroGPU (via l'interface utilisateur ou son API), une certaine durée d'utilisation du GPU est déduite de votre quota personnel, qui est réinitialisé périodiquement. Si vous développez une application, un agent ou un serveur MCP sur la base de Spaces ZeroGPU, vous pouvez suivre votre utilisation avec get_zero_gpu_quota(). Les valeurs sont exprimées en secondes-GPU.

>>> quota = api.get_zero_gpu_quota()
>>> quota
ZeroGpuQuota(base=2400, remaining=1810, resets_at=datetime.datetime(2026, 9, 30, 9, 12, 3, tzinfo=datetime.timezone.utc), overquota_used=0)
>>> if quota.remaining < 60:
...     print(f"Less than 1 minute of ZeroGPU left. Quota resets at {quota.resets_at}.")

resets_at est None si vous n’avez pas utilisé ZeroGPU depuis le dernier réinitialisation. Si vous utilisez un jeton à granularité fine, il doit disposer de l’autorisation « Billing > Read billing usage and payment method status ». Les mêmes informations sont disponibles depuis l’interface en ligne de commande avec hf spaces zero-gpu quota.

Une fois le quota épuisé, les utilisateurs PRO, Team et Enterprise peuvent continuer à utiliser les Spaces ZeroGPU en consommant des crédits prépayés. Vous pouvez acheter des crédits depuis vos paramètres de facturation. Consultez Extension du quota avec des crédits pour plus de détails.

Mettre en pause et redémarrer votre Space

Par défaut, si votre Space est exécuté sur un matériel mis à niveau, il ne sera jamais arrêté. Cependant, pour éviter d'être facturé, vous pouvez souhaiter le mettre en pause lorsque vous ne l'utilisez pas. Cela est possible à l'aide de pause_space(). Un Space en pause restera inactif jusqu'à ce que son propriétaire le redémarre, soit via l'interface utilisateur, soit via l'API en utilisant restart_space(). Pour plus de détails sur le mode en pause, veuillez consulter cette section

# Pause your Space to avoid getting billed
>>> api.pause_space(repo_id=repo_id)
# (...)
# Restart it when you need it
>>> api.restart_space(repo_id=repo_id)

Une autre possibilité consiste à définir un délai d’attente pour votre Space. Si votre Space est inactif pendant une durée supérieure au délai d’attente, il passera en veille. Tout visiteur accédant à votre Space le réveillera. Vous pouvez définir un délai d’attente à l’aide de set_space_sleep_time(). Pour plus de détails sur le mode veille, veuillez consulter cette section.

# Put your Space to sleep after 1h of inactivity
>>> api.set_space_sleep_time(repo_id=repo_id, sleep_time=3600)

Note : si vous utilisez un matériel « cpu-basic », vous ne pouvez pas configurer un temps de veille personnalisé. Votre Space sera automatiquement mis en pause après 48 h d'inactivité.

Bonus : définir un temps de veille lors de la demande de matériel

Le matériel mis à niveau sera automatiquement affecté à votre Space une fois celui-ci construit.

>>> api.request_space_hardware(repo_id=repo_id, hardware=SpaceHardware.T4_MEDIUM, sleep_time=3600)

Bonus : définissez une durée de veille lors de la création ou de la duplication de l'Espace !

>>> api.create_repo(
...     repo_id=repo_id,
...     repo_type="space",
...     space_sdk="gradio",
...     space_hardware="t4-medium",
...     space_sleep_time="3600",
... )
>>> api.duplicate_repo(
...     from_id=repo_id,
...     repo_type="space",
...     space_hardware="t4-medium",
...     space_sleep_time="3600",
... )

Déboguer un Space en échec en lisant ses journaux

Lorsqu’un Space échoue à la compilation ou plante à l’exécution, les journaux que vous consultez normalement dans le navigateur sont également disponibles de manière programmatique via fetch_space_logs(). C’est particulièrement utile dans les scripts ou les flux de travail agentiques où l’ouverture d’un navigateur n’est pas une option.

# Drain the currently available run logs and return immediately (like `docker logs`)
>>> for line in api.fetch_space_logs(repo_id=repo_id):
...     print(line, end="")

# Read the container build logs instead (useful when the Space is stuck in BUILD_ERROR)
>>> for line in api.fetch_space_logs(repo_id=repo_id, build=True):
...     print(line, end="")

# Stream run logs in real time until the server closes the stream (Ctrl-C to stop)
>>> for line in api.fetch_space_logs(repo_id=repo_id, follow=True):
...     print(line, end="")

La même fonctionnalité est disponible depuis l'interface en ligne de commande :

hf spaces logs username/my-space             # drain run logs
hf spaces logs username/my-space --build     # read build logs
hf spaces logs username/my-space -f          # stream in real time
hf spaces logs username/my-space -n 50       # last 50 lines only

Se connecter à un Space via SSH (Mode Dev)

Mode développeur vous permet d’accéder par SSH à un conteneur Space en cours d’exécution pour le débogage et le développement en direct. Utilisez hf spaces ssh pour ouvrir une session directement depuis le terminal. Si le mode développeur n’est pas encore activé sur le Space, l’interface en ligne de commande vous demandera de l’activer (ou passez --auto pour ignorer la demande).

Votre clé publique SSH doit être enregistrée dans vos paramètres.

# SSH into a Space (enables Dev Mode if needed)
hf spaces ssh username/my-space

# Auto-enable Dev Mode without prompting
hf spaces ssh username/my-space --auto

# Print the SSH command without running it
hf spaces ssh username/my-space --dry-run

# Use a specific SSH key
hf spaces ssh username/my-space -i ~/.ssh/id_ed25519

Vous pouvez également activer le mode Dev sans SSH à l’aide de hf spaces dev-mode, qui affiche les instructions de connexion pour SSH, VS Code, Cursor et Windsurf :

hf spaces dev-mode username/my-space

L’activation du mode Dev nécessite un abonnement PRO ou Team & Enterprise. La désactivation est toujours autorisée, par exemple si votre abonnement a expiré alors que le mode Dev était activé :

hf spaces dev-mode username/my-space --stop

Monter des volumes dans votre Space

Vous pouvez monter des ressources du Hub (modèles, jeux de données ou buckets de stockage) en tant que volumes dans le conteneur de votre Space. Cela permet à votre Space d’accéder directement à ces ressources via le système de fichiers, sans avoir à les télécharger dans votre code. Les volumes peuvent être définis directement lors de la création ou de la duplication d’un Space :

>>> from huggingface_hub import Volume
>>> api.create_repo(
...     repo_id=repo_id,
...     repo_type="space",
...     space_sdk="gradio",
...     space_volumes=[
...         Volume(type="model", source="username/my-model", mount_path="/models", read_only=True),
...         Volume(type="bucket", source="username/my-bucket", mount_path="/data"),
...     ],
... )
>>> api.duplicate_repo(
...     from_id=repo_id,
...     repo_type="space",
...     space_volumes=[
...         Volume(type="model", source="username/my-model", mount_path="/models", read_only=True),
...         Volume(type="bucket", source="username/my-bucket", mount_path="/data"),
...     ],
... )

Vous pouvez vérifier les volumes actuellement montés via le runtime de Space :

>>> runtime = api.get_space_runtime(repo_id=repo_id)
>>> runtime.volumes
[Volume(type='model', source='username/my-model', mount_path='/models', read_only=True), ...]

Si vous devez mettre à jour les volumes d'un Space existant, utilisez set_space_volumes(). Notez que cela remplace tous les volumes montés précédemment.

>>> api.set_space_volumes(
...     repo_id=repo_id,
...     volumes=[
...         Volume(type="model", source="username/my-model", mount_path="/models", read_only=True),
...         Volume(type="dataset", source="username/my-dataset", mount_path="/data", read_only=True),
...         Volume(type="bucket", source="username/my-bucket", mount_path="/output"),
...     ],
... )

Pour supprimer tous les volumes de votre Space :

>>> api.delete_space_volumes(repo_id=repo_id)

Les modèles, les jeux de données et les Spaces sont toujours montés en lecture seule. Seuls les buckets de stockage prennent en charge les montages en lecture/écriture.

La définition des volumes remplace les volumes montés précédemment. Pour ajouter un volume à une liste existante, lisez d’abord les volumes actuels depuis le runtime et incluez-les dans la nouvelle liste.

Toutes les opérations sur les volumes sont également disponibles depuis l'interface en ligne de commande :

# List current volumes
hf spaces volumes ls username/my-space

# Set (replace) volumes
hf spaces volumes set username/my-space \
    -v hf://models/username/my-model:/models \
    -v hf://buckets/username/my-bucket:/data

# Remove all volumes
hf spaces volumes delete username/my-space

Plus avancé : mettez temporairement votre Space à niveau !

Les Spaces permettent de couvrir de nombreux cas d’usage. Parfois, vous souhaitez exécuter temporairement un Space sur un matériel spécifique, effectuer une tâche puis l’arrêter. Dans cette section, nous explorons comment tirer parti des Spaces pour affiner un modèle à la demande. Il s’agit là d’une seule approche pour résoudre ce problème particulier. Elle doit être considérée comme une suggestion et adaptée à votre cas d’usage.

Supposons que nous disposions d'un Space pour affiner un modèle. Il s'agit d'une application Gradio qui prend en entrée un identifiant de modèle et un identifiant de jeu de données. Le déroulement est le suivant :

  1. (Demander à l'utilisateur un modèle et un jeu de données)
  2. Chargez le modèle depuis le Hub.
  3. Chargez le jeu de données depuis le Hub.
  4. Effectuez l’ajustement fin du modèle sur le jeu de données.
  5. Téléchargez le nouveau modèle sur le Hub.

Step 3. nécessite un matériel personnalisé, mais vous ne souhaitez pas que votre Space tourne en permanence sur un GPU payant. Une solution consiste à demander dynamiquement le matériel pour l'entraînement, puis à l'arrêter par la suite. Comme la demande de matériel redémarre votre Space, votre application doit d'une manière ou d'une autre « se souvenir » de la tâche qu'elle est en train d'exécuter. Il existe plusieurs façons de le faire. Dans ce guide, nous verrons une solution utilisant un Dataset comme « planificateur de tâches ».

Squelette de l'application

Voici à quoi ressemblerait votre application. Au démarrage, vérifiez si une tâche est planifiée et, le cas échéant, exécutez-la sur le matériel approprié. Une fois terminée, réinitialisez le matériel sur le CPU cpu-basic libre et invitez l'utilisateur à définir une nouvelle tâche.

Un tel flux de travail ne prend pas en charge l'accès concurrent, contrairement aux démos classiques. En particulier, l'interface sera désactivée pendant l'entraînement. Il est préférable de définir votre dépôt en privé pour vous assurer d'être l'unique utilisateur.

# Space will need your token to request hardware: set it as a Secret !
HF_TOKEN = os.environ.get("HF_TOKEN")

# Space own repo_id
TRAINING_SPACE_ID = "Wauplin/dreambooth-training"

from huggingface_hub import HfApi, SpaceHardware
api = HfApi(token=HF_TOKEN)

# On Space startup, check if a task is scheduled. If yes, finetune the model. If not,
# display an interface to request a new task.
task = get_task()
if task is None:
    # Start Gradio app
    def gradio_fn(task):
        # On user request, add task and request hardware
        add_task(task)
        api.request_space_hardware(repo_id=TRAINING_SPACE_ID, hardware=SpaceHardware.T4_MEDIUM)

    gr.Interface(fn=gradio_fn, ...).launch()
else:
    runtime = api.get_space_runtime(repo_id=TRAINING_SPACE_ID)
    # Check if Space is loaded with a GPU.
    if runtime.hardware == SpaceHardware.T4_MEDIUM:
        # If yes, finetune base model on dataset !
        train_and_upload(task)

        # Then, mark the task as "DONE"
        mark_as_done(task)

        # DO NOT FORGET: set back CPU hardware
        api.request_space_hardware(repo_id=TRAINING_SPACE_ID, hardware=SpaceHardware.CPU_BASIC)
    else:
        api.request_space_hardware(repo_id=TRAINING_SPACE_ID, hardware=SpaceHardware.T4_MEDIUM)

Planificateur de tâches

La planification des tâches peut être réalisée de nombreuses manières. Voici un exemple de la façon de le faire à l'aide d'un simple CSV stocké en tant que Dataset.

# Dataset ID in which a `tasks.csv` file contains the tasks to perform.
# Here is a basic example for `tasks.csv` containing inputs (base model and dataset)
# and status (PENDING or DONE).
#     multimodalart/sd-fine-tunable,Wauplin/concept-1,DONE
#     multimodalart/sd-fine-tunable,Wauplin/concept-2,PENDING
TASK_DATASET_ID = "Wauplin/dreambooth-task-scheduler"

def _get_csv_file():
    return hf_hub_download(repo_id=TASK_DATASET_ID, filename="tasks.csv", repo_type="dataset", token=HF_TOKEN)

def get_task():
    with open(_get_csv_file()) as csv_file:
        csv_reader = csv.reader(csv_file, delimiter=',')
        for row in csv_reader:
            if row[2] == "PENDING":
                return row[0], row[1] # model_id, dataset_id

def add_task(task):
    model_id, dataset_id = task
    with open(_get_csv_file()) as csv_file:
        with open(csv_file, "r") as f:
            tasks = f.read()

    api.upload_file(
        repo_id=repo_id,
        repo_type=repo_type,
        path_in_repo="tasks.csv",
        # Quick and dirty way to add a task
        path_or_fileobj=(tasks + f"\n{model_id},{dataset_id},PENDING").encode()
    )

def mark_as_done(task):
    model_id, dataset_id = task
    with open(_get_csv_file()) as csv_file:
        with open(csv_file, "r") as f:
            tasks = f.read()

    api.upload_file(
        repo_id=repo_id,
        repo_type=repo_type,
        path_in_repo="tasks.csv",
        # Quick and dirty way to set the task as DONE
        path_or_fileobj=tasks.replace(
            f"{model_id},{dataset_id},PENDING",
            f"{model_id},{dataset_id},DONE"
        ).encode()
    )
Update on GitHub