Skip to main content

Module 9 — Publishing to a Hugging Face Space

The share link from the previous module is meant for iteration between engineers, not for a durable public URL. When the demo has to live at the same address for weeks and survive your laptop closing, the standard answer for Gradio apps is a Hugging Face Space: a git-backed hosting environment that runs your Python code on a chosen hardware tier and gives you a stable hf.co/spaces/<user>/<name> URL. This module walks through the creation, the mandatory files, secrets, hardware, sleep policy and embedding.

Creating the Space

A Space is a git repository with two special files: an app.py (or app_gradio.py) that Hugging Face will run, and a requirements.txt that lists the Python packages to install. On huggingface.co/new-space, pick a name, select Gradio as the SDK, choose the visibility (public or private) and the hardware tier, and the platform creates an empty repo.

Clone it locally, copy your Gradio app in, and push:

git clone https://huggingface.co/spaces/<username>/<space-name>
cd <space-name>

# Copy your Gradio app as app.py, and drop a minimal requirements.txt:
cat > requirements.txt <<'EOF'
gradio>=4.36
transformers>=4.43
torch>=2.3
EOF

git add app.py requirements.txt
git commit -m "First deploy"
git push

Within a minute or two, the Space is building; within a few more, it is running. The build log is visible on the Space page, and any missing dependency shows up there — not in a silent failure — which is why picking Spaces over a random VM is usually the right first choice.

The files a Space needs

Six files cover the vast majority of Spaces. Four are required, two are optional but worth having.

  • app.py (required). The Python entry point. It must construct a Gradio demo and call demo.launch() at the module level. Hugging Face executes this file on start.
  • requirements.txt (required for Python packages). One package per line, optionally pinned with >= or ==. Everything is installed in an isolated environment on each build.
  • README.md (required). The first block is YAML frontmatter that configures the Space: title, emoji, colors, SDK version, hardware, and whether the app is pinned. Hugging Face reads it, so it is not optional in practice even if git push accepts a repo without it.
  • .gitignore (optional). Exclude __pycache__/, .env, gradio_cached_examples/. A dirty repo is a dirty deploy.
  • packages.txt (optional). One system package per line — ffmpeg, libsndfile1, poppler-utils — installed with apt before Python packages. Needed for audio and PDF workloads.
  • Dockerfile (optional). If you want a custom base image, drop a Dockerfile and change the SDK in the frontmatter to docker. That is an escape hatch, not a default.

A minimal README.md frontmatter looks like this:

---
title: My Chat Assistant
emoji: 🤖
colorFrom: blue
colorTo: green
sdk: gradio
sdk_version: 4.44.0
app_file: app.py
pinned: false
license: apache-2.0
---

The rest of the README is plain Markdown, and it is what visitors see below the demo. Fill it with what the model does, its limitations, examples of prompts to try, and a link to any dataset or paper.

Secrets: API keys never in the repo

If your demo calls an external API — OpenAI, Anthropic, a private endpoint — the API key belongs in the Space's Settings → Repository secrets, not in the code. Secrets are exposed as environment variables inside the Space's runtime, invisible from the file system.

import os
from openai import OpenAI

client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])

On the local machine, use a .env file with python-dotenv, and make sure .env is in .gitignore. Pushing a key to a git repo is the single most common way credentials leak to the internet, and the mistake survives forever in the git history. Rotate immediately if it happens; a two-line audit script that greps for sk- before every commit is cheap insurance.

Hardware tiers

Spaces run on a menu of hardware tiers, from free CPU to A100 GPUs. The full list changes over time, but the shape has been stable enough to plan around:

TierComputeBest for
CPU basic (free)2 vCPU, 16 GB RAMSmall models, embedding search, static tools
CPU upgrade8 vCPU, 32 GB RAMLarger CPU models, faster startup
T4 small1 GPU, 15 GB VRAM7B-parameter chat models in int4
A10G1 GPU, 24 GB VRAM13B-parameter models, image generation
A1001 or 4 GPUs, 40 or 80 GB VRAMLarge models, video, batched inference

The free CPU tier is enough to publish a text summarizer, a small image classifier or a demo that calls an external API. GPU tiers are billed per hour of active runtime and require a paid Hugging Face plan for personal use. Pick the smallest tier that clears the memory footprint of your model, then measure; if the queue backs up (module 7), upgrade.

The sleep policy

A free Space sleeps after a period of inactivity — a few tens of minutes at the time of writing — to save compute. The first visitor after sleep triggers a cold start that reboots the container and reloads the model, which can take from ten seconds to a full minute depending on the tier and the model size. Subsequent visitors within the active window hit the warm server directly.

For a public demo where a first impression matters — a link on a blog post, a portfolio page — the cold-start hesitation is what most visitors experience. Two mitigations exist. First, upgrade the Space to a tier that does not sleep, which is the honest answer if traffic justifies the cost. Second, keep the Space warm with a scheduled ping from a service like GitHub Actions or a cron job on a small VM, hitting the API endpoint every fifteen minutes. That trick works, and it is fair use — the platform's terms are relaxed about it — but do not abuse it on a free tier if you are not the primary user.

Embedding a Space in your website

A published Space can be embedded in any website with a one-line <iframe>:

<iframe
src="https://your-username-your-space.hf.space"
frameborder="0"
width="100%"
height="720"
></iframe>

The iframe URL is the Space's direct hosting URL, not the huggingface.co browse page. Gradio also provides a JavaScript component, @gradio/client, that lets you call the Space's API from a JS or TS front-end and render the result in your own UI. That is the path when the Gradio interface itself does not match your product's design language.

In summary

  • A Space is a git repo with app.py, requirements.txt and a README.md frontmatter; git push deploys, and the build log is public.
  • Store API keys in Repository secrets, never in the code; a leaked key in git history survives forever.
  • Pick the smallest hardware tier that clears the model's memory footprint, then measure and upgrade; free tiers sleep on idle.
  • Embed a Space with an <iframe> on the .hf.space URL, or call its API from your own front-end for a custom UI.

Next module: the full project — a language model demo, streamed, with prefilled examples, a queue, and a Space that ties everything together.