Spaces:
Runtime error
Runtime error
Support optional shared online-OCR key via env var
Browse files- app.py +15 -1
- static/index.html +14 -7
app.py
CHANGED
|
@@ -10,6 +10,7 @@ and off unless you supply your own API key.
|
|
| 10 |
|
| 11 |
import io
|
| 12 |
import json
|
|
|
|
| 13 |
import asyncio
|
| 14 |
from pathlib import Path
|
| 15 |
|
|
@@ -100,7 +101,12 @@ async def capabilities():
|
|
| 100 |
)
|
| 101 |
except Exception:
|
| 102 |
_CAPABILITIES["handwriting"] = False
|
| 103 |
-
return {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 104 |
|
| 105 |
|
| 106 |
@app.post("/api/upload")
|
|
@@ -129,6 +135,14 @@ async def upload(
|
|
| 129 |
|
| 130 |
# Cheap validations BEFORE buffering the whole upload into memory, so a
|
| 131 |
# request that will be rejected anyway doesn't pay a full file read.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 132 |
if onl and not okey:
|
| 133 |
raise HTTPException(
|
| 134 |
status_code=400,
|
|
|
|
| 10 |
|
| 11 |
import io
|
| 12 |
import json
|
| 13 |
+
import os
|
| 14 |
import asyncio
|
| 15 |
from pathlib import Path
|
| 16 |
|
|
|
|
| 101 |
)
|
| 102 |
except Exception:
|
| 103 |
_CAPABILITIES["handwriting"] = False
|
| 104 |
+
return {
|
| 105 |
+
"handwriting": bool(_CAPABILITIES["handwriting"]),
|
| 106 |
+
# True when this deployment provides a shared Gemini key (a Space secret),
|
| 107 |
+
# so the front-end can offer online OCR without the visitor's own key.
|
| 108 |
+
"online_demo": bool(os.environ.get("DEMO_GEMINI_KEY", "").strip()),
|
| 109 |
+
}
|
| 110 |
|
| 111 |
|
| 112 |
@app.post("/api/upload")
|
|
|
|
| 135 |
|
| 136 |
# Cheap validations BEFORE buffering the whole upload into memory, so a
|
| 137 |
# request that will be rejected anyway doesn't pay a full file read.
|
| 138 |
+
#
|
| 139 |
+
# A deployment may provide a shared demo key via the DEMO_GEMINI_KEY env var
|
| 140 |
+
# (set as a Space secret, never committed to the repo). Fall back to it when
|
| 141 |
+
# the visitor turns on online OCR without supplying their own key, so the
|
| 142 |
+
# hosted demo works out of the box. The user's own key always takes
|
| 143 |
+
# precedence; this only fills in a blank.
|
| 144 |
+
if onl and not okey:
|
| 145 |
+
okey = os.environ.get("DEMO_GEMINI_KEY", "").strip()
|
| 146 |
if onl and not okey:
|
| 147 |
raise HTTPException(
|
| 148 |
status_code=400,
|
static/index.html
CHANGED
|
@@ -32,13 +32,19 @@
|
|
| 32 |
fetch("/api/capabilities")
|
| 33 |
.then(function (r) { return r.json(); })
|
| 34 |
.then(function (caps) {
|
| 35 |
-
if (!caps
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
})
|
| 43 |
.catch(function () {});
|
| 44 |
});
|
|
@@ -180,6 +186,7 @@
|
|
| 180 |
<span class="slider" aria-hidden="true"></span>
|
| 181 |
</label>
|
| 182 |
</div>
|
|
|
|
| 183 |
<div class="setting setting-sub" id="onlineRow" hidden>
|
| 184 |
<label class="setting-label" for="onlineKey">Gemini API key</label>
|
| 185 |
<input type="password" id="onlineKey" class="select online-input" placeholder="paste key from aistudio.google.com" autocomplete="off" spellcheck="false" />
|
|
|
|
| 32 |
fetch("/api/capabilities")
|
| 33 |
.then(function (r) { return r.json(); })
|
| 34 |
.then(function (caps) {
|
| 35 |
+
if (!caps) return;
|
| 36 |
+
if (caps.handwriting === false) {
|
| 37 |
+
var hw = document.getElementById("handwritingToggle");
|
| 38 |
+
if (hw) { hw.checked = false; hw.disabled = true; }
|
| 39 |
+
var row = document.getElementById("handwritingRow");
|
| 40 |
+
if (row) row.classList.add("is-unavailable");
|
| 41 |
+
var note = document.getElementById("hwUnavailable");
|
| 42 |
+
if (note) note.hidden = false;
|
| 43 |
+
}
|
| 44 |
+
if (caps.online_demo === true) {
|
| 45 |
+
var on = document.getElementById("onlineDemoNote");
|
| 46 |
+
if (on) on.hidden = false;
|
| 47 |
+
}
|
| 48 |
})
|
| 49 |
.catch(function () {});
|
| 50 |
});
|
|
|
|
| 186 |
<span class="slider" aria-hidden="true"></span>
|
| 187 |
</label>
|
| 188 |
</div>
|
| 189 |
+
<p class="hint hw-note" id="onlineDemoNote" hidden>This demo includes a Gemini key — just turn this on and leave the key field blank. Or paste your own key to use that instead.</p>
|
| 190 |
<div class="setting setting-sub" id="onlineRow" hidden>
|
| 191 |
<label class="setting-label" for="onlineKey">Gemini API key</label>
|
| 192 |
<input type="password" id="onlineKey" class="select online-input" placeholder="paste key from aistudio.google.com" autocomplete="off" spellcheck="false" />
|