Download app/components.py from EATosin/Structura: direct link, hf CLI and curl.
- Browser
- Download file 4.03 kB
-
https://huggingface.co/spaces/EATosin/Structura/resolve/main/app/components.py
- Command line
-
hf download hf://spaces/EATosin/Structura/app/components.py
-
curl -L -o components.py https://huggingface.co/spaces/EATosin/Structura/resolve/main/app/components.py
4.03 kB
| from fasthtml.common import * | |
| def PageLayout(title: str, content: list): | |
| """ | |
| The Base Layout. | |
| Injects PicoCSS (Styling), PrismJS (Syntax Highlight), and HTMX (Interactivity). | |
| """ | |
| return Html( | |
| Head( | |
| Title(title), | |
| # 1. PicoCSS: Semantic minimalist framework | |
| Link(rel="stylesheet", href="https://cdn.jsdelivr.net/npm/@picocss/pico@latest/css/pico.min.css"), | |
| # 2. HTMX (CRITICAL FIX: Prevents page reloads) | |
| Script(src="https://unpkg.com/htmx.org@1.9.10"), | |
| # 3. PrismJS: For beautiful JSON highlighting | |
| Link(rel="stylesheet", href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css"), | |
| Script(src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"), | |
| Script(src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-json.min.js"), | |
| # Custom Styles | |
| Style(""" | |
| body { max-width: 900px; margin: 0 auto; padding: 20px; background-color: #11191f; } | |
| .json-box { border-radius: 8px; overflow: hidden; margin-top: 20px; } | |
| h1 { color: #00E5FF; } | |
| button.contrast { background-color: #00E5FF; border-color: #00E5FF; color: black; font-weight: bold; } | |
| .error-box { background: #3d1a1a; color: #ff8080; padding: 15px; border-radius: 8px; border: 1px solid #ff4d4d; } | |
| """) | |
| ), | |
| Body( | |
| Header( | |
| H1("🛡️ Structura"), | |
| P("The Unbreakable Data Architect", style="opacity: 0.7;"), | |
| style="border-bottom: 1px solid #333; padding-bottom: 20px; margin-bottom: 40px;" | |
| ), | |
| Main(*content), | |
| Footer( | |
| P("Powered by PydanticAI & Gemini 2.5", style="text-align: center; opacity: 0.5; font-size: 0.8rem; margin-top: 50px;") | |
| ) | |
| ) | |
| ) | |
| # ... (Rest of components.py remains the same) | |
| def HeroSection(): | |
| return Div( | |
| H2("Turn Chaos into Structure"), | |
| P("Paste messy emails, invoices, or resumes below. Get guaranteed, type-safe JSON back."), | |
| style="margin-bottom: 30px;" | |
| ) | |
| def ExtractionForm(): | |
| """ | |
| The Interactive Form. | |
| Uses HTMX (hx-post) to swap the result area without a page reload. | |
| """ | |
| return Form( | |
| Label("Raw Input Data"), | |
| Textarea( | |
| name="text_input", | |
| placeholder="e.g. Invoice #909 from CloudFix for $500...", | |
| rows=8, | |
| style="font-family: monospace; background: #0b0f13; color: white; border: 1px solid #333;" | |
| ), | |
| Grid( | |
| Label("Target Schema", | |
| Select( | |
| Option("Invoice Extraction", value="invoice"), | |
| Option("Resume Parsing", value="resume"), | |
| Option("Generic Data", value="generic"), | |
| name="schema_type" | |
| ) | |
| ), | |
| # Empty div for grid balance or future features | |
| Div() | |
| ), | |
| Button("Extract Structure ⚡", cls="contrast", type="submit"), | |
| # HTMX Configuration | |
| hx_post="/extract", | |
| hx_target="#result-area", | |
| hx_swap="innerHTML", | |
| hx_indicator="#loading" | |
| ) | |
| def LoadingIndicator(): | |
| return Div("⚙️ AI is processing...", id="loading", cls="htmx-indicator", style="color: #00E5FF; margin-top: 10px;") | |
| def SuccessDisplay(json_str: str): | |
| return Div( | |
| H4("✅ Validated Output", style="color: #4ade80; margin-bottom: 10px;"), | |
| Div( | |
| Pre(Code(json_str, cls="language-json")), | |
| cls="json-box" | |
| ), | |
| P("Schema Verified by PydanticAI", style="color: grey; font-size: 0.8rem; margin-top: 10px; text-align: right;") | |
| ) | |
| def ErrorDisplay(error_msg: str): | |
| return Div( | |
| H4("❌ Extraction Failed"), | |
| P(error_msg), | |
| cls="error-box" | |
| ) | |