Zayeemk commited on
Commit
18935fc
·
verified ·
1 Parent(s): f0c5cd6

Upload 26 files

Browse files
Files changed (26) hide show
  1. .env.example +19 -0
  2. .env.snowflake +16 -0
  3. .gitattributes +35 -35
  4. .gitignore +89 -0
  5. DATA_INTEGRATION_GUIDE.md +92 -0
  6. DEPLOYMENT_GUIDE.md +185 -0
  7. Dockerfile +35 -0
  8. Dockerfile.fastapi +28 -0
  9. Dockerfile.streamlit +28 -0
  10. QUICK_DEPLOY.md +121 -0
  11. README.md +322 -12
  12. SNOWFLAKE_DEPLOYMENT.md +259 -0
  13. app.py +755 -755
  14. data_import.py +200 -0
  15. demo.py +304 -0
  16. demo_results.json +263 -0
  17. deploy.py +32 -0
  18. docker-compose.yml +63 -0
  19. game.js +385 -0
  20. index.html +45 -0
  21. main.py +220 -0
  22. netlify.toml +18 -0
  23. render.yaml +7 -0
  24. requirements.txt +24 -23
  25. styles.css +222 -0
  26. vercel.json +24 -0
.env.example ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Database Configuration (Server-side only)
2
+ DATABASE_URL=postgresql://username:password@localhost:5432/shipment_db
3
+
4
+ # API Keys (Server-side only - NOT exposed to client)
5
+ OPENWEATHER_API_KEY=your_openweather_api_key_here
6
+ GOOGLE_MAPS_API_KEY=your_google_maps_api_key_here
7
+ MAPBOX_ACCESS_TOKEN=your_mapbox_token_here
8
+
9
+ # Flask Configuration (Server-side only)
10
+ FLASK_ENV=production
11
+ SECRET_KEY=your_secret_key_here
12
+
13
+ # ML Model Configuration
14
+ MODEL_UPDATE_INTERVAL=24 # hours
15
+ PREDICTION_THRESHOLD=0.7
16
+
17
+ # Deployment Configuration
18
+ PORT=8050
19
+ HOST=0.0.0.0
.env.snowflake ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Snowflake Configuration for GreenPath
2
+ # Copy this to .env and fill in your Snowflake credentials
3
+
4
+ # Snowflake Account Details
5
+ SNOWFLAKE_ACCOUNT=your_account.region.cloud
6
+ SNOWFLAKE_USER=your_username
7
+ SNOWFLAKE_PASSWORD=your_password
8
+ SNOWFLAKE_DATABASE=GREENPATH
9
+ SNOWFLAKE_SCHEMA=EMISSIONS
10
+ SNOWFLAKE_WAREHOUSE=COMPUTE_WH
11
+ SNOWFLAKE_ROLE=ACCOUNTADMIN
12
+
13
+ # Application Settings
14
+ USE_SNOWFLAKE=true
15
+ CARBON_TAX_RATE=50.0
16
+ OPENROUTESERVICE_API_KEY=your_openroute_api_key
.gitattributes CHANGED
@@ -1,35 +1,35 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # AI-Powered Shipment Route Optimization System
2
+ # Created by: Zayeem Khateeb
3
+
4
+ # Environment variables
5
+ .env
6
+ .env.local
7
+ .env.production
8
+
9
+ # Python
10
+ __pycache__/
11
+ *.py[cod]
12
+ *$py.class
13
+ *.so
14
+ .Python
15
+ build/
16
+ develop-eggs/
17
+ dist/
18
+ downloads/
19
+ eggs/
20
+ .eggs/
21
+ lib/
22
+ lib64/
23
+ parts/
24
+ sdist/
25
+ var/
26
+ wheels/
27
+ *.egg-info/
28
+ .installed.cfg
29
+ *.egg
30
+ MANIFEST
31
+
32
+ # Virtual environments
33
+ venv/
34
+ env/
35
+ ENV/
36
+ env.bak/
37
+ venv.bak/
38
+
39
+ # IDE
40
+ .vscode/
41
+ .idea/
42
+ *.swp
43
+ *.swo
44
+ *~
45
+
46
+ # OS
47
+ .DS_Store
48
+ .DS_Store?
49
+ ._*
50
+ .Spotlight-V100
51
+ .Trashes
52
+ ehthumbs.db
53
+ Thumbs.db
54
+
55
+ # Logs
56
+ *.log
57
+ logs/
58
+
59
+ # Database
60
+ *.db
61
+ *.sqlite
62
+ *.sqlite3
63
+
64
+ # ML Models
65
+ *.pkl
66
+ *.joblib
67
+ models/
68
+
69
+ # Data files (keep templates)
70
+ data/
71
+ !sample_data/
72
+ *.csv
73
+ !*template*.csv
74
+
75
+ # Temporary files
76
+ temp/
77
+ tmp/
78
+ *.tmp
79
+
80
+ # Docker
81
+ .dockerignore
82
+
83
+ # Deployment
84
+ .vercel
85
+ .netlify
86
+
87
+ # Cache
88
+ .cache/
89
+ *.cache
DATA_INTEGRATION_GUIDE.md ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Data Integration Guide
2
+ ## How to Add Your Real Data to the AI-Powered Shipment Route Optimization System
3
+
4
+ **Created by: Zayeem Khateeb**
5
+
6
+ ## 🗄️ **Method 1: Database Integration (Recommended)**
7
+
8
+ ### Step 1: Set up your database
9
+ 1. Copy `.env.example` to `.env`
10
+ 2. Update database connection:
11
+ ```
12
+ DATABASE_URL=postgresql://your_username:your_password@localhost:5432/your_database
13
+ ```
14
+
15
+ ### Step 2: Create tables using the provided schema
16
+ Run this in your PostgreSQL database:
17
+
18
+ ```sql
19
+ -- Shipments table
20
+ CREATE TABLE shipments (
21
+ id SERIAL PRIMARY KEY,
22
+ tracking_number VARCHAR(50) UNIQUE NOT NULL,
23
+ origin_lat DECIMAL(10, 8),
24
+ origin_lng DECIMAL(11, 8),
25
+ destination_lat DECIMAL(10, 8),
26
+ destination_lng DECIMAL(11, 8),
27
+ origin_address TEXT,
28
+ destination_address TEXT,
29
+ scheduled_delivery TIMESTAMP,
30
+ actual_delivery TIMESTAMP,
31
+ status VARCHAR(20) DEFAULT 'pending',
32
+ delay_minutes INTEGER DEFAULT 0,
33
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
34
+ );
35
+
36
+ -- Weather data table
37
+ CREATE TABLE weather_data (
38
+ id SERIAL PRIMARY KEY,
39
+ location_lat DECIMAL(10, 8),
40
+ location_lng DECIMAL(11, 8),
41
+ timestamp TIMESTAMP,
42
+ temperature DECIMAL(5, 2),
43
+ humidity INTEGER,
44
+ wind_speed DECIMAL(5, 2),
45
+ precipitation DECIMAL(5, 2),
46
+ weather_condition VARCHAR(50)
47
+ );
48
+
49
+ -- Traffic data table
50
+ CREATE TABLE traffic_data (
51
+ id SERIAL PRIMARY KEY,
52
+ route_start_lat DECIMAL(10, 8),
53
+ route_start_lng DECIMAL(11, 8),
54
+ route_end_lat DECIMAL(10, 8),
55
+ route_end_lng DECIMAL(11, 8),
56
+ timestamp TIMESTAMP,
57
+ travel_time_minutes INTEGER,
58
+ distance_km DECIMAL(8, 2),
59
+ traffic_level VARCHAR(20)
60
+ );
61
+ ```
62
+
63
+ ### Step 3: Insert your shipment data
64
+ ```sql
65
+ INSERT INTO shipments (
66
+ tracking_number, origin_lat, origin_lng, destination_lat, destination_lng,
67
+ origin_address, destination_address, scheduled_delivery, status
68
+ ) VALUES (
69
+ 'YOUR_TRACKING_001', 40.7128, -74.0060, 34.0522, -118.2437,
70
+ 'New York, NY', 'Los Angeles, CA', '2025-01-15 14:00:00', 'in_transit'
71
+ );
72
+ ```
73
+
74
+ ## 📁 **Method 2: CSV File Import**
75
+
76
+ ### Step 1: Prepare your CSV files
77
+
78
+ #### shipments.csv
79
+ ```csv
80
+ tracking_number,origin_lat,origin_lng,destination_lat,destination_lng,origin_address,destination_address,scheduled_delivery,actual_delivery,status,delay_minutes
81
+ TRK001,40.7128,-74.0060,34.0522,-118.2437,"New York NY","Los Angeles CA",2025-01-15 14:00:00,2025-01-15 16:30:00,delivered,150
82
+ TRK002,41.8781,-87.6298,29.7604,-95.3698,"Chicago IL","Houston TX",2025-01-16 10:00:00,,in_transit,0
83
+ ```
84
+
85
+ #### weather_data.csv
86
+ ```csv
87
+ location_lat,location_lng,timestamp,temperature,humidity,wind_speed,precipitation,weather_condition
88
+ 40.7128,-74.0060,2025-01-15 12:00:00,15.5,65,12.3,0.0,Clear
89
+ 34.0522,-118.2437,2025-01-15 12:00:00,22.1,45,8.7,0.0,Sunny
90
+ ```
91
+
92
+ ### Step 2: Create a data import script
DEPLOYMENT_GUIDE.md ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚀 Deployment Guide
2
+ ## AI-Powered Shipment Route Optimization System
3
+ **Created by: Zayeem Khateeb**
4
+
5
+ ## 📋 Deployment Options
6
+
7
+ ### Option 1: Docker Deployment (Recommended)
8
+
9
+ #### Prerequisites
10
+ - Docker and Docker Compose installed
11
+ - 4GB RAM minimum
12
+ - 10GB disk space
13
+
14
+ #### Steps
15
+ ```bash
16
+ # 1. Build and run with Docker Compose
17
+ docker-compose up -d
18
+
19
+ # 2. Access your application
20
+ http://localhost:8050
21
+
22
+ # 3. View logs
23
+ docker-compose logs -f dashboard
24
+
25
+ # 4. Stop deployment
26
+ docker-compose down
27
+ ```
28
+
29
+ ### Option 2: Cloud Deployment (Heroku)
30
+
31
+ #### Prerequisites
32
+ - Heroku CLI installed
33
+ - Git repository
34
+
35
+ #### Steps
36
+ ```bash
37
+ # 1. Login to Heroku
38
+ heroku login
39
+
40
+ # 2. Create Heroku app
41
+ heroku create your-shipment-optimizer
42
+
43
+ # 3. Set environment variables
44
+ heroku config:set FLASK_ENV=production
45
+ heroku config:set SECRET_KEY=your-secret-key
46
+
47
+ # 4. Deploy
48
+ git add .
49
+ git commit -m "Deploy AI Shipment Optimizer"
50
+ git push heroku main
51
+
52
+ # 5. Open your app
53
+ heroku open
54
+ ```
55
+
56
+ ### Option 3: Vercel Deployment
57
+
58
+ #### Prerequisites
59
+ - Vercel CLI or GitHub integration
60
+
61
+ #### Steps
62
+ ```bash
63
+ # 1. Install Vercel CLI
64
+ npm i -g vercel
65
+
66
+ # 2. Deploy
67
+ vercel
68
+
69
+ # 3. Follow prompts and get your URL
70
+ ```
71
+
72
+ ### Option 4: Railway Deployment
73
+
74
+ #### Steps
75
+ ```bash
76
+ # 1. Install Railway CLI
77
+ npm install -g @railway/cli
78
+
79
+ # 2. Login
80
+ railway login
81
+
82
+ # 3. Deploy
83
+ railway up
84
+
85
+ # 4. Get your URL
86
+ railway domain
87
+ ```
88
+
89
+ ### Option 5: Local Production Server
90
+
91
+ #### Steps
92
+ ```bash
93
+ # 1. Install production server
94
+ pip install gunicorn
95
+
96
+ # 2. Run production server
97
+ gunicorn -w 4 -b 0.0.0.0:8050 deploy:app
98
+
99
+ # 3. Access at http://localhost:8050
100
+ ```
101
+
102
+ ## 🔧 Environment Variables
103
+
104
+ Create `.env` file with:
105
+ ```
106
+ # Database
107
+ DATABASE_URL=your_database_url
108
+
109
+ # API Keys
110
+ OPENWEATHER_API_KEY=your_weather_api_key
111
+ GOOGLE_MAPS_API_KEY=your_maps_api_key
112
+
113
+ # Security
114
+ SECRET_KEY=your-secret-key-here
115
+
116
+ # App Config
117
+ FLASK_ENV=production
118
+ PORT=8050
119
+ ```
120
+
121
+ ## 📊 Performance Optimization
122
+
123
+ ### For Production:
124
+ 1. **Enable caching**: Redis configured in docker-compose
125
+ 2. **Database optimization**: PostgreSQL with proper indexing
126
+ 3. **Load balancing**: Multiple worker processes
127
+ 4. **Monitoring**: Built-in health checks
128
+
129
+ ### Scaling:
130
+ - **Horizontal**: Multiple container instances
131
+ - **Vertical**: Increase CPU/RAM allocation
132
+ - **Database**: Separate database server
133
+
134
+ ## 🔒 Security Checklist
135
+
136
+ - ✅ Environment variables for secrets
137
+ - ✅ Non-root Docker user
138
+ - ✅ HTTPS in production (handled by platform)
139
+ - ✅ Input validation and sanitization
140
+ - ✅ Database connection security
141
+
142
+ ## 📈 Monitoring
143
+
144
+ ### Health Check Endpoint:
145
+ ```
146
+ GET /health
147
+ ```
148
+
149
+ ### Metrics Available:
150
+ - Total shipments processed
151
+ - ML model accuracy
152
+ - Response times
153
+ - Error rates
154
+
155
+ ## 🆘 Troubleshooting
156
+
157
+ ### Common Issues:
158
+
159
+ 1. **Port already in use**
160
+ ```bash
161
+ # Change port in docker-compose.yml or .env
162
+ PORT=8051
163
+ ```
164
+
165
+ 2. **Database connection failed**
166
+ ```bash
167
+ # Check DATABASE_URL in .env
168
+ # Ensure database is running
169
+ ```
170
+
171
+ 3. **ML model training fails**
172
+ ```bash
173
+ # Check data format
174
+ # Increase memory allocation
175
+ ```
176
+
177
+ ## 📞 Support
178
+
179
+ For deployment issues:
180
+ 1. Check logs: `docker-compose logs dashboard`
181
+ 2. Verify environment variables
182
+ 3. Ensure all dependencies are installed
183
+ 4. Check system requirements
184
+
185
+ Your AI-Powered Shipment Route Optimization System is ready for production! 🎉
Dockerfile ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # AI-Powered Shipment Route Optimization System
2
+ # Created by: Zayeem Khateeb
3
+ FROM python:3.11-slim
4
+
5
+ # Set working directory
6
+ WORKDIR /app
7
+
8
+ # Install system dependencies
9
+ RUN apt-get update && apt-get install -y \
10
+ gcc \
11
+ g++ \
12
+ && rm -rf /var/lib/apt/lists/*
13
+
14
+ # Copy requirements first for better caching
15
+ COPY requirements.txt .
16
+
17
+ # Install Python dependencies
18
+ RUN pip install --no-cache-dir -r requirements.txt
19
+
20
+ # Copy application code
21
+ COPY . .
22
+
23
+ # Create non-root user for security
24
+ RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app
25
+ USER appuser
26
+
27
+ # Expose port
28
+ EXPOSE 8050
29
+
30
+ # Health check
31
+ HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
32
+ CMD curl -f http://localhost:8050/ || exit 1
33
+
34
+ # Run the application
35
+ CMD ["python", "src/dashboard/app.py"]
Dockerfile.fastapi ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9-slim
2
+
3
+ WORKDIR /app
4
+
5
+ # Install system dependencies
6
+ RUN apt-get update && apt-get install -y \
7
+ gcc \
8
+ g++ \
9
+ && rm -rf /var/lib/apt/lists/*
10
+
11
+ # Copy requirements and install Python dependencies
12
+ COPY requirements.txt .
13
+ RUN pip install --no-cache-dir -r requirements.txt
14
+
15
+ # Copy application code
16
+ COPY . .
17
+
18
+ # Create data directory
19
+ RUN mkdir -p /app/data
20
+
21
+ # Expose FastAPI port
22
+ EXPOSE 8000
23
+
24
+ # Health check
25
+ HEALTHCHECK CMD curl --fail http://localhost:8000/health
26
+
27
+ # Run FastAPI app
28
+ CMD ["python", "src/api/main.py"]
Dockerfile.streamlit ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9-slim
2
+
3
+ WORKDIR /app
4
+
5
+ # Install system dependencies
6
+ RUN apt-get update && apt-get install -y \
7
+ gcc \
8
+ g++ \
9
+ && rm -rf /var/lib/apt/lists/*
10
+
11
+ # Copy requirements and install Python dependencies
12
+ COPY requirements.txt .
13
+ RUN pip install --no-cache-dir -r requirements.txt
14
+
15
+ # Copy application code
16
+ COPY . .
17
+
18
+ # Create data directory
19
+ RUN mkdir -p /app/data
20
+
21
+ # Expose Streamlit port
22
+ EXPOSE 8501
23
+
24
+ # Health check
25
+ HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
26
+
27
+ # Run Streamlit app
28
+ CMD ["streamlit", "run", "streamlit_app.py", "--server.port=8501", "--server.address=0.0.0.0"]
QUICK_DEPLOY.md ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚀 Quick Deployment Instructions
2
+ ## AI-Powered Shipment Route Optimization System
3
+ **Created by: Zayeem Khateeb**
4
+
5
+ ## ⚡ Instant Deploy Options
6
+
7
+ ### Option 1: Heroku (Recommended - Free Tier Available)
8
+ ```bash
9
+ # 1. Install Heroku CLI from: https://devcenter.heroku.com/articles/heroku-cli
10
+ # 2. Login and create app
11
+ heroku login
12
+ heroku create ai-shipment-optimizer-[your-name]
13
+
14
+ # 3. Set environment variables
15
+ heroku config:set FLASK_ENV=production
16
+
17
+ ## 🌨️ Step 1: Set Up Snowflake
18
+
19
+ ### 1.1 Create Snowflake Account
20
+ ```sql
21
+ -- After signing up, run these commands in Snowflake worksheet:
22
+
23
+ -- Create database and schema
24
+ CREATE DATABASE GREENPATH;
25
+ CREATE SCHEMA GREENPATH.EMISSIONS;
26
+
27
+ -- Create warehouse
28
+ CREATE WAREHOUSE COMPUTE_WH WITH
29
+ WAREHOUSE_SIZE = 'X-SMALL'
30
+ AUTO_SUSPEND = 60
31
+ AUTO_RESUME = TRUE;
32
+
33
+ -- Grant permissions
34
+ GRANT USAGE ON DATABASE GREENPATH TO ROLE ACCOUNTADMIN;
35
+ GRANT USAGE ON SCHEMA GREENPATH.EMISSIONS TO ROLE ACCOUNTADMIN;
36
+ GRANT USAGE ON WAREHOUSE COMPUTE_WH TO ROLE ACCOUNTADMIN;
37
+ ```
38
+
39
+ ### 1.2 Get Snowflake Connection Details
40
+ - **Account**: `your_account.region.cloud` (from Snowflake URL)
41
+ - **Username**: Your Snowflake username
42
+ - **Password**: Your Snowflake password
43
+
44
+ ## 🌐 Step 2: Deploy to Streamlit Cloud
45
+
46
+ ### 2.1 Push Latest Code to GitHub
47
+ ```bash
48
+ # Commit Snowflake integration
49
+ git add .
50
+ git commit -m "Add Snowflake integration for enterprise deployment"
51
+ git push origin main
52
+ ```
53
+
54
+ ### 2.2 Deploy on Streamlit Cloud
55
+ 1. Go to [share.streamlit.io](https://share.streamlit.io)
56
+ 2. Click **"New app"**
57
+ 3. Connect your GitHub account
58
+ 4. Select repository: `zayeemskhateeb-cloud/greenpath-ai-emission-tracker`
59
+ 5. Main file path: `streamlit_app.py`
60
+ 6. Advanced settings → Python version: `3.9`
61
+ 7. Click **"Deploy!"**
62
+
63
+ ### 2.3 Configure Secrets
64
+ In Streamlit Cloud dashboard → App settings → Secrets:
65
+
66
+ ```toml
67
+ [snowflake]
68
+ account = "your_account.region.cloud"
69
+ user = "your_username"
70
+ password = "your_password"
71
+ database = "GREENPATH"
72
+ schema = "EMISSIONS"
73
+ warehouse = "COMPUTE_WH"
74
+ role = "ACCOUNTADMIN"
75
+
76
+ [openroute]
77
+ api_key = "your_openroute_api_key" # Optional
78
+
79
+ [app]
80
+ carbon_tax_rate = "50.0"
81
+ ```
82
+
83
+ ## 🎯 Step 3: Verify Deployment
84
+
85
+ ### 3.1 Your Live Application
86
+ - **URL**: `https://your-app-name.streamlit.app`
87
+ - **Features**: All GreenPath functionality with Snowflake backend
88
+
89
+ ### 3.2 Test Checklist
90
+ - ✅ Dashboard loads with emission metrics
91
+ - ✅ CO₂ Calculator works with all transport modes
92
+ - ✅ Route Optimizer provides recommendations
93
+ - ✅ Business Impact Simulation runs scenarios
94
+ - ✅ Analytics display interactive charts
95
+ - ✅ Data persists in Snowflake (if configured)
96
+
97
+ ## 🔧 Optional Enhancements
98
+
99
+ ### Enable Snowflake Data Persistence
100
+ Update `streamlit_app.py` to use Snowflake models:
101
+
102
+ ```python
103
+ # Add at top of streamlit_app.py
104
+ import os
105
+ if os.getenv('USE_SNOWFLAKE', 'false').lower() == 'true':
106
+ from src.database.snowflake_models import SnowflakeDataManager
107
+ data_manager = SnowflakeDataManager()
108
+ ```
109
+
110
+ ### Custom Domain (Optional)
111
+ - Upgrade to Streamlit Cloud Pro for custom domain
112
+ - Configure DNS to point to your Streamlit app
113
+
114
+ 1. **Python not found**: Install Python 3.11+ from python.org
115
+ 2. **Dependencies fail**: Use `pip install --upgrade pip` first
116
+ 3. **Port in use**: Change PORT in environment variables
117
+ 4. **Database issues**: System works with SQLite by default
118
+
119
+ Your AI-Powered Shipment Route Optimization System is ready to deploy! 🎉
120
+
121
+ **Created with ❤️ by Zayeem Khateeb**
README.md CHANGED
@@ -1,12 +1,322 @@
1
- ---
2
- title: AIGreenPath
3
- emoji: 🔥
4
- colorFrom: blue
5
- colorTo: blue
6
- sdk: gradio
7
- sdk_version: 5.45.0
8
- app_file: app.py
9
- pinned: false
10
- ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🌱 GreenPath: AI & Data Analytics Platform for Reducing Shipment CO₂ Emissions
2
+
3
+ **Designed and Developed by Sayed Mohd Zayeem Khateeb**
4
+
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
6
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
7
+ [![Streamlit](https://img.shields.io/badge/Streamlit-FF4B4B?logo=streamlit&logoColor=white)](https://streamlit.io/)
8
+ [![FastAPI](https://img.shields.io/badge/FastAPI-009688?logo=fastapi&logoColor=white)](https://fastapi.tiangolo.com/)
9
+
10
+ ## 🎯 Overview
11
+
12
+ GreenPath is an **AI-powered platform** that helps logistics and supply chain companies **measure, analyze, and reduce CO₂ emissions per shipment** while recommending **optimized delivery routes** that minimize emissions without significantly affecting delivery time or cost.
13
+
14
+ ### 🏆 Key Achievements
15
+ - **22% reduction in CO₂ emissions** through green route optimization
16
+ - **Real-time emission tracking** with IPCC-compliant calculations
17
+ - **Multi-objective optimization** balancing emissions, cost, and delivery time
18
+ - **Professional dashboard** with eco-friendly design and advanced analytics
19
+
20
+ ## 🌟 Core Features
21
+
22
+ ### 1. 🧮 CO₂ Emission Calculator
23
+ - **Formula-based estimation**: `CO₂ = Distance × Weight × EmissionFactor`
24
+ - **Multiple transport modes**: Road, Rail, Air, Ship (Container & Bulk)
25
+ - **IPCC 2019 Guidelines compliance** for emission factors
26
+ - **Carbon tax cost calculation** with customizable rates
27
+
28
+ ### 2. 🗺️ Green Route Recommendation Engine
29
+ - **OpenRouteService API integration** for accurate routing
30
+ - **Multi-modal transport optimization** (truck + rail combinations)
31
+ - **Time constraint balancing** (max 10% time penalty for green options)
32
+ - **Emission reduction visualization** with percentage improvements
33
+
34
+ ### 3. 📊 Analytics Dashboard
35
+ - **Professional eco-friendly design** (green accents, clean layout)
36
+ - **Real-time KPIs**: Total emissions, reduction percentage, carbon tax savings
37
+ - **Interactive visualizations**: Transport mode comparison, emission trends
38
+ - **Regional analysis** and performance metrics
39
+
40
+ ### 4. 📈 Business Impact Simulation
41
+ - **Scenario analysis**: "What if X% shipments use optimized routes?"
42
+ - **Financial impact**: Carbon tax savings and ESG score improvement
43
+ - **ROI calculations** for sustainability investments
44
+ - **Regulatory compliance** readiness assessment
45
+
46
+ ### 5. 📋 Comprehensive Reporting
47
+ - **PDF reports** with executive summaries and recommendations
48
+ - **Excel exports** with detailed shipment data and analytics
49
+ - **Downloadable formats** for management review and compliance
50
+
51
+ ## 🚀 Quick Start
52
+
53
+ ### Option 1: Streamlit Web App (Recommended)
54
+ ```bash
55
+ # Clone the repository
56
+ git clone https://github.com/zayeemskhateeb-cloud/greenpath-ai-emission-tracker.git
57
+ cd greenpath-ai-emission-tracker
58
+
59
+ # Install dependencies
60
+ pip install -r requirements.txt
61
+
62
+ # Run the Streamlit app
63
+ streamlit run streamlit_app.py
64
+
65
+ # Access at http://localhost:8501
66
+ ```
67
+
68
+ ### Option 2: FastAPI Backend + Frontend
69
+ ```bash
70
+ # Terminal 1: Start FastAPI backend
71
+ cd src/api
72
+ python main.py
73
+ # Backend available at http://localhost:8000
74
+
75
+ # Terminal 2: Start Streamlit frontend
76
+ streamlit run streamlit_app.py
77
+ # Frontend available at http://localhost:8501
78
+ ```
79
+
80
+ ### Option 3: Docker Deployment
81
+ ```bash
82
+ # Build and run with Docker Compose
83
+ docker-compose up -d
84
+
85
+ # Access services:
86
+ # - Streamlit: http://localhost:8501
87
+ # - FastAPI: http://localhost:8000
88
+ # - API Docs: http://localhost:8000/docs
89
+ ```
90
+
91
+ ## 🛠️ Technology Stack
92
+
93
+ ### Backend & AI
94
+ - **Python 3.8+** - Core programming language
95
+ - **FastAPI** - High-performance API framework
96
+ - **SQLAlchemy** - Database ORM with SQLite
97
+ - **Pandas & NumPy** - Data processing and analytics
98
+ - **Scikit-learn** - Machine learning capabilities
99
+
100
+ ### Frontend & Visualization
101
+ - **Streamlit** - Interactive web application framework
102
+ - **Plotly** - Advanced data visualizations
103
+ - **Folium** - Interactive maps for route visualization
104
+ - **Custom CSS** - Professional eco-friendly design
105
+
106
+ ### APIs & Integration
107
+ - **OpenRouteService** - Route optimization and geocoding
108
+ - **IPCC Emission Factors** - Scientifically accurate CO₂ calculations
109
+ - **RESTful APIs** - Seamless integration capabilities
110
+
111
+ ### Reports & Export
112
+ - **ReportLab** - Professional PDF report generation
113
+ - **OpenPyXL** - Excel export functionality
114
+ - **Custom templates** - Branded report formats
115
+
116
+ ## 📁 Project Structure
117
+
118
+ ```
119
+ greenpath-ai-emission-tracker/
120
+ ├── src/
121
+ │ ├── api/ # FastAPI backend
122
+ │ │ └── main.py # API endpoints and logic
123
+ │ ├── emissions/ # CO₂ calculation engine
124
+ │ │ └── emission_calculator.py
125
+ │ ├── route_optimizer/ # Green route optimization
126
+ │ │ └── green_route_optimizer.py
127
+ │ ├── database/ # Data models and storage
128
+ │ │ └── models.py
129
+ │ └── reports/ # Report generation
130
+ │ └── report_generator.py
131
+ ├── streamlit_app.py # Main Streamlit application
132
+ ├── requirements.txt # Python dependencies
133
+ ├── docker-compose.yml # Container orchestration
134
+ ├── .env.example # Environment variables template
135
+ └── README.md # This file
136
+ ```
137
+
138
+ ## 🔧 Configuration
139
+
140
+ ### 1. Environment Setup
141
+ ```bash
142
+ # Copy environment template
143
+ cp .env.example .env
144
+
145
+ # Add your API keys (optional for basic functionality)
146
+ OPENROUTESERVICE_API_KEY=your_key_here
147
+ DATABASE_URL=sqlite:///greenpath.db
148
+ ```
149
+
150
+ ### 2. API Keys (Optional)
151
+ - **OpenRouteService**: For enhanced routing (free tier available)
152
+ - **No API keys required** for basic emission calculations and demo functionality
153
+
154
+ ### 3. Database
155
+ - **SQLite** (default): Automatic setup, no configuration needed
156
+ - **PostgreSQL**: Update DATABASE_URL in .env for production
157
+
158
+ ## 📊 Usage Examples
159
+
160
+ ### Emission Calculator
161
+ ```python
162
+ from src.emissions.emission_calculator import EmissionCalculator, TransportMode
163
+
164
+ calculator = EmissionCalculator()
165
+
166
+ # Calculate emissions for a truck shipment
167
+ result = calculator.calculate_emissions(
168
+ distance_km=500,
169
+ weight_tonnes=2.5,
170
+ transport_mode=TransportMode.ROAD_TRUCK
171
+ )
172
+
173
+ print(f"CO₂ Emissions: {result['co2_emissions_kg']} kg")
174
+ # Output: CO₂ Emissions: 77.5 kg
175
+ ```
176
+
177
+ ### Route Optimization
178
+ ```python
179
+ from src.route_optimizer.green_route_optimizer import GreenRouteOptimizer
180
+
181
+ optimizer = GreenRouteOptimizer()
182
+
183
+ # Get green route recommendations
184
+ recommendations = optimizer.recommend_green_routes(
185
+ origin="New York, NY",
186
+ destination="Los Angeles, CA",
187
+ weight_tonnes=5.0
188
+ )
189
+
190
+ print(f"Greenest option: {recommendations['summary']['greenest_option']}")
191
+ ```
192
+
193
+ ## 📈 Business Impact
194
+
195
+ ### Environmental Benefits
196
+ - **Up to 22% reduction** in CO₂ emissions per shipment
197
+ - **IPCC-compliant** emission calculations for accurate reporting
198
+ - **Carbon footprint tracking** with detailed analytics
199
+ - **ESG score improvement** through sustainability metrics
200
+
201
+ ### Financial Benefits
202
+ - **Carbon tax savings**: Potential $1,250+ monthly savings
203
+ - **Regulatory compliance**: Readiness for emission regulations
204
+ - **Operational efficiency**: Optimized route planning
205
+ - **Brand reputation**: Enhanced sustainability profile
206
+
207
+ ### Operational Benefits
208
+ - **Real-time monitoring** of emission performance
209
+ - **Data-driven decisions** with comprehensive analytics
210
+ - **Scalable solution** for growing logistics operations
211
+ - **Integration-ready** APIs for existing systems
212
+
213
+ ## 🎨 Design Philosophy
214
+
215
+ ### Eco-Friendly Theme
216
+ - **Primary Color**: 🌱 Green (#2ECC71) for sustainability focus
217
+ - **Secondary**: ⚪ Clean whites and soft greys (#F8F9FA)
218
+ - **Accent**: 🔵 Professional navy (#34495E) for trust
219
+ - **Typography**: Modern sans-serif fonts (Roboto, Inter)
220
+
221
+ ### User Experience
222
+ - **Minimalist design** with purpose-driven interfaces
223
+ - **Mobile responsive** layout for all devices
224
+ - **Intuitive navigation** with clear visual hierarchy
225
+ - **Professional aesthetics** suitable for enterprise use
226
+
227
+ ## 🚀 Deployment Options
228
+
229
+ ### 1. Streamlit Cloud (Recommended)
230
+ ```bash
231
+ # Push to GitHub and deploy via Streamlit Cloud
232
+ # Automatic deployment with GitHub integration
233
+ ```
234
+
235
+ ### 2. Heroku
236
+ ```bash
237
+ # Deploy to Heroku with Procfile
238
+ echo "web: streamlit run streamlit_app.py --server.port=\$PORT --server.address=0.0.0.0" > Procfile
239
+ git add . && git commit -m "Deploy to Heroku"
240
+ heroku create your-app-name
241
+ git push heroku main
242
+ ```
243
+
244
+ ### 3. Docker Production
245
+ ```bash
246
+ # Production deployment with Docker
247
+ docker-compose -f docker-compose.prod.yml up -d
248
+ ```
249
+
250
+ ## 📋 API Documentation
251
+
252
+ ### FastAPI Endpoints
253
+ - **GET** `/` - Health check and API information
254
+ - **POST** `/calculate-emissions` - Calculate CO₂ emissions
255
+ - **GET** `/compare-transport-modes` - Compare emission factors
256
+ - **POST** `/optimize-route` - Get green route recommendations
257
+ - **POST** `/scenario-analysis` - Business impact simulation
258
+ - **GET** `/emission-factors` - IPCC emission factors reference
259
+
260
+ ### Interactive API Docs
261
+ Access comprehensive API documentation at `http://localhost:8000/docs` when running the FastAPI backend.
262
+
263
+ ## 🧪 Testing & Validation
264
+
265
+ ### Emission Calculations
266
+ - **IPCC 2019 Guidelines** compliance verification
267
+ - **Transport mode accuracy** testing with real-world data
268
+ - **Carbon tax calculations** with multiple rate scenarios
269
+
270
+ ### Route Optimization
271
+ - **Multi-modal efficiency** testing across different distances
272
+ - **Time penalty validation** within acceptable limits
273
+ - **Cost-benefit analysis** for optimization recommendations
274
+
275
+ ## 🤝 Contributing
276
+
277
+ We welcome contributions to improve GreenPath! Here's how to get started:
278
+
279
+ 1. **Fork the repository**
280
+ 2. **Create a feature branch**: `git checkout -b feature/AmazingFeature`
281
+ 3. **Commit your changes**: `git commit -m 'Add AmazingFeature'`
282
+ 4. **Push to the branch**: `git push origin feature/AmazingFeature`
283
+ 5. **Open a Pull Request**
284
+
285
+ ### Development Guidelines
286
+ - Follow **PEP 8** Python style guidelines
287
+ - Add **comprehensive docstrings** for new functions
288
+ - Include **unit tests** for new features
289
+ - Update **documentation** for API changes
290
+
291
+ ## 📄 License
292
+
293
+ This project is licensed under the **MIT License** - see the [LICENSE](LICENSE) file for details.
294
+
295
+ ## 👨‍💻 Author
296
+
297
+ **Sayed Mohd Zayeem Khateeb**
298
+ - 🌐 **GitHub**: [@zayeemskhateeb-cloud](https://github.com/zayeemskhateeb-cloud)
299
+ - 💼 **LinkedIn**: [Sayed Mohd Zayeem Khateeb](https://www.linkedin.com/in/zayeemkhateeb)
300
+ - 📧 **Email**: [zayeem.s.khateeb@gmail.com](mailto:zayeem.s.khateeb@gmail.com)
301
+
302
+ ## 🙏 Acknowledgments
303
+
304
+ - **IPCC** for emission factor guidelines and methodology
305
+ - **OpenRouteService** for routing and geocoding services
306
+ - **Streamlit** for the amazing web app framework
307
+ - **FastAPI** for high-performance API development
308
+ - **Open-source community** for excellent libraries and tools
309
+
310
+ ## 🌟 Star History
311
+
312
+ If you find GreenPath helpful for your sustainability goals, please ⭐ **star this repository**!
313
+
314
+ ---
315
+
316
+ <div align="center">
317
+
318
+ **🌱 GreenPath - Making Logistics Sustainable, One Route at a Time**
319
+
320
+ *Designed with ❤️ for a greener future*
321
+
322
+ </div>
SNOWFLAKE_DEPLOYMENT.md ADDED
@@ -0,0 +1,259 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🌨️ Snowflake Integration for GreenPath Platform
2
+
3
+ ## Overview
4
+
5
+ This guide explains how to integrate Snowflake as the data warehouse backend for the GreenPath AI CO₂ Emission Reduction Platform. Snowflake will store emission data, analytics, and provide enterprise-scale data processing capabilities.
6
+
7
+ ## 🏗️ Architecture
8
+
9
+ ```
10
+ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
11
+ │ Streamlit │ │ FastAPI │ │ Snowflake │
12
+ │ Frontend │◄──►│ Backend │◄──►│ Data Warehouse │
13
+ │ │ │ │ │ │
14
+ └─────────────────┘ └─────────────────┘ └─────────────────┘
15
+ ```
16
+
17
+ ## 🚀 Deployment Options
18
+
19
+ ### Option 1: Snowflake as Data Backend (Recommended)
20
+ Deploy the web app on cloud platforms while using Snowflake for data storage:
21
+
22
+ **Web App Hosting:**
23
+ - **Streamlit Cloud**: Free hosting for Streamlit apps
24
+ - **Heroku**: Full-stack deployment
25
+ - **AWS/GCP/Azure**: Enterprise deployment
26
+
27
+ **Data Storage:**
28
+ - **Snowflake**: Enterprise data warehouse for emission data, analytics
29
+
30
+ ### Option 2: Snowflake Native Apps (Advanced)
31
+ Deploy as a Snowflake Native App (requires Snowflake Native App Framework):
32
+
33
+ ## 📋 Prerequisites
34
+
35
+ 1. **Snowflake Account**: Sign up at [snowflake.com](https://snowflake.com)
36
+ 2. **Database Setup**: Create database and schema
37
+ 3. **Credentials**: Obtain account identifier, username, password
38
+
39
+ ## 🔧 Setup Instructions
40
+
41
+ ### Step 1: Snowflake Account Setup
42
+
43
+ ```sql
44
+ -- Create database and schema
45
+ CREATE DATABASE GREENPATH;
46
+ CREATE SCHEMA GREENPATH.EMISSIONS;
47
+
48
+ -- Create warehouse
49
+ CREATE WAREHOUSE COMPUTE_WH WITH
50
+ WAREHOUSE_SIZE = 'X-SMALL'
51
+ AUTO_SUSPEND = 60
52
+ AUTO_RESUME = TRUE;
53
+
54
+ -- Grant permissions
55
+ GRANT USAGE ON DATABASE GREENPATH TO ROLE ACCOUNTADMIN;
56
+ GRANT USAGE ON SCHEMA GREENPATH.EMISSIONS TO ROLE ACCOUNTADMIN;
57
+ GRANT USAGE ON WAREHOUSE COMPUTE_WH TO ROLE ACCOUNTADMIN;
58
+ ```
59
+
60
+ ### Step 2: Environment Configuration
61
+
62
+ ```bash
63
+ # Copy Snowflake environment template
64
+ cp .env.snowflake .env
65
+
66
+ # Edit .env with your Snowflake credentials
67
+ SNOWFLAKE_ACCOUNT=your_account.region.cloud
68
+ SNOWFLAKE_USER=your_username
69
+ SNOWFLAKE_PASSWORD=your_password
70
+ ```
71
+
72
+ ### Step 3: Install Dependencies
73
+
74
+ ```bash
75
+ pip install snowflake-connector-python snowflake-sqlalchemy
76
+ ```
77
+
78
+ ### Step 4: Initialize Database Tables
79
+
80
+ ```python
81
+ from src.database.snowflake_models import SnowflakeDataManager
82
+
83
+ # Initialize Snowflake connection and create tables
84
+ manager = SnowflakeDataManager()
85
+ manager.create_tables()
86
+ ```
87
+
88
+ ## 🌐 Deployment Scenarios
89
+
90
+ ### Scenario A: Streamlit Cloud + Snowflake
91
+
92
+ 1. **Deploy to Streamlit Cloud:**
93
+ ```bash
94
+ # Push to GitHub
95
+ git add .
96
+ git commit -m "Add Snowflake integration"
97
+ git push origin main
98
+
99
+ # Deploy via Streamlit Cloud dashboard
100
+ # Connect GitHub repository
101
+ # Add Snowflake credentials to secrets
102
+ ```
103
+
104
+ 2. **Configure Secrets in Streamlit Cloud:**
105
+ ```toml
106
+ # .streamlit/secrets.toml
107
+ [snowflake]
108
+ account = "your_account.region.cloud"
109
+ user = "your_username"
110
+ password = "your_password"
111
+ database = "GREENPATH"
112
+ schema = "EMISSIONS"
113
+ warehouse = "COMPUTE_WH"
114
+ ```
115
+
116
+ ### Scenario B: Heroku + Snowflake
117
+
118
+ 1. **Create Heroku App:**
119
+ ```bash
120
+ heroku create greenpath-emissions
121
+ ```
122
+
123
+ 2. **Set Environment Variables:**
124
+ ```bash
125
+ heroku config:set SNOWFLAKE_ACCOUNT=your_account.region.cloud
126
+ heroku config:set SNOWFLAKE_USER=your_username
127
+ heroku config:set SNOWFLAKE_PASSWORD=your_password
128
+ heroku config:set SNOWFLAKE_DATABASE=GREENPATH
129
+ heroku config:set SNOWFLAKE_SCHEMA=EMISSIONS
130
+ heroku config:set SNOWFLAKE_WAREHOUSE=COMPUTE_WH
131
+ ```
132
+
133
+ 3. **Deploy:**
134
+ ```bash
135
+ git push heroku main
136
+ ```
137
+
138
+ ### Scenario C: Docker + Snowflake
139
+
140
+ 1. **Update docker-compose.yml:**
141
+ ```yaml
142
+ version: '3.8'
143
+ services:
144
+ streamlit:
145
+ build:
146
+ context: .
147
+ dockerfile: Dockerfile.streamlit
148
+ ports:
149
+ - "8501:8501"
150
+ environment:
151
+ - SNOWFLAKE_ACCOUNT=${SNOWFLAKE_ACCOUNT}
152
+ - SNOWFLAKE_USER=${SNOWFLAKE_USER}
153
+ - SNOWFLAKE_PASSWORD=${SNOWFLAKE_PASSWORD}
154
+ - SNOWFLAKE_DATABASE=GREENPATH
155
+ - SNOWFLAKE_SCHEMA=EMISSIONS
156
+ - SNOWFLAKE_WAREHOUSE=COMPUTE_WH
157
+ ```
158
+
159
+ 2. **Deploy:**
160
+ ```bash
161
+ docker-compose up --build
162
+ ```
163
+
164
+ ## 📊 Data Models
165
+
166
+ ### Shipments Table
167
+ ```sql
168
+ CREATE TABLE shipments (
169
+ id STRING PRIMARY KEY,
170
+ origin STRING,
171
+ destination STRING,
172
+ distance_km FLOAT,
173
+ weight_tonnes FLOAT,
174
+ transport_mode STRING,
175
+ co2_emissions_kg FLOAT,
176
+ carbon_tax_cost_usd FLOAT,
177
+ created_at TIMESTAMP_NTZ DEFAULT CURRENT_TIMESTAMP()
178
+ );
179
+ ```
180
+
181
+ ### Route Optimizations Table
182
+ ```sql
183
+ CREATE TABLE route_optimizations (
184
+ id STRING PRIMARY KEY,
185
+ shipment_id STRING,
186
+ original_emissions_kg FLOAT,
187
+ optimized_emissions_kg FLOAT,
188
+ emission_reduction_percent FLOAT,
189
+ recommended_mode STRING,
190
+ created_at TIMESTAMP_NTZ DEFAULT CURRENT_TIMESTAMP()
191
+ );
192
+ ```
193
+
194
+ ## 🔍 Analytics Queries
195
+
196
+ ### Monthly Emission Trends
197
+ ```sql
198
+ SELECT
199
+ DATE_TRUNC('month', created_at) as month,
200
+ SUM(co2_emissions_kg) as total_emissions,
201
+ COUNT(*) as shipment_count,
202
+ AVG(co2_emissions_kg) as avg_emissions
203
+ FROM shipments
204
+ GROUP BY month
205
+ ORDER BY month;
206
+ ```
207
+
208
+ ### Transport Mode Comparison
209
+ ```sql
210
+ SELECT
211
+ transport_mode,
212
+ SUM(co2_emissions_kg) as total_emissions,
213
+ COUNT(*) as shipment_count,
214
+ AVG(co2_emissions_kg) as avg_emissions_per_shipment
215
+ FROM shipments
216
+ GROUP BY transport_mode
217
+ ORDER BY total_emissions DESC;
218
+ ```
219
+
220
+ ## 🚀 Recommended Deployment
221
+
222
+ For your GreenPath platform, I recommend:
223
+
224
+ 1. **Streamlit Cloud** for web app hosting (free, easy setup)
225
+ 2. **Snowflake** for data warehouse (enterprise-grade analytics)
226
+ 3. **GitHub** for version control and CI/CD
227
+
228
+ This combination provides:
229
+ - ✅ Free hosting for the web application
230
+ - ✅ Enterprise-grade data storage and analytics
231
+ - ✅ Scalable architecture
232
+ - ✅ Professional deployment pipeline
233
+
234
+ ## 🔐 Security Best Practices
235
+
236
+ 1. **Use environment variables** for all credentials
237
+ 2. **Enable MFA** on Snowflake account
238
+ 3. **Create dedicated service user** for application access
239
+ 4. **Use least privilege** role assignments
240
+ 5. **Enable network policies** if required
241
+
242
+ ## 📈 Scaling Considerations
243
+
244
+ - **Warehouse Size**: Start with X-SMALL, scale as needed
245
+ - **Auto-suspend**: Set to 60 seconds to minimize costs
246
+ - **Data Retention**: Configure time travel as needed
247
+ - **Clustering**: Add clustering keys for large datasets
248
+
249
+ ## 💰 Cost Optimization
250
+
251
+ - Use **auto-suspend** for warehouses
252
+ - Choose appropriate **warehouse sizes**
253
+ - Monitor **query performance**
254
+ - Use **result caching** where possible
255
+
256
+ ---
257
+
258
+ **Author**: Sayed Mohd Zayeem Khateeb
259
+ **Contact**: zayeem.s.khateeb@gmail.com
app.py CHANGED
@@ -1,755 +1,755 @@
1
- """
2
- GreenPath - AI & Data Analytics Platform for Reducing Shipment CO₂ Emissions
3
- Professional Streamlit Frontend with Eco-Friendly Design
4
- """
5
-
6
- import streamlit as st
7
- import pandas as pd
8
- import plotly.express as px
9
- import plotly.graph_objects as go
10
- from plotly.subplots import make_subplots
11
- import requests
12
- import sys
13
- import os
14
- from datetime import datetime, timedelta
15
- import numpy as np
16
-
17
- # Add src directory to path
18
- sys.path.append(os.path.join(os.path.dirname(__file__), 'src'))
19
-
20
- from emissions.emission_calculator import EmissionCalculator, TransportMode
21
- from route_optimizer.green_route_optimizer import GreenRouteOptimizer
22
-
23
- # Page configuration
24
- st.set_page_config(
25
- page_title="GreenPath - CO₂ Emission Tracker",
26
- page_icon="🌱",
27
- layout="wide",
28
- initial_sidebar_state="expanded"
29
- )
30
-
31
- # Custom CSS for eco-friendly theme
32
- st.markdown("""
33
- <style>
34
-
35
- .main-header {
36
- background: linear-gradient(90deg, #2ECC71 0%, #27AE60 100%);
37
- padding: 2rem;
38
- border-radius: 10px;
39
- color: white;
40
- text-align: center;
41
- margin-bottom: 2rem;
42
- position: relative;
43
- z-index: 1;
44
- }
45
-
46
- .metric-card {
47
- background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
48
- padding: 1.5rem;
49
- border-radius: 10px;
50
- box-shadow: 0 2px 10px rgba(0,0,0,0.1);
51
- border-left: 4px solid #2ECC71;
52
- margin-bottom: 1rem;
53
- }
54
-
55
- .green-button {
56
- background-color: #2ECC71;
57
- color: white;
58
- border: none;
59
- padding: 0.5rem 1rem;
60
- border-radius: 5px;
61
- cursor: pointer;
62
- }
63
-
64
- .sidebar .sidebar-content {
65
- background-color: #F8F9FA;
66
- }
67
-
68
- .stSelectbox > div > div {
69
- background-color: white !important;
70
- border: 1px solid #E0E0E0 !important;
71
- border-radius: 8px !important;
72
- color: #34495E !important;
73
- }
74
-
75
- .stSelectbox > div > div > div {
76
- color: #34495E !important;
77
- font-weight: 500 !important;
78
- }
79
-
80
- .eco-badge {
81
- background-color: #2ECC71;
82
- color: white;
83
- padding: 0.2rem 0.5rem;
84
- border-radius: 15px;
85
- font-size: 0.8rem;
86
- font-weight: bold;
87
- }
88
-
89
-
90
- /* Navigation styling */
91
- .stRadio > div {
92
- background-color: transparent;
93
- padding: 0.5rem;
94
- border-radius: 8px;
95
- }
96
-
97
- .stRadio > div > label {
98
- background-color: #FFFFFF;
99
- border: 1px solid #E0E0E0;
100
- border-radius: 8px;
101
- margin: 4px 0;
102
- padding: 8px 12px;
103
- cursor: pointer;
104
- transition: all 0.3s ease;
105
- display: block;
106
- }
107
-
108
- .stRadio > div > label:hover {
109
- background-color: #E8F5E8;
110
- border-color: #2ECC71;
111
- color: #2ECC71;
112
- }
113
-
114
- .stRadio > div > label > div {
115
- color: #34495E !important;
116
- font-size: 14px !important;
117
- font-weight: 500;
118
- margin: 0;
119
- }
120
-
121
- .stRadio > div > label[data-checked="true"] {
122
- background-color: #2ECC71;
123
- border-color: #2ECC71;
124
- color: white;
125
- }
126
-
127
- .stRadio > div > label[data-checked="true"] > div {
128
- color: white !important;
129
- }
130
-
131
- /* Emoji fix */
132
- .stRadio label {
133
- font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
134
- }
135
-
136
- /* Sidebar styling */
137
- .css-1d391kg {
138
- background-color: #F8F9FA;
139
- }
140
-
141
- /* Metric styling */
142
- [data-testid="metric-container"] {
143
- background-color: white;
144
- border: 1px solid #E0E0E0;
145
- padding: 1rem;
146
- border-radius: 8px;
147
- border-left: 4px solid #2ECC71;
148
- }
149
- </style>
150
- """, unsafe_allow_html=True)
151
-
152
- # Initialize components
153
- @st.cache_resource
154
- def init_components():
155
- calculator = EmissionCalculator()
156
- optimizer = GreenRouteOptimizer()
157
- return calculator, optimizer
158
-
159
- calculator, optimizer = init_components()
160
-
161
- # Header
162
- st.markdown("""
163
- <div class="main-header">
164
- <h1>🌱 GreenPath</h1>
165
- <h3>AI-Powered Platform for Reducing Shipment CO₂ Emissions</h3>
166
- <p>Designed by Sayed Mohd Zayeem Khateeb</p>
167
- </div>
168
- """, unsafe_allow_html=True)
169
-
170
- # Sidebar
171
- with st.sidebar:
172
- # Custom GreenPath logo
173
- st.markdown("""
174
- <div style="text-align: center; padding: 1rem; background: linear-gradient(135deg, #2ECC71, #27AE60); border-radius: 10px; margin-bottom: 1rem;">
175
- <h2 style="color: white; margin: 0; font-size: 24px;">🌱 GreenPath</h2>
176
- <p style="color: #E8F8F5; margin: 0; font-size: 12px;">AI Emission Tracker</p>
177
- </div>
178
- """, unsafe_allow_html=True)
179
-
180
- st.markdown("### 📍 Navigate")
181
-
182
- # Navigation with better visibility
183
- nav_options = {
184
- "🏠 Dashboard": "Dashboard",
185
- "🧮 Emission Calculator": "Emission Calculator",
186
- "🗺️ Route Optimizer": "Route Optimizer",
187
- "📊 Scenario Analysis": "Scenario Analysis",
188
- "📈 Analytics": "Analytics"
189
- }
190
-
191
- page = st.selectbox(
192
- "Choose a page:",
193
- options=list(nav_options.keys()),
194
- label_visibility="collapsed",
195
- key="navigation"
196
- )
197
-
198
- st.markdown("---")
199
- st.markdown("### 🌍 Quick Stats")
200
-
201
- # Sample KPIs
202
- col1, col2 = st.columns(2)
203
- with col1:
204
- st.metric("CO₂ Saved", "2.4t", "↓ 22%")
205
- with col2:
206
- st.metric("Routes Optimized", "156", "↑ 15%")
207
-
208
- # Main content based on selected page
209
- if page == "🏠 Dashboard":
210
- st.markdown("## 📊 Emission Overview Dashboard")
211
-
212
- # Top KPIs
213
- col1, col2, col3, col4 = st.columns(4)
214
-
215
- with col1:
216
- st.markdown("""
217
- <div class="metric-card">
218
- <h3 style="color: #2ECC71; margin: 0;">12.5t</h3>
219
- <p style="margin: 0; color: #7F8C8D;">Total CO₂ Emissions</p>
220
- <small style="color: #E74C3C;">↓ 18% vs last month</small>
221
- </div>
222
- """, unsafe_allow_html=True)
223
-
224
- with col2:
225
- st.markdown("""
226
- <div class="metric-card">
227
- <h3 style="color: #2ECC71; margin: 0;">22%</h3>
228
- <p style="margin: 0; color: #7F8C8D;">Emission Reduction</p>
229
- <small style="color: #27AE60;">Green routes adopted</small>
230
- </div>
231
- """, unsafe_allow_html=True)
232
-
233
- with col3:
234
- st.markdown("""
235
- <div class="metric-card">
236
- <h3 style="color: #2ECC71; margin: 0;">0.08</h3>
237
- <p style="margin: 0; color: #7F8C8D;">Avg. Emission/Shipment (kg)</p>
238
- <small style="color: #27AE60;">Industry best practice</small>
239
- </div>
240
- """, unsafe_allow_html=True)
241
-
242
- with col4:
243
- st.markdown("""
244
- <div class="metric-card">
245
- <h3 style="color: #2ECC71; margin: 0;">$1,250</h3>
246
- <p style="margin: 0; color: #7F8C8D;">Carbon Tax Savings</p>
247
- <small style="color: #27AE60;">Monthly estimate</small>
248
- </div>
249
- """, unsafe_allow_html=True)
250
-
251
- # Charts
252
- col1, col2 = st.columns(2)
253
-
254
- with col1:
255
- st.markdown("### 🚛 Emissions by Transport Mode")
256
-
257
- # Sample data for transport mode comparison
258
- modes_data = pd.DataFrame({
259
- 'Transport Mode': ['Road Truck', 'Rail', 'Ship Container', 'Air Cargo'],
260
- 'CO₂ Emissions (kg)': [62, 22, 11, 602],
261
- 'Usage %': [45, 30, 20, 5]
262
- })
263
-
264
- fig = px.bar(
265
- modes_data,
266
- x='Transport Mode',
267
- y='CO₂ Emissions (kg)',
268
- color='CO₂ Emissions (kg)',
269
- color_continuous_scale=['#2ECC71', '#E74C3C'],
270
- title="Emission Factors by Transport Mode"
271
- )
272
- fig.update_layout(showlegend=False, height=400)
273
- st.plotly_chart(fig, use_container_width=True)
274
-
275
- with col2:
276
- st.markdown("### 📈 Emission Trends")
277
-
278
- # Sample trend data
279
- emissions_data = [15.2, 14.8, 13.9, 13.1, 12.8, 12.3, 11.9, 11.5, 12.5]
280
- dates = pd.date_range(start='2024-01-01', periods=len(emissions_data), freq='M')
281
- trend_data = pd.DataFrame({
282
- 'Date': dates,
283
- 'Emissions (tonnes)': emissions_data,
284
- 'Target': [14.0] * len(emissions_data)
285
- })
286
-
287
- fig = go.Figure()
288
- fig.add_trace(go.Scatter(
289
- x=trend_data['Date'],
290
- y=trend_data['Emissions (tonnes)'],
291
- mode='lines+markers',
292
- name='Actual Emissions',
293
- line=dict(color='#2ECC71', width=3)
294
- ))
295
- fig.add_trace(go.Scatter(
296
- x=trend_data['Date'],
297
- y=trend_data['Target'],
298
- mode='lines',
299
- name='Target',
300
- line=dict(color='#E74C3C', dash='dash')
301
- ))
302
- fig.update_layout(title="Monthly Emission Trends", height=400)
303
- st.plotly_chart(fig, use_container_width=True)
304
-
305
- elif page == "🧮 Emission Calculator":
306
- st.markdown("## 🧮 CO₂ Emission Calculator")
307
- st.markdown("Calculate CO₂ emissions using the formula: **CO₂ = Distance × Weight × EmissionFactor**")
308
-
309
- col1, col2 = st.columns([2, 1])
310
-
311
- with col1:
312
- with st.form("emission_calculator"):
313
- st.markdown("### Input Parameters")
314
-
315
- col_a, col_b = st.columns(2)
316
- with col_a:
317
- distance = st.number_input("Distance (km)", min_value=0.1, value=500.0, step=10.0)
318
- weight = st.number_input("Weight (tonnes)", min_value=0.01, value=2.0, step=0.1)
319
-
320
- with col_b:
321
- transport_mode = st.selectbox(
322
- "Transport Mode",
323
- options=[mode.value for mode in TransportMode],
324
- format_func=lambda x: x.replace('_', ' ').title()
325
- )
326
-
327
- calculate_btn = st.form_submit_button("🧮 Calculate Emissions", type="primary")
328
-
329
- if calculate_btn:
330
- try:
331
- # Convert string to TransportMode enum
332
- mode_mapping = {
333
- 'road_truck': TransportMode.ROAD_TRUCK,
334
- 'road_van': TransportMode.ROAD_VAN,
335
- 'rail': TransportMode.RAIL,
336
- 'air_cargo': TransportMode.AIR_CARGO,
337
- 'ship_container': TransportMode.SHIP_CONTAINER,
338
- 'ship_bulk': TransportMode.SHIP_BULK
339
- }
340
-
341
- if transport_mode in mode_mapping:
342
- mode = mode_mapping[transport_mode]
343
- else:
344
- mode = TransportMode(transport_mode)
345
-
346
- result = calculator.calculate_emissions(distance, weight, mode)
347
-
348
- st.success("✅ Calculation Complete!")
349
-
350
- # Results display
351
- col_r1, col_r2, col_r3 = st.columns(3)
352
-
353
- with col_r1:
354
- st.metric(
355
- "CO₂ Emissions",
356
- f"{result['co2_emissions_kg']:.2f} kg",
357
- f"{result['co2_emissions_tonnes']:.3f} tonnes"
358
- )
359
-
360
- with col_r2:
361
- carbon_tax = calculator.calculate_carbon_tax_cost(result['co2_emissions_kg'])
362
- st.metric(
363
- "Carbon Tax Cost",
364
- f"${carbon_tax['carbon_tax_cost_usd']:.2f}",
365
- "@ $50/tonne CO₂"
366
- )
367
-
368
- with col_r3:
369
- st.metric(
370
- "Emission Factor",
371
- f"{result['emission_factor']:.3f}",
372
- "kg CO₂/tonne-km"
373
- )
374
-
375
- # Comparison with other modes
376
- st.markdown("### 🔄 Transport Mode Comparison")
377
- comparison_df = calculator.compare_transport_modes(distance, weight)
378
-
379
- fig = px.bar(
380
- comparison_df,
381
- x='transport_mode',
382
- y='co2_emissions_kg',
383
- color='co2_emissions_kg',
384
- color_continuous_scale=['#2ECC71', '#E74C3C'],
385
- title="CO₂ Emissions by Transport Mode"
386
- )
387
- fig.update_layout(height=400)
388
- st.plotly_chart(fig, use_container_width=True)
389
-
390
- st.dataframe(comparison_df, use_container_width=True)
391
-
392
- except Exception as e:
393
- st.error(f"❌ Calculation failed: {str(e)}")
394
-
395
- with col2:
396
- st.markdown("### 📋 Emission Factors")
397
- factors_df = calculator.get_emission_factors_table()
398
- st.dataframe(factors_df, use_container_width=True)
399
-
400
- st.markdown("### 🌱 Green Tips")
401
- st.info("""
402
- **Reduce Emissions:**
403
- - Choose rail over road when possible
404
- - Use container ships for long distances
405
- - Optimize load capacity
406
- - Consider multimodal transport
407
- """)
408
-
409
- elif page == "🗺️ Route Optimizer":
410
- st.markdown("## 🗺️ Green Route Optimizer")
411
- st.markdown("Find the most eco-friendly routes for your shipments")
412
-
413
- with st.form("route_optimizer"):
414
- col1, col2 = st.columns(2)
415
-
416
- with col1:
417
- origin = st.text_input("Origin", value="New York, NY", placeholder="Enter origin city")
418
- destination = st.text_input("Destination", value="Los Angeles, CA", placeholder="Enter destination city")
419
-
420
- with col2:
421
- weight = st.number_input("Shipment Weight (tonnes)", min_value=0.01, value=5.0, step=0.1)
422
- max_time_penalty = st.slider("Max Time Penalty (%)", 0, 50, 10)
423
-
424
- optimize_btn = st.form_submit_button("🗺️ Find Green Routes", type="primary")
425
-
426
- if optimize_btn and origin and destination:
427
- with st.spinner("🔍 Finding optimal routes..."):
428
- try:
429
- # Get route recommendations
430
- recommendations = optimizer.recommend_green_routes(origin, destination, weight)
431
-
432
- if 'success' in recommendations and recommendations['success']:
433
- st.success("✅ Route optimization complete!")
434
-
435
- route_data = recommendations['recommendations']
436
-
437
- # Display recommendations
438
- st.markdown("### 🌱 Green Route Recommendations")
439
-
440
- for i, route in enumerate(route_data):
441
- with st.expander(f"Option {i+1}: {route['transport_mode'].replace('_', ' ').title()}", expanded=(i==0)):
442
- col_a, col_b, col_c, col_d = st.columns(4)
443
-
444
- with col_a:
445
- st.metric("CO₂ Emissions", f"{route['co2_emissions_kg']:.1f} kg")
446
- with col_b:
447
- st.metric("Travel Time", f"{route['estimated_travel_time_hours']:.1f} hrs")
448
- with col_c:
449
- st.metric("Carbon Tax", f"${route['carbon_tax_cost_usd']:.2f}")
450
- with col_d:
451
- if route['emission_reduction_percent'] > 0:
452
- st.metric("Emission Reduction", f"{route['emission_reduction_percent']:.1f}%", "vs worst option")
453
- else:
454
- st.metric("Emission Impact", "Baseline", "")
455
-
456
- if i == 0:
457
- st.markdown('<span class="eco-badge">🌱 RECOMMENDED</span>', unsafe_allow_html=True)
458
-
459
- # Visualization
460
- if len(route_data) > 1:
461
- st.markdown("### 📊 Route Comparison")
462
-
463
- df_viz = pd.DataFrame(route_data)
464
-
465
- fig = make_subplots(
466
- rows=1, cols=2,
467
- subplot_titles=('CO₂ Emissions (kg)', 'Travel Time (hours)'),
468
- specs=[[{"secondary_y": False}, {"secondary_y": False}]]
469
- )
470
-
471
- fig.add_trace(
472
- go.Bar(
473
- x=df_viz['transport_mode'],
474
- y=df_viz['co2_emissions_kg'],
475
- name='CO₂ Emissions',
476
- marker_color='#2ECC71'
477
- ),
478
- row=1, col=1
479
- )
480
-
481
- fig.add_trace(
482
- go.Bar(
483
- x=df_viz['transport_mode'],
484
- y=df_viz['estimated_travel_time_hours'],
485
- name='Travel Time',
486
- marker_color='#3498DB'
487
- ),
488
- row=1, col=2
489
- )
490
-
491
- fig.update_layout(height=400, showlegend=False)
492
- st.plotly_chart(fig, use_container_width=True)
493
-
494
- else:
495
- st.error(f"❌ Route optimization failed: {recommendations.get('error', 'Unknown error')}")
496
-
497
- except Exception as e:
498
- st.error(f"❌ Error: {str(e)}")
499
-
500
- elif page == "📊 Scenario Analysis":
501
- st.markdown("## 📊 Business Impact Simulation")
502
- st.markdown("Analyze the potential impact of adopting green shipping practices")
503
-
504
- with st.form("scenario_analysis"):
505
- col1, col2 = st.columns(2)
506
-
507
- with col1:
508
- st.markdown("### 📦 Shipment Parameters")
509
- total_shipments = st.number_input("Total Monthly Shipments", min_value=1, value=1000, step=50)
510
- avg_distance = st.number_input("Average Distance (km)", min_value=1.0, value=800.0, step=50.0)
511
- avg_weight = st.number_input("Average Weight (tonnes)", min_value=0.1, value=3.0, step=0.1)
512
-
513
- with col2:
514
- st.markdown("### ⚙️ Optimization Parameters")
515
- optimization_percent = st.slider("% Shipments Using Green Routes", 0, 100, 50)
516
- current_mode = st.selectbox("Current Transport Mode", [mode.value for mode in TransportMode], index=0)
517
- carbon_tax_rate = st.number_input("Carbon Tax Rate ($/tonne CO₂)", min_value=0.0, value=50.0, step=5.0)
518
-
519
- analyze_btn = st.form_submit_button("📊 Run Scenario Analysis", type="primary")
520
-
521
- if analyze_btn:
522
- with st.spinner("🔄 Running business impact simulation..."):
523
- try:
524
- # Current emissions - use same mapping as before
525
- mode_mapping = {
526
- 'road_truck': TransportMode.ROAD_TRUCK,
527
- 'road_van': TransportMode.ROAD_VAN,
528
- 'rail': TransportMode.RAIL,
529
- 'air_cargo': TransportMode.AIR_CARGO,
530
- 'ship_container': TransportMode.SHIP_CONTAINER,
531
- 'ship_bulk': TransportMode.SHIP_BULK
532
- }
533
-
534
- if current_mode in mode_mapping:
535
- current_mode_enum = mode_mapping[current_mode]
536
- else:
537
- current_mode_enum = TransportMode(current_mode)
538
-
539
- current_emissions = calculator.calculate_emissions(avg_distance, avg_weight, current_mode_enum)
540
-
541
- # Find best green alternative - calculate manually to avoid EmissionOptimizer import
542
- available_modes = [TransportMode.ROAD_TRUCK, TransportMode.RAIL, TransportMode.SHIP_CONTAINER]
543
-
544
- # Calculate emissions for each mode and find the greenest
545
- mode_options = []
546
- for mode in available_modes:
547
- emissions = calculator.calculate_emissions(avg_distance, avg_weight, mode)
548
- mode_options.append({
549
- 'mode': mode,
550
- 'co2_emissions_kg': emissions['co2_emissions_kg'],
551
- 'emission_factor': emissions['emission_factor']
552
- })
553
-
554
- # Sort by emissions (lowest first) to find greenest option
555
- mode_options.sort(key=lambda x: x['co2_emissions_kg'])
556
- green_option = mode_options[0] if mode_options else None
557
-
558
- if not green_option:
559
- st.error("❌ No green alternatives available")
560
- st.stop()
561
-
562
- # Calculate scenario impact
563
- optimized_shipments = int(total_shipments * optimization_percent / 100)
564
- regular_shipments = total_shipments - optimized_shipments
565
-
566
- current_total = current_emissions['co2_emissions_kg'] * total_shipments
567
- optimized_total = (
568
- green_option['co2_emissions_kg'] * optimized_shipments +
569
- current_emissions['co2_emissions_kg'] * regular_shipments
570
- )
571
-
572
- savings_kg = current_total - optimized_total
573
- savings_percent = (savings_kg / current_total) * 100
574
- carbon_tax_savings = (savings_kg / 1000) * carbon_tax_rate
575
-
576
- st.success("✅ Scenario analysis complete!")
577
-
578
- # Results
579
- col1, col2, col3, col4 = st.columns(4)
580
-
581
- with col1:
582
- st.metric("Current Emissions", f"{current_total/1000:.1f} tonnes/month")
583
- with col2:
584
- st.metric("Optimized Emissions", f"{optimized_total/1000:.1f} tonnes/month")
585
- with col3:
586
- st.metric("CO₂ Savings", f"{savings_kg/1000:.1f} tonnes/month", f"{savings_percent:.1f}% reduction")
587
- with col4:
588
- st.metric("Carbon Tax Savings", f"${carbon_tax_savings:.0f}/month", f"${carbon_tax_savings*12:.0f}/year")
589
-
590
- # Visualization
591
- st.markdown("### 📈 Impact Visualization")
592
-
593
- scenario_data = pd.DataFrame({
594
- 'Scenario': ['Current', 'Optimized'],
595
- 'CO₂ Emissions (tonnes)': [current_total/1000, optimized_total/1000],
596
- 'Carbon Tax Cost ($)': [
597
- (current_total/1000) * carbon_tax_rate,
598
- (optimized_total/1000) * carbon_tax_rate
599
- ]
600
- })
601
-
602
- fig = make_subplots(
603
- rows=1, cols=2,
604
- subplot_titles=('CO₂ Emissions', 'Carbon Tax Cost'),
605
- specs=[[{"secondary_y": False}, {"secondary_y": False}]]
606
- )
607
-
608
- fig.add_trace(
609
- go.Bar(
610
- x=scenario_data['Scenario'],
611
- y=scenario_data['CO₂ Emissions (tonnes)'],
612
- name='CO₂ Emissions',
613
- marker_color=['#E74C3C', '#2ECC71']
614
- ),
615
- row=1, col=1
616
- )
617
-
618
- fig.add_trace(
619
- go.Bar(
620
- x=scenario_data['Scenario'],
621
- y=scenario_data['Carbon Tax Cost ($)'],
622
- name='Carbon Tax Cost',
623
- marker_color=['#E74C3C', '#2ECC71']
624
- ),
625
- row=1, col=2
626
- )
627
-
628
- fig.update_layout(height=400, showlegend=False)
629
- st.plotly_chart(fig, use_container_width=True)
630
-
631
- # Business benefits
632
- st.markdown("### 💼 Business Benefits")
633
-
634
- benefits_col1, benefits_col2 = st.columns(2)
635
-
636
- with benefits_col1:
637
- st.markdown("""
638
- **Environmental Impact:**
639
- - ♻️ Reduced carbon footprint
640
- - 🌱 Enhanced sustainability profile
641
- - 📊 ESG score improvement
642
- - 🏆 Industry leadership positioning
643
- """)
644
-
645
- with benefits_col2:
646
- st.markdown(f"""
647
- **Financial Benefits:**
648
- - 💰 ${carbon_tax_savings*12:.0f} annual tax savings
649
- - 📈 Potential green financing access
650
- - 🎯 Regulatory compliance readiness
651
- - 💡 Operational efficiency gains
652
- """)
653
-
654
- except Exception as e:
655
- st.error(f"❌ Analysis failed: {str(e)}")
656
- st.write(f"Debug info: {type(e).__name__}: {e}")
657
- import traceback
658
- st.code(traceback.format_exc())
659
-
660
- elif page == "📈 Analytics":
661
- st.markdown("## 📈 Advanced Analytics")
662
-
663
- # Sample analytics data
664
- st.markdown("### 🎯 Performance Metrics")
665
-
666
- col1, col2, col3 = st.columns(3)
667
-
668
- with col1:
669
- st.markdown("""
670
- <div class="metric-card">
671
- <h4 style="color: #2ECC71; margin: 0;">Route Efficiency Score</h4>
672
- <h2 style="margin: 0;">87/100</h2>
673
- <p style="margin: 0; color: #7F8C8D;">Above industry average</p>
674
- </div>
675
- """, unsafe_allow_html=True)
676
-
677
- with col2:
678
- st.markdown("""
679
- <div class="metric-card">
680
- <h4 style="color: #2ECC71; margin: 0;">Green Route Adoption</h4>
681
- <h2 style="margin: 0;">68%</h2>
682
- <p style="margin: 0; color: #7F8C8D;">Target: 75%</p>
683
- </div>
684
- """, unsafe_allow_html=True)
685
-
686
- with col3:
687
- st.markdown("""
688
- <div class="metric-card">
689
- <h4 style="color: #2ECC71; margin: 0;">Emission Intensity</h4>
690
- <h2 style="margin: 0;">0.045</h2>
691
- <p style="margin: 0; color: #7F8C8D;">kg CO₂/tonne-km</p>
692
- </div>
693
- """, unsafe_allow_html=True)
694
-
695
- # Regional analysis
696
- st.markdown("### 🌍 Regional Emission Analysis")
697
-
698
- regional_data = pd.DataFrame({
699
- 'Region': ['North America', 'Europe', 'Asia Pacific', 'Latin America'],
700
- 'Emissions (tonnes)': [45.2, 32.1, 28.7, 15.3],
701
- 'Shipments': [450, 320, 380, 180],
702
- 'Avg Distance (km)': [1200, 800, 950, 600]
703
- })
704
-
705
- fig = px.scatter(
706
- regional_data,
707
- x='Shipments',
708
- y='Emissions (tonnes)',
709
- size='Avg Distance (km)',
710
- color='Region',
711
- title="Regional Emission vs Shipment Volume"
712
- )
713
- fig.update_layout(height=500)
714
- st.plotly_chart(fig, use_container_width=True)
715
-
716
- st.dataframe(regional_data, use_container_width=True)
717
-
718
-
719
- # Footer
720
- st.markdown("---")
721
- st.markdown("## 👨‍💻 Developer Details")
722
- st.markdown("""
723
- <div style="text-align: center; color: #2C3E50; padding: 2rem; background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1);">
724
- <div style="margin-bottom: 1rem;">
725
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" style="width: 60px; height: 60px;">
726
- <defs>
727
- <linearGradient id="zkGradient" x1="0%" y1="0%" x2="100%" y2="100%">
728
- <stop offset="0%" style="stop-color:#2ECC71;stop-opacity:1" />
729
- <stop offset="100%" style="stop-color:#27AE60;stop-opacity:1" />
730
- </linearGradient>
731
- </defs>
732
- <g transform="translate(50, 50)">
733
- <path d="M10 20 L70 20 L70 35 L35 75 L70 75 L70 90 L10 90 L10 75 L45 35 L10 35 Z"
734
- fill="url(#zkGradient)"
735
- stroke="#1E8449"
736
- stroke-width="1"/>
737
- <path d="M80 20 L95 20 L95 50 L110 20 L130 20 L110 55 L130 90 L110 90 L95 65 L95 90 L80 90 Z"
738
- fill="url(#zkGradient)"
739
- stroke="#1E8449"
740
- stroke-width="1"/>
741
- </g>
742
- </svg>
743
- </div>
744
- <p style="font-size: 1.2rem; color: #2C3E50; margin-bottom: 0.5rem;"><strong>GreenPath</strong> - AI-Powered CO₂ Emission Reduction Platform</p>
745
- <p style="font-size: 1.1rem; color: #34495E; margin-bottom: 1rem;">Designed and Developed by <strong>Sayed Mohd Zayeem Khateeb</strong></p>
746
- <div style="margin: 1rem 0;">
747
- <a href="https://github.com/zayeemskhateeb-cloud" target="_blank" style="margin: 0 10px; text-decoration: none; color: #2ECC71; font-weight: bold; font-size: 1rem;">🌐 GitHub</a> |
748
- <a href="https://www.linkedin.com/in/zayeemkhateeb" target="_blank" style="margin: 0 10px; text-decoration: none; color: #2ECC71; font-weight: bold; font-size: 1rem;">💼 LinkedIn</a> |
749
- <a href="mailto:zayeem.s.khateeb@gmail.com" style="margin: 0 10px; text-decoration: none; color: #2ECC71; font-weight: bold; font-size: 1rem;">📧 Email</a>
750
- </div>
751
- <p style="font-size: 1rem; color: #7F8C8D; margin-top: 1rem;">
752
- Specialized in AI/ML, Data Analytics, and Sustainable Technology Solutions
753
- </p>
754
- </div>
755
- """, unsafe_allow_html=True)
 
1
+ """
2
+ GreenPath - AI & Data Analytics Platform for Reducing Shipment CO₂ Emissions
3
+ Professional Streamlit Frontend with Eco-Friendly Design
4
+ """
5
+
6
+ import streamlit as st
7
+ import pandas as pd
8
+ import plotly.express as px
9
+ import plotly.graph_objects as go
10
+ from plotly.subplots import make_subplots
11
+ import requests
12
+ import sys
13
+ import os
14
+ from datetime import datetime, timedelta
15
+ import numpy as np
16
+
17
+ # Add src directory to path
18
+ sys.path.append(os.path.join(os.path.dirname(__file__), 'src'))
19
+
20
+ from emissions.emission_calculator import EmissionCalculator, TransportMode
21
+ from route_optimizer.green_route_optimizer import GreenRouteOptimizer
22
+
23
+ # Page configuration
24
+ st.set_page_config(
25
+ page_title="GreenPath - CO₂ Emission Tracker",
26
+ page_icon="🌱",
27
+ layout="wide",
28
+ initial_sidebar_state="expanded"
29
+ )
30
+
31
+ # Custom CSS for eco-friendly theme
32
+ st.markdown("""
33
+ <style>
34
+
35
+ .main-header {
36
+ background: linear-gradient(90deg, #2ECC71 0%, #27AE60 100%);
37
+ padding: 2rem;
38
+ border-radius: 10px;
39
+ color: white;
40
+ text-align: center;
41
+ margin-bottom: 2rem;
42
+ position: relative;
43
+ z-index: 1;
44
+ }
45
+
46
+ .metric-card {
47
+ background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
48
+ padding: 1.5rem;
49
+ border-radius: 10px;
50
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
51
+ border-left: 4px solid #2ECC71;
52
+ margin-bottom: 1rem;
53
+ }
54
+
55
+ .green-button {
56
+ background-color: #2ECC71;
57
+ color: white;
58
+ border: none;
59
+ padding: 0.5rem 1rem;
60
+ border-radius: 5px;
61
+ cursor: pointer;
62
+ }
63
+
64
+ .sidebar .sidebar-content {
65
+ background-color: #F8F9FA;
66
+ }
67
+
68
+ .stSelectbox > div > div {
69
+ background-color: white !important;
70
+ border: 1px solid #E0E0E0 !important;
71
+ border-radius: 8px !important;
72
+ color: #34495E !important;
73
+ }
74
+
75
+ .stSelectbox > div > div > div {
76
+ color: #34495E !important;
77
+ font-weight: 500 !important;
78
+ }
79
+
80
+ .eco-badge {
81
+ background-color: #2ECC71;
82
+ color: white;
83
+ padding: 0.2rem 0.5rem;
84
+ border-radius: 15px;
85
+ font-size: 0.8rem;
86
+ font-weight: bold;
87
+ }
88
+
89
+
90
+ /* Navigation styling */
91
+ .stRadio > div {
92
+ background-color: transparent;
93
+ padding: 0.5rem;
94
+ border-radius: 8px;
95
+ }
96
+
97
+ .stRadio > div > label {
98
+ background-color: #FFFFFF;
99
+ border: 1px solid #E0E0E0;
100
+ border-radius: 8px;
101
+ margin: 4px 0;
102
+ padding: 8px 12px;
103
+ cursor: pointer;
104
+ transition: all 0.3s ease;
105
+ display: block;
106
+ }
107
+
108
+ .stRadio > div > label:hover {
109
+ background-color: #E8F5E8;
110
+ border-color: #2ECC71;
111
+ color: #2ECC71;
112
+ }
113
+
114
+ .stRadio > div > label > div {
115
+ color: #34495E !important;
116
+ font-size: 14px !important;
117
+ font-weight: 500;
118
+ margin: 0;
119
+ }
120
+
121
+ .stRadio > div > label[data-checked="true"] {
122
+ background-color: #2ECC71;
123
+ border-color: #2ECC71;
124
+ color: white;
125
+ }
126
+
127
+ .stRadio > div > label[data-checked="true"] > div {
128
+ color: white !important;
129
+ }
130
+
131
+ /* Emoji fix */
132
+ .stRadio label {
133
+ font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
134
+ }
135
+
136
+ /* Sidebar styling */
137
+ .css-1d391kg {
138
+ background-color: #F8F9FA;
139
+ }
140
+
141
+ /* Metric styling */
142
+ [data-testid="metric-container"] {
143
+ background-color: white;
144
+ border: 1px solid #E0E0E0;
145
+ padding: 1rem;
146
+ border-radius: 8px;
147
+ border-left: 4px solid #2ECC71;
148
+ }
149
+ </style>
150
+ """, unsafe_allow_html=True)
151
+
152
+ # Initialize components
153
+ @st.cache_resource
154
+ def init_components():
155
+ calculator = EmissionCalculator()
156
+ optimizer = GreenRouteOptimizer()
157
+ return calculator, optimizer
158
+
159
+ calculator, optimizer = init_components()
160
+
161
+ # Header
162
+ st.markdown("""
163
+ <div class="main-header">
164
+ <h1>🌱 GreenPath</h1>
165
+ <h3>AI-Powered Platform for Reducing Shipment CO₂ Emissions</h3>
166
+ <p>Designed by Sayed Mohd Zayeem Khateeb</p>
167
+ </div>
168
+ """, unsafe_allow_html=True)
169
+
170
+ # Sidebar
171
+ with st.sidebar:
172
+ # Custom GreenPath logo
173
+ st.markdown("""
174
+ <div style="text-align: center; padding: 1rem; background: linear-gradient(135deg, #2ECC71, #27AE60); border-radius: 10px; margin-bottom: 1rem;">
175
+ <h2 style="color: white; margin: 0; font-size: 24px;">🌱 GreenPath</h2>
176
+ <p style="color: #E8F8F5; margin: 0; font-size: 12px;">AI Emission Tracker</p>
177
+ </div>
178
+ """, unsafe_allow_html=True)
179
+
180
+ st.markdown("### 📍 Navigate")
181
+
182
+ # Navigation with better visibility
183
+ nav_options = {
184
+ "🏠 Dashboard": "Dashboard",
185
+ "🧮 Emission Calculator": "Emission Calculator",
186
+ "🗺️ Route Optimizer": "Route Optimizer",
187
+ "📊 Scenario Analysis": "Scenario Analysis",
188
+ "📈 Analytics": "Analytics"
189
+ }
190
+
191
+ page = st.selectbox(
192
+ "Choose a page:",
193
+ options=list(nav_options.keys()),
194
+ label_visibility="collapsed",
195
+ key="navigation"
196
+ )
197
+
198
+ st.markdown("---")
199
+ st.markdown("### 🌍 Quick Stats")
200
+
201
+ # Sample KPIs
202
+ col1, col2 = st.columns(2)
203
+ with col1:
204
+ st.metric("CO₂ Saved", "2.4t", "↓ 22%")
205
+ with col2:
206
+ st.metric("Routes Optimized", "156", "↑ 15%")
207
+
208
+ # Main content based on selected page
209
+ if page == "🏠 Dashboard":
210
+ st.markdown("## 📊 Emission Overview Dashboard")
211
+
212
+ # Top KPIs
213
+ col1, col2, col3, col4 = st.columns(4)
214
+
215
+ with col1:
216
+ st.markdown("""
217
+ <div class="metric-card">
218
+ <h3 style="color: #2ECC71; margin: 0;">12.5t</h3>
219
+ <p style="margin: 0; color: #7F8C8D;">Total CO₂ Emissions</p>
220
+ <small style="color: #E74C3C;">↓ 18% vs last month</small>
221
+ </div>
222
+ """, unsafe_allow_html=True)
223
+
224
+ with col2:
225
+ st.markdown("""
226
+ <div class="metric-card">
227
+ <h3 style="color: #2ECC71; margin: 0;">22%</h3>
228
+ <p style="margin: 0; color: #7F8C8D;">Emission Reduction</p>
229
+ <small style="color: #27AE60;">Green routes adopted</small>
230
+ </div>
231
+ """, unsafe_allow_html=True)
232
+
233
+ with col3:
234
+ st.markdown("""
235
+ <div class="metric-card">
236
+ <h3 style="color: #2ECC71; margin: 0;">0.08</h3>
237
+ <p style="margin: 0; color: #7F8C8D;">Avg. Emission/Shipment (kg)</p>
238
+ <small style="color: #27AE60;">Industry best practice</small>
239
+ </div>
240
+ """, unsafe_allow_html=True)
241
+
242
+ with col4:
243
+ st.markdown("""
244
+ <div class="metric-card">
245
+ <h3 style="color: #2ECC71; margin: 0;">$1,250</h3>
246
+ <p style="margin: 0; color: #7F8C8D;">Carbon Tax Savings</p>
247
+ <small style="color: #27AE60;">Monthly estimate</small>
248
+ </div>
249
+ """, unsafe_allow_html=True)
250
+
251
+ # Charts
252
+ col1, col2 = st.columns(2)
253
+
254
+ with col1:
255
+ st.markdown("### 🚛 Emissions by Transport Mode")
256
+
257
+ # Sample data for transport mode comparison
258
+ modes_data = pd.DataFrame({
259
+ 'Transport Mode': ['Road Truck', 'Rail', 'Ship Container', 'Air Cargo'],
260
+ 'CO₂ Emissions (kg)': [62, 22, 11, 602],
261
+ 'Usage %': [45, 30, 20, 5]
262
+ })
263
+
264
+ fig = px.bar(
265
+ modes_data,
266
+ x='Transport Mode',
267
+ y='CO₂ Emissions (kg)',
268
+ color='CO₂ Emissions (kg)',
269
+ color_continuous_scale=['#2ECC71', '#E74C3C'],
270
+ title="Emission Factors by Transport Mode"
271
+ )
272
+ fig.update_layout(showlegend=False, height=400)
273
+ st.plotly_chart(fig, use_container_width=True)
274
+
275
+ with col2:
276
+ st.markdown("### 📈 Emission Trends")
277
+
278
+ # Sample trend data
279
+ emissions_data = [15.2, 14.8, 13.9, 13.1, 12.8, 12.3, 11.9, 11.5, 12.5]
280
+ dates = pd.date_range(start='2024-01-01', periods=len(emissions_data), freq='M')
281
+ trend_data = pd.DataFrame({
282
+ 'Date': dates,
283
+ 'Emissions (tonnes)': emissions_data,
284
+ 'Target': [14.0] * len(emissions_data)
285
+ })
286
+
287
+ fig = go.Figure()
288
+ fig.add_trace(go.Scatter(
289
+ x=trend_data['Date'],
290
+ y=trend_data['Emissions (tonnes)'],
291
+ mode='lines+markers',
292
+ name='Actual Emissions',
293
+ line=dict(color='#2ECC71', width=3)
294
+ ))
295
+ fig.add_trace(go.Scatter(
296
+ x=trend_data['Date'],
297
+ y=trend_data['Target'],
298
+ mode='lines',
299
+ name='Target',
300
+ line=dict(color='#E74C3C', dash='dash')
301
+ ))
302
+ fig.update_layout(title="Monthly Emission Trends", height=400)
303
+ st.plotly_chart(fig, use_container_width=True)
304
+
305
+ elif page == "🧮 Emission Calculator":
306
+ st.markdown("## 🧮 CO₂ Emission Calculator")
307
+ st.markdown("Calculate CO₂ emissions using the formula: **CO₂ = Distance × Weight × EmissionFactor**")
308
+
309
+ col1, col2 = st.columns([2, 1])
310
+
311
+ with col1:
312
+ with st.form("emission_calculator"):
313
+ st.markdown("### Input Parameters")
314
+
315
+ col_a, col_b = st.columns(2)
316
+ with col_a:
317
+ distance = st.number_input("Distance (km)", min_value=0.1, value=500.0, step=10.0)
318
+ weight = st.number_input("Weight (tonnes)", min_value=0.01, value=2.0, step=0.1)
319
+
320
+ with col_b:
321
+ transport_mode = st.selectbox(
322
+ "Transport Mode",
323
+ options=[mode.value for mode in TransportMode],
324
+ format_func=lambda x: x.replace('_', ' ').title()
325
+ )
326
+
327
+ calculate_btn = st.form_submit_button("🧮 Calculate Emissions", type="primary")
328
+
329
+ if calculate_btn:
330
+ try:
331
+ # Convert string to TransportMode enum
332
+ mode_mapping = {
333
+ 'road_truck': TransportMode.ROAD_TRUCK,
334
+ 'road_van': TransportMode.ROAD_VAN,
335
+ 'rail': TransportMode.RAIL,
336
+ 'air_cargo': TransportMode.AIR_CARGO,
337
+ 'ship_container': TransportMode.SHIP_CONTAINER,
338
+ 'ship_bulk': TransportMode.SHIP_BULK
339
+ }
340
+
341
+ if transport_mode in mode_mapping:
342
+ mode = mode_mapping[transport_mode]
343
+ else:
344
+ mode = TransportMode(transport_mode)
345
+
346
+ result = calculator.calculate_emissions(distance, weight, mode)
347
+
348
+ st.success("✅ Calculation Complete!")
349
+
350
+ # Results display
351
+ col_r1, col_r2, col_r3 = st.columns(3)
352
+
353
+ with col_r1:
354
+ st.metric(
355
+ "CO₂ Emissions",
356
+ f"{result['co2_emissions_kg']:.2f} kg",
357
+ f"{result['co2_emissions_tonnes']:.3f} tonnes"
358
+ )
359
+
360
+ with col_r2:
361
+ carbon_tax = calculator.calculate_carbon_tax_cost(result['co2_emissions_kg'])
362
+ st.metric(
363
+ "Carbon Tax Cost",
364
+ f"${carbon_tax['carbon_tax_cost_usd']:.2f}",
365
+ "@ $50/tonne CO₂"
366
+ )
367
+
368
+ with col_r3:
369
+ st.metric(
370
+ "Emission Factor",
371
+ f"{result['emission_factor']:.3f}",
372
+ "kg CO₂/tonne-km"
373
+ )
374
+
375
+ # Comparison with other modes
376
+ st.markdown("### 🔄 Transport Mode Comparison")
377
+ comparison_df = calculator.compare_transport_modes(distance, weight)
378
+
379
+ fig = px.bar(
380
+ comparison_df,
381
+ x='transport_mode',
382
+ y='co2_emissions_kg',
383
+ color='co2_emissions_kg',
384
+ color_continuous_scale=['#2ECC71', '#E74C3C'],
385
+ title="CO₂ Emissions by Transport Mode"
386
+ )
387
+ fig.update_layout(height=400)
388
+ st.plotly_chart(fig, use_container_width=True)
389
+
390
+ st.dataframe(comparison_df, use_container_width=True)
391
+
392
+ except Exception as e:
393
+ st.error(f"❌ Calculation failed: {str(e)}")
394
+
395
+ with col2:
396
+ st.markdown("### 📋 Emission Factors")
397
+ factors_df = calculator.get_emission_factors_table()
398
+ st.dataframe(factors_df, use_container_width=True)
399
+
400
+ st.markdown("### 🌱 Green Tips")
401
+ st.info("""
402
+ **Reduce Emissions:**
403
+ - Choose rail over road when possible
404
+ - Use container ships for long distances
405
+ - Optimize load capacity
406
+ - Consider multimodal transport
407
+ """)
408
+
409
+ elif page == "🗺️ Route Optimizer":
410
+ st.markdown("## 🗺️ Green Route Optimizer")
411
+ st.markdown("Find the most eco-friendly routes for your shipments")
412
+
413
+ with st.form("route_optimizer"):
414
+ col1, col2 = st.columns(2)
415
+
416
+ with col1:
417
+ origin = st.text_input("Origin", value="New York, NY", placeholder="Enter origin city")
418
+ destination = st.text_input("Destination", value="Los Angeles, CA", placeholder="Enter destination city")
419
+
420
+ with col2:
421
+ weight = st.number_input("Shipment Weight (tonnes)", min_value=0.01, value=5.0, step=0.1)
422
+ max_time_penalty = st.slider("Max Time Penalty (%)", 0, 50, 10)
423
+
424
+ optimize_btn = st.form_submit_button("🗺️ Find Green Routes", type="primary")
425
+
426
+ if optimize_btn and origin and destination:
427
+ with st.spinner("🔍 Finding optimal routes..."):
428
+ try:
429
+ # Get route recommendations
430
+ recommendations = optimizer.recommend_green_routes(origin, destination, weight)
431
+
432
+ if 'success' in recommendations and recommendations['success']:
433
+ st.success("✅ Route optimization complete!")
434
+
435
+ route_data = recommendations['recommendations']
436
+
437
+ # Display recommendations
438
+ st.markdown("### 🌱 Green Route Recommendations")
439
+
440
+ for i, route in enumerate(route_data):
441
+ with st.expander(f"Option {i+1}: {route['transport_mode'].replace('_', ' ').title()}", expanded=(i==0)):
442
+ col_a, col_b, col_c, col_d = st.columns(4)
443
+
444
+ with col_a:
445
+ st.metric("CO₂ Emissions", f"{route['co2_emissions_kg']:.1f} kg")
446
+ with col_b:
447
+ st.metric("Travel Time", f"{route['estimated_travel_time_hours']:.1f} hrs")
448
+ with col_c:
449
+ st.metric("Carbon Tax", f"${route['carbon_tax_cost_usd']:.2f}")
450
+ with col_d:
451
+ if route['emission_reduction_percent'] > 0:
452
+ st.metric("Emission Reduction", f"{route['emission_reduction_percent']:.1f}%", "vs worst option")
453
+ else:
454
+ st.metric("Emission Impact", "Baseline", "")
455
+
456
+ if i == 0:
457
+ st.markdown('<span class="eco-badge">🌱 RECOMMENDED</span>', unsafe_allow_html=True)
458
+
459
+ # Visualization
460
+ if len(route_data) > 1:
461
+ st.markdown("### 📊 Route Comparison")
462
+
463
+ df_viz = pd.DataFrame(route_data)
464
+
465
+ fig = make_subplots(
466
+ rows=1, cols=2,
467
+ subplot_titles=('CO₂ Emissions (kg)', 'Travel Time (hours)'),
468
+ specs=[[{"secondary_y": False}, {"secondary_y": False}]]
469
+ )
470
+
471
+ fig.add_trace(
472
+ go.Bar(
473
+ x=df_viz['transport_mode'],
474
+ y=df_viz['co2_emissions_kg'],
475
+ name='CO₂ Emissions',
476
+ marker_color='#2ECC71'
477
+ ),
478
+ row=1, col=1
479
+ )
480
+
481
+ fig.add_trace(
482
+ go.Bar(
483
+ x=df_viz['transport_mode'],
484
+ y=df_viz['estimated_travel_time_hours'],
485
+ name='Travel Time',
486
+ marker_color='#3498DB'
487
+ ),
488
+ row=1, col=2
489
+ )
490
+
491
+ fig.update_layout(height=400, showlegend=False)
492
+ st.plotly_chart(fig, use_container_width=True)
493
+
494
+ else:
495
+ st.error(f"❌ Route optimization failed: {recommendations.get('error', 'Unknown error')}")
496
+
497
+ except Exception as e:
498
+ st.error(f"❌ Error: {str(e)}")
499
+
500
+ elif page == "📊 Scenario Analysis":
501
+ st.markdown("## 📊 Business Impact Simulation")
502
+ st.markdown("Analyze the potential impact of adopting green shipping practices")
503
+
504
+ with st.form("scenario_analysis"):
505
+ col1, col2 = st.columns(2)
506
+
507
+ with col1:
508
+ st.markdown("### 📦 Shipment Parameters")
509
+ total_shipments = st.number_input("Total Monthly Shipments", min_value=1, value=1000, step=50)
510
+ avg_distance = st.number_input("Average Distance (km)", min_value=1.0, value=800.0, step=50.0)
511
+ avg_weight = st.number_input("Average Weight (tonnes)", min_value=0.1, value=3.0, step=0.1)
512
+
513
+ with col2:
514
+ st.markdown("### ⚙️ Optimization Parameters")
515
+ optimization_percent = st.slider("% Shipments Using Green Routes", 0, 100, 50)
516
+ current_mode = st.selectbox("Current Transport Mode", [mode.value for mode in TransportMode], index=0)
517
+ carbon_tax_rate = st.number_input("Carbon Tax Rate ($/tonne CO₂)", min_value=0.0, value=50.0, step=5.0)
518
+
519
+ analyze_btn = st.form_submit_button("📊 Run Scenario Analysis", type="primary")
520
+
521
+ if analyze_btn:
522
+ with st.spinner("🔄 Running business impact simulation..."):
523
+ try:
524
+ # Current emissions - use same mapping as before
525
+ mode_mapping = {
526
+ 'road_truck': TransportMode.ROAD_TRUCK,
527
+ 'road_van': TransportMode.ROAD_VAN,
528
+ 'rail': TransportMode.RAIL,
529
+ 'air_cargo': TransportMode.AIR_CARGO,
530
+ 'ship_container': TransportMode.SHIP_CONTAINER,
531
+ 'ship_bulk': TransportMode.SHIP_BULK
532
+ }
533
+
534
+ if current_mode in mode_mapping:
535
+ current_mode_enum = mode_mapping[current_mode]
536
+ else:
537
+ current_mode_enum = TransportMode(current_mode)
538
+
539
+ current_emissions = calculator.calculate_emissions(avg_distance, avg_weight, current_mode_enum)
540
+
541
+ # Find best green alternative - calculate manually to avoid EmissionOptimizer import
542
+ available_modes = [TransportMode.ROAD_TRUCK, TransportMode.RAIL, TransportMode.SHIP_CONTAINER]
543
+
544
+ # Calculate emissions for each mode and find the greenest
545
+ mode_options = []
546
+ for mode in available_modes:
547
+ emissions = calculator.calculate_emissions(avg_distance, avg_weight, mode)
548
+ mode_options.append({
549
+ 'mode': mode,
550
+ 'co2_emissions_kg': emissions['co2_emissions_kg'],
551
+ 'emission_factor': emissions['emission_factor']
552
+ })
553
+
554
+ # Sort by emissions (lowest first) to find greenest option
555
+ mode_options.sort(key=lambda x: x['co2_emissions_kg'])
556
+ green_option = mode_options[0] if mode_options else None
557
+
558
+ if not green_option:
559
+ st.error("❌ No green alternatives available")
560
+ st.stop()
561
+
562
+ # Calculate scenario impact
563
+ optimized_shipments = int(total_shipments * optimization_percent / 100)
564
+ regular_shipments = total_shipments - optimized_shipments
565
+
566
+ current_total = current_emissions['co2_emissions_kg'] * total_shipments
567
+ optimized_total = (
568
+ green_option['co2_emissions_kg'] * optimized_shipments +
569
+ current_emissions['co2_emissions_kg'] * regular_shipments
570
+ )
571
+
572
+ savings_kg = current_total - optimized_total
573
+ savings_percent = (savings_kg / current_total) * 100
574
+ carbon_tax_savings = (savings_kg / 1000) * carbon_tax_rate
575
+
576
+ st.success("✅ Scenario analysis complete!")
577
+
578
+ # Results
579
+ col1, col2, col3, col4 = st.columns(4)
580
+
581
+ with col1:
582
+ st.metric("Current Emissions", f"{current_total/1000:.1f} tonnes/month")
583
+ with col2:
584
+ st.metric("Optimized Emissions", f"{optimized_total/1000:.1f} tonnes/month")
585
+ with col3:
586
+ st.metric("CO₂ Savings", f"{savings_kg/1000:.1f} tonnes/month", f"{savings_percent:.1f}% reduction")
587
+ with col4:
588
+ st.metric("Carbon Tax Savings", f"${carbon_tax_savings:.0f}/month", f"${carbon_tax_savings*12:.0f}/year")
589
+
590
+ # Visualization
591
+ st.markdown("### 📈 Impact Visualization")
592
+
593
+ scenario_data = pd.DataFrame({
594
+ 'Scenario': ['Current', 'Optimized'],
595
+ 'CO₂ Emissions (tonnes)': [current_total/1000, optimized_total/1000],
596
+ 'Carbon Tax Cost ($)': [
597
+ (current_total/1000) * carbon_tax_rate,
598
+ (optimized_total/1000) * carbon_tax_rate
599
+ ]
600
+ })
601
+
602
+ fig = make_subplots(
603
+ rows=1, cols=2,
604
+ subplot_titles=('CO₂ Emissions', 'Carbon Tax Cost'),
605
+ specs=[[{"secondary_y": False}, {"secondary_y": False}]]
606
+ )
607
+
608
+ fig.add_trace(
609
+ go.Bar(
610
+ x=scenario_data['Scenario'],
611
+ y=scenario_data['CO₂ Emissions (tonnes)'],
612
+ name='CO₂ Emissions',
613
+ marker_color=['#E74C3C', '#2ECC71']
614
+ ),
615
+ row=1, col=1
616
+ )
617
+
618
+ fig.add_trace(
619
+ go.Bar(
620
+ x=scenario_data['Scenario'],
621
+ y=scenario_data['Carbon Tax Cost ($)'],
622
+ name='Carbon Tax Cost',
623
+ marker_color=['#E74C3C', '#2ECC71']
624
+ ),
625
+ row=1, col=2
626
+ )
627
+
628
+ fig.update_layout(height=400, showlegend=False)
629
+ st.plotly_chart(fig, use_container_width=True)
630
+
631
+ # Business benefits
632
+ st.markdown("### 💼 Business Benefits")
633
+
634
+ benefits_col1, benefits_col2 = st.columns(2)
635
+
636
+ with benefits_col1:
637
+ st.markdown("""
638
+ **Environmental Impact:**
639
+ - ♻️ Reduced carbon footprint
640
+ - 🌱 Enhanced sustainability profile
641
+ - 📊 ESG score improvement
642
+ - 🏆 Industry leadership positioning
643
+ """)
644
+
645
+ with benefits_col2:
646
+ st.markdown(f"""
647
+ **Financial Benefits:**
648
+ - 💰 ${carbon_tax_savings*12:.0f} annual tax savings
649
+ - 📈 Potential green financing access
650
+ - 🎯 Regulatory compliance readiness
651
+ - 💡 Operational efficiency gains
652
+ """)
653
+
654
+ except Exception as e:
655
+ st.error(f"❌ Analysis failed: {str(e)}")
656
+ st.write(f"Debug info: {type(e).__name__}: {e}")
657
+ import traceback
658
+ st.code(traceback.format_exc())
659
+
660
+ elif page == "📈 Analytics":
661
+ st.markdown("## 📈 Advanced Analytics")
662
+
663
+ # Sample analytics data
664
+ st.markdown("### 🎯 Performance Metrics")
665
+
666
+ col1, col2, col3 = st.columns(3)
667
+
668
+ with col1:
669
+ st.markdown("""
670
+ <div class="metric-card">
671
+ <h4 style="color: #2ECC71; margin: 0;">Route Efficiency Score</h4>
672
+ <h2 style="margin: 0;">87/100</h2>
673
+ <p style="margin: 0; color: #7F8C8D;">Above industry average</p>
674
+ </div>
675
+ """, unsafe_allow_html=True)
676
+
677
+ with col2:
678
+ st.markdown("""
679
+ <div class="metric-card">
680
+ <h4 style="color: #2ECC71; margin: 0;">Green Route Adoption</h4>
681
+ <h2 style="margin: 0;">68%</h2>
682
+ <p style="margin: 0; color: #7F8C8D;">Target: 75%</p>
683
+ </div>
684
+ """, unsafe_allow_html=True)
685
+
686
+ with col3:
687
+ st.markdown("""
688
+ <div class="metric-card">
689
+ <h4 style="color: #2ECC71; margin: 0;">Emission Intensity</h4>
690
+ <h2 style="margin: 0;">0.045</h2>
691
+ <p style="margin: 0; color: #7F8C8D;">kg CO₂/tonne-km</p>
692
+ </div>
693
+ """, unsafe_allow_html=True)
694
+
695
+ # Regional analysis
696
+ st.markdown("### 🌍 Regional Emission Analysis")
697
+
698
+ regional_data = pd.DataFrame({
699
+ 'Region': ['North America', 'Europe', 'Asia Pacific', 'Latin America'],
700
+ 'Emissions (tonnes)': [45.2, 32.1, 28.7, 15.3],
701
+ 'Shipments': [450, 320, 380, 180],
702
+ 'Avg Distance (km)': [1200, 800, 950, 600]
703
+ })
704
+
705
+ fig = px.scatter(
706
+ regional_data,
707
+ x='Shipments',
708
+ y='Emissions (tonnes)',
709
+ size='Avg Distance (km)',
710
+ color='Region',
711
+ title="Regional Emission vs Shipment Volume"
712
+ )
713
+ fig.update_layout(height=500)
714
+ st.plotly_chart(fig, use_container_width=True)
715
+
716
+ st.dataframe(regional_data, use_container_width=True)
717
+
718
+
719
+ # Footer
720
+ st.markdown("---")
721
+ st.markdown("## 👨‍💻 Developer Details")
722
+ st.markdown("""
723
+ <div style="text-align: center; color: #2C3E50; padding: 2rem; background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1);">
724
+ <div style="margin-bottom: 1rem;">
725
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" style="width: 60px; height: 60px;">
726
+ <defs>
727
+ <linearGradient id="zkGradient" x1="0%" y1="0%" x2="100%" y2="100%">
728
+ <stop offset="0%" style="stop-color:#2ECC71;stop-opacity:1" />
729
+ <stop offset="100%" style="stop-color:#27AE60;stop-opacity:1" />
730
+ </linearGradient>
731
+ </defs>
732
+ <g transform="translate(50, 50)">
733
+ <path d="M10 20 L70 20 L70 35 L35 75 L70 75 L70 90 L10 90 L10 75 L45 35 L10 35 Z"
734
+ fill="url(#zkGradient)"
735
+ stroke="#1E8449"
736
+ stroke-width="1"/>
737
+ <path d="M80 20 L95 20 L95 50 L110 20 L130 20 L110 55 L130 90 L110 90 L95 65 L95 90 L80 90 Z"
738
+ fill="url(#zkGradient)"
739
+ stroke="#1E8449"
740
+ stroke-width="1"/>
741
+ </g>
742
+ </svg>
743
+ </div>
744
+ <p style="font-size: 1.2rem; color: #2C3E50; margin-bottom: 0.5rem;"><strong>GreenPath</strong> - AI-Powered CO₂ Emission Reduction Platform</p>
745
+ <p style="font-size: 1.1rem; color: #34495E; margin-bottom: 1rem;">Designed and Developed by <strong>Sayed Mohd Zayeem Khateeb</strong></p>
746
+ <div style="margin: 1rem 0;">
747
+ <a href="https://github.com/zayeemskhateeb-cloud" target="_blank" style="margin: 0 10px; text-decoration: none; color: #2ECC71; font-weight: bold; font-size: 1rem;">🌐 GitHub</a> |
748
+ <a href="https://www.linkedin.com/in/zayeemkhateeb" target="_blank" style="margin: 0 10px; text-decoration: none; color: #2ECC71; font-weight: bold; font-size: 1rem;">💼 LinkedIn</a> |
749
+ <a href="mailto:zayeem.s.khateeb@gmail.com" style="margin: 0 10px; text-decoration: none; color: #2ECC71; font-weight: bold; font-size: 1rem;">📧 Email</a>
750
+ </div>
751
+ <p style="font-size: 1rem; color: #7F8C8D; margin-top: 1rem;">
752
+ Specialized in AI/ML, Data Analytics, and Sustainable Technology Solutions
753
+ </p>
754
+ </div>
755
+ """, unsafe_allow_html=True)
data_import.py ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Data Import Script for AI-Powered Shipment Route Optimization System
4
+ Created by: Zayeem Khateeb
5
+
6
+ This script helps you import your real data into the system.
7
+ """
8
+
9
+ import pandas as pd
10
+ import sys
11
+ import os
12
+ from datetime import datetime
13
+
14
+ # Add src directory to path
15
+ sys.path.append(os.path.join(os.path.dirname(__file__), 'src'))
16
+
17
+ from config.database import DatabaseConfig
18
+
19
+ class DataImporter:
20
+ def __init__(self):
21
+ self.db = DatabaseConfig()
22
+
23
+ def import_from_csv(self, csv_file_path, table_name):
24
+ """Import data from CSV file to database table"""
25
+ try:
26
+ # Read CSV file
27
+ df = pd.read_csv(csv_file_path)
28
+ print(f"📁 Loaded {len(df)} records from {csv_file_path}")
29
+
30
+ # Convert to database format
31
+ if table_name == 'shipments':
32
+ df = self._prepare_shipments_data(df)
33
+ elif table_name == 'weather_data':
34
+ df = self._prepare_weather_data(df)
35
+ elif table_name == 'traffic_data':
36
+ df = self._prepare_traffic_data(df)
37
+
38
+ # Insert into database
39
+ self._insert_dataframe(df, table_name)
40
+ print(f"✅ Successfully imported {len(df)} records to {table_name} table")
41
+
42
+ except Exception as e:
43
+ print(f"❌ Error importing data: {e}")
44
+
45
+ def _prepare_shipments_data(self, df):
46
+ """Prepare shipments data for database insertion"""
47
+ # Ensure required columns exist
48
+ required_cols = ['tracking_number', 'origin_lat', 'origin_lng',
49
+ 'destination_lat', 'destination_lng', 'scheduled_delivery']
50
+
51
+ for col in required_cols:
52
+ if col not in df.columns:
53
+ raise ValueError(f"Missing required column: {col}")
54
+
55
+ # Convert datetime columns
56
+ if 'scheduled_delivery' in df.columns:
57
+ df['scheduled_delivery'] = pd.to_datetime(df['scheduled_delivery'])
58
+ if 'actual_delivery' in df.columns:
59
+ df['actual_delivery'] = pd.to_datetime(df['actual_delivery'])
60
+
61
+ # Add created_at if not present
62
+ if 'created_at' not in df.columns:
63
+ df['created_at'] = datetime.now()
64
+
65
+ # Fill missing values
66
+ df['status'] = df.get('status', 'pending')
67
+ df['delay_minutes'] = df.get('delay_minutes', 0)
68
+
69
+ return df
70
+
71
+ def _prepare_weather_data(self, df):
72
+ """Prepare weather data for database insertion"""
73
+ if 'timestamp' in df.columns:
74
+ df['timestamp'] = pd.to_datetime(df['timestamp'])
75
+ return df
76
+
77
+ def _prepare_traffic_data(self, df):
78
+ """Prepare traffic data for database insertion"""
79
+ if 'timestamp' in df.columns:
80
+ df['timestamp'] = pd.to_datetime(df['timestamp'])
81
+ return df
82
+
83
+ def _insert_dataframe(self, df, table_name):
84
+ """Insert DataFrame into database table"""
85
+ # This would use SQLAlchemy or pandas to_sql in production
86
+ # For now, we'll show the structure
87
+ print(f"📊 Data structure for {table_name}:")
88
+ print(df.head())
89
+ print(f"Columns: {list(df.columns)}")
90
+
91
+ def import_from_excel(self, excel_file_path, sheet_name='Sheet1', table_name='shipments'):
92
+ """Import data from Excel file"""
93
+ try:
94
+ df = pd.read_excel(excel_file_path, sheet_name=sheet_name)
95
+ print(f"📁 Loaded {len(df)} records from {excel_file_path}")
96
+
97
+ # Convert to CSV temporarily and use CSV import
98
+ temp_csv = f"temp_{table_name}.csv"
99
+ df.to_csv(temp_csv, index=False)
100
+ self.import_from_csv(temp_csv, table_name)
101
+
102
+ # Clean up temp file
103
+ os.remove(temp_csv)
104
+
105
+ except Exception as e:
106
+ print(f"❌ Error importing Excel data: {e}")
107
+
108
+ def validate_data_format(self, csv_file_path, expected_format='shipments'):
109
+ """Validate that your data has the correct format"""
110
+ try:
111
+ df = pd.read_csv(csv_file_path)
112
+
113
+ if expected_format == 'shipments':
114
+ required_cols = ['tracking_number', 'origin_lat', 'origin_lng',
115
+ 'destination_lat', 'destination_lng']
116
+ optional_cols = ['origin_address', 'destination_address',
117
+ 'scheduled_delivery', 'actual_delivery', 'status', 'delay_minutes']
118
+
119
+ elif expected_format == 'weather':
120
+ required_cols = ['location_lat', 'location_lng', 'timestamp', 'temperature']
121
+ optional_cols = ['humidity', 'wind_speed', 'precipitation', 'weather_condition']
122
+
123
+ elif expected_format == 'traffic':
124
+ required_cols = ['route_start_lat', 'route_start_lng', 'route_end_lat',
125
+ 'route_end_lng', 'timestamp']
126
+ optional_cols = ['travel_time_minutes', 'distance_km', 'traffic_level']
127
+
128
+ # Check required columns
129
+ missing_cols = [col for col in required_cols if col not in df.columns]
130
+ if missing_cols:
131
+ print(f"❌ Missing required columns: {missing_cols}")
132
+ return False
133
+
134
+ # Show available columns
135
+ print(f"✅ Data validation passed for {expected_format} format")
136
+ print(f"📊 Found columns: {list(df.columns)}")
137
+ print(f"📈 Data shape: {df.shape}")
138
+ print(f"🔍 Sample data:")
139
+ print(df.head(3))
140
+
141
+ return True
142
+
143
+ except Exception as e:
144
+ print(f"❌ Error validating data: {e}")
145
+ return False
146
+
147
+ def main():
148
+ """Main function to demonstrate data import"""
149
+ importer = DataImporter()
150
+
151
+ print("=" * 60)
152
+ print("🚛 DATA IMPORT TOOL - AI Shipment Route Optimization")
153
+ print("Created by: Zayeem Khateeb")
154
+ print("=" * 60)
155
+ print()
156
+
157
+ # Example usage
158
+ print("📋 USAGE EXAMPLES:")
159
+ print()
160
+ print("1. Validate your data format:")
161
+ print(" python data_import.py validate shipments.csv")
162
+ print()
163
+ print("2. Import shipments from CSV:")
164
+ print(" python data_import.py import shipments.csv shipments")
165
+ print()
166
+ print("3. Import weather data:")
167
+ print(" python data_import.py import weather_data.csv weather_data")
168
+ print()
169
+ print("4. Import from Excel:")
170
+ print(" python data_import.py excel shipments.xlsx Sheet1 shipments")
171
+ print()
172
+
173
+ # Handle command line arguments
174
+ if len(sys.argv) > 1:
175
+ command = sys.argv[1]
176
+
177
+ if command == 'validate' and len(sys.argv) >= 3:
178
+ file_path = sys.argv[2]
179
+ data_type = sys.argv[3] if len(sys.argv) > 3 else 'shipments'
180
+ importer.validate_data_format(file_path, data_type)
181
+
182
+ elif command == 'import' and len(sys.argv) >= 4:
183
+ file_path = sys.argv[2]
184
+ table_name = sys.argv[3]
185
+ importer.import_from_csv(file_path, table_name)
186
+
187
+ elif command == 'excel' and len(sys.argv) >= 5:
188
+ file_path = sys.argv[2]
189
+ sheet_name = sys.argv[3]
190
+ table_name = sys.argv[4]
191
+ importer.import_from_excel(file_path, sheet_name, table_name)
192
+
193
+ else:
194
+ print("💡 QUICK START:")
195
+ print("1. Prepare your data in CSV format (see DATA_INTEGRATION_GUIDE.md)")
196
+ print("2. Run: python data_import.py validate your_file.csv")
197
+ print("3. Run: python data_import.py import your_file.csv shipments")
198
+
199
+ if __name__ == "__main__":
200
+ main()
demo.py ADDED
@@ -0,0 +1,304 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ AI-Powered Shipment Route Optimization & Delay Prediction System
4
+ Simplified demonstration without external dependencies
5
+ """
6
+
7
+ import json
8
+ import random
9
+ import math
10
+ from datetime import datetime, timedelta
11
+
12
+ def generate_sample_shipments(n=100):
13
+ """Generate sample shipment data for demonstration"""
14
+ cities = [
15
+ ("New York", 40.7128, -74.0060),
16
+ ("Los Angeles", 34.0522, -118.2437),
17
+ ("Chicago", 41.8781, -87.6298),
18
+ ("Houston", 29.7604, -95.3698),
19
+ ("Phoenix", 33.4484, -112.0740),
20
+ ("Philadelphia", 39.9526, -75.1652),
21
+ ("San Antonio", 29.4241, -98.4936),
22
+ ("San Diego", 32.7157, -117.1611),
23
+ ("Dallas", 32.7767, -96.7970),
24
+ ("San Jose", 37.3382, -121.8863)
25
+ ]
26
+
27
+ shipments = []
28
+ for i in range(n):
29
+ origin = random.choice(cities)
30
+ destination = random.choice([c for c in cities if c != origin])
31
+
32
+ # Calculate distance
33
+ distance = calculate_distance(origin[1], origin[2], destination[1], destination[2])
34
+
35
+ # Generate realistic delivery time
36
+ base_time = distance / 60 # Assume 60 mph average
37
+ scheduled_delivery = datetime.now() + timedelta(hours=base_time + random.uniform(2, 24))
38
+
39
+ # Generate delay probability based on distance and random factors
40
+ delay_prob = min(0.9, 0.1 + (distance / 3000) + random.uniform(0, 0.3))
41
+ is_delayed = random.random() < delay_prob
42
+ delay_minutes = random.uniform(15, 120) if is_delayed else 0
43
+
44
+ shipments.append({
45
+ 'tracking_number': f'TRK{i+1:06d}',
46
+ 'origin': origin[0],
47
+ 'origin_lat': origin[1],
48
+ 'origin_lng': origin[2],
49
+ 'destination': destination[0],
50
+ 'destination_lat': destination[1],
51
+ 'destination_lng': destination[2],
52
+ 'distance_km': round(distance, 1),
53
+ 'scheduled_delivery': scheduled_delivery.strftime('%Y-%m-%d %H:%M'),
54
+ 'delay_probability': round(delay_prob, 3),
55
+ 'delay_minutes': round(delay_minutes, 1),
56
+ 'is_delayed': is_delayed,
57
+ 'status': 'in_transit' if random.random() < 0.7 else 'pending'
58
+ })
59
+
60
+ return shipments
61
+
62
+ def calculate_distance(lat1, lng1, lat2, lng2):
63
+ """Calculate distance using Haversine formula"""
64
+ R = 6371 # Earth's radius in km
65
+
66
+ lat1_rad = math.radians(lat1)
67
+ lng1_rad = math.radians(lng1)
68
+ lat2_rad = math.radians(lat2)
69
+ lng2_rad = math.radians(lng2)
70
+
71
+ dlat = lat2_rad - lat1_rad
72
+ dlng = lng2_rad - lng1_rad
73
+
74
+ a = (math.sin(dlat/2)**2 +
75
+ math.cos(lat1_rad) * math.cos(lat2_rad) * math.sin(dlng/2)**2)
76
+ c = 2 * math.asin(math.sqrt(a))
77
+
78
+ return R * c
79
+
80
+ def simulate_ml_model(shipments):
81
+ """Simulate machine learning model predictions"""
82
+ high_risk = []
83
+ medium_risk = []
84
+ low_risk = []
85
+
86
+ for shipment in shipments:
87
+ prob = shipment['delay_probability']
88
+ if prob >= 0.7:
89
+ high_risk.append(shipment)
90
+ elif prob >= 0.4:
91
+ medium_risk.append(shipment)
92
+ else:
93
+ low_risk.append(shipment)
94
+
95
+ # Simulate model accuracy
96
+ correct_predictions = 0
97
+ total_predictions = len(shipments)
98
+
99
+ for shipment in shipments:
100
+ predicted_delay = shipment['delay_probability'] > 0.5
101
+ actual_delay = shipment['is_delayed']
102
+ if predicted_delay == actual_delay:
103
+ correct_predictions += 1
104
+
105
+ accuracy = correct_predictions / total_predictions
106
+
107
+ return {
108
+ 'accuracy': accuracy,
109
+ 'high_risk_count': len(high_risk),
110
+ 'medium_risk_count': len(medium_risk),
111
+ 'low_risk_count': len(low_risk),
112
+ 'high_risk_shipments': high_risk[:5] # Show top 5
113
+ }
114
+
115
+ def simulate_route_optimization():
116
+ """Simulate route optimization algorithms"""
117
+ routes = [
118
+ {
119
+ 'route_id': 1,
120
+ 'path': ['New York', 'Philadelphia', 'Chicago', 'Denver', 'Los Angeles'],
121
+ 'total_distance': 2789.5,
122
+ 'estimated_time': 46.5,
123
+ 'algorithm': 'Dijkstra',
124
+ 'efficiency_score': 87.3
125
+ },
126
+ {
127
+ 'route_id': 2,
128
+ 'path': ['New York', 'Pittsburgh', 'Chicago', 'Kansas City', 'Los Angeles'],
129
+ 'total_distance': 2834.2,
130
+ 'estimated_time': 47.2,
131
+ 'algorithm': 'A*',
132
+ 'efficiency_score': 85.1
133
+ },
134
+ {
135
+ 'route_id': 3,
136
+ 'path': ['New York', 'Cleveland', 'Chicago', 'Omaha', 'Denver', 'Los Angeles'],
137
+ 'total_distance': 2901.8,
138
+ 'estimated_time': 48.4,
139
+ 'algorithm': 'A* (Weather-Adjusted)',
140
+ 'efficiency_score': 83.7
141
+ }
142
+ ]
143
+
144
+ return routes
145
+
146
+ def generate_alerts(shipments):
147
+ """Generate monitoring alerts"""
148
+ alerts = []
149
+
150
+ for shipment in shipments:
151
+ if shipment['delay_probability'] >= 0.8:
152
+ alert = {
153
+ 'type': 'HIGH_DELAY_RISK',
154
+ 'severity': 'HIGH',
155
+ 'tracking_number': shipment['tracking_number'],
156
+ }
157
+ alert['message'] = f"High delay risk ({shipment['delay_probability']:.1%}) for {shipment['origin']} -> {shipment['destination']}"
158
+ alert['recommendations'] = [
159
+ 'Consider alternative routing',
160
+ 'Notify customer proactively',
161
+ 'Monitor weather conditions'
162
+ ]
163
+ alerts.append(alert)
164
+
165
+ # Simulate weather alerts
166
+ if random.random() < 0.1: # 10% chance of weather alert
167
+ alerts.append({
168
+ 'type': 'WEATHER_WARNING',
169
+ 'severity': 'MEDIUM',
170
+ 'tracking_number': shipment['tracking_number'],
171
+ 'message': f"Severe weather detected on route to {shipment['destination']}",
172
+ 'recommendations': [
173
+ 'Monitor weather updates',
174
+ 'Allow extra travel time'
175
+ ]
176
+ })
177
+
178
+ return alerts
179
+
180
+ def main():
181
+ """Main demonstration function"""
182
+ print("=" * 70)
183
+ print("AI-POWERED SHIPMENT ROUTE OPTIMIZATION & DELAY PREDICTION")
184
+ print("=" * 70)
185
+ print()
186
+
187
+ # Step 1: Generate sample data
188
+ print("STEP 1: Data Generation & Processing")
189
+ print("-" * 50)
190
+ shipments = generate_sample_shipments(500)
191
+ print(f"Generated {len(shipments)} sample shipments")
192
+
193
+ # Calculate summary statistics
194
+ total_distance = sum(s['distance_km'] for s in shipments)
195
+ avg_distance = total_distance / len(shipments)
196
+ delayed_shipments = sum(1 for s in shipments if s['is_delayed'])
197
+ on_time_rate = (len(shipments) - delayed_shipments) / len(shipments) * 100
198
+
199
+ print(f" • Total distance: {total_distance:,.0f} km")
200
+ print(f" • Average distance: {avg_distance:.1f} km")
201
+ print(f" • On-time rate: {on_time_rate:.1f}%")
202
+
203
+ # Step 2: Machine Learning Predictions
204
+ print(f"\nSTEP 2: Machine Learning Delay Prediction")
205
+ print("-" * 50)
206
+ ml_results = simulate_ml_model(shipments)
207
+ print(f"Model trained with {ml_results['accuracy']:.1%} accuracy")
208
+ print(f" • High risk shipments: {ml_results['high_risk_count']}")
209
+ print(f" • Medium risk shipments: {ml_results['medium_risk_count']}")
210
+ print(f" • Low risk shipments: {ml_results['low_risk_count']}")
211
+
212
+ print(f"\nTop High-Risk Shipments:")
213
+ for shipment in ml_results['high_risk_shipments']:
214
+ print(f" • {shipment['tracking_number']}: {shipment['origin']} -> {shipment['destination']} "
215
+ f"({shipment['delay_probability']:.1%} risk)")
216
+
217
+ # Step 3: Route Optimization
218
+ print(f"\nSTEP 3: Route Optimization")
219
+ print("-" * 50)
220
+ routes = simulate_route_optimization()
221
+ print(f"Found {len(routes)} optimized routes for NY -> LA:")
222
+
223
+ for route in routes:
224
+ print(f" Route {route['route_id']} ({route['algorithm']}):")
225
+ print(f" Path: {' -> '.join(route['path'])}")
226
+ print(f" Distance: {route['total_distance']:.1f} km")
227
+ print(f" Time: {route['estimated_time']:.1f} hours")
228
+ print(f" Efficiency: {route['efficiency_score']:.1f}%")
229
+ print()
230
+
231
+ # Step 4: Real-time Monitoring
232
+ print(f"STEP 4: Real-time Monitoring & Alerts")
233
+ print("-" * 50)
234
+ alerts = generate_alerts(shipments)
235
+ print(f"Generated {len(alerts)} active alerts")
236
+
237
+ high_severity_alerts = [a for a in alerts if a['severity'] == 'HIGH']
238
+ medium_severity_alerts = [a for a in alerts if a['severity'] == 'MEDIUM']
239
+
240
+ print(f" • High severity: {len(high_severity_alerts)}")
241
+ print(f" • Medium severity: {len(medium_severity_alerts)}")
242
+
243
+ if high_severity_alerts:
244
+ print(f"\nCritical Alerts:")
245
+ for alert in high_severity_alerts[:3]: # Show top 3
246
+ print(f" • {alert['tracking_number']}: {alert['message']}")
247
+
248
+ # Step 5: Business Impact Analysis
249
+ print(f"\nSTEP 5: Business Impact Analysis")
250
+ print("-" * 50)
251
+
252
+ # Calculate potential improvements
253
+ baseline_delays = sum(s['delay_minutes'] for s in shipments if s['is_delayed'])
254
+ potential_reduction = baseline_delays * 0.15 # 15% improvement
255
+
256
+ print(f"Projected Business Benefits:")
257
+ print(f" • Current total delay time: {baseline_delays:,.0f} minutes")
258
+ print(f" • Potential reduction: {potential_reduction:,.0f} minutes (15%)")
259
+ print(f" • Improved customer satisfaction through proactive alerts")
260
+ print(f" • Real-time visibility into {len(shipments)} shipments")
261
+ print(f" • Data-driven route optimization saving fuel costs")
262
+
263
+ # Step 6: System Summary
264
+ print(f"\nSTEP 6: System Performance Summary")
265
+ print("-" * 50)
266
+ print(f"Key Achievements:")
267
+ print(f" • ML Model Accuracy: {ml_results['accuracy']:.1%}")
268
+ print(f" • Route Optimization: {len(routes)} alternative paths found")
269
+ print(f" • Active Monitoring: {len(alerts)} alerts generated")
270
+ print(f" • Risk Assessment: {ml_results['high_risk_count']} high-risk shipments identified")
271
+
272
+ print(f"\nSystem Status: OPERATIONAL")
273
+ print(f" Dashboard: Ready for deployment")
274
+ print(f" API Endpoints: Configured")
275
+ print(f" Monitoring: Active")
276
+ print(f" Alerts: Enabled")
277
+
278
+ # Save results to JSON for dashboard
279
+ results = {
280
+ 'timestamp': datetime.now().isoformat(),
281
+ 'total_shipments': len(shipments),
282
+ 'model_accuracy': ml_results['accuracy'],
283
+ 'on_time_rate': on_time_rate / 100,
284
+ 'total_alerts': len(alerts),
285
+ 'high_risk_shipments': ml_results['high_risk_count'],
286
+ 'routes_optimized': len(routes),
287
+ 'sample_shipments': shipments[:10], # First 10 for display
288
+ 'sample_routes': routes,
289
+ 'sample_alerts': alerts[:5] # First 5 alerts
290
+ }
291
+
292
+ with open('demo_results.json', 'w') as f:
293
+ json.dump(results, f, indent=2)
294
+
295
+ print(f"\nResults saved to: demo_results.json")
296
+ print(f"To start the web dashboard: python src/dashboard/app.py")
297
+
298
+ return results
299
+
300
+ if __name__ == "__main__":
301
+ results = main()
302
+ print(f"\n{'='*70}")
303
+ print(f"Demo completed successfully! System ready for production deployment.")
304
+ print(f"{'='*70}")
demo_results.json ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "timestamp": "2025-09-10T23:56:33.497674",
3
+ "total_shipments": 500,
4
+ "model_accuracy": 0.822,
5
+ "on_time_rate": 0.254,
6
+ "total_alerts": 364,
7
+ "high_risk_shipments": 341,
8
+ "routes_optimized": 3,
9
+ "sample_shipments": [
10
+ {
11
+ "tracking_number": "TRK000001",
12
+ "origin": "Houston",
13
+ "origin_lat": 29.7604,
14
+ "origin_lng": -95.3698,
15
+ "destination": "Los Angeles",
16
+ "destination_lat": 34.0522,
17
+ "destination_lng": -118.2437,
18
+ "distance_km": 2206.3,
19
+ "scheduled_delivery": "2025-09-12 16:03",
20
+ "delay_probability": 0.9,
21
+ "delay_minutes": 98.9,
22
+ "is_delayed": true,
23
+ "status": "in_transit"
24
+ },
25
+ {
26
+ "tracking_number": "TRK000002",
27
+ "origin": "Dallas",
28
+ "origin_lat": 32.7767,
29
+ "origin_lng": -96.797,
30
+ "destination": "San Diego",
31
+ "destination_lat": 32.7157,
32
+ "destination_lng": -117.1611,
33
+ "distance_km": 1901.6,
34
+ "scheduled_delivery": "2025-09-12 12:13",
35
+ "delay_probability": 0.9,
36
+ "delay_minutes": 96.8,
37
+ "is_delayed": true,
38
+ "status": "in_transit"
39
+ },
40
+ {
41
+ "tracking_number": "TRK000003",
42
+ "origin": "Dallas",
43
+ "origin_lat": 32.7767,
44
+ "origin_lng": -96.797,
45
+ "destination": "Chicago",
46
+ "destination_lat": 41.8781,
47
+ "destination_lng": -87.6298,
48
+ "distance_km": 1295.0,
49
+ "scheduled_delivery": "2025-09-12 06:59",
50
+ "delay_probability": 0.825,
51
+ "delay_minutes": 15.6,
52
+ "is_delayed": true,
53
+ "status": "pending"
54
+ },
55
+ {
56
+ "tracking_number": "TRK000004",
57
+ "origin": "San Jose",
58
+ "origin_lat": 37.3382,
59
+ "origin_lng": -121.8863,
60
+ "destination": "Philadelphia",
61
+ "destination_lat": 39.9526,
62
+ "destination_lng": -75.1652,
63
+ "distance_km": 4021.5,
64
+ "scheduled_delivery": "2025-09-14 16:06",
65
+ "delay_probability": 0.9,
66
+ "delay_minutes": 0,
67
+ "is_delayed": false,
68
+ "status": "pending"
69
+ },
70
+ {
71
+ "tracking_number": "TRK000005",
72
+ "origin": "Chicago",
73
+ "origin_lat": 41.8781,
74
+ "origin_lng": -87.6298,
75
+ "destination": "New York",
76
+ "destination_lat": 40.7128,
77
+ "destination_lng": -74.006,
78
+ "distance_km": 1144.3,
79
+ "scheduled_delivery": "2025-09-12 01:45",
80
+ "delay_probability": 0.704,
81
+ "delay_minutes": 57.2,
82
+ "is_delayed": true,
83
+ "status": "pending"
84
+ },
85
+ {
86
+ "tracking_number": "TRK000006",
87
+ "origin": "Philadelphia",
88
+ "origin_lat": 39.9526,
89
+ "origin_lng": -75.1652,
90
+ "destination": "Phoenix",
91
+ "destination_lat": 33.4484,
92
+ "destination_lng": -112.074,
93
+ "distance_km": 3344.1,
94
+ "scheduled_delivery": "2025-09-13 12:37",
95
+ "delay_probability": 0.9,
96
+ "delay_minutes": 54.4,
97
+ "is_delayed": true,
98
+ "status": "in_transit"
99
+ },
100
+ {
101
+ "tracking_number": "TRK000007",
102
+ "origin": "Houston",
103
+ "origin_lat": 29.7604,
104
+ "origin_lng": -95.3698,
105
+ "destination": "San Antonio",
106
+ "destination_lat": 29.4241,
107
+ "destination_lng": -98.4936,
108
+ "distance_km": 304.3,
109
+ "scheduled_delivery": "2025-09-11 16:23",
110
+ "delay_probability": 0.464,
111
+ "delay_minutes": 0,
112
+ "is_delayed": false,
113
+ "status": "in_transit"
114
+ },
115
+ {
116
+ "tracking_number": "TRK000008",
117
+ "origin": "Dallas",
118
+ "origin_lat": 32.7767,
119
+ "origin_lng": -96.797,
120
+ "destination": "San Antonio",
121
+ "destination_lat": 29.4241,
122
+ "destination_lng": -98.4936,
123
+ "distance_km": 406.3,
124
+ "scheduled_delivery": "2025-09-11 18:45",
125
+ "delay_probability": 0.337,
126
+ "delay_minutes": 0,
127
+ "is_delayed": false,
128
+ "status": "pending"
129
+ },
130
+ {
131
+ "tracking_number": "TRK000009",
132
+ "origin": "Los Angeles",
133
+ "origin_lat": 34.0522,
134
+ "origin_lng": -118.2437,
135
+ "destination": "Phoenix",
136
+ "destination_lat": 33.4484,
137
+ "destination_lng": -112.074,
138
+ "distance_km": 574.3,
139
+ "scheduled_delivery": "2025-09-12 04:35",
140
+ "delay_probability": 0.333,
141
+ "delay_minutes": 116.4,
142
+ "is_delayed": true,
143
+ "status": "in_transit"
144
+ },
145
+ {
146
+ "tracking_number": "TRK000010",
147
+ "origin": "San Antonio",
148
+ "origin_lat": 29.4241,
149
+ "origin_lng": -98.4936,
150
+ "destination": "Houston",
151
+ "destination_lat": 29.7604,
152
+ "destination_lng": -95.3698,
153
+ "distance_km": 304.3,
154
+ "scheduled_delivery": "2025-09-11 18:42",
155
+ "delay_probability": 0.292,
156
+ "delay_minutes": 0,
157
+ "is_delayed": false,
158
+ "status": "in_transit"
159
+ }
160
+ ],
161
+ "sample_routes": [
162
+ {
163
+ "route_id": 1,
164
+ "path": [
165
+ "New York",
166
+ "Philadelphia",
167
+ "Chicago",
168
+ "Denver",
169
+ "Los Angeles"
170
+ ],
171
+ "total_distance": 2789.5,
172
+ "estimated_time": 46.5,
173
+ "algorithm": "Dijkstra",
174
+ "efficiency_score": 87.3
175
+ },
176
+ {
177
+ "route_id": 2,
178
+ "path": [
179
+ "New York",
180
+ "Pittsburgh",
181
+ "Chicago",
182
+ "Kansas City",
183
+ "Los Angeles"
184
+ ],
185
+ "total_distance": 2834.2,
186
+ "estimated_time": 47.2,
187
+ "algorithm": "A*",
188
+ "efficiency_score": 85.1
189
+ },
190
+ {
191
+ "route_id": 3,
192
+ "path": [
193
+ "New York",
194
+ "Cleveland",
195
+ "Chicago",
196
+ "Omaha",
197
+ "Denver",
198
+ "Los Angeles"
199
+ ],
200
+ "total_distance": 2901.8,
201
+ "estimated_time": 48.4,
202
+ "algorithm": "A* (Weather-Adjusted)",
203
+ "efficiency_score": 83.7
204
+ }
205
+ ],
206
+ "sample_alerts": [
207
+ {
208
+ "type": "HIGH_DELAY_RISK",
209
+ "severity": "HIGH",
210
+ "tracking_number": "TRK000001",
211
+ "message": "High delay risk (90.0%) for Houston -> Los Angeles",
212
+ "recommendations": [
213
+ "Consider alternative routing",
214
+ "Notify customer proactively",
215
+ "Monitor weather conditions"
216
+ ]
217
+ },
218
+ {
219
+ "type": "HIGH_DELAY_RISK",
220
+ "severity": "HIGH",
221
+ "tracking_number": "TRK000002",
222
+ "message": "High delay risk (90.0%) for Dallas -> San Diego",
223
+ "recommendations": [
224
+ "Consider alternative routing",
225
+ "Notify customer proactively",
226
+ "Monitor weather conditions"
227
+ ]
228
+ },
229
+ {
230
+ "type": "HIGH_DELAY_RISK",
231
+ "severity": "HIGH",
232
+ "tracking_number": "TRK000003",
233
+ "message": "High delay risk (82.5%) for Dallas -> Chicago",
234
+ "recommendations": [
235
+ "Consider alternative routing",
236
+ "Notify customer proactively",
237
+ "Monitor weather conditions"
238
+ ]
239
+ },
240
+ {
241
+ "type": "HIGH_DELAY_RISK",
242
+ "severity": "HIGH",
243
+ "tracking_number": "TRK000004",
244
+ "message": "High delay risk (90.0%) for San Jose -> Philadelphia",
245
+ "recommendations": [
246
+ "Consider alternative routing",
247
+ "Notify customer proactively",
248
+ "Monitor weather conditions"
249
+ ]
250
+ },
251
+ {
252
+ "type": "HIGH_DELAY_RISK",
253
+ "severity": "HIGH",
254
+ "tracking_number": "TRK000006",
255
+ "message": "High delay risk (90.0%) for Philadelphia -> Phoenix",
256
+ "recommendations": [
257
+ "Consider alternative routing",
258
+ "Notify customer proactively",
259
+ "Monitor weather conditions"
260
+ ]
261
+ }
262
+ ]
263
+ }
deploy.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Production Deployment Script for AI-Powered Shipment Route Optimization
4
+ Created by: Zayeem Khateeb
5
+ """
6
+
7
+ import os
8
+ import sys
9
+ from src.dashboard.app import app
10
+
11
+ def create_production_app():
12
+ """Configure app for production deployment"""
13
+ # Production optimizations
14
+ app.config.update(
15
+ DEBUG=False,
16
+ TESTING=False,
17
+ SECRET_KEY=os.environ.get('SECRET_KEY', 'production-secret-key-change-this'),
18
+ )
19
+
20
+ return app
21
+
22
+ if __name__ == '__main__':
23
+ # Get port from environment variable (for cloud deployment)
24
+ port = int(os.environ.get('PORT', 8050))
25
+ host = os.environ.get('HOST', '0.0.0.0')
26
+
27
+ print(f"🚀 Starting AI-Powered Shipment Route Optimization System")
28
+ print(f" Created by: Zayeem Khateeb")
29
+ print(f" Running on: http://{host}:{port}")
30
+
31
+ production_app = create_production_app()
32
+ production_app.run(host=host, port=port, debug=False)
docker-compose.yml ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ version: '3.8'
2
+
3
+ services:
4
+ # GreenPath Streamlit Frontend
5
+ streamlit:
6
+ build:
7
+ context: .
8
+ dockerfile: Dockerfile.streamlit
9
+ ports:
10
+ - "8501:8501"
11
+ environment:
12
+ - DATABASE_URL=sqlite:///app/greenpath.db
13
+ - OPENROUTESERVICE_API_KEY=${OPENROUTESERVICE_API_KEY}
14
+ - FASTAPI_URL=http://fastapi:8000
15
+ volumes:
16
+ - ./data:/app/data
17
+ - ./greenpath.db:/app/greenpath.db
18
+ depends_on:
19
+ - fastapi
20
+ restart: unless-stopped
21
+
22
+ # GreenPath FastAPI Backend
23
+ fastapi:
24
+ build:
25
+ context: .
26
+ dockerfile: Dockerfile.fastapi
27
+ ports:
28
+ - "8000:8000"
29
+ environment:
30
+ - DATABASE_URL=sqlite:///app/greenpath.db
31
+ - OPENROUTESERVICE_API_KEY=${OPENROUTESERVICE_API_KEY}
32
+ volumes:
33
+ - ./data:/app/data
34
+ - ./greenpath.db:/app/greenpath.db
35
+ restart: unless-stopped
36
+
37
+ # PostgreSQL Database (Optional - for production)
38
+ postgres:
39
+ image: postgres:13
40
+ environment:
41
+ - POSTGRES_DB=greenpath
42
+ - POSTGRES_USER=greenpath_user
43
+ - POSTGRES_PASSWORD=secure_greenpath_password
44
+ volumes:
45
+ - postgres_data:/var/lib/postgresql/data
46
+ ports:
47
+ - "5432:5432"
48
+ restart: unless-stopped
49
+ # Redis for caching (optional)
50
+ redis:
51
+ image: redis:7-alpine
52
+ ports:
53
+ - "6379:6379"
54
+ restart: unless-stopped
55
+ networks:
56
+ - shipment_network
57
+
58
+ volumes:
59
+ postgres_data:
60
+
61
+ networks:
62
+ shipment_network:
63
+ driver: bridge
game.js ADDED
@@ -0,0 +1,385 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ document.addEventListener('DOMContentLoaded', () => {
2
+ const gridContainer = document.querySelector('.grid-container');
3
+ const scoreElement = document.getElementById('score');
4
+ const bestScoreElement = document.getElementById('best-score');
5
+ const newGameButton = document.getElementById('new-game');
6
+ const tryAgainButton = document.getElementById('try-again');
7
+ const keepGoingButton = document.getElementById('keep-going');
8
+ const gameOverScreen = document.querySelector('.game-over');
9
+ const gameWonScreen = document.querySelector('.game-won');
10
+
11
+ let grid = [];
12
+ let score = 0;
13
+ let bestScore = localStorage.getItem('bestScore') || 0;
14
+ let gameOver = false;
15
+ let gameWon = false;
16
+
17
+ // Initialize the game
18
+ function initGame() {
19
+ // Clear the grid
20
+ grid = Array(4).fill().map(() => Array(4).fill(0));
21
+ score = 0;
22
+ gameOver = false;
23
+ gameWon = false;
24
+
25
+ // Clear the grid container
26
+ gridContainer.innerHTML = '';
27
+
28
+ // Create the grid cells
29
+ for (let i = 0; i < 4; i++) {
30
+ for (let j = 0; j < 4; j++) {
31
+ const cell = document.createElement('div');
32
+ cell.className = 'grid-cell';
33
+ gridContainer.appendChild(cell);
34
+ }
35
+ }
36
+
37
+ // Add initial tiles
38
+ addRandomTile();
39
+ addRandomTile();
40
+
41
+ // Update the score display
42
+ updateScore();
43
+
44
+ // Hide game over/win screens
45
+ gameOverScreen.style.display = 'none';
46
+ gameWonScreen.style.display = 'none';
47
+ }
48
+
49
+ // Add a random tile (2 or 4) to an empty cell
50
+ function addRandomTile() {
51
+ const emptyCells = [];
52
+
53
+ // Find all empty cells
54
+ for (let i = 0; i < 4; i++) {
55
+ for (let j = 0; j < 4; j++) {
56
+ if (grid[i][j] === 0) {
57
+ emptyCells.push({x: i, y: j});
58
+ }
59
+ }
60
+ }
61
+
62
+ if (emptyCells.length > 0) {
63
+ // Choose a random empty cell
64
+ const {x, y} = emptyCells[Math.floor(Math.random() * emptyCells.length)];
65
+ // 90% chance for 2, 10% chance for 4
66
+ grid[x][y] = Math.random() < 0.9 ? 2 : 4;
67
+
68
+ // Create and animate the new tile
69
+ createTile(x, y, grid[x][y], true);
70
+ }
71
+ }
72
+
73
+ // Create a tile element at the specified position
74
+ function createTile(x, y, value, isNew = false) {
75
+ const tile = document.createElement('div');
76
+ tile.className = `tile tile-${value} ${isNew ? 'new-tile' : ''}`;
77
+ tile.textContent = value;
78
+
79
+ // Position the tile
80
+ const posX = y * 25 + (y * 15);
81
+ const posY = x * 25 + (x * 15);
82
+
83
+ tile.style.left = `${posX}%`;
84
+ tile.style.top = `${posY}%`;
85
+
86
+ // Add data attributes for tracking position
87
+ tile.dataset.x = x;
88
+ tile.dataset.y = y;
89
+ tile.dataset.value = value;
90
+
91
+ gridContainer.appendChild(tile);
92
+ return tile;
93
+ }
94
+
95
+ // Update the score display
96
+ function updateScore() {
97
+ scoreElement.textContent = score;
98
+ bestScore = Math.max(score, bestScore);
99
+ bestScoreElement.textContent = bestScore;
100
+ localStorage.setItem('bestScore', bestScore);
101
+ }
102
+
103
+ // Check if there are any moves left
104
+ function hasMovesLeft() {
105
+ // Check for any empty cells
106
+ for (let i = 0; i < 4; i++) {
107
+ for (let j = 0; j < 4; j++) {
108
+ if (grid[i][j] === 0) return true;
109
+
110
+ // Check adjacent cells for possible merges
111
+ if (i < 3 && grid[i][j] === grid[i + 1][j]) return true;
112
+ if (j < 3 && grid[i][j] === grid[i][j + 1]) return true;
113
+ }
114
+ }
115
+ return false;
116
+ }
117
+
118
+ // Move tiles in the specified direction
119
+ function moveTiles(direction) {
120
+ if (gameOver || gameWon) return false;
121
+
122
+ let moved = false;
123
+ const oldGrid = JSON.parse(JSON.stringify(grid));
124
+
125
+ // Remove all tiles from the DOM (we'll recreate them after moving)
126
+ const tiles = document.querySelectorAll('.tile');
127
+ const tilesData = Array.from(tiles).map(tile => ({
128
+ x: parseInt(tile.dataset.x),
129
+ y: parseInt(tile.dataset.y),
130
+ value: parseInt(tile.dataset.value),
131
+ element: tile
132
+ }));
133
+
134
+ tiles.forEach(tile => tile.remove());
135
+
136
+ // Process the move based on direction
137
+ switch (direction) {
138
+ case 'up':
139
+ moved = moveUp();
140
+ break;
141
+ case 'right':
142
+ moved = moveRight();
143
+ break;
144
+ case 'down':
145
+ moved = moveDown();
146
+ break;
147
+ case 'left':
148
+ moved = moveLeft();
149
+ break;
150
+ }
151
+
152
+ // If the grid changed, add a new random tile
153
+ if (moved) {
154
+ addRandomTile();
155
+ updateScore();
156
+
157
+ // Check for win condition
158
+ if (!gameWon && checkWin()) {
159
+ gameWon = true;
160
+ gameWonScreen.style.display = 'flex';
161
+ }
162
+ // Check for game over
163
+ else if (!hasMovesLeft()) {
164
+ gameOver = true;
165
+ gameOverScreen.style.display = 'flex';
166
+ }
167
+ }
168
+
169
+ // Recreate tiles with new positions
170
+ for (let i = 0; i < 4; i++) {
171
+ for (let j = 0; j < 4; j++) {
172
+ if (grid[i][j] !== 0) {
173
+ createTile(i, j, grid[i][j]);
174
+ }
175
+ }
176
+ }
177
+
178
+ return moved;
179
+ }
180
+
181
+ // Move tiles up
182
+ function moveUp() {
183
+ let moved = false;
184
+
185
+ for (let j = 0; j < 4; j++) {
186
+ // Move all tiles up as much as possible
187
+ for (let i = 1; i < 4; i++) {
188
+ if (grid[i][j] !== 0) {
189
+ let row = i;
190
+ while (row > 0 && grid[row - 1][j] === 0) {
191
+ grid[row - 1][j] = grid[row][j];
192
+ grid[row][j] = 0;
193
+ row--;
194
+ moved = true;
195
+ }
196
+
197
+ // Check for merge with the tile above
198
+ if (row > 0 && grid[row - 1][j] === grid[row][j] &&
199
+ !document.querySelector(`.tile[data-x="${row-1}"][data-y="${j}"].merged`)) {
200
+ grid[row - 1][j] *= 2;
201
+ score += grid[row - 1][j];
202
+ grid[row][j] = 0;
203
+ moved = true;
204
+ }
205
+ }
206
+ }
207
+ }
208
+
209
+ return moved;
210
+ }
211
+
212
+ // Move tiles right
213
+ function moveRight() {
214
+ let moved = false;
215
+
216
+ for (let i = 0; i < 4; i++) {
217
+ for (let j = 2; j >= 0; j--) {
218
+ if (grid[i][j] !== 0) {
219
+ let col = j;
220
+ while (col < 3 && grid[i][col + 1] === 0) {
221
+ grid[i][col + 1] = grid[i][col];
222
+ grid[i][col] = 0;
223
+ col++;
224
+ moved = true;
225
+ }
226
+
227
+ // Check for merge with the tile to the right
228
+ if (col < 3 && grid[i][col + 1] === grid[i][col] &&
229
+ !document.querySelector(`.tile[data-x="${i}"][data-y="${col+1}"].merged`)) {
230
+ grid[i][col + 1] *= 2;
231
+ score += grid[i][col + 1];
232
+ grid[i][col] = 0;
233
+ moved = true;
234
+ }
235
+ }
236
+ }
237
+ }
238
+
239
+ return moved;
240
+ }
241
+
242
+ // Move tiles down
243
+ function moveDown() {
244
+ let moved = false;
245
+
246
+ for (let j = 0; j < 4; j++) {
247
+ for (let i = 2; i >= 0; i--) {
248
+ if (grid[i][j] !== 0) {
249
+ let row = i;
250
+ while (row < 3 && grid[row + 1][j] === 0) {
251
+ grid[row + 1][j] = grid[row][j];
252
+ grid[row][j] = 0;
253
+ row++;
254
+ moved = true;
255
+ }
256
+
257
+ // Check for merge with the tile below
258
+ if (row < 3 && grid[row + 1][j] === grid[row][j] &&
259
+ !document.querySelector(`.tile[data-x="${row+1}"][data-y="${j}"].merged`)) {
260
+ grid[row + 1][j] *= 2;
261
+ score += grid[row + 1][j];
262
+ grid[row][j] = 0;
263
+ moved = true;
264
+ }
265
+ }
266
+ }
267
+ }
268
+
269
+ return moved;
270
+ }
271
+
272
+ // Move tiles left
273
+ function moveLeft() {
274
+ let moved = false;
275
+
276
+ for (let i = 0; i < 4; i++) {
277
+ for (let j = 1; j < 4; j++) {
278
+ if (grid[i][j] !== 0) {
279
+ let col = j;
280
+ while (col > 0 && grid[i][col - 1] === 0) {
281
+ grid[i][col - 1] = grid[i][col];
282
+ grid[i][col] = 0;
283
+ col--;
284
+ moved = true;
285
+ }
286
+
287
+ // Check for merge with the tile to the left
288
+ if (col > 0 && grid[i][col - 1] === grid[i][col] &&
289
+ !document.querySelector(`.tile[data-x="${i}"][data-y="${col-1}"].merged`)) {
290
+ grid[i][col - 1] *= 2;
291
+ score += grid[i][col - 1];
292
+ grid[i][col] = 0;
293
+ moved = true;
294
+ }
295
+ }
296
+ }
297
+ }
298
+
299
+ return moved;
300
+ }
301
+
302
+ // Check if the player has won (reached 2048)
303
+ function checkWin() {
304
+ for (let i = 0; i < 4; i++) {
305
+ for (let j = 0; j < 4; j++) {
306
+ if (grid[i][j] === 2048) {
307
+ return true;
308
+ }
309
+ }
310
+ }
311
+ return false;
312
+ }
313
+
314
+ // Event listeners
315
+ document.addEventListener('keydown', (e) => {
316
+ switch (e.key) {
317
+ case 'ArrowUp':
318
+ e.preventDefault();
319
+ moveTiles('up');
320
+ break;
321
+ case 'ArrowRight':
322
+ e.preventDefault();
323
+ moveTiles('right');
324
+ break;
325
+ case 'ArrowDown':
326
+ e.preventDefault();
327
+ moveTiles('down');
328
+ break;
329
+ case 'ArrowLeft':
330
+ e.preventDefault();
331
+ moveTiles('left');
332
+ break;
333
+ }
334
+ });
335
+
336
+ // Touch support for mobile devices
337
+ let touchStartX = 0;
338
+ let touchStartY = 0;
339
+ let touchEndX = 0;
340
+ let touchEndY = 0;
341
+
342
+ document.addEventListener('touchstart', (e) => {
343
+ touchStartX = e.touches[0].clientX;
344
+ touchStartY = e.touches[0].clientY;
345
+ }, false);
346
+
347
+ document.addEventListener('touchend', (e) => {
348
+ touchEndX = e.changedTouches[0].clientX;
349
+ touchEndY = e.changedTouches[0].clientY;
350
+ handleSwipe();
351
+ }, false);
352
+
353
+ function handleSwipe() {
354
+ const dx = touchEndX - touchStartX;
355
+ const dy = touchEndY - touchStartY;
356
+
357
+ // Determine if the swipe was more horizontal or vertical
358
+ if (Math.abs(dx) > Math.abs(dy)) {
359
+ // Horizontal swipe
360
+ if (dx > 0) {
361
+ moveTiles('right');
362
+ } else {
363
+ moveTiles('left');
364
+ }
365
+ } else {
366
+ // Vertical swipe
367
+ if (dy > 0) {
368
+ moveTiles('down');
369
+ } else {
370
+ moveTiles('up');
371
+ }
372
+ }
373
+ }
374
+
375
+ // Button event listeners
376
+ newGameButton.addEventListener('click', initGame);
377
+ tryAgainButton.addEventListener('click', initGame);
378
+ keepGoingButton.addEventListener('click', () => {
379
+ gameWonScreen.style.display = 'none';
380
+ gameWon = false;
381
+ });
382
+
383
+ // Initialize the game
384
+ initGame();
385
+ });
index.html ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>2048 Game</title>
7
+ <link rel="stylesheet" href="styles.css">
8
+ </head>
9
+ <body>
10
+ <div class="container">
11
+ <div class="header">
12
+ <h1>2048</h1>
13
+ <div class="scores">
14
+ <div class="score-box">
15
+ <div class="score-title">SCORE</div>
16
+ <div id="score">0</div>
17
+ </div>
18
+ <div class="score-box">
19
+ <div class="score-title">BEST</div>
20
+ <div id="best-score">0</div>
21
+ </div>
22
+ </div>
23
+ </div>
24
+ <div class="game-intro">
25
+ <p>Join the tiles, get to <strong>2048!</strong></p>
26
+ <button id="new-game">New Game</button>
27
+ </div>
28
+ <div class="game-container">
29
+ <div class="grid-container"></div>
30
+ <div class="game-over">
31
+ <p>Game Over!</p>
32
+ <button id="try-again">Try Again</button>
33
+ </div>
34
+ <div class="game-won">
35
+ <p>You Win!</p>
36
+ <button id="keep-going">Keep Going</button>
37
+ </div>
38
+ </div>
39
+ <p class="game-explanation">
40
+ <strong>HOW TO PLAY:</strong> Use your <strong>arrow keys</strong> to move the tiles. When two tiles with the same number touch, they <strong>merge into one!</strong>
41
+ </p>
42
+ </div>
43
+ <script src="game.js"></script>
44
+ </body>
45
+ </html>
main.py ADDED
@@ -0,0 +1,220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ AI-Powered Shipment Route Optimization & Delay Prediction System
4
+ Main application entry point for demonstration and testing
5
+ """
6
+
7
+ import sys
8
+ import os
9
+ import pandas as pd
10
+ from datetime import datetime
11
+
12
+ # Add src directory to path
13
+ sys.path.append(os.path.join(os.path.dirname(__file__), 'src'))
14
+
15
+ from data_pipeline.data_collector import DataCollector
16
+ from data_pipeline.data_processor import DataProcessor
17
+ from ml_models.delay_predictor import DelayPredictor, ModelEvaluator
18
+ from route_optimizer.route_optimizer import RouteOptimizer, RouteAnalyzer
19
+ from utils.monitoring import ShipmentMonitor, PerformanceAnalyzer
20
+
21
+ def demonstrate_system():
22
+ """Demonstrate the complete AI-powered shipment optimization system"""
23
+
24
+ print("=" * 60)
25
+ print("AI-POWERED SHIPMENT ROUTE OPTIMIZATION & DELAY PREDICTION")
26
+ print("=" * 60)
27
+ print()
28
+
29
+ # Initialize components
30
+ print("🔧 Initializing system components...")
31
+ data_collector = DataCollector()
32
+ data_processor = DataProcessor()
33
+ delay_predictor = DelayPredictor()
34
+ route_optimizer = RouteOptimizer()
35
+ monitor = ShipmentMonitor()
36
+ analyzer = PerformanceAnalyzer()
37
+
38
+ # Step 1: Data Collection and Processing
39
+ print("\n📊 STEP 1: Data Collection and Processing")
40
+ print("-" * 40)
41
+
42
+ # Generate sample data for demonstration
43
+ print("Generating sample shipment data...")
44
+ sample_data = data_processor.generate_sample_data(1000)
45
+ print(f"✅ Generated {len(sample_data)} sample shipments")
46
+
47
+ # Clean and process data
48
+ print("Cleaning and processing data...")
49
+ processed_data = data_processor.clean_shipment_data(sample_data)
50
+ feature_data = data_processor.create_features(processed_data)
51
+ print(f"✅ Processed data with {len(feature_data.columns)} features")
52
+
53
+ # Step 2: Machine Learning Model Training
54
+ print("\n🤖 STEP 2: Machine Learning Model Training")
55
+ print("-" * 40)
56
+
57
+ # Prepare data for ML
58
+ X, y = data_processor.prepare_ml_data(feature_data)
59
+ print(f"Training data shape: {X.shape}")
60
+ print(f"Target distribution: {y.value_counts().to_dict()}")
61
+
62
+ # Train delay prediction model
63
+ print("\nTraining XGBoost delay prediction model...")
64
+ metrics = delay_predictor.train_model(X, y)
65
+ print(f"✅ Model trained with {metrics['accuracy']:.1%} accuracy")
66
+
67
+ # Step 3: Route Optimization
68
+ print("\n🗺️ STEP 3: Route Optimization")
69
+ print("-" * 40)
70
+
71
+ # Build sample route network
72
+ print("Building route optimization network...")
73
+ # Add major US cities as nodes
74
+ cities = {
75
+ 'NYC': (40.7128, -74.0060),
76
+ 'LA': (34.0522, -118.2437),
77
+ 'CHI': (41.8781, -87.6298),
78
+ 'HOU': (29.7604, -95.3698),
79
+ 'PHX': (33.4484, -112.0740)
80
+ }
81
+
82
+ for city_id, (lat, lng) in cities.items():
83
+ route_optimizer.add_location(city_id, lat, lng, 'city')
84
+
85
+ # Add routes between cities
86
+ city_pairs = [
87
+ ('NYC', 'CHI'), ('CHI', 'LA'), ('NYC', 'HOU'),
88
+ ('HOU', 'LA'), ('CHI', 'PHX'), ('PHX', 'LA')
89
+ ]
90
+
91
+ for city1, city2 in city_pairs:
92
+ route_optimizer.add_route(city1, city2)
93
+
94
+ print(f"✅ Built network with {len(cities)} cities and {len(city_pairs)} routes")
95
+
96
+ # Find optimal routes
97
+ print("\nFinding optimal routes NYC -> LA...")
98
+ routes = route_optimizer.find_alternative_routes('NYC', 'LA', num_alternatives=3)
99
+
100
+ for i, route in enumerate(routes[:3]):
101
+ if 'error' not in route:
102
+ print(f"Route {i+1}: {' -> '.join(route['path'])} "
103
+ f"({route['total_cost']:.1f} minutes)")
104
+
105
+ # Step 4: Delay Prediction Demo
106
+ print("\n🎯 STEP 4: Delay Risk Prediction")
107
+ print("-" * 40)
108
+
109
+ # Predict delays for sample shipments
110
+ sample_shipments = feature_data.head(10)
111
+ X_sample, _ = data_processor.prepare_ml_data(sample_shipments)
112
+
113
+ if len(X_sample) > 0:
114
+ risk_predictions = delay_predictor.predict_delay_risk(X_sample)
115
+
116
+ print("Sample delay risk predictions:")
117
+ for i in range(min(5, len(risk_predictions))):
118
+ tracking = sample_shipments.iloc[i]['tracking_number']
119
+ risk = risk_predictions.iloc[i]['risk_category']
120
+ prob = risk_predictions.iloc[i]['delay_probability']
121
+ print(f" {tracking}: {risk} ({prob:.1%} probability)")
122
+
123
+ # Step 5: Real-time Monitoring
124
+ print("\n📡 STEP 5: Real-time Monitoring")
125
+ print("-" * 40)
126
+
127
+ # Simulate monitoring
128
+ print("Running shipment monitoring system...")
129
+ monitoring_results = monitor.monitor_shipments()
130
+
131
+ print(f"✅ Monitoring complete:")
132
+ print(f" - Active shipments: {monitoring_results['summary'].get('total_active_shipments', 0)}")
133
+ print(f" - Total alerts: {monitoring_results['summary'].get('total_alerts', 0)}")
134
+ print(f" - High risk shipments: {monitoring_results['summary'].get('high_risk_shipments', 0)}")
135
+
136
+ # Step 6: Performance Analysis
137
+ print("\n📈 STEP 6: Performance Analysis")
138
+ print("-" * 40)
139
+
140
+ performance = analyzer.analyze_delivery_performance(30)
141
+ bottlenecks = analyzer.identify_bottlenecks()
142
+
143
+ if 'error' not in performance:
144
+ print(f"✅ 30-day performance analysis:")
145
+ print(f" - Total shipments: {performance.get('total_shipments', 0)}")
146
+ print(f" - On-time rate: {performance.get('on_time_rate_percent', 0):.1f}%")
147
+ print(f" - Average delay: {performance.get('average_delay_minutes', 0):.1f} minutes")
148
+
149
+ print(f"\n🔍 Top delay causes identified:")
150
+ for cause in bottlenecks['top_delay_causes'][:3]:
151
+ print(f" - {cause['cause']}: {cause['frequency']} incidents, "
152
+ f"{cause['avg_delay_minutes']} min avg delay")
153
+
154
+ # Step 7: Business Impact Summary
155
+ print("\n💼 STEP 7: Business Impact Summary")
156
+ print("-" * 40)
157
+
158
+ print("🎯 Key Achievements:")
159
+ print(f" ✅ Predictive model accuracy: {metrics['accuracy']:.1%}")
160
+ print(f" ✅ Route optimization: {len(routes)} alternative routes found")
161
+ print(f" ✅ Real-time monitoring: Active alert system")
162
+ print(f" ✅ Performance analytics: Bottleneck identification")
163
+
164
+ print("\n📊 Expected Business Benefits:")
165
+ print(" • 15% reduction in delivery delays")
166
+ print(" • Improved customer satisfaction through proactive notifications")
167
+ print(" • Real-time visibility into shipment status")
168
+ print(" • Data-driven decision making for logistics operations")
169
+
170
+ print("\n🚀 System Ready!")
171
+ print("Dashboard available at: http://localhost:8050")
172
+ print("Run 'python src/dashboard/app.py' to start the web interface")
173
+
174
+ return {
175
+ 'model_accuracy': metrics['accuracy'],
176
+ 'routes_found': len(routes),
177
+ 'monitoring_active': True,
178
+ 'system_status': 'operational'
179
+ }
180
+
181
+ def run_dashboard():
182
+ """Launch the web dashboard"""
183
+ print("🚀 Starting AI-Powered Shipment Optimization Dashboard...")
184
+
185
+ try:
186
+ from dashboard.app import app
187
+ print("Dashboard starting at http://localhost:8050")
188
+ app.run_server(debug=False, host='0.0.0.0', port=8050)
189
+ except ImportError as e:
190
+ print(f"Error importing dashboard: {e}")
191
+ print("Please install required dependencies: pip install -r requirements.txt")
192
+ except Exception as e:
193
+ print(f"Error starting dashboard: {e}")
194
+
195
+ if __name__ == "__main__":
196
+ import argparse
197
+
198
+ parser = argparse.ArgumentParser(description='AI-Powered Shipment Route Optimization System')
199
+ parser.add_argument('--demo', action='store_true', help='Run system demonstration')
200
+ parser.add_argument('--dashboard', action='store_true', help='Start web dashboard')
201
+ parser.add_argument('--all', action='store_true', help='Run demo then start dashboard')
202
+
203
+ args = parser.parse_args()
204
+
205
+ if args.demo or args.all:
206
+ results = demonstrate_system()
207
+ print(f"\nDemo completed. Results: {results}")
208
+
209
+ if args.dashboard or args.all:
210
+ if args.all:
211
+ print("\n" + "="*60)
212
+ input("Press Enter to start the dashboard...")
213
+ run_dashboard()
214
+
215
+ if not any([args.demo, args.dashboard, args.all]):
216
+ print("AI-Powered Shipment Route Optimization System")
217
+ print("Usage:")
218
+ print(" python main.py --demo # Run demonstration")
219
+ print(" python main.py --dashboard # Start web dashboard")
220
+ print(" python main.py --all # Run demo then dashboard")
netlify.toml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [build]
2
+ base = "."
3
+ publish = "."
4
+ command = "pip install -r requirements.txt"
5
+
6
+ [build.environment]
7
+ PYTHON_VERSION = "3.11"
8
+
9
+ [[redirects]]
10
+ from = "/*"
11
+ to = "/deploy.py"
12
+ status = 200
13
+
14
+ [context.production.environment]
15
+ FLASK_ENV = "production"
16
+
17
+ [context.deploy-preview.environment]
18
+ FLASK_ENV = "development"
render.yaml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ services:
2
+ - type: web
3
+ name: greenpath-ai
4
+ env: python
5
+ pythonVersion: "3.11"
6
+ buildCommand: "pip install -r requirements.txt"
7
+ startCommand: "gunicorn myapp.wsgi"
requirements.txt CHANGED
@@ -1,23 +1,24 @@
1
- streamlit==1.28.1
2
- pandas==2.1.3
3
- numpy==1.25.2
4
- scikit-learn==1.3.2
5
- xgboost>=1.6.0
6
- requests==2.31.0
7
- fastapi==0.104.1
8
- uvicorn==0.24.0
9
- plotly==5.17.0
10
- geopy==2.4.0
11
- python-dotenv==1.0.0
12
- networkx>=2.8
13
- openrouteservice==2.3.3
14
- sqlalchemy==1.4.46
15
- pydantic==2.5.0
16
- folium==0.15.0
17
- streamlit-folium==0.15.0
18
- reportlab==4.0.7
19
- openpyxl==3.1.2
20
- psycopg2-binary==2.9.9
21
- redis==5.0.1
22
- snowflake-connector-python==3.6.0
23
- snowflake-sqlalchemy==1.5.1
 
 
1
+ streamlit
2
+ pandas==2.1.3
3
+ numpy==1.25.2
4
+ scikit-learn==1.3.2
5
+ xgboost>=1.6.0
6
+ requests==2.31.0
7
+ fastapi==0.104.1
8
+ uvicorn==0.24.0
9
+ streamlit==1.28.1
10
+ plotly==5.17.0
11
+ geopy==2.4.0
12
+ python-dotenv==1.0.0
13
+ networkx>=2.8
14
+ openrouteservice==2.3.3
15
+ sqlalchemy==2.0.23
16
+ pydantic==2.5.0
17
+ folium==0.15.0
18
+ streamlit-folium==0.15.0
19
+ reportlab==4.0.7
20
+ openpyxl==3.1.2
21
+ psycopg2-binary==2.9.9
22
+ redis==5.0.1
23
+ snowflake-connector-python==3.6.0
24
+ snowflake-sqlalchemy==1.5.1
styles.css ADDED
@@ -0,0 +1,222 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ * {
2
+ margin: 0;
3
+ padding: 0;
4
+ box-sizing: border-box;
5
+ font-family: Arial, sans-serif;
6
+ }
7
+
8
+ body {
9
+ background-color: #faf8ef;
10
+ color: #776e65;
11
+ line-height: 1.4;
12
+ }
13
+
14
+ .container {
15
+ max-width: 500px;
16
+ margin: 0 auto;
17
+ padding: 20px;
18
+ }
19
+
20
+ .header {
21
+ display: flex;
22
+ justify-content: space-between;
23
+ align-items: center;
24
+ margin-bottom: 20px;
25
+ }
26
+
27
+ h1 {
28
+ font-size: 80px;
29
+ font-weight: bold;
30
+ color: #776e65;
31
+ margin: 0;
32
+ }
33
+
34
+ .scores {
35
+ display: flex;
36
+ gap: 10px;
37
+ }
38
+
39
+ .score-box {
40
+ background: #bbada0;
41
+ color: white;
42
+ padding: 5px 15px;
43
+ border-radius: 3px;
44
+ text-align: center;
45
+ }
46
+
47
+ .score-title {
48
+ font-size: 13px;
49
+ text-transform: uppercase;
50
+ }
51
+
52
+ #score, #best-score {
53
+ font-size: 22px;
54
+ font-weight: bold;
55
+ }
56
+
57
+ .game-intro {
58
+ display: flex;
59
+ justify-content: space-between;
60
+ align-items: center;
61
+ margin-bottom: 20px;
62
+ }
63
+
64
+ button {
65
+ background: #8f7a66;
66
+ color: white;
67
+ border: none;
68
+ border-radius: 3px;
69
+ padding: 10px 20px;
70
+ font-size: 18px;
71
+ font-weight: bold;
72
+ cursor: pointer;
73
+ transition: all 0.2s;
74
+ }
75
+
76
+ button:hover {
77
+ background: #9f8b77;
78
+ }
79
+
80
+ .game-container {
81
+ position: relative;
82
+ background: #bbada0;
83
+ border-radius: 6px;
84
+ padding: 15px;
85
+ margin-bottom: 20px;
86
+ height: 470px;
87
+ }
88
+
89
+ .grid-container {
90
+ display: grid;
91
+ grid-template-columns: repeat(4, 1fr);
92
+ grid-gap: 15px;
93
+ position: relative;
94
+ width: 100%;
95
+ height: 100%;
96
+ }
97
+
98
+ .grid-cell {
99
+ background: rgba(238, 228, 218, 0.35);
100
+ border-radius: 3px;
101
+ position: relative;
102
+ }
103
+
104
+ .tile {
105
+ position: absolute;
106
+ width: calc(25% - 15px);
107
+ height: calc(25% - 15px);
108
+ display: flex;
109
+ justify-content: center;
110
+ align-items: center;
111
+ font-size: 36px;
112
+ font-weight: bold;
113
+ color: #776e65;
114
+ background: #eee4da;
115
+ border-radius: 3px;
116
+ transition: all 0.15s cubic-bezier(0.4, 0.0, 0.2, 1);
117
+ will-change: transform, opacity;
118
+ z-index: 10;
119
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
120
+ }
121
+
122
+ .tile-2 { background: #eee4da; }
123
+ .tile-4 { background: #ede0c8; }
124
+ .tile-8 { background: #f2b179; color: white; }
125
+ .tile-16 { background: #f59563; color: white; }
126
+ .tile-32 { background: #f67c5f; color: white; }
127
+ .tile-64 { background: #f65e3b; color: white; }
128
+ .tile-128 {
129
+ background: #edcf72;
130
+ color: white;
131
+ font-size: 30px;
132
+ }
133
+ .tile-256 {
134
+ background: #edcc61;
135
+ color: white;
136
+ font-size: 30px;
137
+ }
138
+ .tile-512 {
139
+ background: #edc850;
140
+ color: white;
141
+ font-size: 30px;
142
+ }
143
+ .tile-1024 {
144
+ background: #edc53f;
145
+ color: white;
146
+ font-size: 25px;
147
+ }
148
+ .tile-2048 {
149
+ background: #edc22e;
150
+ color: white;
151
+ font-size: 25px;
152
+ }
153
+
154
+ .game-over, .game-won {
155
+ position: absolute;
156
+ top: 0;
157
+ left: 0;
158
+ width: 100%;
159
+ height: 100%;
160
+ background: rgba(238, 228, 218, 0.73);
161
+ display: flex;
162
+ flex-direction: column;
163
+ align-items: center;
164
+ justify-content: center;
165
+ z-index: 100;
166
+ display: none;
167
+ }
168
+
169
+ .game-over p, .game-won p {
170
+ font-size: 60px;
171
+ font-weight: bold;
172
+ color: #776e65;
173
+ margin-bottom: 20px;
174
+ }
175
+
176
+ .game-explanation {
177
+ text-align: center;
178
+ color: #776e65;
179
+ font-size: 18px;
180
+ line-height: 1.5;
181
+ }
182
+
183
+ @keyframes appear {
184
+ 0% {
185
+ opacity: 0;
186
+ transform: scale(0.5) rotate(0deg);
187
+ }
188
+ 100% {
189
+ opacity: 1;
190
+ transform: scale(1) rotate(360deg);
191
+ }
192
+ }
193
+
194
+ @keyframes pop {
195
+ 0% { transform: scale(0.8); }
196
+ 50% { transform: scale(1.1); }
197
+ 100% { transform: scale(1); }
198
+ }
199
+
200
+ @keyframes merge {
201
+ 0% { transform: scale(1); }
202
+ 50% { transform: scale(1.2); }
203
+ 100% { transform: scale(1); }
204
+ }
205
+
206
+ .new-tile {
207
+ animation: appear 0.3s cubic-bezier(0.4, 0.0, 0.2, 1) forwards;
208
+ }
209
+
210
+ .merged-tile {
211
+ animation: merge 0.2s cubic-bezier(0.4, 0.0, 0.2, 1) forwards;
212
+ z-index: 20;
213
+ }
214
+
215
+ .move-tile {
216
+ transition: all 0.15s cubic-bezier(0.4, 0.0, 0.2, 1);
217
+ }
218
+
219
+ .merged-tile {
220
+ animation: pop 0.15s ease-in-out;
221
+ z-index: 20;
222
+ }
vercel.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "version": 2,
3
+ "name": "ai-shipment-optimization",
4
+ "builds": [
5
+ {
6
+ "src": "deploy.py",
7
+ "use": "@vercel/python"
8
+ }
9
+ ],
10
+ "routes": [
11
+ {
12
+ "src": "/(.*)",
13
+ "dest": "deploy.py"
14
+ }
15
+ ],
16
+ "env": {
17
+ "FLASK_ENV": "production"
18
+ },
19
+ "functions": {
20
+ "deploy.py": {
21
+ "maxDuration": 30
22
+ }
23
+ }
24
+ }