# How to serve an HTML file?

**URL:** </static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-to-serve-an-html-file%2F33921%3E%5C
**Category:** 🔒 Gradio\
**Created:** [March 16, 2023, 7:40am UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-to-serve-an-html-file%2F33921 "2023-03-16T07:40:42Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![mandyvarel](https://sea2.discourse-cdn.com/hellohellohello/user_avatar/discuss.huggingface.co/mandyvarel/32/14755_2.png) [@mandyvarel](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fmandyvarel)%5C
**Post date:** [March 16, 2023, 7:40am UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-to-serve-an-html-file%2F33921%2F1 "2023-03-16T07:40:42Z")

</div>

When running Gradio, I am generating an HTML file on the background, that I would like to serve  
in a URL like: [https://123455a.gradio.live/output.html](https://123455a.gradio.live/output.html)

I was able to generate the file, but when I try to access, I get:

```auto
{"detail":"Not Found"}

```

What should I do?

Thank you

---

<div class="post-metadata">

**Author:** ![radames](https://sea2.discourse-cdn.com/hellohellohello/user_avatar/discuss.huggingface.co/radames/32/28246_2.png) [@radames](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fradames)%5C
**Post date:** [March 16, 2023, 8:33pm UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-to-serve-an-html-file%2F33921%2F2 "2023-03-16T20:33:34Z")

</div>

Hi @mandyvarel ,

That’s a great question. You can’t serve the static pages direct from Gradio, but you can mount Gradio within [another FastAPI app](https://gradio.app/sharing-your-app/#mounting-within-another-fastapi-app).  
Then use the FastAPI app StaticFiles to serve the static pages under `/static` and the Gradio app under `/`.

Here is a complete example of how to do that:

```python
from pathlib import Path
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
import uvicorn
import gradio as gr
from datetime import datetime

# create a FastAPI app
app = FastAPI()

# create a static directory to store the static files
static_dir = Path('./static')
static_dir.mkdir(parents=True, exist_ok=True)

# mount FastAPI StaticFiles server
app.mount("/static", StaticFiles(directory=static_dir), name="static")

# Gradio code
def predict(text_input):
    file_name = f"{datetime.utcnow().strftime('%s')}.html"
    file_path = static_dir / file_name
    print(file_path)
    with open(file_path, "w") as f:
        f.write(f"""<h2>Hello {text_input} </h2>
        <h3>{file_name}</h3>
        """)

    return f'<a href="/static/{file_name}" target="_blank">{file_name}</a>'

with gr.Blocks() as block:
    text_input = gr.Textbox(label="Name")
    markdown = gr.Markdown(label="Output Box")
    new_btn = gr.Button("New")
    new_btn.click(fn=predict, inputs=[text_input], outputs=[markdown])

# mount Gradio app to FastAPI app
app = gr.mount_gradio_app(app, block, path="/")

# serve the app
if __name__ == " __main__":
    uvicorn.run(app, host="0.0.0.0", port=7860)

# run the app with
# python app.py
# or
# uvicorn "app:app" --host "0.0.0.0" --port 7860 --reload

```

To run,

```shell
python app.py

```

or

```shell
uvicorn "app:app" --host "0.0.0.0" --port 7860 --reload

```

If you’re running on Colab you need an slightly different approach:

Here’s an example

> **[Google Colaboratory](https://colab.research.google.com/drive/1MzOckfJHs9fw3CEUthof6_qLPRZZBN2a)**

---

<div class="post-metadata">

**Author:** ![mandyvarel](https://sea2.discourse-cdn.com/hellohellohello/user_avatar/discuss.huggingface.co/mandyvarel/32/14755_2.png) [@mandyvarel](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fmandyvarel)%5C
**Post date:** [March 16, 2023, 11:30pm UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-to-serve-an-html-file%2F33921%2F3 "2023-03-16T23:30:52Z")

</div>

Thanks for your explanation Radames.  
I copied your entire code on a file called app.py  
And ran the command as you suggested

`uvicorn "app:app" --host "0.0.0.0" --port 7860 --reload`

I got the following answer:

```auto

INFO: Uvicorn running on http://0.0.0.0:7860 (Press CTRL+C to quit)
INFO: Started reloader process [4637] using StatReload
Starting to load FastAPI app...
INFO: Started server process [4639]
INFO: Waiting for application startup.
INFO: Application startup complete.

```

But, I couldn’t access the app anywhere. As it didn’t offer me a local or remote address. What am I doing wrong?

Thanks!

---

<div class="post-metadata">

**Author:** ![radames](https://sea2.discourse-cdn.com/hellohellohello/user_avatar/discuss.huggingface.co/radames/32/28246_2.png) [@radames](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fradames)%5C
**Post date:** [March 16, 2023, 11:32pm UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-to-serve-an-html-file%2F33921%2F4 "2023-03-16T23:32:31Z")

</div>

hi @mandyvarel,

Your app is now running on [http://0.0.0.0:7860](http://0.0.0.0:7860) , can you try open that link on your browser?  
Just to double check, you’re not on colab/jupyter but on your localmachine right?

---

<div class="post-metadata">

**Author:** ![radames](https://sea2.discourse-cdn.com/hellohellohello/user_avatar/discuss.huggingface.co/radames/32/28246_2.png) [@radames](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fradames)%5C
**Post date:** [March 17, 2023, 4:39am UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-to-serve-an-html-file%2F33921%2F5 "2023-03-17T04:39:07Z")

</div>

Hi @mandyvarel , I’ve published a live demo here if that helps

> **[Gradio Fastapi Static Server - a Hugging Face Space by radames](https://huggingface.co/spaces/radames/gradio-fastapi-static-server)**
>
> Discover amazing ML apps made by the community

---

<div class="post-metadata">

**Author:** ![mandyvarel](https://sea2.discourse-cdn.com/hellohellohello/user_avatar/discuss.huggingface.co/mandyvarel/32/14755_2.png) [@mandyvarel](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fmandyvarel)%5C
**Post date:** [March 17, 2023, 7:59am UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-to-serve-an-html-file%2F33921%2F6 "2023-03-17T07:59:22Z")

</div>

Great @radames, I managed to move one step forward and making it run. In your code, you had:

```auto
if __name__ == " __main__":
    uvicorn.run(app, host="0.0.0.0", port=7860)

```

I changed to:

```auto
if __name__ == " __main__":
    uvicorn.run(app, host="127.0.0.1", port=7862)

```

And it’s working. Locally (never worked with 0.0.0.0)  
Now, the question, can I make this work with the automatic external address creation? Like it works when I use `launch(share=True)` on gradio?

And yes, I am not on Jupyter or Collab. I am on my machine.

Thank you

---

<div class="post-metadata">

**Author:** ![abidlabs](https://sea2.discourse-cdn.com/hellohellohello/user_avatar/discuss.huggingface.co/abidlabs/32/21878_2.png) [@abidlabs](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fabidlabs)%5C
**Post date:** [March 17, 2023, 4:58pm UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-to-serve-an-html-file%2F33921%2F7 "2023-03-17T16:58:26Z")

</div>

Hi @mandyvarel just chiming in here. So we don’t support share links using this approach (there are other free solutions [like ngrok](https://ngrok.com/) which can allow you create a public link for any arbitrary local server you could try)

But I wanted to potentially suggest a simpler solution. If you do not need the URL to be exactly [https://123455a.gradio.live/output.html](https://123455a.gradio.live/output.html), then Gradio does allow you to serve static files in the same directory (or child directory) using the [https://123455a.gradio.live/file=](https://123455a.gradio.live/file=) URL prefix. In your case, something like: [https://123455a.gradio.live/file=output.html](https://123455a.gradio.live/file=output.html) would produce the HTML file. (This approach means that you wouldn’t have to mount Gradio at all and should work locally and using the share links)

---

<div class="post-metadata">

**Author:** ![radames](https://sea2.discourse-cdn.com/hellohellohello/user_avatar/discuss.huggingface.co/radames/32/28246_2.png) [@radames](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fradames)%5C
**Post date:** [March 17, 2023, 5:43pm UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-to-serve-an-html-file%2F33921%2F8 "2023-03-17T17:43:47Z")

</div>

amazing @abidlabs, that’s much better, no need to mount Gradio with FastAPI then,

here is the solution now with the `share=True` feature!

```python
from pathlib import Path
import gradio as gr
from datetime import datetime
import sys

# create a static directory to store the static files
static_dir = Path('./static')
static_dir.mkdir(parents=True, exist_ok=True)

def predict(text_input):
    file_name = f"{datetime.utcnow().strftime('%s')}.html"
    file_path = static_dir / file_name
    print(file_path)
    with open(file_path, "w") as f:
        f.write(f"""
        <script src="https://cdn.tailwindcss.com"></script>
        <body class="bg-gray-200 dark:text-white dark:bg-gray-900">
        <h1 class="text-3xl font-bold">
        Hello <i>{text_input}</i> From Gradio Iframe
        </h1>
        <h3>Filename: {file_name}</h3>
        """)
    iframe = f"""<iframe src="file={file_path}" width="100%" height="500px"></iframe>"""
    link = f'<a href="file={file_path}" target="_blank">{file_name}</a>'
    return link, iframe

with gr.Blocks() as block:
    gr.Markdown("""
## Gradio + FastAPI + Static Server
This is a demo of how to use Gradio with FastAPI and a static server.
The Gradio app generates dynamic HTML files and stores them in a static directory. FastAPI serves the static files.
""")
    with gr.Row():
        with gr.Column():
            text_input = gr.Textbox(label="Name")
            markdown = gr.Markdown(label="Output Box")
            new_btn = gr.Button("New")
        with gr.Column():
            html = gr.HTML(label="HTML preview", show_label=True)

    new_btn.click(fn=predict, inputs=[text_input], outputs=[markdown, html])

block.launch(debug=True, share=True)

```

---

<div class="post-metadata">

**Author:** ![mandyvarel](https://sea2.discourse-cdn.com/hellohellohello/user_avatar/discuss.huggingface.co/mandyvarel/32/14755_2.png) [@mandyvarel](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fmandyvarel)%5C
**Post date:** [March 18, 2023, 6:48am UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-to-serve-an-html-file%2F33921%2F9 "2023-03-18T06:48:26Z")

</div>

Yes! Working beautifully! Thank you legends!

---

<div class="post-metadata">

**Author:** ![manel00](https://avatars.discourse-cdn.com/v4/letter/m/e480ec/32.png) [@manel00](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fmanel00)%5C
**Post date:** [June 14, 2023, 8:32am UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-to-serve-an-html-file%2F33921%2F10 "2023-06-14T08:32:13Z")

</div>

Hello, I am curious, is it possible to show it on a gr.HTML? (With tailwind and so on?) I’ve already tried it but I could not, thank you!

Regards
