Theflame47 commited on
Commit
a42c87f
·
verified ·
1 Parent(s): c2b54fb

Update Deployment_UI.py

Browse files
Files changed (1) hide show
  1. Deployment_UI.py +21 -40
Deployment_UI.py CHANGED
@@ -31,17 +31,14 @@ def deployment_ui_page():
31
  .thumb { max-width: 420px; border:1px solid #ccc; border-radius:6px; }
32
  .meta { font-size:12px; color:#555; margin-top:4px; }
33
  .download { display:inline-block; margin-top:6px; }
34
-
35
  /* Blob row (new, minimal) */
36
  #blob-bar { display:flex; gap:8px; margin:0 0 10px; align-items:center; }
37
  #blob-url { flex:1; padding:8px; border:1px solid #ccc; border-radius:8px; }
38
  #blob-load, #blob-ingest { padding:8px 12px; border:1px solid #ccc; border-radius:8px; background:#f7f7f7; cursor:pointer; }
39
  #blob-load:hover, #blob-ingest:hover { background:#eee; }
40
  #blob-status { font-size:12px; color:#555; }
41
-
42
  /* Blob preview box styled like logs/results */
43
  #blob-preview { border:1px solid #ddd; border-radius:8px; padding:10px; background:#fff; font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; font-size:12px; max-height:220px; overflow:auto; margin-bottom:10px; }
44
-
45
  /* loading mask */
46
  #boot-mask{position:fixed;inset:0;background:rgba(255,255,255,.85);display:none;
47
  align-items:center;justify-content:center;flex-direction:column;z-index:9999}
@@ -53,7 +50,6 @@ def deployment_ui_page():
53
  </head>
54
  <body>
55
  <a href="/trythis" class="button">← Back</a>
56
-
57
  <!-- New: Blob tools row (keeps your visual rhythm) -->
58
  <div id="blob-bar">
59
  <input id="blob-url" type="text" placeholder="/modelblob.json" />
@@ -62,7 +58,6 @@ def deployment_ui_page():
62
  <div id="blob-status"></div>
63
  </div>
64
  <pre id="blob-preview" aria-live="polite" style="display:none;"></pre>
65
-
66
  <div id="chat-window"></div>
67
  <div id="input-area">
68
  <input type="text" id="user-input" placeholder="Describe an image to generate…" />
@@ -94,15 +89,13 @@ def deployment_ui_page():
94
  const chat = document.getElementById('chat-window');
95
  const bootMask = document.getElementById('boot-mask');
96
  const bootMsg = document.getElementById('boot-msg');
97
-
98
  // New blob controls
99
  const blobUrl = document.getElementById('blob-url');
100
  const blobLoad = document.getElementById('blob-load');
101
  const blobIngest = document.getElementById('blob-ingest');
102
  const blobStatus = document.getElementById('blob-status');
103
  const blobPreview = document.getElementById('blob-preview');
104
-
105
- let running = false, ready = false;
106
  let MODEL_BASE = null, PREDICT_ROUTE = null;
107
 
108
  // Maintain your existing auto-ingest-on-load behavior (unchanged)
@@ -121,6 +114,7 @@ def deployment_ui_page():
121
  function showBoot(msg){ bootMsg.textContent = msg || 'Starting…'; bootMask.style.display = 'flex'; }
122
  function setBoot(msg){ bootMsg.textContent = msg || 'Working…'; }
123
  function hideBoot(){ bootMask.style.display = 'none'; }
 
124
  function log(msg, cls='log-raw') {
125
  const line = document.createElement('div');
126
  line.className = 'log-line ' + cls;
@@ -128,6 +122,7 @@ def deployment_ui_page():
128
  logs.appendChild(line);
129
  logs.scrollTop = logs.scrollHeight;
130
  }
 
131
  toggleBtn.addEventListener('click', () => {
132
  const collapsed = logs.classList.toggle('collapsed');
133
  toggleBtn.textContent = collapsed ? "Show Logs" : "Hide Logs";
@@ -139,6 +134,7 @@ def deployment_ui_page():
139
  log(text, r.ok ? 'log-ok' : 'log-err');
140
  try { return { ok: r.ok, json: JSON.parse(text) }; } catch { return { ok: r.ok, json: { _raw: text } }; }
141
  }
 
142
  async function del(path) {
143
  const r = await fetch(path, { method: 'DELETE' });
144
  const text = await r.text();
@@ -189,24 +185,28 @@ def deployment_ui_page():
189
  blobLoad.addEventListener('click', loadBlob);
190
  blobIngest.addEventListener('click', ingestBlob);
191
 
192
- // create + wait for true readiness (isReady)
193
  async function begin() {
194
  if (running) return;
195
- running = true; ready = false;
196
  showBoot('Creating instance…');
197
  const create = await post('/api/compute/create_instance');
198
- if (!create.ok) { running = false; hideBoot(); return; }
199
- const ok = await ensureReady(true);
200
  hideBoot();
 
 
 
201
  }
 
202
  async function stopOnce() {
203
  await del('/api/compute/delete_instance');
204
- hideBoot(); setBoot(''); ready = false; running = false;
205
  }
 
206
  async function endAll() {
207
  await stopOnce();
208
  MODEL_BASE = null; PREDICT_ROUTE = null;
209
  }
 
210
  function appendResult(job_id, b64, timings) {
211
  const div = document.createElement('div'); div.className = 'result';
212
  const img = document.createElement('img'); img.className = 'thumb'; img.src = 'data:image/png;base64,' + b64;
@@ -214,7 +214,9 @@ def deployment_ui_page():
214
  const meta = document.createElement('div'); meta.className = 'meta'; meta.textContent = `job ${job_id} | ${JSON.stringify(timings || {})}`;
215
  div.append(img, document.createTextNode(' '), a, meta); results.prepend(div);
216
  }
 
217
  function escapeHtml(s){ return String(s).replace(/[&<>"']/g, m => ({ '&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;' }[m])); }
 
218
  function addBlock(sender, html) {
219
  const wrap = document.createElement('div');
220
  wrap.style.margin = '8px 0';
@@ -223,8 +225,10 @@ def deployment_ui_page():
223
  chat.scrollTop = chat.scrollHeight;
224
  return wrap;
225
  }
 
226
  function addUser(text) { return addBlock('You', `<div>${escapeHtml(text)}</div>`); }
227
  function addModel(text) { return addBlock('Model', `<div>${escapeHtml(text)}</div>`); }
 
228
  function addModelImg(b64){
229
  const wrap = addBlock('Model', '');
230
  const img = document.createElement('img');
@@ -233,37 +237,13 @@ def deployment_ui_page():
233
  wrap.lastElementChild.appendChild(img);
234
  return wrap;
235
  }
 
236
  function addLoader() {
237
  const wrap = addBlock('Model', `<div id="spinner" style="display:inline-block">Loading…</div>`);
238
  return wrap;
239
  }
240
- function looksBase64(s){ return /^[A-Za-z0-9+/=\\s]+$/.test(s||'') && String(s||'').length > 100; }
241
 
242
- // poll for true readiness (kept identical to your flow)
243
- async function ensureReady(verbose=false) {
244
- for (let i = 0; i < 60; i++) {
245
- const r = await fetch('/api/compute/wait_instance');
246
- const j = await r.json();
247
- const cs = j.cachedState || {};
248
- const status = (cs.status || '').toUpperCase();
249
- if (verbose) {
250
- if (cs.isReady === true) setBoot('Ready');
251
- else if (status === 'RUNNING' && cs.base) setBoot('Warming model…');
252
- else setBoot(`Status: ${status || '…'}`);
253
- }
254
- if (cs.base && cs.predictRoute && cs.isReady === true) {
255
- MODEL_BASE = cs.base;
256
- PREDICT_ROUTE = cs.predictRoute.startsWith('/') ? cs.predictRoute : `/${cs.predictRoute}`;
257
- log(`PROMPT_ENDPOINT ${MODEL_BASE}${PREDICT_ROUTE}`, 'log-ok');
258
- ready = true;
259
- return true;
260
- }
261
- log(`READY_POLL base=${cs.base ? 'yes' : 'no'} route=${cs.predictRoute || ''} isReady=${cs.isReady === true} status=${status}`, 'log-raw');
262
- await new Promise(res => setTimeout(res, 1000));
263
- }
264
- ready = false;
265
- return false;
266
- }
267
 
268
  // backend hop for prompts
269
  async function sendViaBackend(prompt) {
@@ -276,10 +256,11 @@ def deployment_ui_page():
276
  log(`POST /api/middleware/infer → ${r.status}`, r.ok ? 'log-ok' : 'log-err');
277
  try { return { ok: r.ok, json: JSON.parse(text) }; } catch { return { ok: r.ok, json: { _raw: text } }; }
278
  }
 
279
  async function sendMessage() {
280
  const prompt = (userInput.value || '').trim();
281
  if (!prompt) return;
282
- if (!ready) { addModel('Instance not ready yet. Try Start, or wait a moment.'); return; }
283
  addUser(prompt);
284
  const loader = addLoader();
285
  userInput.disabled = true;
 
31
  .thumb { max-width: 420px; border:1px solid #ccc; border-radius:6px; }
32
  .meta { font-size:12px; color:#555; margin-top:4px; }
33
  .download { display:inline-block; margin-top:6px; }
 
34
  /* Blob row (new, minimal) */
35
  #blob-bar { display:flex; gap:8px; margin:0 0 10px; align-items:center; }
36
  #blob-url { flex:1; padding:8px; border:1px solid #ccc; border-radius:8px; }
37
  #blob-load, #blob-ingest { padding:8px 12px; border:1px solid #ccc; border-radius:8px; background:#f7f7f7; cursor:pointer; }
38
  #blob-load:hover, #blob-ingest:hover { background:#eee; }
39
  #blob-status { font-size:12px; color:#555; }
 
40
  /* Blob preview box styled like logs/results */
41
  #blob-preview { border:1px solid #ddd; border-radius:8px; padding:10px; background:#fff; font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; font-size:12px; max-height:220px; overflow:auto; margin-bottom:10px; }
 
42
  /* loading mask */
43
  #boot-mask{position:fixed;inset:0;background:rgba(255,255,255,.85);display:none;
44
  align-items:center;justify-content:center;flex-direction:column;z-index:9999}
 
50
  </head>
51
  <body>
52
  <a href="/trythis" class="button">← Back</a>
 
53
  <!-- New: Blob tools row (keeps your visual rhythm) -->
54
  <div id="blob-bar">
55
  <input id="blob-url" type="text" placeholder="/modelblob.json" />
 
58
  <div id="blob-status"></div>
59
  </div>
60
  <pre id="blob-preview" aria-live="polite" style="display:none;"></pre>
 
61
  <div id="chat-window"></div>
62
  <div id="input-area">
63
  <input type="text" id="user-input" placeholder="Describe an image to generate…" />
 
89
  const chat = document.getElementById('chat-window');
90
  const bootMask = document.getElementById('boot-mask');
91
  const bootMsg = document.getElementById('boot-msg');
 
92
  // New blob controls
93
  const blobUrl = document.getElementById('blob-url');
94
  const blobLoad = document.getElementById('blob-load');
95
  const blobIngest = document.getElementById('blob-ingest');
96
  const blobStatus = document.getElementById('blob-status');
97
  const blobPreview = document.getElementById('blob-preview');
98
+ let running = false;
 
99
  let MODEL_BASE = null, PREDICT_ROUTE = null;
100
 
101
  // Maintain your existing auto-ingest-on-load behavior (unchanged)
 
114
  function showBoot(msg){ bootMsg.textContent = msg || 'Starting…'; bootMask.style.display = 'flex'; }
115
  function setBoot(msg){ bootMsg.textContent = msg || 'Working…'; }
116
  function hideBoot(){ bootMask.style.display = 'none'; }
117
+
118
  function log(msg, cls='log-raw') {
119
  const line = document.createElement('div');
120
  line.className = 'log-line ' + cls;
 
122
  logs.appendChild(line);
123
  logs.scrollTop = logs.scrollHeight;
124
  }
125
+
126
  toggleBtn.addEventListener('click', () => {
127
  const collapsed = logs.classList.toggle('collapsed');
128
  toggleBtn.textContent = collapsed ? "Show Logs" : "Hide Logs";
 
134
  log(text, r.ok ? 'log-ok' : 'log-err');
135
  try { return { ok: r.ok, json: JSON.parse(text) }; } catch { return { ok: r.ok, json: { _raw: text } }; }
136
  }
137
+
138
  async function del(path) {
139
  const r = await fetch(path, { method: 'DELETE' });
140
  const text = await r.text();
 
185
  blobLoad.addEventListener('click', loadBlob);
186
  blobIngest.addEventListener('click', ingestBlob);
187
 
188
+ // create instance (no readiness gating)
189
  async function begin() {
190
  if (running) return;
191
+ running = true;
192
  showBoot('Creating instance…');
193
  const create = await post('/api/compute/create_instance');
 
 
194
  hideBoot();
195
+ if (!create.ok) {
196
+ running = false;
197
+ }
198
  }
199
+
200
  async function stopOnce() {
201
  await del('/api/compute/delete_instance');
202
+ hideBoot(); setBoot(''); running = false;
203
  }
204
+
205
  async function endAll() {
206
  await stopOnce();
207
  MODEL_BASE = null; PREDICT_ROUTE = null;
208
  }
209
+
210
  function appendResult(job_id, b64, timings) {
211
  const div = document.createElement('div'); div.className = 'result';
212
  const img = document.createElement('img'); img.className = 'thumb'; img.src = 'data:image/png;base64,' + b64;
 
214
  const meta = document.createElement('div'); meta.className = 'meta'; meta.textContent = `job ${job_id} | ${JSON.stringify(timings || {})}`;
215
  div.append(img, document.createTextNode(' '), a, meta); results.prepend(div);
216
  }
217
+
218
  function escapeHtml(s){ return String(s).replace(/[&<>"']/g, m => ({ '&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;' }[m])); }
219
+
220
  function addBlock(sender, html) {
221
  const wrap = document.createElement('div');
222
  wrap.style.margin = '8px 0';
 
225
  chat.scrollTop = chat.scrollHeight;
226
  return wrap;
227
  }
228
+
229
  function addUser(text) { return addBlock('You', `<div>${escapeHtml(text)}</div>`); }
230
  function addModel(text) { return addBlock('Model', `<div>${escapeHtml(text)}</div>`); }
231
+
232
  function addModelImg(b64){
233
  const wrap = addBlock('Model', '');
234
  const img = document.createElement('img');
 
237
  wrap.lastElementChild.appendChild(img);
238
  return wrap;
239
  }
240
+
241
  function addLoader() {
242
  const wrap = addBlock('Model', `<div id="spinner" style="display:inline-block">Loading…</div>`);
243
  return wrap;
244
  }
 
245
 
246
+ function looksBase64(s){ return /^[A-Za-z0-9+/=\\s]+$/.test(s||'') && String(s||'').length > 100; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
 
248
  // backend hop for prompts
249
  async function sendViaBackend(prompt) {
 
256
  log(`POST /api/middleware/infer → ${r.status}`, r.ok ? 'log-ok' : 'log-err');
257
  try { return { ok: r.ok, json: JSON.parse(text) }; } catch { return { ok: r.ok, json: { _raw: text } }; }
258
  }
259
+
260
  async function sendMessage() {
261
  const prompt = (userInput.value || '').trim();
262
  if (!prompt) return;
263
+
264
  addUser(prompt);
265
  const loader = addLoader();
266
  userInput.disabled = true;