editableweb / app.py
AkashKumarave's picture
Update app.py
ae39b5f verified
raw
history blame
6.23 kB
import gradio as gr
import requests
import base64
import os
import time
import jwt
import logging
from pathlib import Path
# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# ===== CONFIGURATION =====
ACCESS_KEY_ID = "AFyHfnQATghFdCMyAG3gRPbNY4TNKFGB"
ACCESS_KEY_SECRET = "TTepeLyBterLNM3brYPGmdndBnnyKJBA"
BASE_URL = "https://api-singapore.klingai.com"
CREATE_TASK_URL = f"{BASE_URL}/v1/images/generations"
# ===== UTILITY FUNCTIONS =====
def generate_jwt_token():
"""Generate JWT token for API authentication"""
payload = {
"iss": ACCESS_KEY_ID,
"exp": int(time.time()) + 1800, # Expires in 30 mins
"nbf": int(time.time()) - 5 # Not before 5 seconds ago
}
return jwt.encode(payload, ACCESS_KEY_SECRET, algorithm="HS256")
def validate_image(image_path):
"""Check image meets API requirements"""
try:
img_size = os.path.getsize(image_path) / 1024 / 1024 # MB
if img_size > 10:
return False, "Image too large (max 10MB)"
# Add actual dimension check if possible (requires PIL)
return True, ""
except Exception as e:
return False, f"Image validation error: {str(e)}"
# ===== API FUNCTIONS =====
def create_image_task(image_base64, prompt):
"""Create image generation task"""
headers = {
"Authorization": f"Bearer {generate_jwt_token()}",
"Content-Type": "application/json"
}
payload = {
"model_name": "kling-v2", # Best for image-to-image
"prompt": prompt,
"image": image_base64,
"resolution": "2k",
"n": 1,
"aspect_ratio": "1:1"
}
try:
response = requests.post(CREATE_TASK_URL, json=payload, headers=headers)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
logger.error(f"API request failed: {str(e)}")
return None
def get_task_result(task_id):
"""Retrieve task results"""
headers = {"Authorization": f"Bearer {generate_jwt_token()}"}
task_url = f"{BASE_URL}/v1/images/generations/{task_id}"
try:
response = requests.get(task_url, headers=headers)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
logger.error(f"Task status check failed: {str(e)}")
return None
# ===== MAIN PROCESSING =====
def generate_image(image_path, prompt=""):
"""Handle end-to-end image generation"""
# Validate input image
is_valid, error_msg = validate_image(image_path)
if not is_valid:
return None, error_msg
# Prepare image data
try:
with open(image_path, "rb") as img_file:
image_base64 = base64.b64encode(img_file.read()).decode("utf-8")
except Exception as e:
return None, f"Image processing error: {str(e)}"
# Create generation task
task_response = create_image_task(image_base64, prompt or "Transform into a vibrant cartoon style")
if not task_response or task_response.get("code") != 0:
return None, "Failed to create task"
task_id = task_response["data"]["task_id"]
logger.info(f"Created task: {task_id}")
# Poll for results (max 10 mins)
for _ in range(60):
task_data = get_task_result(task_id)
if not task_data:
time.sleep(5)
continue
status = task_data["data"]["task_status"]
if status == "succeed":
image_url = task_data["data"]["task_result"]["images"][0]["url"]
try:
img_data = requests.get(image_url).content
output_path = Path(f"/tmp/kling_output_{task_id}.png")
with open(output_path, "wb") as f:
f.write(img_data)
return str(output_path), None
except Exception as e:
return None, f"Failed to save image: {str(e)}"
elif status in ("failed", "canceled"):
return None, f"Task failed: {task_data.get('task_status_msg', 'Unknown error')}"
time.sleep(10)
return None, "Task timed out after 10 minutes"
# ===== GRADIO INTERFACE =====
def chatbot_interface(image, prompt):
if not image:
return None, None, "Please upload an image first"
output_path, error = generate_image(image, prompt)
if error:
return None, None, error
return output_path, output_path, "Generation successful!"
with gr.Blocks(title="Kling AI Image Transformer") as app:
gr.Markdown("# 🎨 Kling AI Image-to-Image Generator")
gr.Markdown("Transform images using Kling AI's Kolors technology")
with gr.Row():
with gr.Column():
gr.Markdown("## Input Settings")
image_input = gr.Image(
type="filepath",
label="Upload Image",
sources=["upload"],
)
prompt_input = gr.Textbox(
lines=2,
label="Transformation Prompt",
placeholder="Describe how you want to transform the image (e.g. 'vibrant watercolor painting')"
)
generate_btn = gr.Button("Generate", variant="primary")
gr.Markdown("### Requirements")
gr.Markdown("""
- Max image size: 10MB
- Min dimensions: 300x300px
- Supported formats: JPG, PNG
- Aspect ratio: Between 1:2.5 and 2.5:1
""")
with gr.Column():
gr.Markdown("## Output")
output_image = gr.Image(label="Generated Image", interactive=False)
output_file = gr.File(label="Download Result", file_types=["image/png"])
status_output = gr.Textbox(label="Status", interactive=False)
generate_btn.click(
fn=chatbot_interface,
inputs=[image_input, prompt_input],
outputs=[output_image, output_file, status_output]
)
if __name__ == "__main__":
app.launch(
server_name="0.0.0.0",
server_port=7860,
share=False,
show_error=True
)