MySafeCode commited on
Commit
3c3161a
·
verified ·
1 Parent(s): cd80757

Delete lapi.py

Browse files
Files changed (1) hide show
  1. lapi.py +0 -291
lapi.py DELETED
@@ -1,291 +0,0 @@
1
- import os
2
- import time
3
- import gradio as gr
4
- from byteplussdkarkruntime import Ark
5
- import requests
6
-
7
- # Get API key from Hugging Face secret "Key" and CLEAN it
8
- API_KEY = os.environ.get("Key", "").strip()
9
- print(f"✅ Key loaded, length: {len(API_KEY)}")
10
-
11
- # Initialize client with proxy
12
- client = Ark(
13
- base_url="https://1hit.no/proxy/proxy.php",
14
- api_key=API_KEY,
15
- timeout=30.0,
16
- max_retries=3,
17
- )
18
-
19
- # Fresh new prompts
20
- DEFAULT_PROMPTS = {
21
- "Cinematic Nature": "Majestic drone shot soaring above misty mountains at golden hour, sunlight breaking through clouds, cinematic 4k quality, smooth motion --duration 5 --camerafixed false",
22
- "Urban Exploration": "Dynamic drone flight through narrow alleyways of a neon-lit Tokyo street at night, rain-slicked surfaces reflecting lights, cyberpunk aesthetic --duration 5 --camerafixed false",
23
- "Action Sequence": "High-speed drone chasing a sports car through a winding coastal road, dramatic cliffside views, action movie style --duration 5 --camerafixed false",
24
- "Abstract Art": "Surreal drone flight through floating geometric shapes in a dreamlike void, pastel colors, ethereal atmosphere --duration 5 --camerafixed false",
25
- "Wildlife Documentary": "Drone following a herd of elephants across the African savanna at sunset, National Geographic style, majestic wildlife cinematography --duration 5 --camerafixed false",
26
- "Sports Highlight": "Drone racing alongside professional skiers carving through fresh powder in the Alps, high-energy sports broadcast style --duration 5 --camerafixed false",
27
- "Beach Paradise": "Drone gliding over turquoise waters and white sand beaches, palm trees swaying, tropical paradise aerial view --duration 5 --camerafixed false",
28
- "Ancient Temple": "Drone circling around ancient Angkor Wat temple at dawn, mystical atmosphere, historical documentary style --duration 5 --camerafixed false"
29
- }
30
-
31
- def poll_via_json(task_id):
32
- """Check io.json for task status"""
33
- json_url = "https://1hit.no/proxy/io.json"
34
- try:
35
- response = requests.get(json_url)
36
- data = response.json()
37
- if task_id in data:
38
- task_data = data[task_id]
39
- status = task_data.get('status')
40
- if status == 'succeeded':
41
- return task_data.get('video_url')
42
- elif status == 'failed':
43
- return "FAILED"
44
- else:
45
- return "PROCESSING"
46
- except:
47
- pass
48
- return None
49
-
50
- def generate_video(image_path, prompt_text, progress=gr.Progress()):
51
- """Generate video with proper polling"""
52
-
53
- if not API_KEY:
54
- yield "❌ API Key not configured. Please add 'Key' secret.", None
55
- return
56
-
57
- if image_path is None:
58
- yield "⚠️ Please upload an image first", None
59
- return
60
-
61
- try:
62
- progress(0, desc="Preparing image...")
63
-
64
- # FOR TESTING: Use working image URL
65
- image_url = "https://ark-doc.tos-ap-southeast-1.bytepluses.com/seepro_i2v%20.png"
66
- print(f"Using image URL: {image_url}")
67
-
68
- yield "✅ Image ready! Creating video request...", None
69
-
70
- progress(0.2, desc="Creating request...")
71
-
72
- # Create task
73
- try:
74
- create_result = client.content_generation.tasks.create(
75
- model="seedance-1-5-pro-251215",
76
- content=[
77
- {"type": "text", "text": prompt_text},
78
- {"type": "image_url", "image_url": {"url": image_url}}
79
- ]
80
- )
81
- except Exception as e:
82
- yield f"❌ API Error: {str(e)}", None
83
- return
84
-
85
- task_id = create_result.id
86
- print(f"Task created: {task_id}")
87
- yield f"✅ Task created: {task_id}", None
88
-
89
- progress(0.3, desc="Polling for results...")
90
-
91
- # Poll for results - TRY SDK FIRST, then fallback to JSON
92
- attempts = 0
93
- max_attempts = 120
94
- used_fallback = False
95
-
96
- while attempts < max_attempts:
97
- try:
98
- # Try SDK method first
99
- get_result = client.content_generation.tasks.get(task_id=task_id)
100
- status = get_result.status
101
-
102
- if status == "succeeded":
103
- progress(1.0, desc="Complete!")
104
- video_url = get_result.content.video_url if hasattr(get_result, 'content') else None
105
- yield "✅ Video generated successfully!", video_url
106
- return
107
-
108
- elif status == "failed":
109
- error_msg = get_result.error if hasattr(get_result, 'error') else "Unknown error"
110
- yield f"❌ Failed: {error_msg}", None
111
- return
112
- else:
113
- progress(0.3 + (attempts/max_attempts)*0.7, desc=f"Status: {status}")
114
- yield f"⏳ Status: {status}... (attempt {attempts + 1})", None
115
- time.sleep(2)
116
- attempts += 1
117
-
118
- except Exception as e:
119
- # If SDK fails, use JSON fallback
120
- if not used_fallback:
121
- print("SDK polling failed, using JSON fallback...")
122
- used_fallback = True
123
-
124
- # Poll JSON every 5 seconds
125
- result = poll_via_json(task_id)
126
- if result == "FAILED":
127
- yield "❌ Task failed (via JSON)", None
128
- return
129
- elif result and result != "PROCESSING":
130
- yield "✅ Video generated successfully! (via JSON)", result
131
- return
132
- else:
133
- progress(0.3 + (attempts/max_attempts)*0.7, desc="Status: processing (JSON)")
134
- yield f"⏳ Status: processing... (JSON fallback, attempt {attempts + 1})", None
135
- time.sleep(5)
136
- attempts += 1
137
-
138
- yield "⏰ Timeout after 2 minutes", None
139
-
140
- except Exception as e:
141
- yield f"❌ Error: {str(e)}", None
142
-
143
- def update_prompt(choice):
144
- return DEFAULT_PROMPTS.get(choice, "")
145
-
146
- # MANUAL POLLING FUNCTIONS
147
- def manual_poll(task_id):
148
- """Manually poll a specific task and update io.json"""
149
- if not task_id:
150
- return "❌ Please enter a task ID"
151
-
152
- try:
153
- # Call proxy to poll this specific task
154
- url = f"https://1hit.no/proxy/proxy.php?task_id={task_id}"
155
- headers = {"Authorization": f"Bearer {API_KEY}"}
156
-
157
- response = requests.get(url, headers=headers)
158
-
159
- # Also fetch updated io.json
160
- io_response = requests.get("https://1hit.no/proxy/io.json")
161
- io_data = io_response.json()
162
-
163
- if task_id in io_data:
164
- status = io_data[task_id].get('status')
165
- video_url = io_data[task_id].get('video_url')
166
-
167
- result = f"✅ Task {task_id}\n"
168
- result += f"Status: {status}\n"
169
- if video_url:
170
- result += f"Video URL: {video_url}\n"
171
- if 'response' in io_data[task_id]:
172
- result += f"Full response: {io_data[task_id]['response']}\n"
173
- return result
174
- else:
175
- return f"❌ Task {task_id} not found in io.json"
176
-
177
- except Exception as e:
178
- return f"❌ Error: {str(e)}"
179
-
180
- def get_raw_json():
181
- """Fetch raw io.json"""
182
- try:
183
- r = requests.get("https://1hit.no/proxy/io.json")
184
- return r.json()
185
- except:
186
- return {"error": "Could not fetch io.json"}
187
-
188
- # Create the interface WITHOUT theme in Blocks constructor
189
- with gr.Blocks(title="BytePlus Video Generator") as demo:
190
-
191
- gr.Markdown("# 🎥 BytePlus Video Generator")
192
-
193
- with gr.Row():
194
- if API_KEY:
195
- gr.Markdown("✅ **API Key:** Configured")
196
- else:
197
- gr.Markdown("❌ **API Key:** Not configured - please add 'Key' secret")
198
-
199
- # Create tabs properly in Gradio 6.5.1
200
- with gr.Tabs():
201
- with gr.TabItem("🎬 Generate Video"):
202
- with gr.Row():
203
- with gr.Column():
204
- image_input = gr.Image(
205
- label="Upload Starting Image",
206
- type="filepath",
207
- height=300
208
- )
209
-
210
- shot_type = gr.Dropdown(
211
- choices=list(DEFAULT_PROMPTS.keys()),
212
- label="🎬 Shot Type",
213
- value="Cinematic Nature"
214
- )
215
-
216
- prompt = gr.Textbox(
217
- label="📝 Custom Prompt",
218
- lines=3,
219
- value=DEFAULT_PROMPTS["Cinematic Nature"]
220
- )
221
-
222
- shot_type.change(fn=update_prompt, inputs=shot_type, outputs=prompt)
223
-
224
- generate_btn = gr.Button("🚀 Generate Video", variant="primary", size="lg")
225
-
226
- with gr.Column():
227
- status = gr.Textbox(label="Status", lines=6)
228
- video_output = gr.Video(label="Generated Video")
229
-
230
- # Quick shot buttons
231
- gr.Markdown("### Quick Shot Select")
232
- with gr.Row():
233
- gr.Button("🏔️ Nature").click(fn=lambda: "Cinematic Nature", outputs=shot_type)
234
- gr.Button("🌃 City").click(fn=lambda: "Urban Exploration", outputs=shot_type)
235
- gr.Button("🏎️ Action").click(fn=lambda: "Action Sequence", outputs=shot_type)
236
- gr.Button("🎨 Abstract").click(fn=lambda: "Abstract Art", outputs=shot_type)
237
- gr.Button("🦁 Wildlife").click(fn=lambda: "Wildlife Documentary", outputs=shot_type)
238
- gr.Button("⛷️ Sports").click(fn=lambda: "Sports Highlight", outputs=shot_type)
239
-
240
- with gr.TabItem("🔧 Manual Polling"):
241
- gr.Markdown("### 🔧 Manual Polling & Debug")
242
-
243
- with gr.Row():
244
- with gr.Column():
245
- gr.Markdown("#### Poll Specific Task")
246
- task_id_input = gr.Textbox(
247
- label="Task ID",
248
- placeholder="Enter task ID (cgt-...)"
249
- )
250
- poll_btn = gr.Button("🔄 Poll Now", variant="primary")
251
- poll_result = gr.Textbox(label="Poll Result", lines=10)
252
-
253
- poll_btn.click(
254
- fn=manual_poll,
255
- inputs=task_id_input,
256
- outputs=poll_result
257
- )
258
-
259
- with gr.Column():
260
- gr.Markdown("#### Current io.json")
261
- refresh_btn = gr.Button("🔄 Refresh io.json", variant="secondary")
262
- raw_json = gr.JSON(label="io.json Contents")
263
-
264
- refresh_btn.click(
265
- fn=get_raw_json,
266
- outputs=raw_json
267
- )
268
-
269
- gr.Markdown("""
270
- ### 📝 Instructions
271
- 1. Copy a task ID from above (like `cgt-20260217072358-hszt9`)
272
- 2. Paste it in the Task ID field
273
- 3. Click "Poll Now" to force an update
274
- 4. Check io.json to see if status changed
275
-
276
- This manually triggers the proxy to poll BytePlus for updates!
277
- """)
278
-
279
- # Connect generate button
280
- generate_btn.click(
281
- fn=generate_video,
282
- inputs=[image_input, prompt],
283
- outputs=[status, video_output]
284
- )
285
-
286
- if __name__ == "__main__":
287
- # Move theme to launch()
288
- demo.launch(
289
- server_name="0.0.0.0",
290
- theme=gr.themes.Soft()
291
- )