Fred808 commited on
Commit
f995463
·
verified ·
1 Parent(s): 8e3a102

Update download_api.py

Browse files
Files changed (1) hide show
  1. download_api.py +99 -5
download_api.py CHANGED
@@ -5,6 +5,7 @@ import threading
5
  from fastapi import FastAPI, HTTPException, BackgroundTasks
6
  from fastapi.middleware.cors import CORSMiddleware
7
  from fastapi.responses import JSONResponse, FileResponse
 
8
  import uvicorn
9
  from typing import Dict
10
  from pathlib import Path
@@ -13,18 +14,18 @@ from datetime import datetime
13
 
14
  import torch
15
 
16
-
17
  # Import from vision_analyzer (previously cursor_tracker)
18
  from vision_analyzer import (
19
  main_processing_loop,
20
  processing_status,
21
  ANALYSIS_OUTPUT_FOLDER, # Changed from CURSOR_TRACKING_OUTPUT_FOLDER
22
- log_message
 
23
  )
24
 
25
  # FastAPI App Definition
26
  app = FastAPI(title="Video Analysis API",
27
- description="API to access video frame analysis results",
28
  version="1.0.0")
29
 
30
  # Add CORS middleware to allow cross-origin requests
@@ -71,6 +72,9 @@ async def root():
71
  "/status": "Get processing status",
72
  "/analysis-data": "List available analysis files",
73
  "/analysis-data/{filename}": "Get specific analysis data",
 
 
 
74
  "/start-processing": "Start processing pipeline",
75
  "/stop-processing": "Stop processing pipeline"
76
  }
@@ -82,9 +86,97 @@ async def get_status():
82
  return {
83
  "processing_status": processing_status,
84
  "analysis_folder": ANALYSIS_OUTPUT_FOLDER,
85
- "folder_exists": os.path.exists(ANALYSIS_OUTPUT_FOLDER)
 
 
86
  }
87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  @app.get("/analysis-data")
89
  async def list_analysis_data():
90
  """List all available analysis JSON files"""
@@ -257,6 +349,7 @@ if __name__ == "__main__":
257
 
258
  # Ensure the analysis output folder exists
259
  os.makedirs(ANALYSIS_OUTPUT_FOLDER, exist_ok=True)
 
260
 
261
  uvicorn.run(
262
  app,
@@ -264,4 +357,5 @@ if __name__ == "__main__":
264
  port=8000,
265
  log_level="info",
266
  reload=False # Set to False for production
267
- )
 
 
5
  from fastapi import FastAPI, HTTPException, BackgroundTasks
6
  from fastapi.middleware.cors import CORSMiddleware
7
  from fastapi.responses import JSONResponse, FileResponse
8
+ from fastapi.staticfiles import StaticFiles
9
  import uvicorn
10
  from typing import Dict
11
  from pathlib import Path
 
14
 
15
  import torch
16
 
 
17
  # Import from vision_analyzer (previously cursor_tracker)
18
  from vision_analyzer import (
19
  main_processing_loop,
20
  processing_status,
21
  ANALYSIS_OUTPUT_FOLDER, # Changed from CURSOR_TRACKING_OUTPUT_FOLDER
22
+ log_message,
23
+ FRAMES_OUTPUT_FOLDER # Add this import for frames directory
24
  )
25
 
26
  # FastAPI App Definition
27
  app = FastAPI(title="Video Analysis API",
28
+ description="API to access video frame analysis results and extracted images",
29
  version="1.0.0")
30
 
31
  # Add CORS middleware to allow cross-origin requests
 
72
  "/status": "Get processing status",
73
  "/analysis-data": "List available analysis files",
74
  "/analysis-data/{filename}": "Get specific analysis data",
75
+ "/courses": "List all available course folders",
76
+ "/images/{course_folder}": "List images in a course folder",
77
+ "/images/{course_folder}/{frame_filename}": "Get specific frame image",
78
  "/start-processing": "Start processing pipeline",
79
  "/stop-processing": "Stop processing pipeline"
80
  }
 
86
  return {
87
  "processing_status": processing_status,
88
  "analysis_folder": ANALYSIS_OUTPUT_FOLDER,
89
+ "frames_folder": FRAMES_OUTPUT_FOLDER,
90
+ "analysis_folder_exists": os.path.exists(ANALYSIS_OUTPUT_FOLDER),
91
+ "frames_folder_exists": os.path.exists(FRAMES_OUTPUT_FOLDER)
92
  }
