AkashKumarave commited on
Commit
ae39b5f
·
verified ·
1 Parent(s): c3f22c6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +139 -67
app.py CHANGED
@@ -1,114 +1,186 @@
1
  import gradio as gr
2
  import requests
3
  import base64
4
- from pathlib import Path
5
- import jwt
6
  import time
 
7
  import logging
 
8
 
9
- # Set up logging for debugging
10
- logging.basicConfig(level=logging.DEBUG)
11
  logger = logging.getLogger(__name__)
12
 
13
- # Kling AI API configuration
14
  ACCESS_KEY_ID = "AFyHfnQATghFdCMyAG3gRPbNY4TNKFGB"
15
  ACCESS_KEY_SECRET = "TTepeLyBterLNM3brYPGmdndBnnyKJBA"
16
- API_URL = "https://api-singapore.klingai.com/v1/images/generations"
 
17
 
 
18
  def generate_jwt_token():
19
- """Generate JWT token for Kling AI API authentication."""
20
  payload = {
21
  "iss": ACCESS_KEY_ID,
22
- "exp": int(time.time()) + 1800,
23
- "nbf": int(time.time()) - 5
24
  }
25
- token = jwt.encode(payload, ACCESS_KEY_SECRET, algorithm="HS256")
26
- return token if isinstance(token, str) else token.decode("utf-8")
27
-
28
- def generate_image(image, prompt=""):
29
- """Call Kling AI API for image-to-image generation."""
30
- if not image:
31
- return None, "Error: Please upload a valid image."
32
 
 
 
33
  try:
34
- with open(image, "rb") as img_file:
35
- image_base64 = base64.b64encode(img_file.read()).decode("utf-8")
 
 
 
 
36
  except Exception as e:
37
- return None, f"Error: Failed to process image. Details: {str(e)}"
38
 
 
 
 
39
  headers = {
40
  "Authorization": f"Bearer {generate_jwt_token()}",
41
  "Content-Type": "application/json"
42
  }
43
-
44
  payload = {
45
- "model": "kolors-v2.1",
46
- "prompt": prompt or "Transform the face into a cartoon style while preserving identity",
47
- "image_base64_list": [image_base64],
48
- "strength": 0.97,
49
- "output_format": "png",
50
- "num_outputs": 1,
51
  "aspect_ratio": "1:1"
52
  }
 
 
 
 
 
 
 
 
53
 
 
 
 
 
 
54
  try:
55
- logger.debug(f"Sending POST to {API_URL} with payload")
56
- response = requests.post(API_URL, json=payload, headers=headers, timeout=30)
57
  response.raise_for_status()
58
- data = response.json()
59
- logger.debug(f"API response: {data}")
 
 
60
 
61
- task_id = data.get("data", {}).get("task_id")
62
- if not task_id:
63
- return None, "Error: No task ID returned."
 
 
 
 
64
 
65
- # Poll task until completion
66
- status_url = f"https://api-singapore.klingai.com/v1/images/task/{task_id}"
67
- for _ in range(60): # up to 5 minutes
68
- status_response = requests.get(status_url, headers=headers, timeout=30)
69
- status_response.raise_for_status()
70
- status_data = status_response.json()
71
- logger.debug(f"Status: {status_data}")
72
- task_status = status_data.get("data", {}).get("task_status")
73
- if task_status == "succeed":
74
- image_url = status_data["data"]["images"][0]["url"]
75
- img_resp = requests.get(image_url, timeout=30)
76
- output_path = Path("/tmp/output_image.png")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  with open(output_path, "wb") as f:
78
- f.write(img_resp.content)
79
  return str(output_path), None
80
- elif task_status in ("failed", "canceled"):
81
- return None, f"Error: Task failed. Details: {status_data}"
82
- time.sleep(5)
83
- return None, "Error: Task polling timed out."
84
-
85
- except requests.exceptions.RequestException as e:
86
- return None, f"Error: API request failed. Details: {str(e)}"
 
 
87
 
 
88
  def chatbot_interface(image, prompt):
 
 
 
89
  output_path, error = generate_image(image, prompt)
90
  if error:
91
  return None, None, error
92
- return output_path, output_path, None
 
93
 
