Spaces:
Running
Running
File size: 7,842 Bytes
e547b24 25d39b9 764029a e547b24 c64e303 e547b24 c64e303 974dc33 25d39b9 974dc33 dd21ab3 974dc33 dd21ab3 25d39b9 c64e303 25d39b9 c64e303 b5176b4 dd21ab3 c64e303 b5176b4 dd21ab3 c64e303 dd21ab3 c64e303 e547b24 c64e303 974dc33 c64e303 974dc33 c64e303 974dc33 e547b24 c64e303 764029a c64e303 764029a c64e303 764029a c64e303 764029a e547b24 c64e303 764029a c64e303 764029a c64e303 764029a c64e303 06ff1bc c64e303 e547b24 02f8cfa c64e303 02f8cfa 73f7edc e547b24 c64e303 4d6cbec c64e303 02f8cfa c64e303 25d39b9 c64e303 02f8cfa c64e303 4d6cbec c64e303 02f8cfa c64e303 02f8cfa c64e303 4d6cbec c64e303 02f8cfa c64e303 e547b24 c64e303 b5176b4 c64e303 b5176b4 c64e303 b5176b4 25d39b9 c64e303 b5176b4 c64e303 b5176b4 e547b24 c64e303 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
import gradio as gr
import random
import os
from PIL import Image
from typing import Optional
from huggingface_hub import InferenceClient
# Project by Nymbo
API_TOKEN = os.getenv("HF_READ_TOKEN")
timeout = 100
# Function to query the API and return the generated image
def flux_krea_generate(
prompt: str,
negative_prompt: str = "(deformed, distorted, disfigured), poorly drawn, bad anatomy, wrong anatomy, extra limb, missing limb, floating limbs, (mutated hands and fingers), disconnected limbs, mutation, mutated, ugly, disgusting, blurry, amputation, misspellings, typos",
steps: int = 35,
cfg_scale: float = 7.0,
sampler: str = "DPM++ 2M Karras",
seed: int = -1,
strength: float = 0.7,
width: int = 1024,
height: int = 1024
) -> Optional[Image.Image]:
"""
Text-to-image generation with FLUX.1-Krea-dev (no input image required).
This tool generates a single image from a text prompt using the
black-forest-labs/FLUX.1-Krea-dev model on Hugging Face Inference.
Args:
prompt: Text description of the image to generate.
negative_prompt: What should NOT appear in the image.
steps: Number of denoising steps (1-100). Higher is slower but can improve quality.
cfg_scale: Classifier-free guidance scale (1-20). Higher = follow the prompt more closely.
sampler: Sampling method to use. One of: "DPM++ 2M Karras", "DPM++ SDE Karras", "Euler", "Euler a", "Heun", "DDIM".
seed: Random seed for reproducible results. Use -1 for a random seed per call.
strength: Generation strength (0-1). Kept for parity; not an input image strength.
width: Output width in pixels (64-1216, multiple of 32 recommended).
height: Output height in pixels (64-1216, multiple of 32 recommended).
Returns:
A PIL.Image of the generated result. No input image is expected or required.
"""
if prompt == "" or prompt is None:
return None
key = random.randint(0, 999)
# Add some extra flair to the prompt
enhanced_prompt = f"{prompt} | ultra detail, ultra elaboration, ultra quality, perfect."
print(f'\033[1mGeneration {key}:\033[0m {enhanced_prompt}')
try:
# Initialize the Hugging Face Inference Client
# Try different providers in order of preference
providers = ["auto", "replicate", "fal-ai"]
for provider in providers:
try:
client = InferenceClient(
api_key=API_TOKEN,
provider=provider
)
# Generate the image using the proper client
image = client.text_to_image(
prompt=enhanced_prompt,
negative_prompt=negative_prompt,
model="black-forest-labs/FLUX.1-Krea-dev",
width=width,
height=height,
num_inference_steps=steps,
guidance_scale=cfg_scale,
seed=seed if seed != -1 else random.randint(1, 1000000000)
)
print(f'\033[1mGeneration {key} completed with {provider}!\033[0m ({enhanced_prompt})')
return image
except Exception as provider_error:
print(f"Provider {provider} failed: {provider_error}")
if provider == providers[-1]: # Last provider
raise provider_error
continue
except Exception as e:
print(f"Error during image generation: {e}")
if "404" in str(e):
raise gr.Error("Model not found. Please ensure the FLUX.1-Krea-dev model is accessible with your API token.")
elif "503" in str(e):
raise gr.Error("The model is currently being loaded. Please try again in a moment.")
elif "401" in str(e) or "403" in str(e):
raise gr.Error("Authentication failed. Please check your HF_READ_TOKEN environment variable.")
else:
raise gr.Error(f"Image generation failed: {str(e)}")
return None
# CSS to style the app
css = """
#app-container {
max-width: 800px;
margin-left: auto;
margin-right: auto;
}
"""
# Build the Gradio UI with Blocks
with gr.Blocks(theme='Nymbo/Nymbo_Theme', css=css) as app:
# Add a title to the app
gr.HTML("<center><h1>FLUX.1-Krea-dev</h1></center>")
gr.HTML("<center><p>High-quality image generation via Model Context Protocol</p></center>")
# Container for all the UI elements
with gr.Column(elem_id="app-container"):
# Add a text input for the main prompt
with gr.Row():
with gr.Column(elem_id="prompt-container"):
with gr.Row():
text_prompt = gr.Textbox(label="Prompt", placeholder="Enter a prompt here", lines=2, elem_id="prompt-text-input")
# Accordion for advanced settings
with gr.Row():
with gr.Accordion("Advanced Settings", open=False):
negative_prompt = gr.Textbox(label="Negative Prompt", placeholder="What should not be in the image", value="(deformed, distorted, disfigured), poorly drawn, bad anatomy, wrong anatomy, extra limb, missing limb, floating limbs, (mutated hands and fingers), disconnected limbs, mutation, mutated, ugly, disgusting, blurry, amputation, misspellings, typos", lines=3, elem_id="negative-prompt-text-input")
with gr.Row():
width = gr.Slider(label="Width", value=1024, minimum=64, maximum=1216, step=32)
height = gr.Slider(label="Height", value=1024, minimum=64, maximum=1216, step=32)
steps = gr.Slider(label="Sampling steps", value=35, minimum=1, maximum=100, step=1)
cfg = gr.Slider(label="CFG Scale", value=7, minimum=1, maximum=20, step=1)
strength = gr.Slider(label="Strength", value=0.7, minimum=0, maximum=1, step=0.001)
seed = gr.Slider(label="Seed", value=-1, minimum=-1, maximum=1000000000, step=1) # Setting the seed to -1 will make it random
method = gr.Radio(label="Sampling method", value="DPM++ 2M Karras", choices=["DPM++ 2M Karras", "DPM++ SDE Karras", "Euler", "Euler a", "Heun", "DDIM"])
# Add a button to trigger the image generation
with gr.Row():
text_button = gr.Button("Run", variant='primary', elem_id="gen-button")
# Image output area to display the generated image
with gr.Row():
# Output component only; no input image is required by the tool
image_output = gr.Image(label="Image Output", elem_id="gallery")
# Bind the button to the flux_krea_generate function for the UI only
# Hide this event as an MCP tool to avoid schema confusion (UI wires image output)
text_button.click(
flux_krea_generate,
inputs=[text_prompt, negative_prompt, steps, cfg, method, seed, strength, width, height],
outputs=image_output,
show_api=False,
api_description=False,
)
# Expose a dedicated MCP/API endpoint with a clear schema (text-to-image only)
# This avoids clients misinterpreting the UI event as requiring an input image.
gr.api(
flux_krea_generate,
api_name="generate_image",
api_description=(
"Generate an image from a text prompt using FLUX.1-Krea-dev. "
"Inputs are text and numeric parameters only; no input image is required."
),
)
# Launch the Gradio app with MCP server enabled
app.launch(show_api=True, share=False, mcp_server=True) |