Refactor: enhance API response schemas for pagination; update environment variables for Supabase and Vision API; improve Vite configuration for proxy routing
This commit is contained in:
@@ -71,13 +71,21 @@ class VideoInfoResponse(BaseModel):
|
||||
class VideoListResponse(BaseModel):
|
||||
"""Video list response"""
|
||||
videos: List[VideoInfoResponse] = Field(..., description="List of videos")
|
||||
total_count: int = Field(..., description="Total number of videos")
|
||||
total_count: int = Field(..., description="Total number of matching videos (ignores pagination)")
|
||||
page: Optional[int] = Field(None, description="Current page number (if using page/limit)")
|
||||
total_pages: Optional[int] = Field(None, description="Total pages (if using page/limit)")
|
||||
has_next: Optional[bool] = Field(None, description="Is there a next page?")
|
||||
has_previous: Optional[bool] = Field(None, description="Is there a previous page?")
|
||||
|
||||
class Config:
|
||||
schema_extra = {
|
||||
"example": {
|
||||
"videos": [],
|
||||
"total_count": 0
|
||||
"total_count": 0,
|
||||
"page": 1,
|
||||
"total_pages": 1,
|
||||
"has_next": False,
|
||||
"has_previous": False
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +116,8 @@ class VideoListRequest(BaseModel):
|
||||
start_date: Optional[datetime] = Field(None, description="Filter by start date")
|
||||
end_date: Optional[datetime] = Field(None, description="Filter by end date")
|
||||
limit: Optional[int] = Field(50, description="Maximum number of results")
|
||||
include_metadata: bool = Field(False, description="Include video metadata")
|
||||
offset: Optional[int] = Field(0, description="Number of items to skip (for pagination)")
|
||||
include_metadata: bool = Field(False, description="Include video metadata for returned items only")
|
||||
|
||||
class Config:
|
||||
schema_extra = {
|
||||
@@ -117,6 +126,7 @@ class VideoListRequest(BaseModel):
|
||||
"start_date": "2025-08-04T00:00:00",
|
||||
"end_date": "2025-08-04T23:59:59",
|
||||
"limit": 50,
|
||||
"offset": 0,
|
||||
"include_metadata": True
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
version: "3.9"
|
||||
|
||||
services:
|
||||
api:
|
||||
build:
|
||||
@@ -8,11 +6,14 @@ services:
|
||||
working_dir: /app
|
||||
volumes:
|
||||
- ./camera-management-api:/app
|
||||
- ./camera-management-api/storage:/storage
|
||||
- /storage:/storage
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
environment:
|
||||
- PYTHONUNBUFFERED=1
|
||||
- LD_LIBRARY_PATH=/usr/local/lib:/lib:/usr/lib
|
||||
- PYTHONPATH=/app:/app/camera_sdk
|
||||
- TZ=America/New_York
|
||||
command: >
|
||||
sh -lc "
|
||||
apt-get update && apt-get install -y libusb-1.0-0-dev;
|
||||
@@ -39,8 +40,7 @@ services:
|
||||
# Start the application
|
||||
python main.py --config config.compose.json
|
||||
"
|
||||
ports:
|
||||
- "8000:8000"
|
||||
network_mode: host
|
||||
|
||||
web:
|
||||
image: node:20-alpine
|
||||
@@ -49,13 +49,15 @@ services:
|
||||
- ./management-dashboard-web-app:/app
|
||||
environment:
|
||||
- CHOKIDAR_USEPOLLING=true
|
||||
- VITE_SUPABASE_URL=${VITE_SUPABASE_URL}
|
||||
- VITE_SUPABASE_ANON_KEY=${VITE_SUPABASE_ANON_KEY}
|
||||
- TZ=America/New_York
|
||||
command: >
|
||||
sh -lc "
|
||||
npm ci;
|
||||
npm run dev -- --host 0.0.0.0 --port 8080
|
||||
"
|
||||
# Ensure the web container can resolve host.docker.internal on Linux
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
ports:
|
||||
- "8080:8080"
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Environment Configuration for Pecan Experiments Application
|
||||
|
||||
# USDA Vision Camera System API Configuration
|
||||
# Default: http://localhost:8000 (current working setup)
|
||||
# For localhost setup, use: http://localhost:8000
|
||||
# For remote systems, use: http://192.168.1.100:8000 (replace with actual IP)
|
||||
VITE_VISION_API_URL=http://localhost:8000
|
||||
# Recommended default: use a relative path so the dev server proxy routes to the API container
|
||||
# Leave unset to default to "/api" (see vite.config.ts proxy)
|
||||
# To override and point directly, set e.g.:
|
||||
# VITE_VISION_API_URL=http://vm-host-or-ip:8000
|
||||
|
||||
# Supabase Configuration (if needed for production)
|
||||
# VITE_SUPABASE_URL=your_supabase_url
|
||||
|
||||
@@ -15,9 +15,8 @@ import {
|
||||
} from '../types';
|
||||
import { performanceMonitor } from '../utils/performanceMonitor';
|
||||
|
||||
// Configuration - Use environment variable or default to vision container
|
||||
// The API is accessible at localhost:8000 in the current setup
|
||||
const API_BASE_URL = import.meta.env.VITE_VISION_API_URL || 'http://localhost:8000';
|
||||
// Configuration - Prefer env var; default to relative "/api" so Vite proxy can route to the API container
|
||||
const API_BASE_URL = import.meta.env.VITE_VISION_API_URL || '/api';
|
||||
|
||||
/**
|
||||
* Custom error class for video API errors
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import { createClient } from '@supabase/supabase-js'
|
||||
|
||||
// Local development configuration
|
||||
const supabaseUrl = 'http://127.0.0.1:54321'
|
||||
const supabaseAnonKey = '[REDACTED]'
|
||||
// Supabase configuration from environment (Vite)
|
||||
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL
|
||||
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY
|
||||
|
||||
if (!supabaseUrl || !supabaseAnonKey) {
|
||||
throw new Error('Supabase is not configured. Please set VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY in your environment (.env)')
|
||||
}
|
||||
|
||||
export const supabase = createClient(supabaseUrl, supabaseAnonKey)
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Vision System API Client
|
||||
// Base URL for the vision system API - Use environment variable or default to vision container
|
||||
// The API is accessible at localhost:8000 in the current setup
|
||||
const VISION_API_BASE_URL = import.meta.env.VITE_VISION_API_URL || 'http://localhost:8000'
|
||||
// Base URL for the vision system API - Prefer env var; default to relative "/api" so Vite proxy can route to the API container
|
||||
const VISION_API_BASE_URL = import.meta.env.VITE_VISION_API_URL || '/api'
|
||||
|
||||
// Types based on the API documentation
|
||||
export interface SystemStatus {
|
||||
@@ -424,8 +423,8 @@ class VisionApiClient {
|
||||
} catch (error: any) {
|
||||
// If the error is related to missing auto-recording fields, try to handle it gracefully
|
||||
if (error.message?.includes('auto_start_recording_enabled') ||
|
||||
error.message?.includes('auto_recording_max_retries') ||
|
||||
error.message?.includes('auto_recording_retry_delay_seconds')) {
|
||||
error.message?.includes('auto_recording_max_retries') ||
|
||||
error.message?.includes('auto_recording_retry_delay_seconds')) {
|
||||
|
||||
// Try to get the raw camera data and add default auto-recording fields
|
||||
try {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
interface ImportMetaEnv {
|
||||
readonly VITE_SUPABASE_URL: string;
|
||||
readonly VITE_SUPABASE_ANON_KEY: string;
|
||||
readonly VITE_VISION_API_URL?: string; // optional; defaults to "/api" via vite proxy
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
|
||||
@@ -1 +1 @@
|
||||
v2.31.8
|
||||
v2.33.9
|
||||
@@ -9,9 +9,16 @@ export default defineConfig({
|
||||
tailwindcss(),
|
||||
],
|
||||
server: {
|
||||
// Allow connecting via this VM's hostname
|
||||
allowedHosts: ['exp-dash'],
|
||||
// host is provided via CLI in docker-compose, but keeping this commented for local use:
|
||||
// host: true,
|
||||
// Allow connections from the VM hostname and any other host/IP
|
||||
allowedHosts: ['exp-dash', 'localhost'],
|
||||
// Proxy API calls from the browser to the API container via the compose service name
|
||||
proxy: {
|
||||
'/api': {
|
||||
// Route to API via the host so this works whether API is on bridge (via port mapping) or host network
|
||||
target: 'http://host.docker.internal:8000',
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api/, ''),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user