jomasego commited on
Commit
996f027
·
1 Parent(s): cc456c6

Refactor: Send video URL as JSON to backend to fix 413 error

Browse files
Files changed (1) hide show
  1. app.py +83 -138
app.py CHANGED
@@ -108,164 +108,109 @@ def process_video_input(input_string: str) -> Dict[str, Any]:
108
  }
109
 
110
  video_path_to_process = None
111
- created_temp_dir = None # To store path of temp directory if created for download
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
 
113
  try:
114
  if input_string.startswith(('http://', 'https://')):
115
- print(f"Input is a URL: {input_string}")
116
- created_temp_dir = tempfile.mkdtemp()
117
- print(f"Created temporary directory for download: {created_temp_dir}")
118
- downloaded_path = download_video(input_string, created_temp_dir)
119
-
120
- if downloaded_path and os.path.exists(downloaded_path):
121
- video_path_to_process = downloaded_path
122
- else:
123
- # Error message is already printed by download_video or this block
124
- print(f"Failed to download or locate video from URL: {input_string}")
125
- # Cleanup is handled in finally, so just return error
126
- return {
127
- "status": "error",
128
- "error_details": {
129
- "message": "Failed to download video from URL.",
130
- "input_received": input_string
131
- }
132
- }
133
 
134
  elif os.path.exists(input_string):
135
- print(f"Input is a local file path: {input_string}")
136
- video_path_to_process = input_string
137
- else:
138
- return {
139
- "status": "error",
140
- "error_details": {
141
- "message": f"Input '{input_string}' is not a valid URL or an existing file path.",
142
- "input_received": input_string
143
- }
144
- }
145
-
146
- if video_path_to_process:
147
- print(f"Processing video: {video_path_to_process}")
148
- print(f"Video path to process: {video_path_to_process}")
149
  try:
150
- print("Reading video file into bytes...")
151
  with open(video_path_to_process, "rb") as video_file:
152
  video_bytes_content = video_file.read()
153
- print(f"Read {len(video_bytes_content)} bytes from video file.")
154
-
155
- # Ensure MODAL_TOKEN_ID and MODAL_TOKEN_SECRET are set as environment variables
156
- # in your Hugging Face Space. For local `python app.py` runs, Modal CLI's
157
- # authenticated state is usually used.
158
- # os.environ["MODAL_TOKEN_ID"] = "your_modal_token_id" # Replace or set in HF Space
159
- # os.environ["MODAL_TOKEN_SECRET"] = "your_modal_token_secret" # Replace or set in HF Space
160
-
161
- print("Preparing to call Modal FastAPI endpoint for comprehensive analysis...")
162
- # IMPORTANT: Replace this with your actual Modal app's deployed FastAPI endpoint URL
163
- # This URL is typically found in your Modal deployment logs or dashboard.
164
- # It will look something like: https://YOUR_MODAL_WORKSPACE--video-analysis-gradio-pipeline-process-video-for-analysis.modal.run/analyze_video
165
- # Or, if the FastAPI endpoint function itself is not separately deployed but part of the main app deployment:
166
- # https://YOUR_MODAL_WORKSPACE--video-analysis-gradio-pipeline-fastapi-app.modal.run/analyze_video
167
- # (The exact name depends on how Modal names the deployed web endpoint for the FastAPI app)
168
- # For now, using a placeholder. This MUST be configured.
169
- base_modal_url = os.getenv("MODAL_APP_BASE_URL")
170
- if not base_modal_url:
171
- print("ERROR: MODAL_APP_BASE_URL environment variable not set.")
172
- return {
173
- "status": "error",
174
- "error_details": {
175
- "message": "Modal application base URL is not configured. Please set the MODAL_APP_BASE_URL environment variable.",
176
- "input_received": input_string
177
- }
178
- }
179
- modal_endpoint_url = f"{base_modal_url.rstrip('/')}/analyze_video"
180
-
181
  files = {'video_file': (os.path.basename(video_path_to_process), video_bytes_content, 'video/mp4')}
