Antigravity Agent commited on
Commit
8e722e0
·
1 Parent(s): 6989ecc

Add fallback logic and logger fix

Browse files
Files changed (5) hide show
  1. Dockerfile +3 -1
  2. __pycache__/app.cpython-312.pyc +0 -0
  3. api.py +164 -0
  4. git-lfs.tar.gz +3 -0
  5. requirements.txt +0 -1
Dockerfile CHANGED
@@ -14,9 +14,11 @@ COPY requirements.txt .
14
  RUN pip install --no-cache-dir -r requirements.txt
15
  # Copy App and Model
16
  COPY app.py .
 
17
  COPY best.pt .
 
18
  # Expose the default HF Space port
19
  ENV PORT=7860
20
  EXPOSE 7860
21
  # Run the FastAPI app with Uvicorn
22
- CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
 
14
  RUN pip install --no-cache-dir -r requirements.txt
15
  # Copy App and Model
16
  COPY app.py .
17
+ COPY api.py .
18
  COPY best.pt .
19
+
20
  # Expose the default HF Space port
21
  ENV PORT=7860
22
  EXPOSE 7860
23
  # Run the FastAPI app with Uvicorn
24
+ CMD ["uvicorn", "api:app", "--host", "0.0.0.0", "--port", "7860"]
__pycache__/app.cpython-312.pyc ADDED
Binary file (7.04 kB). View file
 
