Spaces:
Sleeping
Sleeping
Navy
commited on
Commit
·
d5327ae
1
Parent(s):
1b6f8a9
feat: adding code response
Browse files- app.py +28 -16
- core/defect_detection.py +2 -9
app.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
from fastapi import FastAPI
|
|
|
|
| 2 |
from fastapi.middleware.cors import CORSMiddleware
|
| 3 |
from ultralytics import YOLO
|
| 4 |
|
|
@@ -70,7 +71,15 @@ async def start_detection(data: Dict):
|
|
| 70 |
cameras = data.get("cameras", [])
|
| 71 |
|
| 72 |
if not station_id or not parts or not webhook_url or not cameras:
|
| 73 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
|
| 75 |
# -------------------------------
|
| 76 |
# VALIDATION BEFORE EXECUTION
|
|
@@ -87,14 +96,15 @@ async def start_detection(data: Dict):
|
|
| 87 |
logger.error("[VALIDATION FAILED] Input data is invalid.")
|
| 88 |
for err in validation_errors:
|
| 89 |
logger.error(f" - {err}")
|
| 90 |
-
return
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
|
|
|
| 98 |
logger.info(f"[INFO] Get metadata parts")
|
| 99 |
model_path = model_by_id_metadata(parts['id'])
|
| 100 |
|
|
@@ -112,13 +122,15 @@ async def start_detection(data: Dict):
|
|
| 112 |
# running background
|
| 113 |
asyncio.create_task(run_detection_group(station_id, cameras, webhook_url, model, parts))
|
| 114 |
|
| 115 |
-
return
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
|
|
|
|
|
|
| 122 |
|
| 123 |
|
| 124 |
# ============================================================
|
|
|
|
| 1 |
from fastapi import FastAPI
|
| 2 |
+
from fastapi.responses import JSONResponse
|
| 3 |
from fastapi.middleware.cors import CORSMiddleware
|
| 4 |
from ultralytics import YOLO
|
| 5 |
|
|
|
|
| 71 |
cameras = data.get("cameras", [])
|
| 72 |
|
| 73 |
if not station_id or not parts or not webhook_url or not cameras:
|
| 74 |
+
return JSONResponse(
|
| 75 |
+
status_code=400,
|
| 76 |
+
content={
|
| 77 |
+
"status": "error",
|
| 78 |
+
"station_id": station_id,
|
| 79 |
+
"camera_count": len(cameras),
|
| 80 |
+
"message": "Missing required fields"
|
| 81 |
+
}
|
| 82 |
+
)
|
| 83 |
|
| 84 |
# -------------------------------
|
| 85 |
# VALIDATION BEFORE EXECUTION
|
|
|
|
| 96 |
logger.error("[VALIDATION FAILED] Input data is invalid.")
|
| 97 |
for err in validation_errors:
|
| 98 |
logger.error(f" - {err}")
|
| 99 |
+
return JSONResponse(
|
| 100 |
+
status_code=400,
|
| 101 |
+
content={
|
| 102 |
+
"status": "error",
|
| 103 |
+
"station_id": station_id,
|
| 104 |
+
"camera_count": len(cameras),
|
| 105 |
+
"message": " | ".join(validation_errors)
|
| 106 |
+
}
|
| 107 |
+
)
|
| 108 |
logger.info(f"[INFO] Get metadata parts")
|
| 109 |
model_path = model_by_id_metadata(parts['id'])
|
| 110 |
|
|
|
|
| 122 |
# running background
|
| 123 |
asyncio.create_task(run_detection_group(station_id, cameras, webhook_url, model, parts))
|
| 124 |
|
| 125 |
+
return JSONResponse(
|
| 126 |
+
status_code=200,
|
| 127 |
+
content={
|
| 128 |
+
"status": "started",
|
| 129 |
+
"station_id": station_id,
|
| 130 |
+
"camera_count": len(cameras),
|
| 131 |
+
"message": "Detection is running in background."
|
| 132 |
+
}
|
| 133 |
+
)
|
| 134 |
|
| 135 |
|
| 136 |
# ============================================================
|
core/defect_detection.py
CHANGED
|
@@ -10,9 +10,9 @@ load_dotenv()
|
|
| 10 |
MODEL_VERSION = os.getenv("MODEL_VERSION","v1.0.0")
|
| 11 |
WEBHOOK_URL = os.getenv("WEBHOOK_URL")
|
| 12 |
|
| 13 |
-
MAX_RUNTIME_SEC = float(os.getenv("MAX_RUNTIME_SEC", "
|
| 14 |
FRAME_FAIL_SLEEP = float(os.getenv("FRAME_FAIL_SLEEP", "0.05"))
|
| 15 |
-
DEFAULT_FPS = float(os.getenv("DEFAULT_FPS", "
|
| 16 |
WEBHOOK_TIMEOUT = float(os.getenv("WEBHOOK_TIMEOUT", "10.0"))
|
| 17 |
|
| 18 |
# ============================================================
|
|
@@ -31,7 +31,6 @@ def detect_defect_from_video_url(station_id, camera_id: str, video_url: str, mod
|
|
| 31 |
if not cap.isOpened():
|
| 32 |
logger.error(f"[ERROR] Cannot open video URL: {video_url}")
|
| 33 |
return {
|
| 34 |
-
"code": 400,
|
| 35 |
"station_id": station_id,
|
| 36 |
"camera_id": camera_id,
|
| 37 |
"status": "error",
|
|
@@ -111,7 +110,6 @@ def detect_defect_from_video_url(station_id, camera_id: str, video_url: str, mod
|
|
| 111 |
logger.info(f"[DETECTED] Camera {camera_id} → {defect_name} ({conf:.2f})")
|
| 112 |
|
| 113 |
return {
|
| 114 |
-
"code": 200,
|
| 115 |
"station_id": station_id,
|
| 116 |
"camera_id": camera_id,
|
| 117 |
"status": "success",
|
|
@@ -145,7 +143,6 @@ def detect_defect_from_video_url(station_id, camera_id: str, video_url: str, mod
|
|
| 145 |
filepath = None
|
| 146 |
|
| 147 |
return {
|
| 148 |
-
"code": 200,
|
| 149 |
"station_id": station_id,
|
| 150 |
"camera_id": camera_id,
|
| 151 |
"status": "success",
|
|
@@ -192,19 +189,15 @@ async def run_detection_group(station_id: str, cameras: List[Dict], webhook_url:
|
|
| 192 |
|
| 193 |
if all_error:
|
| 194 |
status = "error"
|
| 195 |
-
code = 400
|
| 196 |
message = "All cameras failed during detection"
|
| 197 |
elif has_error:
|
| 198 |
status = "partial_error"
|
| 199 |
-
code = 200
|
| 200 |
message = "Some cameras failed during detection"
|
| 201 |
else:
|
| 202 |
status = "success"
|
| 203 |
-
code = 200
|
| 204 |
message = "Success detecting defects"
|
| 205 |
|
| 206 |
payload = {
|
| 207 |
-
"code": code,
|
| 208 |
"status": status,
|
| 209 |
"timestamp": time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime()),
|
| 210 |
"model_version": MODEL_VERSION,
|
|
|
|
| 10 |
MODEL_VERSION = os.getenv("MODEL_VERSION","v1.0.0")
|
| 11 |
WEBHOOK_URL = os.getenv("WEBHOOK_URL")
|
| 12 |
|
| 13 |
+
MAX_RUNTIME_SEC = float(os.getenv("MAX_RUNTIME_SEC", "20"))
|
| 14 |
FRAME_FAIL_SLEEP = float(os.getenv("FRAME_FAIL_SLEEP", "0.05"))
|
| 15 |
+
DEFAULT_FPS = float(os.getenv("DEFAULT_FPS", "25"))
|
| 16 |
WEBHOOK_TIMEOUT = float(os.getenv("WEBHOOK_TIMEOUT", "10.0"))
|
| 17 |
|
| 18 |
# ============================================================
|
|
|
|
| 31 |
if not cap.isOpened():
|
| 32 |
logger.error(f"[ERROR] Cannot open video URL: {video_url}")
|
| 33 |
return {
|
|
|
|
| 34 |
"station_id": station_id,
|
| 35 |
"camera_id": camera_id,
|
| 36 |
"status": "error",
|
|
|
|
| 110 |
logger.info(f"[DETECTED] Camera {camera_id} → {defect_name} ({conf:.2f})")
|
| 111 |
|
| 112 |
return {
|
|
|
|
| 113 |
"station_id": station_id,
|
| 114 |
"camera_id": camera_id,
|
| 115 |
"status": "success",
|
|
|
|
| 143 |
filepath = None
|
| 144 |
|
| 145 |
return {
|
|
|
|
| 146 |
"station_id": station_id,
|
| 147 |
"camera_id": camera_id,
|
| 148 |
"status": "success",
|
|
|
|
| 189 |
|
| 190 |
if all_error:
|
| 191 |
status = "error"
|
|
|
|
| 192 |
message = "All cameras failed during detection"
|
| 193 |
elif has_error:
|
| 194 |
status = "partial_error"
|
|
|
|
| 195 |
message = "Some cameras failed during detection"
|
| 196 |
else:
|
| 197 |
status = "success"
|
|
|
|
| 198 |
message = "Success detecting defects"
|
| 199 |
|
| 200 |
payload = {
|
|
|
|
| 201 |
"status": status,
|
| 202 |
"timestamp": time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime()),
|
| 203 |
"model_version": MODEL_VERSION,
|