@@ -329,194 +329,11 @@ This lab assumes:
329329 < /copy>
330330 ` ` `
331331
332- 2. Create ` ~/image-search-lab/templates/ index.html` with the following code :
332+ 2. Open a terminal and run the following command to copy the ` index.html` to the templates folder :
333333
334- ` ` ` html
334+ ` ` ` bash
335335 < copy>
336- < ! doctype html>
337- < html lang=" en" >
338- < head>
339- < meta charset=" utf-8" />
340- < meta name=" viewport" content=" width=device-width, initial-scale=1" />
341- < title> Private AI CLIP Image Search< /title>
342- < style>
343- :root {
344- --bg: # f3f5f7;
345- --panel: # ffffff;
346- --ink: # 111827;
347- --muted: # 4b5563;
348- --accent: # c74634;
349- --line: # e5e7eb;
350- --ok: # 0f766e;
351- --err: # b91c1c;
352- }
353- body {
354- margin: 0;
355- font-family: " Segoe UI" , " Noto Sans" , sans-serif;
356- background: var(--bg);
357- color: var(--ink);
358- }
359- .wrap {
360- max-width: 1200px;
361- margin: 0 auto;
362- padding: 24px;
363- }
364- .hero {
365- background: linear-gradient(120deg, # fff 0%, #f9e9e7 100%);
366- border: 1px solid var(--line);
367- border-radius: 16px;
368- padding: 20px;
369- margin-bottom: 16px;
370- }
371- .hero h1 { margin: 0 0 8px 0; }
372- .hero p { margin: 4px 0; color: var(--muted); }
373- .row {
374- display: grid;
375- grid-template-columns: 1fr 1fr;
376- gap: 16px;
377- margin-bottom: 16px;
378- }
379- .panel {
380- background: var(--panel);
381- border: 1px solid var(--line);
382- border-radius: 12px;
383- padding: 16px;
384- }
385- label {
386- display: block;
387- font-size: 12px;
388- color: var(--muted);
389- margin-bottom: 6px;
390- text-transform: uppercase;
391- letter-spacing: 0.03em;
392- }
393- input[type= " text" ] {
394- width: 100%;
395- box-sizing: border-box;
396- padding: 10px 12px;
397- border: 1px solid # cbd5e1;
398- border-radius: 8px;
399- margin-bottom: 10px;
400- }
401- .btn {
402- border: 0;
403- border-radius: 8px;
404- padding: 10px 14px;
405- cursor: pointer;
406- background: var(--accent);
407- color: # fff;
408- font-weight: 600;
409- }
410- .btn.secondary {
411- background: # 111827;
412- }
413- .flash {
414- border-radius: 8px;
415- padding: 10px 12px;
416- margin-bottom: 10px;
417- font-size: 14px;
418- }
419- .flash.success { background: # ecfeff; color: var(--ok); border: 1px solid #99f6e4; }
420- .flash.error { background: # fff1f2; color: var(--err); border: 1px solid #fecdd3; }
421- .meta {
422- display: flex;
423- gap: 16px;
424- flex-wrap: wrap;
425- color: var(--muted);
426- font-size: 14px;
427- }
428- .grid {
429- display: grid;
430- grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
431- gap: 12px;
432- margin-top: 14px;
433- }
434- .card {
435- border: 1px solid var(--line);
436- border-radius: 10px;
437- overflow: hidden;
438- background: # fff;
439- }
440- .card img {
441- width: 100%;
442- height: 180px;
443- object-fit: cover;
444- display: block;
445- background: # f8fafc;
446- }
447- .card .body {
448- padding: 10px;
449- font-size: 13px;
450- }
451- .small { color: var(--muted); font-size: 12px; }
452- @media (max-width: 900px) {
453- .row { grid-template-columns: 1fr; }
454- }
455- < /style>
456- < /head>
457- < body>
458- < div class=" wrap" >
459- < div class=" hero" >
460- < h1> Private AI CLIP Image Search< /h1>
461- < p> Image embeddings model: < b> {{ image_model_id }}< /b></p>
462- < p> Text embeddings model: < b> {{ text_model_id }}< /b></p>
463- < div class=" meta" >
464- < div> Total indexed images: < b> {{ total_images }}< /b></div>
465- < div> Top-K results: < b> 10< /b></div>
466- < /div>
467- < /div>
468-
469- {% with messages = get_flashed_messages(with_categories=true) %}
470- {% if messages %}
471- {% for category, msg in messages %}
472- < div class=" flash {{ category }}" > {{ msg }}< /div>
473- {% endfor %}
474- {% endif %}
475- {% endwith %}
476-
477- < div class=" row" >
478- < div class=" panel" >
479- < h3> 1) Load Image Library into Database< /h3>
480- < form method=" post" >
481- < input type=" hidden" name=" action" value=" load" />
482- < label> Image Root Directory< /label>
483- < input type=" text" name=" image_root" value=" {{ default_image_root }}" />
484- < button class=" btn" type=" submit" > Load + Embed Images< /button>
485- < /form>
486- < /div>
487-
488- < div class=" panel" >
489- < h3> 2) Search by Text< /h3>
490- < form method=" post" >
491- < input type=" hidden" name=" action" value=" search" />
492- < label> Query< /label>
493- < input type=" text" name=" query" value=" {{ query }}" placeholder=" e.g. old ship in ocean storm" />
494- < button class=" btn secondary" type=" submit" > Search Top 10< /button>
495- < /form>
496- < /div>
497- < /div>
498-
499- {% if results %}
500- < div class=" panel" >
501- < h3> Search Results< /h3>
502- < p class=" small" > Query: < b> {{ query }}< /b></p>
503- < div class=" grid" >
504- {% for r in results %}
505- < div class=" card" >
506- < img src=" {{ r.data_uri }}" alt=" {{ r.filename }}" />
507- < div class=" body" >
508- < div><b> {{ r.filename }}< /b></div>
509- < div class=" small" > Category: {{ r.category }}< /div>
510- < div class=" small" > Similarity: {{ r.similarity }}< /div>
511- < /div>
512- < /div>
513- {% endfor %}
514- < /div>
515- < /div>
516- {% endif %}
517- < /div>
518- < /body>
519- < /html>
336+ curl -fsSL " https://raw.githubusercontent.com/oracle-livelabs/developer/main/private-ai-services-container/lab4-flask-image-search/files/templates/index.html" -o ~ /image-search-lab/templates/index.html
520337 < /copy>
521338 ` ` `
522339
0 commit comments