File size: 1,459 Bytes
a62cfd3
 
68385f9
 
 
a62cfd3
9cb1768
 
a62cfd3
 
68385f9
 
2d88665
 
 
68385f9
 
a62cfd3
 
 
 
 
 
92499c3
 
 
 
 
 
 
 
 
a62cfd3
 
 
 
 
 
 
9cb1768
 
 
 
 
 
 
 
 
 
 
73a3de2
92499c3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import os

import spaces
import gradio as gr
import torch
from fastapi.staticfiles import StaticFiles
from starlette.responses import FileResponse
from starlette.routing import Route

FRONTEND = os.path.join(os.path.dirname(os.path.abspath(__file__)), "frontend")


@spaces.GPU(duration=30)
def infer(x):
    return f"cuda available: {torch.cuda.is_available()}, got: {x}"


with gr.Blocks() as demo:
    inp, out = gr.Textbox(), gr.Textbox()
    gr.Button("Run").click(infer, inp, out, api_name="infer")

demo.queue()

# demo.launch() is the officially documented ZeroGPU entrypoint — its
# startup hook is what registers @spaces.GPU functions. We keep it (rather
# than gr.mount_gradio_app on our own FastAPI instance) and instead attach
# custom routes/static files onto the live app it hands back.
app, _local_url, _share_url = demo.launch(
    server_name="0.0.0.0",
    server_port=7860,
    prevent_thread_lock=True,
)


@app.get("/api/health")
def health():
    return {"status": "ok"}


app.mount("/static", StaticFiles(directory=FRONTEND), name="static")


async def index(request):
    return FileResponse(os.path.join(FRONTEND, "index.html"))


# Starlette returns the first matching route and Gradio registered its own "/"
# during launch(), so inserting ahead of it hands the root URL to our UI.
# Gradio's API routes stay intact — it just becomes an invisible GPU engine.
app.router.routes.insert(0, Route("/", index))

demo.block_thread()