182
-
183
- print(f"Calling Modal endpoint: {modal_endpoint_url}")
184
- try:
185
- response = requests.post(modal_endpoint_url, files=files, timeout=1860) # Timeout slightly longer than Modal function
186
- response.raise_for_status() # Raise an exception for HTTP errors (4xx or 5xx)
187
- analysis_results = response.json()
188
- print(f"Received results from Modal endpoint: {str(analysis_results)[:200]}...")
189
- return {
190
- "status": "success",
191
- "data": analysis_results
192
- }
193
- except requests.exceptions.Timeout:
194
- print(f"Request to Modal endpoint {modal_endpoint_url} timed out.")
195
- return {
196
- "status": "error",
197
- "error_details": {
198
- "message": "Request to video analysis service timed out.",
199
- "endpoint_url": modal_endpoint_url
200
- }
201
- }
202
- except requests.exceptions.HTTPError as e:
203
- print(f"HTTP error calling Modal endpoint {modal_endpoint_url}: {e.response.status_code} - {e.response.text}")
204
- return {
205
- "status": "error",
206
- "error_details": {
207
- "message": f"Video analysis service returned an error: {e.response.status_code}",
208
- "details": e.response.text,
209
- "endpoint_url": modal_endpoint_url
210
- }
211
- }
212
- except requests.exceptions.RequestException as e:
213
- print(f"Error calling Modal endpoint {MODAL_ENDPOINT_URL}: {e}")
214
- return {
215
- "status": "error",
216
- "error_details": {
217
- "message": "Failed to connect to video analysis service.",
218
- "details": str(e),
219
- "endpoint_url": MODAL_ENDPOINT_URL
220
- }
221
- }
222
- except FileNotFoundError:
223
- print(f"Error: Video file not found at {video_path_to_process} before sending to Modal.")
224
- return {
225
  "status": "error",
226
  "error_details": {
227
- "message": "Video file disappeared before processing.",
228
  "path_attempted": video_path_to_process
229
  }
230
  }
231
- except modal.Error as e: # Using modal.Error as the base Modal exception
232
- print(f"Modal specific error: {e}")
233
- return {
234
- "status": "error",
235
- "error_details": {
236
- "message": f"Error during Modal operation: {str(e)}",
237
- "exception_type": type(e).__name__
238
- }
239
- }
240
- except Exception as e:
241
- print(f"An unexpected error occurred while calling Modal: {e}")
242
- import traceback
243
- traceback.print_exc()
244
- return {
245
- "status": "error",
246
- "error_details": {
247
- "message": f"Failed to get transcription: {str(e)}",
248
- "exception_type": type(e).__name__
249
- }
250
- }
251
  else:
252
- # This case should ideally be caught by earlier checks
253
- return {
 
254
  "status": "error",
255
  "error_details": {
256
- "message": "No video available to process after input handling.",
257
  "input_received": input_string
258
  }
259
  }
