Skip to content

Manny2706/Pitwatch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

70 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PitWatch Backend

Backend service for PitWatch: user/admin authentication, pothole reporting, geospatial proximity checks, authority notifications, dashboard analytics, and async ML pothole detection.

Table of Contents

Overview

PitWatch backend is a Django REST API with Celery workers for async ML inference.

It provides:

  • Account signup/login for users and admins
  • JWT auth via Authorization header and secure cookies
  • Report submission with geospatial duplicate checks (PostGIS functions)
  • Nearby report lookup and severity clustering
  • Authority and emergency notifications via Brevo email API
  • Async ONNX pothole inference queue via Celery + Redis
  • Admin dashboard summaries and report status management

Core Features

  • User auth and profile endpoints
  • Admin-only report moderation and dashboard summary
  • Pothole report creation and pagination
  • Nearby pothole lookup by coordinates and radius
  • Report status transitions (pending/in_progress/resolved/rejected)
  • Emergency notification endpoint
  • ML detect (sync) and submit/status (async)

Tech Stack

  • Python 3.12
  • Django 5.1
  • Django REST Framework
  • SimpleJWT
  • PostgreSQL (with PostGIS functions used in SQL)
  • Redis (cache + Celery broker/result)
  • Celery
  • ONNX Runtime + OpenCV + NumPy
  • Cloudinary storage
  • Brevo SMTP API (transactional email)
  • Docker + Docker Compose

System Architecture (mmd)

flowchart LR
		FE[Client App / Admin Panel]
		API[Django API\nGunicorn]
		DB[(PostgreSQL)]
		REDIS[(Redis)]
		WORKER[Celery Worker]
		MODEL[ONNX Model\nmodels/best.onnx]
		CLOUD[Cloudinary]
		BREVO[Brevo Email API]
		OSM[OSM APIs\nOverpass + Nominatim]

		FE -->|HTTP| API
		API --> DB
		API --> REDIS
		API --> CLOUD
		API --> OSM
		API --> BREVO

		API -->|queue task| REDIS
		REDIS --> WORKER
		WORKER --> MODEL
		WORKER --> DB
Loading

Repository Structure

Top-level highlights:

  • pitwatch/pitwatch/: Django project config (settings.py, urls.py, celery.py)
  • pitwatch/accounts/: user/admin auth logic
  • pitwatch/reports/: report CRUD, geospatial queries, authority notifications
  • pitwatch/ml/: sync detect + async inference task pipeline
  • pitwatch/dashboard/: admin summary endpoint
  • pitwatch/models/: ONNX model files (best.onnx or pothole_model.onnx)
  • docker-compose.yml, Dockerfile: container runtime

Quick Start (Local)

1. Create and activate virtual environment

python -m venv env
# Windows PowerShell
env\Scripts\Activate.ps1

2. Install dependencies

pip install -r requirements.txt

3. Configure environment

Create a .env in project root and populate required values (see Environment Variables).

4. Run migrations

cd pitwatch
python manage.py migrate

5. Start API server

python manage.py runserver

6. Start Celery worker (separate terminal)

cd pitwatch
celery -A pitwatch worker -l info --without-gossip --without-mingle --without-heartbeat

Run with Docker Compose

docker compose up --build

Compose services:

  • web: runs migrations and starts Gunicorn on port 8000
  • worker: runs Celery worker for ML inference

Note: current compose file expects external DB/Redis endpoints via .env.

Environment Variables

Commonly used settings in pitwatch/pitwatch/settings.py:

Django and API

  • DJANGO_SECRET_KEY (default: dev-only-secret)
  • DJANGO_DEBUG (true/false)
  • DJANGO_ALLOWED_HOSTS (comma-separated)
  • CORS_ALLOWED_ORIGINS (comma-separated)
  • CORS_ALLOW_ALL_ORIGINS (true/false)

Database

  • DB_NAME
  • DB_USER
  • DB_PASSWORD
  • DB_HOST
  • DB_PORT
  • DB_SSLMODE (default: require)

JWT and cookies

  • JWT_COOKIE_SECURE
  • JWT_COOKIE_SAMESITE (default: None)