api.py ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import io
2
+ import json
3
+ import logging
4
+ import os
5
+ from typing import Optional
6
+
7
+ import cv2
8
+ import numpy as np
9
+ import uvicorn
10
+ from fastapi import FastAPI, File, Form, UploadFile, HTTPException
11
+ from fastapi.middleware.cors import CORSMiddleware
12
+ from PIL import Image
13
+ from ultralytics import YOLO
14
+
15
+ # Configure logging
16
+ logging.basicConfig(level=logging.INFO)
17
+ logger = logging.getLogger(__name__)
18
+
19
+ app = FastAPI(title="Arise AI API", version="1.0.0")
20
+
21
+ # CORS
22
+ app.add_middleware(
23
+ CORSMiddleware,
24
+ allow_origins=["*"],
25
+ allow_credentials=True,
26
+ allow_methods=["*"],
27
+ allow_headers=["*"],
28
+ )
29
+
30
+ # Load Model
31
+ try:
32
+ model = YOLO("best.pt")
33
+ logger.info("YOLO model loaded successfully.")
34
+ except Exception as e:
35
+ logger.error(f"Failed to load model: {e}")
36
+ model = None
37
+
38
+ @app.get("/")
39
+ def read_root():
40
+ return {"status": "Active", "service": "Arise AI Backend"}
41
+
42
+ @app.post("/analyze")
43
+ async def analyze_endpoint(
44
+ image: UploadFile = File(...),
45
+ description: str = Form(""),
46
+ latitude: str = Form("0"),
47
+ longitude: str = Form("0"),
48
+ timestamp: str = Form(""),
49
+ user_email: str = Form(None)
50
+ ):
51
+ if not model:
52
+ raise HTTPException(status_code=503, detail="AI Model not initialized")
53
+
54
+ try:
55
+ # Read Image
56
+ contents = await image.read()
57
+ pil_image = Image.open(io.BytesIO(contents)).convert("RGB")
58
+ img_np = np.array(pil_image)
59
+
60
+ # Run Inference
61
+ logger.info("Running YOLO inference...")
62
+ results = model(img_np, conf=0.25) # Lower confidence a bit to catch more
63
+
64
+ detections = []
65
+ primary_issue = "Unknown"
66
+ max_conf = 0.0
67
+
68
+ result = results[0]
69
+
70
+ # Analyze Detections
71
+ if len(result.boxes) > 0:
72
+ for box in result.boxes:
73
+ cls_id = int(box.cls)
74
+ conf = float(box.conf)
75
+ label = model.names[cls_id]
76
+
77
+ detections.append({
78
+ "class": label,
79
+ "confidence": conf
80
+ })
81
+
82
+ if conf > max_conf:
83
+ max_conf = conf
84
+ primary_issue = label
85
+
86
+ # Fallback: Check Description if YOLO fails
87
+ if primary_issue == "Unknown" and description:
88
+ logger.info(f"YOLO failed, checking description: {description}")
89
+ desc_lower = description.lower()
90
+ keywords = {
91
+ "pothole": "Pothole",
92
+ "garbage": "Garbage",
93
+ "trash": "Garbage",
94
+ "street light": "Streetlight",
95
+ "streetlight": "Streetlight",
96
+ "accident": "Accident",
97
+ "water": "Drainagen", # Typo in map, should match category_map keys if possible or be standard
98
+ "drainage": "Drainagen"
99
+ }
100
+
101
+ for key, val in keywords.items():
102
+ if key in desc_lower:
103
+ primary_issue = val
104
+ max_conf = 0.5 # Moderate confidence for text match
105
+ ai_summary = f"Issue identified based on description: {val}"
106
+ break
107
+
108
+
109
+ # Process Image for Overlay (if needed)
110
+ # We can return the base64 of the plotted image
111
+ annotated_frame = result.plot()
112
+ is_success, buffer = cv2.imencode(".jpg", cv2.cvtColor(annotated_frame, cv2.COLOR_RGB2BGR))
113
+ processed_image_base64 = None
114
+ if is_success:
115
+ import base64
116
+ processed_image_base64 = base64.b64encode(buffer).decode("utf-8")
117
+
118
+ # Map to Civicsense categories
119
+ category_map = {
120
+ "pothole": "Public Works",
121
+ "garbage": "Sanitation",
122
+ "streetlight": "Electricity",
123
+ "accident": "Emergency",
124
+ "drainagen": "Water & Sewerage"
125
+ # Add more mappings as per trained model classes
126
+ }
127
+
128
+ department = category_map.get(primary_issue.lower(), "General")
129
+
130
+ # Determine Severity
131
+ severity = "Medium"
132
+ if primary_issue.lower() in ["accident", "pothole"]:
133
+ severity = "High" if max_conf > 0.7 else "Medium"
134
+ elif primary_issue.lower() == "garbage":
135
+ severity = "Low" if max_conf < 0.5 else "Medium"
136
+
137
+ # Generate specific summary
138
+ ai_summary = f"Detected {primary_issue} with {max_conf:.2f} confidence." if primary_issue != "Unknown" else "No specific civic issues detected."
139
+
140
+ response_data = {
141
+ "status": "Success",
142
+ "issue_type": primary_issue,
143
+ "civic_confidence": max_conf,
144
+ "severity": severity,
145
+ "department": department,
146
+ "ai_summary": ai_summary,
147
+ "detections": detections,
148
+ "processed_image": processed_image_base64,
149
+ "resolution_estimation": {
150
+ "estimated_hours": 24 if severity == "High" else 48
151
+ }
152
+ }
153
+
154
+ logger.info(f"Analysis complete: {primary_issue}")
155
+ return response_data
156
+
157
+ except Exception as e:
158
+ logger.error(f"Analysis Failed: {e}")
159
+ import traceback
160
+ traceback.print_exc()
161
+ raise HTTPException(status_code=500, detail=str(e))
162
+
163
+ if __name__ == "__main__":
164
+ uvicorn.run(app, host="0.0.0.0", port=7860)
git-lfs.tar.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1772dc260961db27958088740b7e9ecebf945abad8c2d504d412448f53faf147
3
+ size 4930444
requirements.txt CHANGED
@@ -8,4 +8,3 @@ geopy
8
  fastapi
9
  uvicorn
10
  python-multipart
11
- gradio
 
8
  fastapi
9
  uvicorn
10
  python-multipart