Mindket

Hugging Face Spaces and Gradio tutorial: build a demo and host it

A black banner titled "Hugging Face" over the line "Find, run and share open models".

Gradio turns a Python function into a web page, and a Hugging Face Space hosts that page at a public address. This lesson builds a Gradio app, runs it on your machine, then publishes the docs' hot dog classifier to a Space. It also covers the plan you need, secrets, sleep and ZeroGPU, the shared GPU pool.

In this lesson

  • Confirm what your account may host before you choose how the Space runs.
  • Hand credentials to the Space privately, because a public app's source is open to all.
  • Put the model on the graphics card once, as the app boots, and request only the GPU seconds a call uses.
  • Change the Gradio version on purpose in the README, then watch the rebuild.
All courses
On this page
  1. Before you start
  2. Build a Gradio app on your machine
  3. Publish it on Hugging Face Spaces
  4. Settings, secrets and a GPU with ZeroGPU
  5. Lucain Pouget on Space templates, Lysandre on MCP Spaces
  6. Common mistakes
  7. Try it yourself
  8. Next course: Fine-tuning
  9. Check yourself
  10. Frequently asked questions
  11. Sources

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 🚀
Interface arguments from the Interface class guide, read on 5 November 2026.
ArgumentWhat it takesIn the hot dog app
fnAny Python functionpredict, which runs the classifier
inputsOne component per argument of fnAn image box that takes an upload or a webcam shot
outputsOne component per return value, in orderThe image again, then a label showing the top 2 classes
examplesA nested list of sample inputs shown under the formNot set
title, descriptionText above the formThe 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()
  1. On the Spaces page, click Create new Space. Choose a name, an optional license and a visibility, then pick Gradio as the SDK.
  2. Add a file named requirements.txt with two lines, transformers and torch. The Space installs them on every build. It already has gradio, huggingface_hub, requests, datasets and common Debian packages such as ffmpeg. For a system package it lacks, list the name in a packages.txt file, one per line, and the build installs each with apt-get install.
  3. Add app.py with the code above. Thanks to its last two lines, the same file also runs on your machine with python app.py.
  4. Push the files. Spaces are git repositories, so clone yours, commit and push after signing in with hf auth login. Or run gradio deploy in your app folder: it uploads every file there except those .gitignore lists, then starts the Space.
  5. Wait for the build, then open the App tab. Upload a photo and read the two labels it returns.
  6. 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
Variables and secrets as the Spaces overview describes them, read on 5 November 2026.
QuestionVariablesSecrets
Meant forSettings that are not sensitive, such as a model idAccess tokens, API keys and passwords
Who can read the valueAnyone, it is publicNo one, and the settings page hides it once saved
Copied when someone duplicates the SpaceYes, filled in for themNo, they add their own
How the app reads itAs an environment variable, for example with os.getenvThe same way
Daily ZeroGPU time by account typeMinutes of GPU time a visitor can use per day across ZeroGPU Spaces. The PRO, Team and Enterprise quotas can be extended.
  • Signed out2min
  • Free account5min
  • PRO account40min
  • Team member40min
  • Enterprise member60min

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.

Lucain Pouget, Maintainer of huggingface_hub · X (read November 5, 2026)
Lucain Pouget (@Wauplin) on X, 9 July 2026. Quickest way to spin up a complete Space. huggingface_hub v1.23.0 lets you create a Space from an official template, such as JupyterLab or a Gradio chatbot, in just one command. The command is hf repos create my-lab --template jupyterlab. List what is available with hf spaces templates.
Lucain Pouget on X, 9 July 2026
Lysandre (@LysandreJik) on X, 6 June 2025. Selecting any MCP Space through hf.co/mcp to use it in MCP Client is now possible. I see roughly 900 MCP Spaces already, with images (flux), video (ltx), audio, code and more.
Lysandre on X, 6 June 2025

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 no transformers or torch, and the app stops at its first import.
  • Asking for the xlarge GPU size by habit. It burns twice the daily quota of the default large, 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.py first and push once it works.
  • Leaving short_description empty 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_ID set to julien-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

  1. 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.

  2. 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.

  3. 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.

  4. 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

  1. Gradio: Quickstart (read November 5, 2026)https://www.gradio.app/guides/quickstart
  2. Gradio: The Interface class (read November 5, 2026)https://www.gradio.app/guides/the-interface-class
  3. Gradio: Sharing your app (read November 5, 2026)https://www.gradio.app/guides/sharing-your-app
  4. Hugging Face Hub: Spaces overview (read November 5, 2026)https://huggingface.co/docs/hub/spaces-overview
  5. Hugging Face Hub: Gradio Spaces (read November 5, 2026)https://huggingface.co/docs/hub/spaces-sdks-gradio
  6. Hugging Face Hub: Handling Spaces dependencies (read November 5, 2026)https://huggingface.co/docs/hub/spaces-dependencies
  7. Hugging Face Hub: Spaces configuration reference (read November 5, 2026)https://huggingface.co/docs/hub/spaces-config-reference
  8. Hugging Face Hub: Using GPU Spaces (read November 5, 2026)https://huggingface.co/docs/hub/spaces-gpus
  9. Hugging Face Hub: Spaces ZeroGPU (read November 5, 2026)https://huggingface.co/docs/hub/spaces-zerogpu
  10. huggingface_hub: CLI reference (read November 5, 2026)https://huggingface.co/docs/huggingface_hub/package_reference/cli
  11. Hugging Face Hub: HF MCP Server (read November 5, 2026)https://huggingface.co/docs/hub/hf-mcp-server
  12. Lucain Pouget on X: create a Space from a template in huggingface_hub v1.23.0 (read November 5, 2026)https://x.com/Wauplin/status/2075242347760107797
  13. Lysandre on X: MCP Spaces through hf.co/mcp (read November 5, 2026)https://x.com/LysandreJik/status/1931022549221056981

Share this lesson

Browse MCP servers on Mindket

See how others package Python tools as MCP servers, with their setup notes, before you start the MCP course.

Browse MCP servers

This lesson as Markdown · Hugging Face course: find, run and share open models · All courses