waslap-flux / app.py
marahmerah's picture
Update app.py
bde90af verified
raw
history blame
8.71 kB
import os
import gradio as gr
import base64
from random import randint
from all_models import models
from io import BytesIO
from PIL import Image
from fastapi import FastAPI, Request
from deep_translator import GoogleTranslator
# CSS yang lebih lengkap dengan berbagai elemen styling
css_code = """
/* General Styling */
.gradio-container {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
min-height: 100vh;
padding: 20px;
}
/* Textbox Styling */
#custom_textbox {
min-height: 150px;
padding: 15px;
border-radius: 12px;
border: 2px solid #e0e0e0;
font-size: 16px;
background: rgba(255, 255, 255, 0.9);
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
}
#custom_textbox:focus {
border-color: #4facfe;
box-shadow: 0 0 0 3px rgba(79, 172, 254, 0.2);
outline: none;
}
/* Button Styling */
#custom_gen_button {
background: linear-gradient(to right, #4facfe 0%, #00f2fe 100%);
color: white;
border: none;
border-radius: 12px;
padding: 12px 24px;
font-weight: 600;
font-size: 16px;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
width: 100%;
margin-bottom: 10px;
}
#custom_gen_button:hover {
transform: translateY(-2px);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
}
#custom_stop_button {
background: linear-gradient(to right, #ff4d4d 0%, #f97878 100%);
color: white;
border: none;
border-radius: 12px;
padding: 12px 24px;
font-weight: 600;
font-size: 16px;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
width: 100%;
}
#custom_stop_button:hover {
transform: translateY(-2px);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
}
/* Image Styling */
#custom_image {
border-radius: 16px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
background: white;
padding: 10px;
max-width: 100%;
height: auto;
}
#custom_image:hover {
transform: scale(1.01);
box-shadow: 0 12px 28px rgba(0, 0, 0, 0.15);
}
/* Dropdown Styling */
.dark .dropdown-option {
background: #2d3748 !important;
}
.dark .dropdown-option:hover {
background: #4a5568 !important;
}
/* Panel Styling */
.gr-box {
border-radius: 16px !important;
background: rgba(255, 255, 255, 0.8) !important;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2) !important;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1) !important;
padding: 20px !important;
}
/* Label Styling */
.gr-label {
font-weight: 600 !important;
color: #2d3748 !important;
margin-bottom: 8px !important;
font-size: 16px !important;
}
/* Responsive Adjustments */
@media (max-width: 768px) {
.gradio-container {
padding: 10px;
}
#custom_textbox {
min-height: 120px;
font-size: 14px;
}
#custom_gen_button, #custom_stop_button {
padding: 10px 15px;
font-size: 14px;
}
}
/* Animation for loading state */
@keyframes pulse {
0% { opacity: 0.6; }
50% { opacity: 1; }
100% { opacity: 0.6; }
}
.loading {
animation: pulse 1.5s infinite;
}
"""
# Initialize translator
translator = GoogleTranslator(source='auto', target='en')
# Load models
models_load = {}
for model in models:
try:
models_load[model] = gr.load(f'models/{model}')
except Exception as error:
models_load[model] = gr.Interface(lambda txt: None, ['text'], ['image'])
app = FastAPI()
def gen_image(model_str, prompt):
if model_str == 'NA':
return None
# Translate prompt to English {noise} {klir}
translated_prompt = translator.translate(prompt)
noise = str(randint(0, 4294967296))
klir = '| ultra detail, ultra elaboration, ultra quality, perfect'
return models_load[model_str](f'{translated_prompt}')
def image_to_base64(image):
buffered = BytesIO()
if isinstance(image, str): # if it's a file path
img = Image.open(image)
img.save(buffered, format="JPEG")
else: # if it's a PIL Image
image.save(buffered, format="JPEG")
return base64.b64encode(buffered.getvalue()).decode()
# API endpoint
@app.post("/generate")
async def api_generate(request: Request):
data = await request.json()
model = data.get('model', models[0])
prompt = data.get('prompt', '')
if model not in models:
return {"error": "Model not found"}
# Translate prompt to English for API endpoint too
translated_prompt = translator.translate(prompt)
image = gen_image(model, translated_prompt)
if image is None:
return {"error": "Image generation failed"}
base64_str = image_to_base64(image)
return {
"status": "success",
"model": model,
"original_prompt": prompt,
"translated_prompt": translated_prompt,
"image_base64": base64_str,
"image_format": "jpeg"
}
# Gradio Interface
def make_me():
with gr.Row():
with gr.Column(scale=4):
txt_input = gr.Textbox(
label='Your prompt:',
lines=4,
container=False,
elem_id="custom_textbox",
placeholder="Describe the image you want to generate...",
interactive=True
)
with gr.Column(scale=1):
gen_button = gr.Button('Generate image', elem_id="custom_gen_button", variant="primary")
stop_button = gr.Button('Stop', variant='secondary', interactive=False,
elem_id="custom_stop_button")
def on_generate_click():
return gr.Button('Generating...', interactive=False, elem_id="custom_gen_button", variant="stop"), gr.Button('Stop', variant='secondary', interactive=True, elem_id="custom_stop_button")
def on_stop_click():
return gr.Button('Generate image', elem_id="custom_gen_button", variant="primary"), gr.Button('Stop', variant='secondary', interactive=False, elem_id="custom_stop_button")
gen_button.click(on_generate_click, inputs=None, outputs=[gen_button, stop_button])
stop_button.click(on_stop_click, inputs=None, outputs=[gen_button, stop_button])
with gr.Row():
with gr.Column():
model_dropdown = gr.Dropdown(models, label="Select Model",
value=models[0] if models else None,
interactive=True,
elem_classes=["model-selector"])
output_image = gr.Image(
label="Generated Image",
width=512,
height=768,
elem_id="custom_image",
show_label=True,
interactive=False
)
# JSON output
json_output = gr.JSON(label="API Response", elem_id="api-response")
def generate_wrapper(model_str, prompt):
# Translate prompt to English
translated_prompt = translator.translate(prompt)
image = gen_image(model_str, translated_prompt)
if image is None:
return None, {"error": "Generation failed"}
base64_str = image_to_base64(image)
response = {
"status": "success",
"model": model_str,
"original_prompt": prompt,
"translated_prompt": translated_prompt,
"image_base64": base64_str,
"image_format": "jpeg"
}
return image, response
gen_event = gen_button.click(generate_wrapper, [model_dropdown, txt_input],
[output_image, json_output])
stop_button.click(on_stop_click, inputs=None,
outputs=[gen_button, stop_button], cancels=[gen_event])
# Create Gradio app
with gr.Blocks(css=css_code, theme=gr.themes.Soft()) as demo:
gr.Markdown("# AI Image Generator", elem_id="title")
gr.Markdown("Generate stunning images from text prompts using advanced AI models", elem_id="subtitle")
make_me()
# Enable queue before mounting
demo.queue()
# Mount Gradio app to FastAPI
app = gr.mount_gradio_app(app, demo, path="/")
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=7860)