94
- # Define Gradio interface
95
- with gr.Blocks() as iface:
96
- gr.Markdown("# Kling AI Image-to-Image Generator")
 
97
  with gr.Row():
98
  with gr.Column():
99
- image_input = gr.Image(type="filepath", label="Upload Image")
100
- prompt_input = gr.Textbox(lines=2, placeholder="Enter prompt", label="Prompt")
101
- generate_button = gr.Button("Generate")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  with gr.Column():
103
- output_image = gr.Image(label="Generated Image")
104
- output_file = gr.File(label="Download Generated Image")
105
- error_message = gr.Textbox(label="Status/Error Message", interactive=False)
106
-
107
- generate_button.click(
 
108
  fn=chatbot_interface,
109
  inputs=[image_input, prompt_input],
110
- outputs=[output_image, output_file, error_message]
111
  )
112
 
113
  if __name__ == "__main__":
114
- iface.launch(server_name="0.0.0.0", server_port=7860)
 
 
 
 
 
 
1
  import gradio as gr
2
  import requests
3
  import base64
4
+ import os
 
5
  import time
6
+ import jwt
7
  import logging
8
+ from pathlib import Path
9
 
10
+ # Set up logging
11
+ logging.basicConfig(level=logging.INFO)
12
  logger = logging.getLogger(__name__)
13
 
14
+ # ===== CONFIGURATION =====
15
  ACCESS_KEY_ID = "AFyHfnQATghFdCMyAG3gRPbNY4TNKFGB"
16
  ACCESS_KEY_SECRET = "TTepeLyBterLNM3brYPGmdndBnnyKJBA"
17
+ BASE_URL = "https://api-singapore.klingai.com"
18
+ CREATE_TASK_URL = f"{BASE_URL}/v1/images/generations"
19
 
20
+ # ===== UTILITY FUNCTIONS =====
21
  def generate_jwt_token():
22
+ """Generate JWT token for API authentication"""
23
  payload = {
24
  "iss": ACCESS_KEY_ID,
25
+ "exp": int(time.time()) + 1800, # Expires in 30 mins
26
+ "nbf": int(time.time()) - 5 # Not before 5 seconds ago
27
  }
28
+ return jwt.encode(payload, ACCESS_KEY_SECRET, algorithm="HS256")
 
 
 
 
 
 
29
 
30
+ def validate_image(image_path):
31
+ """Check image meets API requirements"""
32
  try:
33
+ img_size = os.path.getsize(image_path) / 1024 / 1024 # MB
34
+ if img_size > 10:
35
+ return False, "Image too large (max 10MB)"
36
+
37
+ # Add actual dimension check if possible (requires PIL)
38
+ return True, ""
39
  except Exception as e:
40
+ return False, f"Image validation error: {str(e)}"
41
 
42
+ # ===== API FUNCTIONS =====
43
+ def create_image_task(image_base64, prompt):
44
+ """Create image generation task"""
45
  headers = {
46
  "Authorization": f"Bearer {generate_jwt_token()}",
47
  "Content-Type": "application/json"
48
  }
49
+
50
  payload = {
51
+ "model_name": "kling-v2", # Best for image-to-image
52
+ "prompt": prompt,
53
+ "image": image_base64,
54
+ "resolution": "2k",
55
+ "n": 1,
 
56
  "aspect_ratio": "1:1"
57
  }
58
+
59
+ try:
60
+ response = requests.post(CREATE_TASK_URL, json=payload, headers=headers)
61
+ response.raise_for_status()
62
+ return response.json()
63
+ except requests.exceptions.RequestException as e:
64
+ logger.error(f"API request failed: {str(e)}")
65
+ return None
66
 
67
+ def get_task_result(task_id):
68
+ """Retrieve task results"""
69
+ headers = {"Authorization": f"Bearer {generate_jwt_token()}"}
70
+ task_url = f"{BASE_URL}/v1/images/generations/{task_id}"
71
+
72
  try:
73
+ response = requests.get(task_url, headers=headers)
 
74
  response.raise_for_status()
75
+ return response.json()
76
+ except requests.exceptions.RequestException as e:
77
+ logger.error(f"Task status check failed: {str(e)}")
78
+ return None
79
 
