File size: 2,411 Bytes
d4ec2fa
 
 
 
 
 
 
 
 
 
1068073
d4ec2fa
6650681
 
d4ec2fa
 
 
1068073
 
 
 
 
 
 
 
 
 
 
 
d4ec2fa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15209d2
 
 
 
 
 
 
 
d4ec2fa
 
 
 
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
54
55
56
57
58
59
60
61
62
63
"""
Fallback entrypoint for Hugging Face Spaces using the Gradio SDK instead of Docker.
Mounts the EXACT SAME FastAPI app (api/main.py, unchanged) inside a minimal Gradio
wrapper -- every route (/classify, /search, /corrections, /ask, /stats,
/model-performance, /health) works identically, just served through Gradio's app
object instead of raw uvicorn+Docker.

Only used if the Docker SDK isn't available for free on the account -- otherwise
the Dockerfile path is simpler and preferred.
"""
import spaces

import gradio as gr

from api.main import app as fastapi_app


@spaces.GPU
def _zerogpu_placeholder():
    """
    Required by Hugging Face's ZeroGPU Spaces: at least one @spaces.GPU-decorated
    function must exist for the Space to start, even though this app runs entirely
    on CPU (DistilBERT/MiniLM inference at our scale doesn't need a GPU at all).
    This function is never called by any real request path -- it exists purely to
    satisfy that platform startup check.
    """
    return "not used -- this app runs on CPU only"


def status_check():
    import requests
    try:
        resp = requests.get("http://localhost:7860/health", timeout=5)
        return resp.json()
    except Exception as e:
        return {"error": str(e)}


with gr.Blocks(title="Maintenance Log Classifier API") as demo:
    gr.Markdown("""
    # Maintenance Log Classifier — API
    This Space hosts the backend API only. The real frontend is deployed separately.

    API docs: [/docs](/docs) (FastAPI's auto-generated interactive docs)

    Endpoints: `/classify`, `/search`, `/corrections`, `/ask`, `/stats`, `/model-performance`, `/health`
    """)
    check_btn = gr.Button("Check API health")
    output = gr.JSON()
    check_btn.click(fn=status_check, outputs=output)

    # Wired into the Blocks graph (not just defined standalone) so ZeroGPU's
    # startup detector actually finds this @spaces.GPU function. Hidden since
    # it's not meant for real use -- this app runs entirely on CPU.
    with gr.Row(visible=False):
        gpu_check_btn = gr.Button("_zerogpu_placeholder")
        gpu_output = gr.Textbox()
        gpu_check_btn.click(fn=_zerogpu_placeholder, outputs=gpu_output)


# This is the key line: mount the real FastAPI app (all our actual routes) at the
# root path, with Gradio's own UI living at /gradio instead of /.
app = gr.mount_gradio_app(fastapi_app, demo, path="/gradio")