Spaces:
Sleeping
Sleeping
import os | |
import gradio as gr | |
from PIL import Image | |
import io | |
import requests | |
from typing import Optional, Tuple | |
def load_environment(): | |
""" | |
Attempt to load environment variables with error handling. | |
Returns: | |
Optional[str]: Hugging Face Token or None | |
""" | |
try: | |
from dotenv import load_dotenv | |
load_dotenv() | |
except ImportError: | |
print("python-dotenv not installed. Ensure HF_TOKEN is set in environment.") | |
return os.getenv("HF_TOKEN") | |
def craft_realistic_prompt(base_prompt: str) -> str: | |
""" | |
Enhance prompts for more photorealistic results | |
Args: | |
base_prompt (str): Original user prompt | |
Returns: | |
str: Enhanced, detailed prompt | |
""" | |
realistic_modifiers = [ | |
"photorealistic", | |
"high resolution", | |
"sharp focus", | |
"professional photography", | |
"natural lighting", | |
"detailed textures" | |
] | |
# Combine base prompt with realistic modifiers | |
enhanced_prompt = f"{' '.join(realistic_modifiers)}, {base_prompt}, shot on professional camera, 8k resolution" | |
return enhanced_prompt | |
def query_hf_api( | |
prompt: str, | |
model_url: str = "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0", | |
max_retries: int = 3 | |
) -> Optional[bytes]: | |
""" | |
Query the Hugging Face Inference API with robust error handling and retry mechanism. | |
Args: | |
prompt (str): Text prompt for image generation | |
model_url (str): URL of the Hugging Face model | |
max_retries (int): Maximum number of retry attempts | |
Returns: | |
Optional[bytes]: Generated image bytes or None | |
""" | |
# Validate inputs | |
if not prompt or not prompt.strip(): | |
raise ValueError("Prompt cannot be empty") | |
# Load token | |
HF_TOKEN = load_environment() | |
if not HF_TOKEN: | |
raise ValueError("Hugging Face token not found. Set HF_TOKEN in .env or environment variables.") | |
# Prepare headers | |
headers = { | |
"Authorization": f"Bearer {HF_TOKEN}", | |
"Content-Type": "application/json" | |
} | |
# Payload with enhanced configuration for realism | |
payload = { | |
"inputs": craft_realistic_prompt(prompt), | |
"parameters": { | |
"negative_prompt": "cartoon, anime, low quality, bad anatomy, blurry, unrealistic, painting, drawing, sketch", | |
"num_inference_steps": 75, # Increased steps | |
"guidance_scale": 8.5, # Higher guidance | |
} | |
} | |
# Retry mechanism | |
for attempt in range(max_retries): | |
try: | |
response = requests.post( | |
model_url, | |
headers=headers, | |
json=payload, | |
timeout=120 # 2-minute timeout | |
) | |
response.raise_for_status() # Raise exception for bad status codes | |
return response.content | |
except requests.exceptions.RequestException as e: | |
print(f"Request error (Attempt {attempt + 1}/{max_retries}): {e}") | |
if attempt == max_retries - 1: | |
raise RuntimeError(f"Failed to generate image after {max_retries} attempts: {e}") | |
raise RuntimeError("Unexpected error in image generation") | |
def generate_image(prompt: str) -> Tuple[Optional[Image.Image], str]: | |
""" | |
Generate an image from a text prompt. | |
Args: | |
prompt (str): Text description for image generation | |
Returns: | |
Tuple[Optional[Image.Image], str]: | |
Generated PIL Image and status message | |
""" | |
try: | |
# Validate prompt | |
if not prompt or not prompt.strip(): | |
return None, "Error: Prompt cannot be empty" | |
# Generate image bytes | |
image_bytes = query_hf_api(prompt) | |
# Convert to PIL Image | |
image = Image.open(io.BytesIO(image_bytes)).convert("RGB") | |
return image, "Image generated successfully!" | |
except Exception as e: | |
print(f"Image generation error: {e}") | |
return None, f"Error: {str(e)}" | |
def create_gradio_interface(): | |
""" | |
Create and configure the Gradio interface. | |
Returns: | |
gr.Blocks: Configured Gradio interface | |
""" | |
with gr.Blocks( | |
theme=gr.themes.Soft(), | |
title="π¨ AI Image Generator" | |
) as demo: | |
# Title and Description | |
gr.Markdown("# π¨ AI Image Generator ") | |
gr.Markdown("This webapp is created with β€ by Sumit Yadav as GenAI project. Credits to HuggingFace Spaces and StabilityAI") | |
gr.Markdown("Generate stunning images from your text prompts using AI!") | |
# Input and Output Components | |
with gr.Row(): | |
with gr.Column(scale=3): | |
# Prompt Input | |
text_input = gr.Textbox( | |
label="Enter your image prompt", | |
placeholder="e.g., 'Photorealistic portrait of a woman in natural light'", | |
lines=3 | |
) | |
# Generate Button | |
generate_button = gr.Button("β¨ Generate Image", variant="primary") | |
# Output Image Display | |
with gr.Column(scale=4): | |
output_image = gr.Image( | |
label="Generated Image", | |
type="pil", | |
interactive=False | |
) | |
# Status Output | |
status_output = gr.Textbox(label="Status") | |
# Event Handlers | |
generate_button.click( | |
fn=generate_image, | |
inputs=[text_input], | |
outputs=[output_image, status_output] | |
) | |
return demo | |
def main(): | |
""" | |
Main entry point for the Gradio application. | |
""" | |
try: | |
demo = create_gradio_interface() | |
demo.launch( | |
server_name="0.0.0.0", # Listen on all network interfaces | |
server_port=7860, # Default Gradio port | |
share=True # Set to True for a public link | |
) | |
except Exception as e: | |
print(f"Error launching Gradio app: {e}") | |
if __name__ == "__main__": | |
main() |