80
+ # ===== MAIN PROCESSING =====
81
+ def generate_image(image_path, prompt=""):
82
+ """Handle end-to-end image generation"""
83
+ # Validate input image
84
+ is_valid, error_msg = validate_image(image_path)
85
+ if not is_valid:
86
+ return None, error_msg
87
 
88
+ # Prepare image data
89
+ try:
90
+ with open(image_path, "rb") as img_file:
91
+ image_base64 = base64.b64encode(img_file.read()).decode("utf-8")
92
+ except Exception as e:
93
+ return None, f"Image processing error: {str(e)}"
94
+
95
+ # Create generation task
96
+ task_response = create_image_task(image_base64, prompt or "Transform into a vibrant cartoon style")
97
+ if not task_response or task_response.get("code") != 0:
98
+ return None, "Failed to create task"
99
+
100
+ task_id = task_response["data"]["task_id"]
101
+ logger.info(f"Created task: {task_id}")
102
+
103
+ # Poll for results (max 10 mins)
104
+ for _ in range(60):
105
+ task_data = get_task_result(task_id)
106
+ if not task_data:
107
+ time.sleep(5)
108
+ continue
109
+
110
+ status = task_data["data"]["task_status"]
111
+
112
+ if status == "succeed":
113
+ image_url = task_data["data"]["task_result"]["images"][0]["url"]
114
+ try:
115
+ img_data = requests.get(image_url).content
116
+ output_path = Path(f"/tmp/kling_output_{task_id}.png")
117
  with open(output_path, "wb") as f:
118
+ f.write(img_data)
119
  return str(output_path), None
120
+ except Exception as e:
121
+ return None, f"Failed to save image: {str(e)}"
122
+
123
+ elif status in ("failed", "canceled"):
124
+ return None, f"Task failed: {task_data.get('task_status_msg', 'Unknown error')}"
125
+
126
+ time.sleep(10)
127
+
128
+ return None, "Task timed out after 10 minutes"
129
 
130
+ # ===== GRADIO INTERFACE =====
131
  def chatbot_interface(image, prompt):
132
+ if not image:
133
+ return None, None, "Please upload an image first"
134
+
135
  output_path, error = generate_image(image, prompt)
136
  if error:
137
  return None, None, error
138
+
139
+ return output_path, output_path, "Generation successful!"
140
 
141
+ with gr.Blocks(title="Kling AI Image Transformer") as app:
142
+ gr.Markdown("# 🎨 Kling AI Image-to-Image Generator")
143
+ gr.Markdown("Transform images using Kling AI's Kolors technology")
144
+
145
  with gr.Row():
146
  with gr.Column():
147
+ gr.Markdown("## Input Settings")
148
+ image_input = gr.Image(
149
+ type="filepath",
150
+ label="Upload Image",
151
+ sources=["upload"],
152
+ )
153
+ prompt_input = gr.Textbox(
154
+ lines=2,
155
+ label="Transformation Prompt",
156
+ placeholder="Describe how you want to transform the image (e.g. 'vibrant watercolor painting')"
157
+ )
158
+ generate_btn = gr.Button("Generate", variant="primary")
159
+
160
+ gr.Markdown("### Requirements")
161
+ gr.Markdown("""
162
+ - Max image size: 10MB
163
+ - Min dimensions: 300x300px
164
+ - Supported formats: JPG, PNG
165
+ - Aspect ratio: Between 1:2.5 and 2.5:1
166
+ """)
167
+
168
  with gr.Column():
169
+ gr.Markdown("## Output")
170
+ output_image = gr.Image(label="Generated Image", interactive=False)
171
+ output_file = gr.File(label="Download Result", file_types=["image/png"])
172
+ status_output = gr.Textbox(label="Status", interactive=False)
173
+
174
+ generate_btn.click(
175
  fn=chatbot_interface,
176
  inputs=[image_input, prompt_input],
177
+ outputs=[output_image, output_file, status_output]
178
  )
179
 
180
  if __name__ == "__main__":
181
+ app.launch(
182
+ server_name="0.0.0.0",
183
+ server_port=7860,
184
+ share=False,
185
+ show_error=True
186
+ )