metaai-sdk 2.3.2__tar.gz → 2.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/IMAGE_UPLOAD_README.md +1 -1
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/PKG-INFO +1 -1
- metaai_sdk-2.3.3/final_comprehensive_test.py +302 -0
- metaai_sdk-2.3.3/meta_ai_debug.log +0 -0
- metaai_sdk-2.3.3/quick_video_test.py +122 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/src/metaai_api/api_server.py +6 -2
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/src/metaai_sdk.egg-info/PKG-INFO +1 -1
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/src/metaai_sdk.egg-info/SOURCES.txt +3 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/.env.example +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/CHANGELOG.md +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/CONTRIBUTING.md +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/ChatGPT Image Jan 14, 2026, 06_59_02 PM.png +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/IMPLEMENTATION_SUMMARY.md +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/LICENSE +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/MANIFEST.in +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/QUICK_REFERENCE.md +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/QUICK_USAGE.md +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/README.md +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/SECURITY.md +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/VIDEO_GENERATION_README.md +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/analyze_debug_responses.py +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/debug_async_video_test.py +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/download.jpg +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/enable_debug_logging.py +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/examples/complete_workflow_example.py +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/examples/image_upload_example.py +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/examples/image_workflow_complete.py +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/examples/practical_use_cases.py +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/examples/simple_example.py +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/examples/test_example.py +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/examples/video_generation.py +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/pyproject.toml +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/requirements.txt +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/setup.cfg +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/src/metaai_api/__init__.py +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/src/metaai_api/client.py +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/src/metaai_api/exceptions.py +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/src/metaai_api/image_upload.py +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/src/metaai_api/main.py +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/src/metaai_api/utils.py +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/src/metaai_sdk.egg-info/dependency_links.txt +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/src/metaai_sdk.egg-info/requires.txt +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/src/metaai_sdk.egg-info/top_level.txt +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/test_endpoints.py +0 -0
- {metaai_sdk-2.3.2 → metaai_sdk-2.3.3}/test_image_upload.py +0 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Final Comprehensive Test - All Endpoints
|
|
3
|
+
Tests chat, image, and video endpoints with and without media_ids
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import requests
|
|
7
|
+
import json
|
|
8
|
+
import time
|
|
9
|
+
|
|
10
|
+
API_URL = "http://localhost:8000"
|
|
11
|
+
IMAGE_PATH = r"C:\Users\spike\Downloads\meta-ai-api-main\ChatGPT Image Jan 14, 2026, 06_59_02 PM.png"
|
|
12
|
+
|
|
13
|
+
def print_header(title):
|
|
14
|
+
print("\n" + "="*80)
|
|
15
|
+
print(f" {title}")
|
|
16
|
+
print("="*80)
|
|
17
|
+
|
|
18
|
+
def print_result(success, message):
|
|
19
|
+
symbol = "✓" if success else "✗"
|
|
20
|
+
print(f"{symbol} {message}")
|
|
21
|
+
|
|
22
|
+
# ============================================================================
|
|
23
|
+
# SETUP: Upload Image
|
|
24
|
+
# ============================================================================
|
|
25
|
+
print_header("SETUP: Upload Image for Tests")
|
|
26
|
+
|
|
27
|
+
with open(IMAGE_PATH, 'rb') as f:
|
|
28
|
+
upload_response = requests.post(f"{API_URL}/upload", files={'file': f})
|
|
29
|
+
|
|
30
|
+
if upload_response.status_code != 200:
|
|
31
|
+
print_result(False, f"Upload failed: {upload_response.text}")
|
|
32
|
+
exit(1)
|
|
33
|
+
|
|
34
|
+
upload_result = upload_response.json()
|
|
35
|
+
media_id = upload_result['media_id']
|
|
36
|
+
file_size = upload_result['file_size']
|
|
37
|
+
mime_type = upload_result['mime_type']
|
|
38
|
+
attachment_metadata = {"file_size": file_size, "mime_type": mime_type}
|
|
39
|
+
|
|
40
|
+
print_result(True, f"Uploaded - Media ID: {media_id}")
|
|
41
|
+
|
|
42
|
+
# ============================================================================
|
|
43
|
+
# TEST 1: CHAT WITHOUT MEDIA
|
|
44
|
+
# ============================================================================
|
|
45
|
+
print_header("TEST 1: CHAT Endpoint - WITHOUT media_ids")
|
|
46
|
+
|
|
47
|
+
payload = {
|
|
48
|
+
"message": "What is the capital of France?",
|
|
49
|
+
"stream": False,
|
|
50
|
+
"new_conversation": True
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
try:
|
|
54
|
+
response = requests.post(
|
|
55
|
+
f"{API_URL}/chat",
|
|
56
|
+
headers={"Content-Type": "application/json"},
|
|
57
|
+
data=json.dumps(payload),
|
|
58
|
+
timeout=30
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
if response.status_code == 200:
|
|
62
|
+
result = response.json()
|
|
63
|
+
message = result.get('message', '')
|
|
64
|
+
print_result(True, f"Chat response received ({len(message)} chars)")
|
|
65
|
+
print(f"Response: {message[:200]}...")
|
|
66
|
+
else:
|
|
67
|
+
print_result(False, f"Status {response.status_code}: {response.text[:200]}")
|
|
68
|
+
except Exception as e:
|
|
69
|
+
print_result(False, f"Error: {e}")
|
|
70
|
+
|
|
71
|
+
# ============================================================================
|
|
72
|
+
# TEST 2: CHAT WITH MEDIA
|
|
73
|
+
# ============================================================================
|
|
74
|
+
print_header("TEST 2: CHAT Endpoint - WITH media_ids")
|
|
75
|
+
|
|
76
|
+
payload = {
|
|
77
|
+
"message": "What do you see in this image? Describe it in detail.",
|
|
78
|
+
"media_ids": [media_id],
|
|
79
|
+
"attachment_metadata": attachment_metadata,
|
|
80
|
+
"stream": False,
|
|
81
|
+
"new_conversation": True
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
try:
|
|
85
|
+
response = requests.post(
|
|
86
|
+
f"{API_URL}/chat",
|
|
87
|
+
headers={"Content-Type": "application/json"},
|
|
88
|
+
data=json.dumps(payload),
|
|
89
|
+
timeout=30
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
if response.status_code == 200:
|
|
93
|
+
result = response.json()
|
|
94
|
+
message = result.get('message', '')
|
|
95
|
+
print_result(True, f"Chat with image response received ({len(message)} chars)")
|
|
96
|
+
print(f"Response: {message[:200]}...")
|
|
97
|
+
else:
|
|
98
|
+
print_result(False, f"Status {response.status_code}: {response.text[:200]}")
|
|
99
|
+
except Exception as e:
|
|
100
|
+
print_result(False, f"Error: {e}")
|
|
101
|
+
|
|
102
|
+
# ============================================================================
|
|
103
|
+
# TEST 3: IMAGE WITHOUT MEDIA (Text-to-Image)
|
|
104
|
+
# ============================================================================
|
|
105
|
+
print_header("TEST 3: IMAGE Endpoint - WITHOUT media_ids (Text-to-Image)")
|
|
106
|
+
|
|
107
|
+
payload = {
|
|
108
|
+
"prompt": "A serene mountain landscape at sunset with a lake in the foreground",
|
|
109
|
+
"new_conversation": True
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
try:
|
|
113
|
+
response = requests.post(
|
|
114
|
+
f"{API_URL}/image",
|
|
115
|
+
headers={"Content-Type": "application/json"},
|
|
116
|
+
data=json.dumps(payload),
|
|
117
|
+
timeout=30
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
if response.status_code == 200:
|
|
121
|
+
result = response.json()
|
|
122
|
+
message = result.get('message', '')
|
|
123
|
+
media = result.get('media', [])
|
|
124
|
+
print_result(True, f"Image generation response received")
|
|
125
|
+
print(f"Message: {message[:200]}...")
|
|
126
|
+
print(f"Generated Images: {len(media)}")
|
|
127
|
+
for idx, m in enumerate(media[:2], 1): # Show first 2
|
|
128
|
+
print(f" {idx}. Type: {m.get('type')}, URL: {m.get('url', '')[:80]}...")
|
|
129
|
+
else:
|
|
130
|
+
print_result(False, f"Status {response.status_code}: {response.text[:200]}")
|
|
131
|
+
except Exception as e:
|
|
132
|
+
print_result(False, f"Error: {e}")
|
|
133
|
+
|
|
134
|
+
# ============================================================================
|
|
135
|
+
# TEST 4: IMAGE WITH MEDIA (Image-to-Image)
|
|
136
|
+
# ============================================================================
|
|
137
|
+
print_header("TEST 4: IMAGE Endpoint - WITH media_ids (Image-to-Image)")
|
|
138
|
+
|
|
139
|
+
payload = {
|
|
140
|
+
"prompt": "Create a similar image in anime style",
|
|
141
|
+
"media_ids": [media_id],
|
|
142
|
+
"attachment_metadata": attachment_metadata,
|
|
143
|
+
"new_conversation": True
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
try:
|
|
147
|
+
response = requests.post(
|
|
148
|
+
f"{API_URL}/image",
|
|
149
|
+
headers={"Content-Type": "application/json"},
|
|
150
|
+
data=json.dumps(payload),
|
|
151
|
+
timeout=30
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
if response.status_code == 200:
|
|
155
|
+
result = response.json()
|
|
156
|
+
message = result.get('message', '')
|
|
157
|
+
media = result.get('media', [])
|
|
158
|
+
print_result(True, f"Image-to-image response received")
|
|
159
|
+
print(f"Message: {message[:200]}...")
|
|
160
|
+
print(f"Generated Images: {len(media)}")
|
|
161
|
+
for idx, m in enumerate(media[:2], 1): # Show first 2
|
|
162
|
+
print(f" {idx}. Type: {m.get('type')}, URL: {m.get('url', '')[:80]}...")
|
|
163
|
+
else:
|
|
164
|
+
print_result(False, f"Status {response.status_code}: {response.text[:200]}")
|
|
165
|
+
except Exception as e:
|
|
166
|
+
print_result(False, f"Error: {e}")
|
|
167
|
+
|
|
168
|
+
# ============================================================================
|
|
169
|
+
# TEST 5: VIDEO WITHOUT MEDIA (Text-to-Video)
|
|
170
|
+
# ============================================================================
|
|
171
|
+
print_header("TEST 5: VIDEO Endpoint - WITHOUT media_ids (Text-to-Video)")
|
|
172
|
+
|
|
173
|
+
payload = {
|
|
174
|
+
"prompt": "A beautiful sunset over the ocean with waves",
|
|
175
|
+
"wait_before_poll": 10,
|
|
176
|
+
"max_attempts": 30,
|
|
177
|
+
"wait_seconds": 5,
|
|
178
|
+
"verbose": False
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
try:
|
|
182
|
+
print("Submitting async video job (text-to-video)...")
|
|
183
|
+
response = requests.post(
|
|
184
|
+
f"{API_URL}/video/async",
|
|
185
|
+
headers={"Content-Type": "application/json"},
|
|
186
|
+
data=json.dumps(payload),
|
|
187
|
+
timeout=30
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
if response.status_code == 200:
|
|
191
|
+
result = response.json()
|
|
192
|
+
job_id = result['job_id']
|
|
193
|
+
print_result(True, f"Job submitted - ID: {job_id}")
|
|
194
|
+
|
|
195
|
+
# Poll for result
|
|
196
|
+
print("Polling for result (max 15 attempts, 3s interval)...")
|
|
197
|
+
for attempt in range(1, 16):
|
|
198
|
+
time.sleep(3)
|
|
199
|
+
print(f" Attempt {attempt}/15...", end=" ")
|
|
200
|
+
|
|
201
|
+
status_response = requests.get(f"{API_URL}/video/jobs/{job_id}")
|
|
202
|
+
if status_response.status_code == 200:
|
|
203
|
+
job_status = status_response.json()
|
|
204
|
+
status = job_status['status']
|
|
205
|
+
print(f"Status: {status}")
|
|
206
|
+
|
|
207
|
+
if status == 'succeeded':
|
|
208
|
+
job_result = job_status.get('result', {})
|
|
209
|
+
video_urls = job_result.get('video_urls', [])
|
|
210
|
+
print_result(True, f"Text-to-video SUCCEEDED! Found {len(video_urls)} video(s)")
|
|
211
|
+
for idx, url in enumerate(video_urls, 1):
|
|
212
|
+
print(f" Video {idx}: {url[:80]}...")
|
|
213
|
+
break
|
|
214
|
+
elif status == 'failed':
|
|
215
|
+
error = job_status.get('error', 'Unknown error')
|
|
216
|
+
print_result(False, f"Text-to-video FAILED: {error}")
|
|
217
|
+
break
|
|
218
|
+
else:
|
|
219
|
+
print(f"Failed to get status")
|
|
220
|
+
else:
|
|
221
|
+
print_result(False, "Max polling attempts reached")
|
|
222
|
+
else:
|
|
223
|
+
print_result(False, f"Status {response.status_code}: {response.text[:200]}")
|
|
224
|
+
except Exception as e:
|
|
225
|
+
print_result(False, f"Error: {e}")
|
|
226
|
+
|
|
227
|
+
# ============================================================================
|
|
228
|
+
# TEST 6: VIDEO WITH MEDIA (Image-to-Video)
|
|
229
|
+
# ============================================================================
|
|
230
|
+
print_header("TEST 6: VIDEO Endpoint - WITH media_ids (Image-to-Video)")
|
|
231
|
+
|
|
232
|
+
payload = {
|
|
233
|
+
"prompt": "generate a cinematic video with smooth zoom effect",
|
|
234
|
+
"media_ids": [media_id],
|
|
235
|
+
"attachment_metadata": attachment_metadata,
|
|
236
|
+
"wait_before_poll": 10,
|
|
237
|
+
"max_attempts": 30,
|
|
238
|
+
"wait_seconds": 5,
|
|
239
|
+
"verbose": False
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
try:
|
|
243
|
+
print("Submitting async video job (image-to-video)...")
|
|
244
|
+
response = requests.post(
|
|
245
|
+
f"{API_URL}/video/async",
|
|
246
|
+
headers={"Content-Type": "application/json"},
|
|
247
|
+
data=json.dumps(payload),
|
|
248
|
+
timeout=30
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
if response.status_code == 200:
|
|
252
|
+
result = response.json()
|
|
253
|
+
job_id = result['job_id']
|
|
254
|
+
print_result(True, f"Job submitted - ID: {job_id}")
|
|
255
|
+
|
|
256
|
+
# Poll for result
|
|
257
|
+
print("Polling for result (max 15 attempts, 3s interval)...")
|
|
258
|
+
for attempt in range(1, 16):
|
|
259
|
+
time.sleep(3)
|
|
260
|
+
print(f" Attempt {attempt}/15...", end=" ")
|
|
261
|
+
|
|
262
|
+
status_response = requests.get(f"{API_URL}/video/jobs/{job_id}")
|
|
263
|
+
if status_response.status_code == 200:
|
|
264
|
+
job_status = status_response.json()
|
|
265
|
+
status = job_status['status']
|
|
266
|
+
print(f"Status: {status}")
|
|
267
|
+
|
|
268
|
+
if status == 'succeeded':
|
|
269
|
+
job_result = job_status.get('result', {})
|
|
270
|
+
video_urls = job_result.get('video_urls', [])
|
|
271
|
+
print_result(True, f"Image-to-video SUCCEEDED! Found {len(video_urls)} video(s)")
|
|
272
|
+
for idx, url in enumerate(video_urls, 1):
|
|
273
|
+
print(f" Video {idx}: {url[:80]}...")
|
|
274
|
+
break
|
|
275
|
+
elif status == 'failed':
|
|
276
|
+
error = job_status.get('error', 'Unknown error')
|
|
277
|
+
print_result(False, f"Image-to-video FAILED: {error}")
|
|
278
|
+
break
|
|
279
|
+
else:
|
|
280
|
+
print(f"Failed to get status")
|
|
281
|
+
else:
|
|
282
|
+
print_result(False, "Max polling attempts reached")
|
|
283
|
+
else:
|
|
284
|
+
print_result(False, f"Status {response.status_code}: {response.text[:200]}")
|
|
285
|
+
except Exception as e:
|
|
286
|
+
print_result(False, f"Error: {e}")
|
|
287
|
+
|
|
288
|
+
# ============================================================================
|
|
289
|
+
# SUMMARY
|
|
290
|
+
# ============================================================================
|
|
291
|
+
print_header("TEST SUMMARY")
|
|
292
|
+
print("""
|
|
293
|
+
Tests Completed:
|
|
294
|
+
✓ Chat without media (text chat)
|
|
295
|
+
✓ Chat with media (image analysis)
|
|
296
|
+
✓ Image without media (text-to-image)
|
|
297
|
+
✓ Image with media (image-to-image)
|
|
298
|
+
✓ Video without media (text-to-video)
|
|
299
|
+
✓ Video with media (image-to-video)
|
|
300
|
+
|
|
301
|
+
All major use cases tested!
|
|
302
|
+
""")
|
|
File without changes
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"""Quick test for video generation with fixed URL extraction."""
|
|
2
|
+
import requests
|
|
3
|
+
import json
|
|
4
|
+
import time
|
|
5
|
+
|
|
6
|
+
API_URL = "http://localhost:8000"
|
|
7
|
+
IMAGE_PATH = r"C:\Users\spike\Downloads\meta-ai-api-main\ChatGPT Image Jan 14, 2026, 06_59_02 PM.png"
|
|
8
|
+
|
|
9
|
+
print("\n" + "="*80)
|
|
10
|
+
print("QUICK VIDEO GENERATION TEST")
|
|
11
|
+
print("="*80)
|
|
12
|
+
|
|
13
|
+
# Step 1: Upload image
|
|
14
|
+
print("\n[1/3] Uploading image...")
|
|
15
|
+
with open(IMAGE_PATH, 'rb') as f:
|
|
16
|
+
upload_response = requests.post(f"{API_URL}/upload", files={'file': f})
|
|
17
|
+
|
|
18
|
+
if upload_response.status_code != 200:
|
|
19
|
+
print(f"✗ Upload failed: {upload_response.text}")
|
|
20
|
+
exit(1)
|
|
21
|
+
|
|
22
|
+
upload_result = upload_response.json()
|
|
23
|
+
media_id = upload_result['media_id']
|
|
24
|
+
file_size = upload_result['file_size']
|
|
25
|
+
mime_type = upload_result['mime_type']
|
|
26
|
+
|
|
27
|
+
print(f"✓ Uploaded - Media ID: {media_id}")
|
|
28
|
+
|
|
29
|
+
# Step 2: Submit async video job
|
|
30
|
+
print("\n[2/3] Submitting async video job...")
|
|
31
|
+
|
|
32
|
+
payload = {
|
|
33
|
+
"prompt": "generate a cinematic video with smooth camera movement",
|
|
34
|
+
"media_ids": [media_id],
|
|
35
|
+
"attachment_metadata": {
|
|
36
|
+
"file_size": file_size,
|
|
37
|
+
"mime_type": mime_type
|
|
38
|
+
},
|
|
39
|
+
"wait_before_poll": 10,
|
|
40
|
+
"max_attempts": 30,
|
|
41
|
+
"wait_seconds": 5,
|
|
42
|
+
"verbose": False
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
job_response = requests.post(
|
|
46
|
+
f"{API_URL}/video/async",
|
|
47
|
+
headers={"Content-Type": "application/json"},
|
|
48
|
+
data=json.dumps(payload)
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
if job_response.status_code != 200:
|
|
52
|
+
print(f"✗ Job submission failed: {job_response.text}")
|
|
53
|
+
exit(1)
|
|
54
|
+
|
|
55
|
+
job_result = job_response.json()
|
|
56
|
+
job_id = job_result['job_id']
|
|
57
|
+
print(f"✓ Job submitted - Job ID: {job_id}")
|
|
58
|
+
|
|
59
|
+
# Step 3: Poll job status
|
|
60
|
+
print("\n[3/3] Polling job status...")
|
|
61
|
+
print(f"Will poll up to 20 times (every 3 seconds)...\n")
|
|
62
|
+
|
|
63
|
+
max_polls = 20
|
|
64
|
+
for poll_num in range(1, max_polls + 1):
|
|
65
|
+
time.sleep(3)
|
|
66
|
+
|
|
67
|
+
print(f"Poll #{poll_num}/{max_polls}...", end=" ")
|
|
68
|
+
|
|
69
|
+
status_response = requests.get(f"{API_URL}/video/jobs/{job_id}")
|
|
70
|
+
|
|
71
|
+
if status_response.status_code != 200:
|
|
72
|
+
print(f"✗ Failed to get status")
|
|
73
|
+
continue
|
|
74
|
+
|
|
75
|
+
job_status = status_response.json()
|
|
76
|
+
current_status = job_status['status']
|
|
77
|
+
|
|
78
|
+
print(f"Status: {current_status}")
|
|
79
|
+
|
|
80
|
+
if current_status == 'succeeded':
|
|
81
|
+
print("\n" + "="*80)
|
|
82
|
+
print("✓✓✓ JOB SUCCEEDED ✓✓✓")
|
|
83
|
+
print("="*80)
|
|
84
|
+
|
|
85
|
+
result = job_status.get('result', {})
|
|
86
|
+
video_urls = result.get('video_urls', [])
|
|
87
|
+
|
|
88
|
+
print(f"\nSuccess Flag: {result.get('success')}")
|
|
89
|
+
print(f"Conversation ID: {result.get('conversation_id')}")
|
|
90
|
+
print(f"Video URLs Count: {len(video_urls)}")
|
|
91
|
+
|
|
92
|
+
if video_urls:
|
|
93
|
+
print(f"\n✓✓✓ FOUND {len(video_urls)} VIDEO URL(S)! ✓✓✓")
|
|
94
|
+
for idx, url in enumerate(video_urls, 1):
|
|
95
|
+
print(f"\nVideo {idx}:")
|
|
96
|
+
print(f" URL: {url}")
|
|
97
|
+
print(f" Length: {len(url)} chars")
|
|
98
|
+
print(f" Has .mp4: {'.mp4' in url}")
|
|
99
|
+
print(f" Has fbcdn: {'fbcdn' in url}")
|
|
100
|
+
else:
|
|
101
|
+
print("\n✗✗✗ NO VIDEO URLs FOUND ✗✗✗")
|
|
102
|
+
print("Check meta_ai_debug.log for extraction details")
|
|
103
|
+
|
|
104
|
+
print(f"\nFull Result:")
|
|
105
|
+
print(json.dumps(job_status, indent=2))
|
|
106
|
+
break
|
|
107
|
+
|
|
108
|
+
elif current_status == 'failed':
|
|
109
|
+
print("\n" + "="*80)
|
|
110
|
+
print("✗✗✗ JOB FAILED ✗✗✗")
|
|
111
|
+
print("="*80)
|
|
112
|
+
error = job_status.get('error', 'Unknown error')
|
|
113
|
+
print(f"Error: {error}")
|
|
114
|
+
print(f"\nFull Result:")
|
|
115
|
+
print(json.dumps(job_status, indent=2))
|
|
116
|
+
break
|
|
117
|
+
else:
|
|
118
|
+
print(f"\n⚠ Reached max polls. Check manually: GET {API_URL}/video/jobs/{job_id}")
|
|
119
|
+
|
|
120
|
+
print("\n" + "="*80)
|
|
121
|
+
print("TEST COMPLETE - Check meta_ai_debug.log for detailed extraction logs")
|
|
122
|
+
print("="*80)
|
|
@@ -216,8 +216,10 @@ async def chat(body: ChatRequest, cookies: Dict[str, str] = Depends(get_cookies)
|
|
|
216
216
|
async def image(body: ImageRequest, cookies: Dict[str, str] = Depends(get_cookies)) -> Dict[str, Any]:
|
|
217
217
|
ai = MetaAI(cookies=cookies, proxy=_get_proxies())
|
|
218
218
|
try:
|
|
219
|
+
# Automatically prepend "generate image of" to the prompt
|
|
220
|
+
prompt = f"generate image of {body.prompt}" if not body.prompt.lower().startswith(("generate image", "create image")) else body.prompt
|
|
219
221
|
return cast(Dict[str, Any], ai.prompt(
|
|
220
|
-
|
|
222
|
+
prompt,
|
|
221
223
|
stream=False,
|
|
222
224
|
new_conversation=body.new_conversation,
|
|
223
225
|
media_ids=body.media_ids,
|
|
@@ -233,9 +235,11 @@ async def image(body: ImageRequest, cookies: Dict[str, str] = Depends(get_cookie
|
|
|
233
235
|
async def video(body: VideoRequest, cookies: Dict[str, str] = Depends(get_cookies)) -> Dict[str, Any]:
|
|
234
236
|
ai = MetaAI(cookies=cookies, proxy=_get_proxies())
|
|
235
237
|
try:
|
|
238
|
+
# Automatically prepend "generate a video" to the prompt
|
|
239
|
+
prompt = f"generate a video {body.prompt}" if not body.prompt.lower().startswith(("generate a video", "generate video", "create a video", "create video")) else body.prompt
|
|
236
240
|
return await run_in_threadpool(
|
|
237
241
|
ai.generate_video,
|
|
238
|
-
|
|
242
|
+
prompt,
|
|
239
243
|
body.media_ids,
|
|
240
244
|
body.attachment_metadata,
|
|
241
245
|
body.wait_before_poll,
|
|
@@ -15,7 +15,10 @@ analyze_debug_responses.py
|
|
|
15
15
|
debug_async_video_test.py
|
|
16
16
|
download.jpg
|
|
17
17
|
enable_debug_logging.py
|
|
18
|
+
final_comprehensive_test.py
|
|
19
|
+
meta_ai_debug.log
|
|
18
20
|
pyproject.toml
|
|
21
|
+
quick_video_test.py
|
|
19
22
|
requirements.txt
|
|
20
23
|
test_endpoints.py
|
|
21
24
|
test_image_upload.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|