Redis, cache, Celery

  • CACHE_URL (default: redis://localhost:6379/1)
  • REDIS_URL (default broker: redis://localhost:6379/0)
  • CELERY_RESULT_BACKEND (defaults to broker URL)

Throttling (DRF scoped rates)

  • DRF_ANON_THROTTLE_RATE
  • DRF_USER_THROTTLE_RATE
  • DRF_AUTH_LOGIN_THROTTLE_RATE
  • DRF_AUTH_SIGNUP_THROTTLE_RATE
  • DRF_AUTH_REFRESH_THROTTLE_RATE
  • DRF_ML_PUBLIC_DETECT_THROTTLE_RATE
  • DRF_ML_SUBMIT_THROTTLE_RATE
  • DRF_ML_STATUS_THROTTLE_RATE
  • DRF_REPORTS_THROTTLE_RATE
  • DRF_ADMIN_REPORTS_LIST_THROTTLE_RATE
  • DRF_DASHBOARD_SUMMARY_THROTTLE_RATE

Cloudinary

  • CLOUDINARY_CLOUD_NAME
  • CLOUDINARY_API_KEY
  • CLOUDINARY_API_SECRET

Brevo email

  • BREVO_API_URL (default: https://api.brevo.com/v3/smtp/email)
  • BREVO_API_KEY
  • BREVO_SENDER_EMAIL
  • BREVO_SENDER_NAME

Road authority fallback emails

  • AUTHORITY_EMAIL_NHAI
  • AUTHORITY_EMAIL_STATE_PWD
  • AUTHORITY_EMAIL_MUNICIPAL_AUTHORITY
  • AUTHORITY_EMAIL_MUNICIPAL_CORPORATION
  • AUTHORITY_EMAIL_UNKNOWN

Clustering behavior

  • POTHOLE_CLUSTER_RADIUS_METERS (default: 130)
  • POTHOLE_CLUSTER_THRESHOLD (default: 8)

Authentication Model

PitWatch uses JWT with both token responses and cookie support.

  • Access token cookie: access_token
  • Refresh token cookie: refresh_token
  • Header auth: Authorization: Bearer <access_token>

Notes:

  • Login/signup responses include access and refresh in JSON and set cookies.
  • Some endpoints require strict IsAuthenticated.
  • Admin endpoints additionally check user.is_superuser.

API Conventions

  • Base route: /api/<version>/... (example version: v1)
  • Content type:
    • JSON for most endpoints
    • multipart/form-data for image upload endpoints
  • Pagination pattern (where used): page, page_size

Complete Endpoint Reference

All paths below are shown with v1 example prefix.

Project-level routes

Method Path Auth Description
GET /admin/ Django admin session Django admin site
GET /api/v1/dashboard/summary/ Access token + superuser Aggregate dashboard totals and 7-day trend

Dashboard auth details:

  • Accepts Bearer header token, otherwise falls back to access_token cookie.
  • Returns 401 for missing/invalid token and 403 for non-superusers.

Accounts endpoints

Method Path Auth Description
POST /api/v1/accounts/signup/ Public Create normal user account
POST /api/v1/accounts/login/ Public User login
POST /api/v1/accounts/token/refresh/ User authenticated Refresh user access token
POST /api/v1/accounts/logout/ User authenticated User logout and clear cookies
GET /api/v1/accounts/me/ User authenticated Current user profile
POST /api/v1/accounts/admin/login/ Public (must be superuser creds) Admin login
POST /api/v1/accounts/admin/token/refresh/ Public (with refresh token) Admin access refresh
POST /api/v1/accounts/admin/logout/ Public (with refresh token optional) Admin logout
GET /api/v1/accounts/admin/me/ User authenticated + superuser Admin profile

Request examples

Signup:

POST /api/v1/accounts/signup/
Content-Type: application/json

{
	"username": "alice",
	"email": "alice@example.com",
	"password": "StrongPass123!",
	"first_name": "Alice",
	"last_name": "Doe"
}

User login:

POST /api/v1/accounts/login/
Content-Type: application/json

{
	"username": "alice",
	"password": "StrongPass123!"
}

Reports endpoints

Method Path Auth Description
GET /api/v1/reports/ User authenticated List current user reports (paginated)
POST /api/v1/reports/ User authenticated Create new pothole report
GET /api/v1/reports/counts/ Public (scoped by user if authenticated) Count reports by status
GET /api/v1/reports/admin/all/ User authenticated + superuser Admin list + high-severity zone analytics
GET /api/v1/reports/nearby/ User authenticated Nearby reports around coordinates
PATCH /api/v1/reports/<report_id>/status/ User authenticated + superuser Update report status
POST /api/v1/reports/emergency/ Public Send emergency notification email payload

Report creation payload

{
	"title": "Large pothole near crossing",
	"description": "Deep pothole causing traffic slowdown",
	"latitude": 28.6139,
	"longitude": 77.2090,
	"pothole_severity": "high"
}

Behavior notes:

  • Duplicate protection: if another non-resolved/non-rejected report exists within 10m, API returns existing report instead of creating a new one.
  • Road authority is inferred via OSM and notification is attempted via Brevo.

Nearby query parameters

  • lat (required)
  • lng (required)
  • radius_km (optional)
  • limit (optional, default 10, max 100)

Response includes:

  • warning: None / Moderate / High
  • cluster_count
  • threshold
  • nearest report rows with distance_m

Status values

  • Report status choices:
    • pending
    • in_progress
    • resolved
    • rejected
  • Pothole severity choices:
    • low
    • medium
    • high

ML endpoints

Method Path Auth Description
POST /api/v1/ml/detect/ Public Synchronous pothole probability from uploaded image
POST /api/v1/ml/detect/submit/ User authenticated Queue asynchronous inference task
GET /api/v1/ml/detect/status/<task_id>/ User authenticated Poll task status/result for own task
GET /api/v1/ml/detect/my-reports/ User authenticated List user reports

Detect (sync) request

  • Content type: multipart/form-data
  • Form field: image

Success response:

{
	"pothole": true,
	"confidence": 0.91
}

Submit (async) request

  • Content type: multipart/form-data
  • Form fields:
    • image (required)
    • lat or latitude (optional)
    • lng or longitude (optional)

Accepted response:

{
	"status": "queued",
	"task_id": "<celery-task-id>",
	"message": "Image received"
}

Status response states:

  • queued
  • running
  • success with result: { pothole, confidence }
  • failed with error

Mermaid Flows (mmd)

Auth flow

sequenceDiagram
		participant C as Client
		participant A as Accounts API

		C->>A: POST /accounts/login (username, password)
		A-->>C: access + refresh in JSON
		A-->>C: Set-Cookie access_token, refresh_token

		C->>A: GET /accounts/me (Bearer or cookie)
		A-->>C: user profile

		C->>A: POST /accounts/token/refresh (refresh token)
		A-->>C: new access_token
Loading

Report lifecycle

flowchart TD
		U[Authenticated User] --> R1[POST /reports/]
		R1 --> D{Existing report\nwithin 10m?}
		D -- Yes --> E[Return existing report]
		D -- No --> A[Infer road authority via OSM]
		A --> S[Save report in DB]
		S --> N[Send Brevo authority notification]
		N --> O[Return report + notification_sent]

		ADM[Admin User] --> L[GET /reports/admin/all/]
		L --> C[Cluster analysis and high-severity zones]
		ADM --> P[PATCH /reports/<id>/status]
		P --> DB[(Update status/resolved_at)]
Loading

Async ML inference pipeline

flowchart LR
		C[Client] --> S1[POST /ml/detect/submit/]
		S1 --> Q[Celery task queued in Redis]
		Q --> W[Worker pulls task]
		W --> M[Load ONNX model]
		M --> I[Run inference]
		I --> J[Update InferenceJob]
		J --> K{pothole true?}
		K -- Yes --> R[Create Report + PotholeReport]
		K -- No --> X[No report created]
		C --> P1[GET /ml/detect/status/<task_id>]
		P1 --> J
Loading

Dashboard analytics flow

flowchart TD
		C[Admin Client] --> T[GET /dashboard/summary/]
		T --> V{Bearer token?}
		V -- Yes --> H[Validate header token]
		V -- No --> CK[Validate access_token cookie]
		H --> A{is_superuser?}
		CK --> A
		A -- No --> F[403 Forbidden]
		A -- Yes --> G[Aggregate totals + 7-day trend]
		G --> R[Return dashboard payload]
Loading

AI Disclosure

PitWatch includes AI-assisted pothole detection via ONNX model inference (sync and async ML endpoints).

  • AI outputs are probabilistic and may produce false positives or false negatives.
  • Detection confidence should be treated as decision support, not definitive proof.
  • Administrative action and emergency handling should include human review.
  • Model behavior can vary with image quality, lighting, weather, camera angle, and road context.
  • The system does not provide legal, safety, or engineering guarantees.

Operational Notes

  • ML model lookup order:
    • pitwatch/models/pothole_model.onnx
    • fallback to pitwatch/models/best.onnx
  • PostGIS SQL functions are used directly (ST_DWithin, ST_Distance), so DB must support them.
  • DEFAULT_PERMISSION_CLASSES is IsAuthenticated; public endpoints explicitly override permission classes.

Testing

Run tests:

cd pitwatch
python manage.py test

There are API tests for ML route edge cases in pitwatch/ml/test_api.py.

Troubleshooting

  • 401 on authenticated routes:
    • Ensure Authorization: Bearer <access> is present, or cookie is set.
  • 503 on ML submit:
    • Check Redis connectivity and running Celery worker.
  • 503 or failed notification on reports/emergency:
    • Verify BREVO_API_KEY and sender config.
  • Geospatial query errors:
    • Confirm PostgreSQL has PostGIS extension available.

AI Usage Disclosure

AI tools were used to assist parts of this project's development and documentation. Final implementation decisions and validation were performed by myself.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors