card / app.py
jsakshi's picture
Update app.py
9edb938 verified
'''import requests
from io import BytesIO
from PIL import Image
import gradio as gr
import os
# Hugging Face Inference API setup
API_URL = "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-2"
API_TOKEN = os.getenv("HF_TOKEN") # Loaded from Spaces secrets
HEADERS = {"Authorization": f"Bearer {API_TOKEN}"}
def generate_image(prompt):
"""Generate an image from a text prompt using Hugging Face API."""
if not API_TOKEN:
return None, "Error: HF_API_TOKEN not set in Spaces secrets!"
if not prompt or not prompt.strip():
return None, "Error: Please enter a valid prompt!"
payload = {
"inputs": prompt,
"options": {"wait_for_model": True}
}
try:
response = requests.post(API_URL, headers=HEADERS, json=payload, timeout=30)
response.raise_for_status()
image_bytes = response.content
image = Image.open(BytesIO(image_bytes))
return image, "Image generated successfully!"
except requests.exceptions.Timeout:
return None, "Error: API request timed out after 30 seconds. Try again later."
except requests.exceptions.RequestException as e:
return None, f"API request failed: {str(e)}"
except Exception as e:
return None, f"Image processing failed: {str(e)}"
# Gradio interface
with gr.Blocks(title="Instant Image Generator") as demo:
gr.Markdown("# Instant Image Generator")
gr.Markdown("Enter a text prompt to generate an image in seconds!")
with gr.Row():
prompt_input = gr.Textbox(label="Prompt", placeholder="A futuristic city at sunset")
submit_btn = gr.Button("Generate Image")
output_image = gr.Image(label="Generated Image")
status = gr.Textbox(label="Status", interactive=False)
# Connect button to function
submit_btn.click(
fn=generate_image,
inputs=prompt_input,
outputs=[output_image, status]
)
# Diagnostic check
if not API_TOKEN:
gr.Warning("API token missing! Set HF_API_TOKEN in Spaces Settings > Variables and Secrets.")
demo.launch()'''
import requests
from io import BytesIO
import base64
from PIL import Image
import gradio as gr
import os
import numpy as np
# Hugging Face Inference API setup
API_URL_TEXT = "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-2" # For text-to-image
API_URL_INPAINT = "https://api-inference.huggingface.co/models/runwayml/stable-diffusion-inpainting" # For image-to-image with face
API_TOKEN = os.getenv("HF_TOKEN") # Loaded from environment variable or Spaces secrets
HEADERS = {"Authorization": f"Bearer {API_TOKEN}" if API_TOKEN else ""}
def image_to_base64(image):
"""Convert a PIL Image to a base64-encoded string."""
if image is None:
return None
buffered = BytesIO()
image.save(buffered, format="PNG")
return base64.b64encode(buffered.getvalue()).decode("utf-8")
def base64_to_image(base64_string):
"""Convert a base64-encoded string to a PIL Image."""
if not base64_string or base64_string.strip() == "":
return None
try:
img_data = base64.b64decode(base64_string)
return Image.open(BytesIO(img_data))
except Exception as e:
return None
def generate_image_with_face(prompt, input_image):
"""Generate an image from a text prompt using an optional uploaded face image."""
# Check API token
if not API_TOKEN:
return None, "Error: HF_TOKEN not set in environment variables or Spaces secrets! Please set it and retry."
# Validate prompt
if not prompt or not prompt.strip():
return None, "Error: Please enter a valid prompt!"
# Text-to-image path (no face image uploaded)
if input_image is None or (isinstance(input_image, np.ndarray) and input_image.size == 0):
payload = {
"inputs": prompt,
"options": {"wait_for_model": True}
}
try:
response = requests.post(
API_URL_TEXT,
headers=HEADERS,
json=payload,
timeout=120 # Increased timeout to 120 seconds for text-to-image
)
response.raise_for_status()
# Handle the response (could be bytes or JSON with base64)
if response.headers.get("content-type") == "application/json":
data = response.json()
if isinstance(data, str): # If the response is a base64 string
image = base64_to_image(data)
if image:
return image, "Image generated successfully using text prompt!"
return None, "Error: Failed to decode API response as an image."
elif isinstance(data, dict) and "image" in data:
image = base64_to_image(data["image"])
if image:
return image, "Image generated successfully using text prompt!"
return None, "Error: Failed to decode API response as an image."
return None, "Error: Unexpected API response format."
# If response is bytes (common for image data)
image_bytes = response.content
image = Image.open(BytesIO(image_bytes))
return image, "Image generated successfully using text prompt!"
except requests.exceptions.Timeout:
return None, "Error: API request timed out after 120 seconds. Try again later or check your internet connection."
except requests.exceptions.HTTPError as e:
return None, f"API error: HTTP {e.response.status_code} - {e.response.text}"
except requests.exceptions.RequestException as e:
return None, f"API request failed: {str(e)}"
except Exception as e:
return None, f"Image processing failed: {str(e)}"
# Image-to-image (inpainting) path with face upload
try:
# Convert input image to PIL and resize to 512x512 (Stable Diffusion's default)
input_pil = Image.fromarray(input_image).convert("RGB").resize((512, 512))
# Create a full white mask for inpainting (simplified for now)
mask = Image.new("L", (512, 512), 255) # White mask for full inpainting
# Convert images to base64 for JSON serialization
image_base64 = image_to_base64(input_pil)
mask_base64 = image_to_base64(mask)
if image_base64 is None or mask_base64 is None:
return None, "Error: Failed to process the uploaded image or mask."
# Prepare payload for inpainting
payload = {
"inputs": {
"image": image_base64, # Base64-encoded face image
"mask": mask_base64, # Base64-encoded mask
},
"parameters": {
"prompt": prompt,
"negative_prompt": "blurry, distorted, low quality, extra people, dark lighting",
"strength": 0.8, # Balance between input preservation and generation
"num_inference_steps": 50 # Quality vs. speed tradeoff
},
"options": {"wait_for_model": True}
}
response = requests.post(
API_URL_INPAINT,
headers=HEADERS,
json=payload,
timeout=120 # Keep timeout at 120 seconds for image-to-image
)
response.raise_for_status()
# Handle the response (could be bytes or JSON with base64)
if response.headers.get("content-type") == "application/json":
data = response.json()
if isinstance(data, str): # If the response is a base64 string
image = base64_to_image(data)
if image:
return image, "Image generated successfully using your face and prompt!"
return None, "Error: Failed to decode API response as an image."
elif isinstance(data, dict) and "image" in data:
image = base64_to_image(data["image"])
if image:
return image, "Image generated successfully using your face and prompt!"
return None, "Error: Failed to decode API response as an image."
return None, "Error: Unexpected API response format."
# If response is bytes (common for image data)
image_bytes = response.content
image = Image.open(BytesIO(image_bytes))
return image, "Image generated successfully using your face and prompt!"
except requests.exceptions.Timeout:
return None, "Error: API request timed out for image processing after 120 seconds. Try again later or simplify the prompt."
except requests.exceptions.HTTPError as e:
return None, f"API error: HTTP {e.response.status_code} - {e.response.text}"
except requests.exceptions.RequestException as e:
return None, f"API request failed: {str(e)}"
except Exception as e:
return None, f"Image processing failed: {str(e)}"
# Gradio interface
with gr.Blocks(title="Face-Based Image Generator") as demo:
gr.Markdown("# Face-Based Image Generator")
gr.Markdown("Enter a text prompt and optionally upload your face image to generate a custom image!")
with gr.Row():
prompt_input = gr.Textbox(label="Prompt", placeholder="A joyful person at a birthday party")
image_input = gr.Image(label="Upload Your Face Image (Optional)", type="numpy")
submit_btn = gr.Button("Generate Image")
output_image = gr.Image(label="Generated Image")
status = gr.Textbox(label="Status", interactive=False)
# Connect button to function
submit_btn.click(
fn=generate_image_with_face,
inputs=[prompt_input, image_input],
outputs=[output_image, status]
)
# Diagnostic check
if not API_TOKEN:
gr.Warning("API token missing! Set HF_TOKEN as an environment variable (e.g., in .env or terminal) or in Spaces secrets.")
demo.launch()