Before you start
You need Python 3.10 or later, a Hugging Face account and the Transformers setup from lesson 2. Gradio is an open-source Python package that builds a web page around any Python function: a form for its inputs and a panel for its outputs. Install it in your virtual environment with pip install --upgrade gradio.
A Space is a git repository on the Hub that runs an app. Every push rebuilds the app and restarts it. When you create one, you choose its SDK, the kind of app it runs: Gradio, Docker or static HTML.
Check your plan before you start. Static Spaces are free for everyone. Gradio and Docker Spaces run on compute, so creating one needs a paid plan: PRO for a personal account, Team or Enterprise for an organization.
There is one exception, and it shapes this lesson. A free personal account in good standing can host up to 2 Gradio Spaces on ZeroGPU, a shared GPU service. Good standing means a verified email and an account older than 30 days.
The Gradio quickstart still calls Spaces a place to host Gradio apps "for free". The Hub's Spaces page sets the rules, and on 5 November 2026 it said the opposite for Gradio Spaces outside ZeroGPU. Go by the Hub.
Build a Gradio app on your machine
The quickstart's first app greets whoever types a name. Save the code as app.py and run python app.py. The app opens at http://localhost:7860, and share=True on the last line also creates a public link ending in gradio.live. While you edit, run gradio app.py instead. That is hot reload mode: the page reloads each time you save.
The gr.Interface class takes three core arguments. Its fn is the function to wrap. Its inputs hold one component, a form element such as a textbox or an image upload, for each argument of that function. Its outputs hold one component per return value, in order. You can name a component with a string such as "textbox" or create it as an object such as gr.Textbox(), and Gradio ships more than 30 of them.
A share link is the quickest way to show someone a demo, within limits. The traffic runs through Gradio's share servers, which only relay it to your computer and store nothing. Your machine does the work, so the link stops when you stop the app, and every link expires after a week. Anyone holding the link can use the app, so keep private data and risky actions out of the function.
To keep a demo to a few people, add a login. The sharing guide's example passes auth=("admin", "pass1234") to launch(), one username and password, and a list of such pairs also works. The guide calls this a basic layer of access control, with no multi-factor sign-in, rate limits or lockouts. It also needs third-party cookies, which Safari and Chrome's Incognito mode block by default.
Share links are off unless you ask for one, except in Google Colab notebooks, where Gradio creates them by itself. To show a local app to specific people without any public link, the guide suggests SSH port forwarding instead.
Two other classes cover other shapes. The gr.ChatInterface class builds a chat window around a function that answers messages. The gr.Blocks class lets you place components and chain events yourself, still in Python. This lesson stays with Interface.
import gradio as gr
def greet(name):
return "Hello " + name + "!"
demo = gr.Interface(fn=greet, inputs="textbox", outputs="textbox")
demo.launch(share=True) # Share your demo with just 1 extra parameter 🚀| Argument | What it takes | In the hot dog app |
|---|---|---|
fn | Any Python function | predict, which runs the classifier |
inputs | One component per argument of fn | An image box that takes an upload or a webcam shot |
outputs | One component per return value, in order | The image again, then a label showing the top 2 classes |
examples | A nested list of sample inputs shown under the form | Not set |
title, description | Text above the form | The title "Hot Dog? Or Not?" |
Publish it on Hugging Face Spaces
The Spaces docs walk through a hot dog classifier, and its code follows as published. It loads julien-c/hotdog-not-hotdog with the Transformers pipeline from lesson 2 and wraps it in an Interface. Give it a picture and it returns the picture with two labels, hot dog or not, each with a score.
The docs keep a finished copy of this Space at NimaBoscarino/hotdog-gradio, so you can compare your files with theirs. Because huggingface_hub comes preinstalled, a Space can also call the Inference Providers from lesson 3 instead of loading a model itself. That route needs less compute in the Space.
import gradio as gr
from transformers import pipeline
pipeline = pipeline(task="image-classification", model="julien-c/hotdog-not-hotdog")
def predict(input_img):
predictions = pipeline(input_img)
return input_img, {p["label"]: p["score"] for p in predictions}
gradio_app = gr.Interface(
predict,
inputs=gr.Image(label="Select hot dog candidate", sources=['upload', 'webcam'], type="pil"),
outputs=[gr.Image(label="Processed Image"), gr.Label(label="Result", num_top_classes=2)],
title="Hot Dog? Or Not?",
)
if __name__ == "__main__":
gradio_app.launch()- On the Spaces page, click Create new Space. Choose a name, an optional license and a visibility, then pick Gradio as the SDK.
- Add a file named
requirements.txtwith two lines,transformersandtorch. The Space installs them on every build. It already hasgradio,huggingface_hub,requests,datasetsand common Debian packages such asffmpeg. For a system package it lacks, list the name in apackages.txtfile, one per line, and the build installs each withapt-get install. - Add
app.pywith the code above. Thanks to its last two lines, the same file also runs on your machine withpython app.py. - Push the files. Spaces are git repositories, so clone yours, commit and push after signing in with
hf auth login. Or rungradio deployin your app folder: it uploads every file there except those.gitignorelists, then starts the Space. - Wait for the build, then open the App tab. Upload a photo and read the two labels it returns.
- Share the Space's address. Every later push rebuilds the app, so a fix goes live with the next build.
Settings, secrets and a GPU with ZeroGPU
The YAML block at the top of the Space's README.md configures it, the way a model card's block describes a model. The sdk key says gradio. The sdk_version key holds the Gradio release, set to the latest one when you create the Space, and you edit it to upgrade. Other keys set python_version, which defaults to 3.10, plus app_file, suggested_hardware and short_description. If your app needs more than the default half hour to start, raise startup_duration_timeout.
Keys and settings go in the Space's Settings, as variables or secrets, never in app.py. Both reach your app as environment variables, and the table shows how they differ. A public Space's code is open to everyone, and the Hub scans Spaces for hard-coded secrets and warns their owners.
The default hardware, CPU Basic, gives 2 CPU cores, 16GB of RAM and 50GB of disk that does not survive a restart. That is enough for the hot dog classifier. A CPU Basic Space goes to sleep after 48 hours without visitors, and the next visitor wakes it. Paid hardware is billed only while the Space is starting or running, not during the build, and pausing the Space stops the bill. If a running Space starts to fail, the Hub suspends it and the billing stops too.
Upgraded hardware never sleeps by default. You can give it a custom sleep time in the settings, and it costs nothing while asleep. A Space that needs a GPU it cannot pay for can apply for a community GPU grant from the same sleep time settings.
ZeroGPU lends a Space a GPU only while a function needs one, from a shared pool of NVIDIA RTX Pro 6000 Blackwell cards. It works with the Gradio SDK only. The setup is three moves: pick ZeroGPU hardware in the Space settings, add import spaces, and put @spaces.GPU above each function that needs the GPU. Outside ZeroGPU the decorator does nothing, so the same file still runs on your laptop.
Load the model and move it to cuda, the NVIDIA GPU route from lesson 2, at the top of the file. A real GPU exists only inside the decorated functions, but the docs say startup placement is the efficient path, and moving the model inside a function is much slower. Each call gets 60 seconds of GPU by default. For a longer job, set a duration as in the snippet below. Shorter durations get better places in the queue. The duration can also be a function that takes the same inputs and returns the seconds, so a job with more steps can ask for more time.
The decorator asks for the large size by default, half a card with 48GB of video memory. Passing size="xlarge" gets the full card and its 96GB, at twice the quota cost and usually a longer wait. ZeroGPU supports Gradio 4 or later and PyTorch from version 2.8.0 on.
Every visitor spends their own daily GPU quota, shown in the chart, and it resets 24 hours after their first GPU use. The quota a visitor has left also sets their place in the queue. ZeroGPU does not support torch.compile, and the docs point to ahead-of-time compilation instead. A PRO account raises the hosting limit to 10 ZeroGPU Spaces.
The hf CLI from lesson 1 handles secrets and quotas from a terminal too. In the CLI reference, hf spaces secrets add username/my-space -s HF_TOKEN adds a secret, and hf spaces zero-gpu quota shows your ZeroGPU quota in GPU-seconds.
@spaces.GPU(duration=120)
def generate(prompt):
return pipe(prompt).images| Question | Variables | Secrets |
|---|---|---|
| Meant for | Settings that are not sensitive, such as a model id | Access tokens, API keys and passwords |
| Who can read the value | Anyone, it is public | No one, and the settings page hides it once saved |
| Copied when someone duplicates the Space | Yes, filled in for them | No, they add their own |
| How the app reads it | As an environment variable, for example with os.getenv | The same way |
Source: Hugging Face Hub: Spaces ZeroGPU (read November 5, 2026)
Lucain Pouget on Space templates, Lysandre on MCP Spaces
Lucain Pouget, who maintains huggingface_hub, posted on X on 9 July 2026 that version 1.23.0 builds a whole Space from an official template, such as JupyterLab or a Gradio chatbot, in one command. The CLI reference writes it as hf repos create my-jupyterlab --type space --template SpacesExamples/jupyterlab, and hf spaces templates lists the others. For a chat demo, start from the Gradio chatbot template and swap in your own function.
Lysandre, Chief Open-Source Officer at Hugging Face, posted on X in June 2025 that any MCP Space could be picked through hf.co/mcp and used in an MCP client. He counted roughly 900 of them then, for images, video, audio and code.
The HF MCP server page now has you add them at huggingface.co/settings/mcp and restart the client. The mcp-server filter on the Spaces page lists the ones that serve MCP, so try a few before you build your own.
Quickest way to spin up a complete Space.
Screenshots of X's own embeds of the posts, taken on 5 November 2026, with the time in UTC. Select one to open the post on X.
Common mistakes
- Putting a token in
app.py. In a public Space anyone can read that file, so store the token as a secret. - Forgetting
requirements.txt. The build then has notransformersortorch, and the app stops at its first import. - Asking for the
xlargeGPU size by habit. It burns twice the daily quota of the defaultlarge, so keep it for jobs that need the whole card. - Calling an outside service on an unusual port. A Space can only reach out through ports 80, 443 and 8080.
- Assuming a paid GPU works with no changes. Most Spaces do, but some need the CUDA build of their framework in
requirements.txt, so check the Space logs after the upgrade. - Pushing straight to ZeroGPU without a local run. The decorator is inert on your machine, so check the page with
gradio app.pyfirst and push once it works. - Leaving
short_descriptionempty in the README. That line is what the Space's thumbnail shows, so it is what people read before they open the demo.
Try it yourself
These two lines from the Spaces overview read a variable. Create the variable in Settings first, then add the lines to app.py in your Space.
import os
print(os.getenv('MODEL_REPO_ID'))- Add a variable named
MODEL_REPO_IDset tojulien-c/hotdog-not-hotdog. Where does the printed value show up? - Change the pipeline line to take its model id from that variable. Could someone who duplicates your Space now switch models without touching the code?
- Add
examples=to the Interface with two image files you committed to the repo. What appears under the form? - Run the app locally with
gradio app.py, change the title and save. Does the open page update by itself? - Open a public Space you like, pick Duplicate this Space from the three-dot menu, and note which variables come filled in. Duplicating follows the same plan rule as creating a Space, and the copy starts private on CPU Basic.
Next course: Fine-tuning
That closes the loop: find a model, run it, call a bigger one and put a demo in front of people. The Fine-tuning course comes next. Its first lesson, when to fine-tune, says when training a model on your own data beats a better prompt or RAG, and the course ends with your model on the Hub. The MCP course follows it. Gradio has a shortcut of its own: set mcp_server=True in launch() and the app's functions become MCP tools, which build an MCP server in Python explains. A Space shows people your model, and an MCP server lets their assistants use your code.
Check yourself
Which plan lets a personal account create a Gradio Space on CPU hardware?
Show answer
B. PRO Gradio and Docker Spaces need PRO for a personal account, and a free account in good standing can host up to 2 on ZeroGPU only.
Where should an API key for your Space go?
Show answer
C. In a Space secret, read as an environment variable Secrets stay private, are not copied when someone duplicates the Space, and reach the app as environment variables.
On ZeroGPU, where should the model be moved to cuda?
Show answer
A. At the top of the file, when the app starts The docs place models on cuda at module level, and moving them inside decorated functions is much less efficient.
How long does a Gradio share link last?
Show answer
D. Up to a week, and only while your computer runs the app Share links expire after a week, and your own machine does the work, so the link stops with the app.
Frequently asked questions
Can I keep the code of my Space private?
Yes. A private Space hides both the code and the app from everyone but you and your collaborators. A protected Space hides the code but keeps the app open at its hf.space address, and it needs a PRO, Team or Enterprise plan.
Can I use Docker or plain HTML instead of Gradio?
Yes, both are SDK choices when you create a Space. A Docker Space runs any app you can put in a container and follows the same paid-plan rule as Gradio. A static Space serves HTML, CSS and JavaScript and costs nothing.
How do I call my Space from my own code?
Through the "Use via API" link in the app's footer. Almost any Gradio app works as an API, and that page lists its endpoints with their parameters and example inputs. Gradio's Python client or its JavaScript client sends the requests.
Can I embed a Space in my own website?
Yes. A Gradio Space can be embedded with Web Components or an HTML iframe. Public and protected Spaces also answer at their own hf.space address, which you can link to directly.
Sources
- Gradio: Quickstart https://www.gradio.app/guides/quickstart
- Gradio: The Interface class https://www.gradio.app/guides/the-interface-class
- Gradio: Sharing your app https://www.gradio.app/guides/sharing-your-app
- Hugging Face Hub: Spaces overview https://huggingface.co/docs/hub/spaces-overview
- Hugging Face Hub: Gradio Spaces https://huggingface.co/docs/hub/spaces-sdks-gradio
- Hugging Face Hub: Handling Spaces dependencies https://huggingface.co/docs/hub/spaces-dependencies
- Hugging Face Hub: Spaces configuration reference https://huggingface.co/docs/hub/spaces-config-reference
- Hugging Face Hub: Using GPU Spaces https://huggingface.co/docs/hub/spaces-gpus
- Hugging Face Hub: Spaces ZeroGPU https://huggingface.co/docs/hub/spaces-zerogpu
- huggingface_hub: CLI reference https://huggingface.co/docs/huggingface_hub/package_reference/cli
- Hugging Face Hub: HF MCP Server https://huggingface.co/docs/hub/hf-mcp-server
- Lucain Pouget on X: create a Space from a template in huggingface_hub v1.23.0 https://x.com/Wauplin/status/2075242347760107797
- Lysandre on X: MCP Spaces through hf.co/mcp https://x.com/LysandreJik/status/1931022549221056981