93
 
94
+ # ===== NEW IMAGE SERVING ENDPOINTS =====
95
+
96
+ @app.get("/images/{course_folder}/{frame_filename}")
97
+ async def get_frame_image(course_folder: str, frame_filename: str):
98
+ """
99
+ Serve extracted frame images from course folders
100
+
101
+ Args:
102
+ course_folder: The course folder name (e.g., "course1_video1_mp4_frames")
103
+ frame_filename: The frame file name (e.g., "0001.png")
104
+ """
105
+ # Construct the full path to the image
106
+ image_path = os.path.join(FRAMES_OUTPUT_FOLDER, course_folder, frame_filename)
107
+
108
+ # Check if file exists
109
+ if not os.path.exists(image_path):
110
+ raise HTTPException(status_code=404, detail=f"Image not found: {course_folder}/{frame_filename}")
111
+
112
+ # Verify it's an image file
113
+ if not frame_filename.lower().endswith(('.png', '.jpg', '.jpeg')):
114
+ raise HTTPException(status_code=400, detail="File must be an image (PNG, JPG, JPEG)")
115
+
116
+ # Return the image file
117
+ return FileResponse(image_path)
118
+
119
+ @app.get("/images/{course_folder}")
120
+ async def list_course_images(course_folder: str):
121
+ """
122
+ List all available images in a specific course folder
123
+
124
+ Args:
125
+ course_folder: The course folder name
126
+ """
127
+ folder_path = os.path.join(FRAMES_OUTPUT_FOLDER, course_folder)
128
+
129
+ if not os.path.exists(folder_path):
130
+ raise HTTPException(status_code=404, detail=f"Course folder not found: {course_folder}")
131
+
132
+ # Get all image files
133
+ image_files = []
134
+ for file in os.listdir(folder_path):
135
+ if file.lower().endswith(('.png', '.jpg', '.jpeg')):
136
+ file_path = os.path.join(folder_path, file)
137
+ file_stats = os.stat(file_path)
138
+ image_files.append({
139
+ "filename": file,
140
+ "size_bytes": file_stats.st_size,
141
+ "modified_time": time.ctime(file_stats.st_mtime),
142
+ "url": f"/images/{course_folder}/{file}"
143
+ })
144
+
145
+ return {
146
+ "course_folder": course_folder,
147
+ "total_images": len(image_files),
148
+ "images": image_files
149
+ }
150
+
151
+ @app.get("/courses")
152
+ async def list_all_courses():
153
+ """
154
+ List all available course folders with their image counts
155
+ """
156
+ if not os.path.exists(FRAMES_OUTPUT_FOLDER):
157
+ return {"courses": [], "message": "Frames output folder does not exist yet"}
158
+
159
+ courses = []
160
+ for folder in os.listdir(FRAMES_OUTPUT_FOLDER):
161
+ folder_path = os.path.join(FRAMES_OUTPUT_FOLDER, folder)
162
+ if os.path.isdir(folder_path):
163
+ # Count image files
164
+ image_count = len([f for f in os.listdir(folder_path)
165
+ if f.lower().endswith(('.png', '.jpg', '.jpeg'))])
166
+ courses.append({
167
+ "course_folder": folder,
168
+ "image_count": image_count,
169
+ "images_url": f"/images/{folder}",
170
+ "sample_image_url": f"/images/{folder}/0001.png" if image_count > 0 else None
171
+ })
172
+
173
+ return {
174
+ "total_courses": len(courses),
175
+ "courses": courses
176
+ }
177
+
178
+ # ===== EXISTING ANALYSIS ENDPOINTS =====
179
+
180
  @app.get("/analysis-data")
181
  async def list_analysis_data():
182
  """List all available analysis JSON files"""
 
349
 
350
  # Ensure the analysis output folder exists
351
  os.makedirs(ANALYSIS_OUTPUT_FOLDER, exist_ok=True)
352
+ os.makedirs(FRAMES_OUTPUT_FOLDER, exist_ok=True)
353
 
354
  uvicorn.run(
355
  app,
 
357
  port=8000,
358
  log_level="info",
359
  reload=False # Set to False for production
360
+ )
361
+