| import os |
| import requests |
| import gradio as gr |
|
|
| custom_css = """ |
| .gradio-container { |
| max-width: 1180px !important; |
| margin: 0 auto !important; |
| } |
| |
| #solricks-hero { |
| background: |
| radial-gradient(circle at 80% 20%, rgba(96, 165, 250, 0.28), transparent 32%), |
| radial-gradient(circle at 10% 0%, rgba(124, 58, 237, 0.25), transparent 34%), |
| linear-gradient(135deg, #070814 0%, #111827 45%, #1e1b4b 100%); |
| padding: 30px; |
| border-radius: 22px; |
| margin-bottom: 22px; |
| color: white; |
| border: 1px solid rgba(255,255,255,0.12); |
| box-shadow: 0 18px 55px rgba(15, 23, 42, 0.22); |
| } |
| |
| #solricks-kicker { |
| display: inline-flex; |
| align-items: center; |
| gap: 8px; |
| padding: 7px 12px; |
| border-radius: 999px; |
| background: rgba(255,255,255,0.10); |
| color: rgba(255,255,255,0.82); |
| font-size: 12px; |
| font-weight: 700; |
| letter-spacing: 0.08em; |
| text-transform: uppercase; |
| border: 1px solid rgba(255,255,255,0.14); |
| margin-bottom: 16px; |
| } |
| |
| #solricks-hero h1 { |
| margin: 0 0 10px 0; |
| color: white; |
| font-size: 38px; |
| line-height: 1.05; |
| font-weight: 900; |
| letter-spacing: -0.04em; |
| } |
| |
| #solricks-hero p { |
| margin: 0; |
| max-width: 760px; |
| font-size: 15px; |
| line-height: 1.65; |
| color: rgba(255,255,255,0.78); |
| } |
| |
| #solricks-note-row { |
| display: flex; |
| flex-wrap: wrap; |
| gap: 10px; |
| margin-top: 18px; |
| } |
| |
| .solricks-pill { |
| display: inline-flex; |
| align-items: center; |
| padding: 8px 12px; |
| border-radius: 999px; |
| background: rgba(255,255,255,0.10); |
| color: rgba(255,255,255,0.88); |
| font-size: 13px; |
| font-weight: 700; |
| border: 1px solid rgba(255,255,255,0.14); |
| } |
| |
| #solricks-panel-note { |
| padding: 14px 16px; |
| border-radius: 16px; |
| background: rgba(79, 70, 229, 0.08); |
| border: 1px solid rgba(79, 70, 229, 0.16); |
| font-size: 13px; |
| line-height: 1.55; |
| margin-bottom: 12px; |
| } |
| |
| #solricks-footer { |
| margin-top: 22px; |
| padding: 18px 20px; |
| border-radius: 18px; |
| background: rgba(15, 23, 42, 0.04); |
| border: 1px solid rgba(15, 23, 42, 0.08); |
| font-size: 13px; |
| color: rgba(15, 23, 42, 0.72); |
| } |
| |
| #solricks-footer a { |
| font-weight: 700; |
| text-decoration: none; |
| } |
| |
| button.primary { |
| border-radius: 14px !important; |
| font-weight: 800 !important; |
| } |
| |
| textarea, input, select { |
| border-radius: 12px !important; |
| } |
| |
| .svelte-1ipelgc, .wrap { |
| border-radius: 16px !important; |
| } |
| """ |
|
|
| API_BASE_URL = os.getenv("SOLRICKS_API_BASE_URL", "https://api.solricks.com") |
| API_KEY = os.getenv("SOLRICKS_SPACE_API_KEY", "") |
|
|
| API_ENDPOINT = f"{API_BASE_URL}/api/workflows/visual-ai/run" |
|
|
| ALLOWED_RESOLUTIONS = ["1024x1024", "768x1344", "1344x768"] |
| ALLOWED_STYLES = ["Portrait", "Realistic", "Cinematic", "Product"] |
|
|
|
|
| def generate_image(prompt, style, resolution): |
| prompt = (prompt or "").strip() |
|
|
| if not prompt: |
| return None, "Please enter a prompt." |
|
|
| if len(prompt) > 500: |
| return None, "Prompt is too long. Please keep it under 500 characters." |
|
|
| if resolution not in ALLOWED_RESOLUTIONS: |
| return None, "Invalid resolution." |
|
|
| if style not in ALLOWED_STYLES: |
| return None, "Invalid style." |
|
|
| payload = { |
| "prompt": prompt, |
| "style": style, |
| "resolution": resolution, |
| "enhancePrompt": False, |
| "seedMode": "Random", |
| "source": "huggingface-space", |
| } |
|
|
| headers = { |
| "Content-Type": "application/json", |
| } |
|
|
| if API_KEY: |
| headers["Authorization"] = f"Bearer {API_KEY}" |
|
|
| try: |
| response = requests.post( |
| API_ENDPOINT, |
| json=payload, |
| headers=headers, |
| timeout=240, |
| ) |
|
|
| try: |
| data = response.json() |
| except Exception: |
| return None, "Solricks backend returned an invalid response." |
|
|
| if response.status_code == 429: |
| return None, "Too many requests. Please wait a few minutes and try again." |
|
|
| if not response.ok: |
| return None, data.get("error") or data.get("detail") or "Generation failed." |
|
|
| image_url = data.get("image_url") |
|
|
| if not image_url: |
| return None, "No image was returned." |
|
|
| if image_url.startswith("/"): |
| image_url = f"{API_BASE_URL}{image_url}" |
|
|
| return image_url, "Done. Your image was generated successfully." |
|
|
| except requests.exceptions.Timeout: |
| return None, "Generation timed out. Please try again." |
| except Exception as error: |
| return None, f"Error: {error}" |
|
|
|
|
| theme = gr.themes.Soft( |
| primary_hue="indigo", |
| secondary_hue="blue", |
| neutral_hue="slate", |
| ) |
|
|
| with gr.Blocks( |
| title="SOLRICKS Image Generator", |
| theme=theme, |
| css=custom_css, |
| ) as demo: |
| gr.Markdown( |
| """ |
| <div id="solricks-hero"> |
| <div id="solricks-kicker">SOLRICKS 路 VISUAL AI PREVIEW</div> |
| <h1>SOLRICKS Image Generator</h1> |
| <p>Generate a free preview image using the Solricks visual AI backend.</p> |
| <div id="solricks-note-row"> |
| <span class="solricks-pill">Rate-limited</span> |
| <span class="solricks-pill">Preview generations</span> |
| </div> |
| </div> |
| """ |
| ) |
|
|
| with gr.Row(): |
| with gr.Column(scale=5): |
| prompt = gr.Textbox( |
| label="Prompt", |
| placeholder="Describe the image you want to generate...", |
| lines=6, |
| max_lines=8, |
| ) |
|
|
| with gr.Row(): |
| style = gr.Dropdown( |
| label="Style", |
| choices=ALLOWED_STYLES, |
| value="Portrait", |
| ) |
|
|
| resolution = gr.Dropdown( |
| label="Resolution", |
| choices=ALLOWED_RESOLUTIONS, |
| value="1024x1024", |
| ) |
|
|
| generate_button = gr.Button("Generate Image", variant="primary") |
|
|
| status = gr.Textbox( |
| label="Status", |
| interactive=False, |
| placeholder="Generation status will appear here...", |
| ) |
|
|
| with gr.Column(scale=6): |
| output_image = gr.Image( |
| label="Generated Image", |
| height=460, |
| ) |
|
|
| gr.Examples( |
| examples=[ |
| [ |
| "cinematic close-up portrait of a futuristic android, dark premium lighting, realistic details", |
| "Portrait", |
| "768x1344", |
| ], |
| [ |
| "realistic AI robot in a dark premium technology lab, cinematic lighting, blue accent lights", |
| "Cinematic", |
| "1344x768", |
| ], |
| ], |
| inputs=[prompt, style, resolution], |
| ) |
|
|
| gr.Markdown( |
| """ |
| <div id="solricks-footer"> |
| <strong>SOLRICKS</strong> develops solution bricks for AI-powered systems, visual AI workflows, |
| ComfyUI tools, LoRA resources, and GPU automation. |
| <br><br> |
| <a href="https://solricks.com/" target="_blank">Website</a> |
| 路 |
| <a href="https://github.com/SOLRICKS" target="_blank">GitHub</a> |
| 路 |
| <a href="https://civitai.com/user/Solricks" target="_blank">Civitai</a> |
| </div> |
| """ |
| ) |
|
|
| generate_button.click( |
| fn=generate_image, |
| inputs=[prompt, style, resolution], |
| outputs=[output_image, status], |
| ) |
|
|
| demo.queue(max_size=10).launch() |