How to serve an HTML file?
When running Gradio, I am generating an HTML file on the background, that I would like to servein a URL like:https://123455a.gradio.live/output.htmlI was able to generate the file, but when I try to access, I get:{"detail":"Not Found"}What should I do?Thank you
2023-03-16T20:33:34Z
Hi@mandyvarel,That’s a great question. You can’t serve the static pages direct from Gradio, but you can mount Gradio withinanother FastAPI app.Then use the FastAPI app StaticFiles to serve the static pages under/staticand the Gradio app under/.Here is a complete example of how to do that: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 --reloadTo run,python app.pyoruvicorn "app:app" --host "0.0.0.0" --port 7860 --reloadIf you’re running on Colab you need an slightly different approach:Here’s an examplecolab.research.google.comGoogle Colaboratory
2023-03-16T23:30:52Z
Thanks for your explanation Radames.I copied your entire code on a file called app.pyAnd ran the command as you suggesteduvicorn "app:app" --host "0.0.0.0" --port 7860 --reloadI got the following answer: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!
2023-03-16T23:32:31Z
hi@mandyvarel,Your app is now running onhttp://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?
2023-03-17T04:39:07Z
Hi@mandyvarel, I’ve published a live demo here if that helpshuggingface.coGradio Fastapi Static Server - a Hugging Face Space by radamesDiscover amazing ML apps made by the community
2023-03-17T07:59:22Z
Great@radames, I managed to move one step forward and making it run. In your code, you had:if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=7860)I changed to: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 uselaunch(share=True)on gradio?And yes, I am not on Jupyter or Collab. I am on my machine.Thank you
2023-03-17T16:58:26Z
Hi@mandyvareljust chiming in here. So we don’t support share links using this approach (there are other free solutionslike ngrokwhich 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 exactlyhttps://123455a.gradio.live/output.html, then Gradio does allow you to serve static files in the same directory (or child directory) using thehttps://123455a.gradio.live/file=URL prefix. In your case, something like:https://123455a.gradio.live/file=output.htmlwould 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)
2023-03-17T17:43:47Z
amazing@abidlabs, that’s much better, no need to mount Gradio with FastAPI then,here is the solution now with theshare=Truefeature!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)
2023-03-18T06:48:26Z
Yes! Working beautifully! Thank you legends!
2023-06-14T08:32:13Z
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