Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions backend/routers/detection.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from PIL import Image
import logging
import time
import hashlib

from backend.utils import process_and_detect, validate_uploaded_file, process_uploaded_image
from backend.schemas import DetectionResponse, UrgencyAnalysisRequest, UrgencyAnalysisResponse
Expand Down Expand Up @@ -68,35 +69,44 @@ async def _get_cached_result(key: str, func, *args, **kwargs):
return result

async def _cached_detect_severity(image_bytes: bytes):
key = f"severity_{hash(image_bytes)}"
# Stable cache key using MD5 (hash() is unstable across processes)
image_hash = hashlib.md5(image_bytes).hexdigest()
key = f"severity_{image_hash}"
return await _get_cached_result(key, detect_severity_clip, image_bytes)

async def _cached_detect_smart_scan(image_bytes: bytes):
key = f"smart_scan_{hash(image_bytes)}"
image_hash = hashlib.md5(image_bytes).hexdigest()
key = f"smart_scan_{image_hash}"
return await _get_cached_result(key, detect_smart_scan_clip, image_bytes)
Comment thread
RohanExploit marked this conversation as resolved.

async def _cached_generate_caption(image_bytes: bytes):
key = f"caption_{hash(image_bytes)}"
image_hash = hashlib.md5(image_bytes).hexdigest()
key = f"caption_{image_hash}"
return await _get_cached_result(key, generate_image_caption, image_bytes)

async def _cached_detect_waste(image_bytes: bytes):
key = f"waste_{hash(image_bytes)}"
image_hash = hashlib.md5(image_bytes).hexdigest()
key = f"waste_{image_hash}"
return await _get_cached_result(key, detect_waste_clip, image_bytes)

async def _cached_detect_civic_eye(image_bytes: bytes):
key = f"civic_eye_{hash(image_bytes)}"
image_hash = hashlib.md5(image_bytes).hexdigest()
key = f"civic_eye_{image_hash}"
return await _get_cached_result(key, detect_civic_eye_clip, image_bytes)

async def _cached_detect_graffiti(image_bytes: bytes):
key = f"graffiti_{hash(image_bytes)}"
image_hash = hashlib.md5(image_bytes).hexdigest()
key = f"graffiti_{image_hash}"
return await _get_cached_result(key, detect_graffiti_art_clip, image_bytes)

async def _cached_detect_traffic_sign(image_bytes: bytes):
key = f"traffic_sign_{hash(image_bytes)}"
image_hash = hashlib.md5(image_bytes).hexdigest()
key = f"traffic_sign_{image_hash}"
return await _get_cached_result(key, detect_traffic_sign_clip, image_bytes)

async def _cached_detect_abandoned_vehicle(image_bytes: bytes):
key = f"abandoned_vehicle_{hash(image_bytes)}"
image_hash = hashlib.md5(image_bytes).hexdigest()
key = f"abandoned_vehicle_{image_hash}"
return await _get_cached_result(key, detect_abandoned_vehicle_clip, image_bytes)
Comment thread
RohanExploit marked this conversation as resolved.

# Endpoints
Expand Down
33 changes: 18 additions & 15 deletions backend/routers/issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,24 +346,27 @@ def get_nearby_issues(
)

# Convert to response format and limit results
nearby_responses = [
NearbyIssueResponse(
id=issue.id,
description=issue.description[:100] + "..." if len(issue.description) > 100 else issue.description,
category=issue.category,
latitude=issue.latitude,
longitude=issue.longitude,
distance_meters=distance,
upvotes=issue.upvotes or 0,
created_at=issue.created_at,
status=issue.status
)
for issue, distance in nearby_issues_with_distance[:limit]
]
# Performance Boost: Map directly to dictionaries to avoid Pydantic overhead
nearby_data = []
for issue, distance in nearby_issues_with_distance[:limit]:
desc = issue.description or ""
short_desc = desc[:100] + "..." if len(desc) > 100 else desc

nearby_data.append({
"id": issue.id,
"description": short_desc,
"category": issue.category,
"latitude": issue.latitude,
"longitude": issue.longitude,
"distance_meters": distance,
"upvotes": issue.upvotes or 0,
"created_at": issue.created_at.isoformat() if issue.created_at else None,
"status": issue.status
})

# Performance Boost: Cache serialized JSON to bypass redundant Pydantic validation
# and serialization on cache hits.
json_data = json.dumps([r.model_dump(mode='json') for r in nearby_responses])
json_data = json.dumps(nearby_data)
nearby_issues_cache.set(json_data, cache_key)

return Response(content=json_data, media_type="application/json")
Comment thread
RohanExploit marked this conversation as resolved.
Expand Down
Loading