m-newhauser's picture
Upload folder using huggingface_hub
b3f34c3 verified
Raw
History Blame Contribute Delete
2.76 kB
"""GLiNER 2.5 demo server — identical for every demo.
Serves the static page, answers /api/ready, and POSTs {text, ...} to /api/infer,
which it delegates to model.infer(). All demo-specific logic lives in model.py.
python app.py # local dev on :7860
"""
import os
import threading
import time
from flask import Flask, request, send_from_directory
import model
APP_DIR = os.path.dirname(os.path.abspath(__file__))
STATIC = os.path.join(APP_DIR, "static")
# Shared kit-wide assets live in gliner2.5-demo-kit/assets/. Demo-local overrides
# can be dropped in demos/<name>/static/assets/ and win over shared files of the
# same name. URL space is the same: GET /assets/<rel>.
KIT_ASSETS = os.path.abspath(os.path.join(APP_DIR, "..", "..", "assets"))
_LOCK = threading.Lock() # one inference at a time: CPU threads beat concurrency
print(f"[boot] {model.DEMO['title']} — mock={model.MOCK}", flush=True)
model.warmup() # load model / validate fixtures before first request
print("[boot] ready", flush=True)
app = Flask(__name__)
@app.route("/")
def index():
return send_from_directory(STATIC, "index.html")
@app.route("/<path:name>")
def static_file(name):
# Shared chrome + demo assets. Anything in static/assets/ is served from the
# demo-local dir first; falls back to kit-root assets/ for shared files.
if name in ("brand.css", "strip.js", "favicon.svg", "og-card.png"):
return send_from_directory(STATIC, name)
if name.startswith("assets/"):
rel = name[len("assets/"):]
demo_local = os.path.join(STATIC, "assets", rel)
if os.path.isfile(demo_local):
return send_from_directory(os.path.join(STATIC, "assets"), rel)
kit_shared = os.path.join(KIT_ASSETS, rel)
if os.path.isfile(kit_shared):
return send_from_directory(KIT_ASSETS, rel)
return ("not found", 404)
return ("not found", 404)
@app.route("/api/config")
def config():
"""Demo content for the page: title, subtitle, example chips. No results.
Demos whose examples carry derived fields (inlined texts, result previews)
expose model.config(); others are served straight from model.DEMO."""
cfg = model.config() if hasattr(model, "config") else model.DEMO
return {k: v for k, v in cfg.items() if k != "internal"}
@app.route("/api/ready")
def ready():
return {"ready": True}
@app.route("/api/infer", methods=["POST"])
def infer():
data = request.get_json(silent=True) or {}
t0 = time.perf_counter()
with _LOCK:
out = model.infer(data)
out["ms"] = round((time.perf_counter() - t0) * 1000)
return out
if __name__ == "__main__":
app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 7860)), threaded=True)