cora / tests_backup_ui_dir
tokgae's picture
Upload folder using huggingface_hub
38ab39c verified
import gradio as gr
import requests
import os
import io
from PIL import Image
API_URL = "http://127.0.0.1:8000"
def ui_wrapper(user_prompt, progress=gr.Progress()):
"""Wrapper that calls the API for generation with progress tracking."""
try:
if not user_prompt or not user_prompt.strip():
raise gr.Error("Please enter a subject to generate an archive.")
# Stage 1: Refining prompt
progress(0.1, desc="🔍 Analyzing your request...")
# Stage 2: Generating
progress(0.3, desc="🎨 Generating historical archive... (this may take 1-2 minutes)")
# Call API
response = requests.post(f"{API_URL}/agent/generate", json={
"prompt": user_prompt,
"use_curator": True
}, timeout=120) # Long timeout for SDXL
# Stage 3: Processing result
# Archiving happens in background now, so we skip the wait
if response.status_code == 200:
# Load image from bytes
progress(1.0, desc="✅ Generated! Indexing in background...")
return Image.open(io.BytesIO(response.content))
elif response.status_code == 400:
raise gr.Error("Invalid prompt. Try describing a historical subject or scene.")
elif response.status_code == 500:
raise gr.Error("The archive server is experiencing issues. Please try again in a moment.")
else:
raise gr.Error("Could not generate archive. The server may be busy or offline.")
except requests.exceptions.Timeout:
raise gr.Error("⏱️ Generation is taking longer than expected. Try a simpler subject or check back later.")
except requests.exceptions.ConnectionError:
raise gr.Error("❌ Could not connect to the archive server. Make sure `api.py` is running on port 8000.")
except gr.Error:
raise
except Exception as e:
raise gr.Error(f"Unexpected error: {str(e)}")
def search_wrapper(query):
"""Calls API for semantic search with improved error handling."""
try:
if not query or not query.strip():
raise gr.Error("Please enter search keywords to explore the archive.")
response = requests.post(f"{API_URL}/curator/search", json={
"query": query,
"limit": 9
}, timeout=30)
if response.status_code == 200:
data = response.json()
# Convert results to Gradio Gallery format [(path, label)]
gallery_items = []
for item in data.get("results", []):
# Ensure path is accessible or mapped
gallery_items.append((item['path'], item['tags']))
if not gallery_items:
gr.Info("🔍 No artifacts found. Try different keywords or broader terms.")
return gallery_items
else:
print(f"Search API Error: {response.text}")
raise gr.Error("Search failed. The archive server may be offline.")
except requests.exceptions.Timeout:
raise gr.Error("Search is taking too long. Please try again.")
except requests.exceptions.ConnectionError:
raise gr.Error("Cannot connect to archive. Make sure `api.py` is running.")
except gr.Error:
raise
except Exception as e:
print(f"Search failed: {e}")
raise gr.Error(f"Search error: {str(e)}")
# Interface Definition with Custom CSS
custom_css = """
button {
transition: all 0.2s ease-in-out !important;
}
button:hover {
transform: scale(1.02);
opacity: 0.95;
}
button:active {
transform: scale(0.98);
}
button:focus-visible,
textarea:focus-visible,
input:focus-visible {
outline: 2px solid #8B5CF6 !important;
outline-offset: 2px !important;
}
/* Responsive gallery spacing */
@media (max-width: 768px) {
.gallery {
gap: 0.5rem !important;
}
}
"""
with gr.Blocks(title="Cora — Historical Archive Generator") as app:
# Enhanced Header
gr.Markdown(
"""
# 🏛️ Cora — The Archive Curator
**Generate AI-powered historical illustrations** using SDXL and Visual RAG.
Transform simple prompts into detailed historical scenes, artifacts, and engravings.
**How it works**: Your prompt is enhanced by an AI curator, then rendered as a historically-themed illustration and archived for future semantic search.
"""
)
# Tabs
with gr.Tabs():
with gr.Tab("🎨 Generate"):
with gr.Row():
with gr.Column(scale=1):
# Controls
txt_input = gr.Textbox(
label="Historical Subject",
placeholder="Describe a historical scene, artifact, or character...",
lines=3,
info="Be specific! Mention time periods, cultures, or contexts for best results."
)
btn_generate = gr.Button("🔮 Generate Archive", variant="primary", size="lg")
# Input Examples
gr.Examples(
examples=[
["A Roman gladiator training in the Colosseum at sunset"],
["Medieval blacksmith forging a sword, sparks flying"],
["Viking longship sailing through a stormy Nordic sea"],
["Renaissance artist's studio with easels and oil paintings"],
["Ancient Egyptian scribe writing on papyrus scrolls"],
["Samurai warrior in ceremonial armor during cherry blossom season"]
],
inputs=txt_input,
label="💡 Example Prompts (click to use)"
)
with gr.Column(scale=1):
# Output
output_image = gr.Image(
label="🖼️ Recovered Artifact",
show_label=True
)
# Event Wiring with Progress
btn_generate.click(
fn=ui_wrapper,
inputs=[txt_input],
outputs=output_image,
show_progress="full"
)
with gr.Tab("📚 The Archive"):
gr.Markdown(
"""
### Search the Visual Memory
Use semantic search to find archived artifacts by keywords, themes, or cultural markers.
"""
)
with gr.Row():
search_box = gr.Textbox(
label="Search Query",
placeholder="Try: 'roman armor', 'medieval', 'warrior', or 'architecture'",
scale=4
)
btn_search = gr.Button("🔍 Search", variant="secondary", scale=1)
# Responsive Gallery: columns adapt based on viewport
# Gradio 4.0+ supports column lists [mobile, tablet, desktop]
gallery = gr.Gallery(
label="Found Artifacts",
columns=[1, 2, 3], # 1 col on mobile, 2 on tablet, 3 on desktop
height="auto",
object_fit="contain",
show_label=True
)
# Event Wiring
btn_search.click(
fn=search_wrapper,
inputs=[search_box],
outputs=gallery
)
# Search Examples
gr.Examples(
examples=[
["roman gladiator"],
["medieval castle"],
["viking warrior"],
["renaissance art"]
],
inputs=search_box,
label="💡 Quick Search Terms"
)
if __name__ == "__main__":
app.launch(
server_port=7861,
theme=gr.themes.Monochrome(),
css=custom_css
)