260
-
261
- finally:
262
- if created_temp_dir and os.path.exists(created_temp_dir):
263
- print(f"Cleaning up temporary directory: {created_temp_dir}")
264
- try:
265
- shutil.rmtree(created_temp_dir)
266
- print(f"Successfully removed temporary directory: {created_temp_dir}")
267
- except Exception as e:
268
- print(f"Error removing temporary directory {created_temp_dir}: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
 
270
  # Gradio Interface for the API endpoint
271
  api_interface = gr.Interface(
 
108
  }
109
 
110
  video_path_to_process = None
111
+ # Get base_modal_url and construct modal_endpoint_url
112
+ base_modal_url = os.getenv("MODAL_APP_BASE_URL")
113
+ if not base_modal_url:
114
+ print("ERROR: MODAL_APP_BASE_URL environment variable not set.")
115
+ return {
116
+ "status": "error",
117
+ "error_details": {
118
+ "message": "Modal application base URL is not configured. Please set the MODAL_APP_BASE_URL environment variable.",
119
+ "input_received": input_string
120
+ }
121
+ }
122
+ modal_endpoint_url = f"{base_modal_url.rstrip('/')}/analyze_video"
123
+ print(f"Target Modal endpoint: {modal_endpoint_url}")
124
+
125
+ response_json = None # Initialize to ensure it's always defined before return
126
 
127
  try:
128
  if input_string.startswith(('http://', 'https://')):
129
+ print(f"Input is a URL: {input_string}. Sending URL to Modal endpoint as JSON.")
130
+ payload = {"video_url": input_string}
131
+ headers = {'Content-Type': 'application/json'}
132
+ response = requests.post(modal_endpoint_url, json=payload, headers=headers, timeout=1860)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
 
134
  elif os.path.exists(input_string):
135
+ print(f"Input is a local file path: {input_string}. Sending file content to Modal endpoint.")
136
+ video_path_to_process = input_string # Use input_string as the path
 
 
 
 
 
 
 
 
 
 
 
 
137
  try:
 
138
  with open(video_path_to_process, "rb") as video_file:
139
  video_bytes_content = video_file.read()
140
+ print(f"Read {len(video_bytes_content)} bytes from video file '{video_path_to_process}'.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  files = {'video_file': (os.path.basename(video_path_to_process), video_bytes_content, 'video/mp4')}
142
+ response = requests.post(modal_endpoint_url, files=files, timeout=1860)
143
+ except FileNotFoundError: # Catch if file disappears just before open
144
+ print(f"Error: Video file not found at {video_path_to_process} when trying to read for upload.")
145
+ return { # Return immediately
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  "status": "error",
147
  "error_details": {
148
+ "message": "Video file disappeared before it could be read for upload.",
149
  "path_attempted": video_path_to_process
150
  }
151
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  else:
153
+ # This handles cases where input_string is neither a URL nor an existing file path
154
+ print(f"Input '{input_string}' is not a valid URL or an existing file path.")
155
+ return { # Return immediately
156
  "status": "error",
157
  "error_details": {
158
+ "message": f"Input '{input_string}' is not a valid URL or an existing file path.",
159
  "input_received": input_string
160
  }
161
  }
162
+
163
+ # Common response handling
164
+ response.raise_for_status() # Raise an exception for HTTP errors (4xx or 5xx)
165
+ analysis_results = response.json()
166
+ print(f"Received results from Modal endpoint: {str(analysis_results)[:200]}...")
167
+ response_json = {
168
+ "status": "success",
169
+ "data": analysis_results
170
+ }
171
+
172
+ except requests.exceptions.Timeout:
173
+ print(f"Request to Modal endpoint {modal_endpoint_url} timed out.")
174
+ response_json = {
175
+ "status": "error",
176
+ "error_details": {
177
+ "message": "Request to video analysis service timed out.",
178
+ "endpoint_url": modal_endpoint_url
179
+ }
180
+ }
181
+ except requests.exceptions.HTTPError as e:
182
+ print(f"HTTP error calling Modal endpoint {modal_endpoint_url}: {e.response.status_code} - {e.response.text}")
183
+ response_json = {
184
+ "status": "error",
185
+ "error_details": {
186
+ "message": f"Video analysis service returned an error: {e.response.status_code}",
187
+ "details": e.response.text,
188
+ "endpoint_url": modal_endpoint_url
189
+ }
190
+ }
191
+ except requests.exceptions.RequestException as e: # General request exception
192
+ print(f"Error calling Modal endpoint {modal_endpoint_url}: {e}") # Corrected MODAL_ENDPOINT_URL to modal_endpoint_url
193
+ response_json = {
194
+ "status": "error",
195
+ "error_details": {
196
+ "message": "Failed to connect to video analysis service.",
197
+ "details": str(e),
198
+ "endpoint_url": modal_endpoint_url # Corrected MODAL_ENDPOINT_URL to modal_endpoint_url
199
+ }
200
+ }
201
+ except Exception as e: # Catch-all for other unexpected errors
202
+ print(f"An unexpected error occurred in process_video_input: {e}")
203
+ import traceback
204
+ traceback.print_exc()
205
+ response_json = {
206
+ "status": "error",
207
+ "error_details": {
208
+ "message": f"An unexpected error occurred: {str(e)}",
209
+ "exception_type": type(e).__name__
210
+ }
211
+ }
212
+
213
+ return response_json
214
 
215
  # Gradio Interface for the API endpoint
216
  api_interface = gr.Interface(