Navanihk commited on
Commit
f073c59
·
1 Parent(s): ff5b0d5
Files changed (9) hide show
  1. .gitattributes copy +35 -0
  2. .gitignore +18 -0
  3. Dockerfile +14 -0
  4. README copy.md +72 -0
  5. RainFallModel.py +62 -0
  6. RoofTopCalculation.py +285 -0
  7. app.py +40 -0
  8. requirements.txt +0 -0
  9. vercel.json +15 -0
.gitattributes copy ADDED
@@ -0,0 +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
.gitignore ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .idea/
2
+ .vscode/
3
+ .venv*/
4
+ venv*/
5
+ __pycache__/
6
+ dist/
7
+ .coverage*
8
+ htmlcov/
9
+ .tox/
10
+ docs/_build/
11
+ *.pkl
12
+ *.pyc
13
+ __pycache__/
14
+ venv/
15
+ .env
16
+ instance/
17
+ *.sqlite3
18
+ .vercel
Dockerfile ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use the official Python 3.10.9 image
2
+ FROM python:3.10.9
3
+
4
+ # Copy the current directory contents into the container at .
5
+ COPY . .
6
+
7
+ # Set the working directory to /
8
+ WORKDIR /
9
+
10
+ # Install requirements.txt
11
+ RUN pip install --no-cache-dir --upgrade -r /requirements.txt
12
+
13
+ # Start the FastAPI app on port 7860, the default port expected by Spaces
14
+ CMD ["python", "app.py"]
README copy.md ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Rainwater Harvesting Recommendation System
3
+ emoji: 🌧️
4
+ colorFrom: blue
5
+ colorTo: green
6
+ sdk: docker
7
+ pinned: false
8
+ ---
9
+
10
+ # Rainwater Harvesting Recommendation System
11
+
12
+ This is a FastAPI-based microservice that provides rainwater harvesting recommendations based on location, roof area, and other parameters.
13
+
14
+ ## Features
15
+
16
+ - **Rainfall Prediction**: Uses machine learning to predict rainfall for specific locations and dates
17
+ - **Rooftop Calculation**: Calculates potential rainwater harvesting capacity based on roof area and local conditions
18
+ - **Structure Recommendations**: Suggests appropriate rainwater harvesting structures based on available space and groundwater levels
19
+ - **Cost Analysis**: Provides cost estimates and ROI calculations for rainwater harvesting systems
20
+
21
+ ## API Endpoints
22
+
23
+ ### POST `/api/roofTopCalculation`
24
+
25
+ Calculate rainwater harvesting parameters for a given location and roof specifications.
26
+
27
+ **Request Body:**
28
+ ```json
29
+ {
30
+ "location": "Karur",
31
+ "roof_area": 100,
32
+ "open_space": 50,
33
+ "roof_type": "concrete",
34
+ "dwellers": 4
35
+ }
36
+ ```
37
+
38
+ **Response:**
39
+ Returns detailed calculations including:
40
+ - Runoff volume calculations
41
+ - Harvestable water estimates
42
+ - Structure recommendations
43
+ - Cost analysis
44
+ - Feasibility scores
45
+
46
+ ## Technology Stack
47
+
48
+ - **FastAPI**: Web framework
49
+ - **Pandas**: Data manipulation
50
+ - **Scikit-learn**: Machine learning predictions
51
+ - **Hugging Face Hub**: Model and data hosting
52
+
53
+ ## Installation
54
+
55
+ ```bash
56
+ pip install -r requirements.txt
57
+ ```
58
+
59
+ ## Usage
60
+
61
+ ```bash
62
+ python app.py
63
+ ```
64
+
65
+ The API will be available at `http://localhost:10000`
66
+
67
+ ## Docker
68
+
69
+ ```bash
70
+ docker build -t rainwater-harvesting .
71
+ docker run -p 10000:10000 rainwater-harvesting
72
+ ```
RainFallModel.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import os
3
+ import pandas as pd
4
+ import numpy as np
5
+ from huggingface_hub import hf_hub_download
6
+
7
+ repo_id = "Navanihk/rainfallPrediction"
8
+ cache_dir = '/tmp/hf_cache'
9
+ os.makedirs(cache_dir, exist_ok=True)
10
+ csv_path = hf_hub_download(repo_id=repo_id, filename="rainFallData.csv", cache_dir=cache_dir,
11
+
12
+ )
13
+ # Load as DataFrame
14
+ df= pd.read_csv(csv_path, sep=";")
15
+ # df= pd.read_csv('./rainFallData.csv',sep=";")
16
+ import calendar
17
+ print(df)
18
+ # Function to remove invalid days for each month
19
+ def valid_day(row):
20
+ year = 2025
21
+ month = row['month']
22
+ day = row['day']
23
+ max_day = calendar.monthrange(year, month)[1] # max days in the month
24
+ return day <= max_day
25
+ def calculate_rainfall():
26
+ # Debug: Print actual column names
27
+ print("Available columns in DataFrame:", df.columns.tolist())
28
+ print("DataFrame shape:", df.shape)
29
+ print("First few rows:")
30
+ print(df.head())
31
+
32
+ # Check if required columns exist
33
+ required_cols = ['state', 'district', 'month']
34
+ missing_cols = [col for col in required_cols if col not in df.columns]
35
+
36
+ if missing_cols:
37
+ print(f"ERROR: Missing columns: {missing_cols}")
38
+ print("Please check the actual column names in your CSV file")
39
+ return None
40
+
41
+ # Melt to long format
42
+ day_cols = [col for col in df.columns if col not in ['state', 'district', 'month']]
43
+ df_long = df.melt(
44
+ id_vars=["state", "district", "month"],
45
+ value_vars=day_cols,
46
+ var_name="day",
47
+ value_name="rainfall"
48
+ )
49
+
50
+ # Extract numeric day
51
+ df_long['day'] = df_long['day'].str.extract(r'(\d+)').astype(int)
52
+
53
+ # Keep only valid days
54
+ df_long = df_long[df_long.apply(valid_day, axis=1)]
55
+
56
+ # Create proper date
57
+ df_long['date'] = pd.to_datetime(
58
+ dict(year=2025, month=df_long['month'], day=df_long['day'])
59
+ )
60
+
61
+ df_long = df_long.sort_values(['district', 'date']).reset_index(drop=True)
62
+ return df_long
RoofTopCalculation.py ADDED
@@ -0,0 +1,285 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+ import os
3
+ import pickle
4
+ import pandas as pd
5
+ from huggingface_hub import hf_hub_download
6
+
7
+ repo_id = "Navanihk/rainfallPrediction"
8
+ cache_dir = '/tmp/hf_cache'
9
+ os.makedirs(cache_dir, exist_ok=True)
10
+ def predict_rainfall_for_date(df_long, model, district_name, target_date, lags=7):
11
+ """
12
+ Predict rainfall for a specific district and date.
13
+
14
+ df_long: original dataset (with columns ['district','state','date','rainfall'])
15
+ model: trained LightGBM model
16
+ district_name: name of the district to predict
17
+ target_date: pd.Timestamp or string in 'YYYY-MM-DD'
18
+ lags: number of lag days to use
19
+ """
20
+
21
+
22
+ # Ensure target_date is Timestamp
23
+ target_date = pd.Timestamp(target_date)
24
+
25
+ # Get district data up to the day before target_date
26
+ district_data = df_long[(df_long['district']==district_name) &
27
+ (df_long['date'] < target_date)].sort_values('date')
28
+
29
+ # Check if enough data for lags
30
+ if len(district_data) < lags:
31
+ raise ValueError(f"Not enough data to create {lags} lag features for {district_name}")
32
+
33
+ # Get last 'lags' days of rainfall (most recent first)
34
+ lag_values = list(district_data['rainfall'].tail(lags).values[::-1])
35
+
36
+ # Create feature vector: lag + date features
37
+ features = lag_values + [target_date.month, target_date.day, target_date.dayofyear]
38
+
39
+ # Predict
40
+ pred_rain = model.predict([features])[0]
41
+
42
+ return {
43
+ 'district': district_name,
44
+ 'state': district_data['state'].iloc[0],
45
+ 'date': target_date,
46
+ 'predicted_rainfall': pred_rain
47
+ }
48
+
49
+
50
+
51
+ def rainFallPrediction(location,RainFallData):
52
+ """Predict average annual rainfall for a given location using RainFallData"""
53
+ model_path = hf_hub_download(repo_id=repo_id, filename="rainfall.pkl", cache_dir=cache_dir,
54
+
55
+ )
56
+
57
+ # Load the actual model from the downloaded file
58
+ with open(model_path, 'rb') as f:
59
+ model = pickle.load(f)
60
+
61
+ # model = pickle.load(open('rainfall.pkl','rb'))
62
+ date = "2025-01-10"
63
+ print("predict_rainfall_for_date called")
64
+
65
+ pred_result = predict_rainfall_for_date(RainFallData, model, location, date)
66
+ print(pred_result)
67
+ return pred_result['predicted_rainfall'] # Default to Delhi-like rainfall if location not found
68
+ def RooftTopCalculation(input_data,RainFallData):
69
+ """
70
+ Calculate rainwater harvesting parameters based on input data
71
+ """
72
+ # Extract input parameters
73
+ location = input_data.get('location', 'Unknown')
74
+ roof_area = input_data.get('roof_area', 0)
75
+ open_space = input_data.get('open_space', 0)
76
+ roof_type = input_data.get('roof_type', 'null')
77
+ dwellers = input_data.get('dwellers', 1)
78
+
79
+
80
+ # Default values for calculations (these would typically come from ML models or databases)
81
+ # Using Delhi-like values as defaults
82
+ default_rainfall = rainFallPrediction(location,RainFallData) # mm/year
83
+ default_runoff_coefficient = 0.8 # typical for concrete/tiled roofs
84
+ groundwater_level = 15 # meters below ground level
85
+ soil_type = "Loamy"
86
+ aquifer_type = "Alluvial Aquifer"
87
+
88
+ # Get coordinates (default to Delhi coordinates if location not found)
89
+ coordinates = get_coordinates(location)
90
+
91
+ # Calculate runoff volume (in liters/year)
92
+ runoff_volume = roof_area * default_rainfall * default_runoff_coefficient
93
+
94
+ # Calculate harvestable water (considering losses - typically 15-20% loss)
95
+ loss_factor = 0.15
96
+ harvestable_water = int(runoff_volume * (1 - loss_factor))
97
+
98
+ # Calculate recharge potential (typically 60-70% of harvestable water)
99
+ recharge_potential = int(harvestable_water * 0.65)
100
+
101
+ # Determine structure suggestion based on available space and groundwater level
102
+ structure_suggestion = determine_structure(open_space, groundwater_level, roof_area)
103
+
104
+ # Calculate recommended dimensions
105
+ dimensions = calculate_dimensions(structure_suggestion, harvestable_water)
106
+
107
+ # Calculate capacity
108
+ capacity = dimensions['length'] * dimensions['width'] * dimensions['depth'] * 1000 # in liters
109
+
110
+ # Cost analysis
111
+ estimated_cost = calculate_cost(structure_suggestion, dimensions, roof_area)
112
+ water_saved_value = calculate_water_savings(harvestable_water)
113
+ roi_years = round(estimated_cost / water_saved_value, 1) if water_saved_value > 0 else 0
114
+
115
+ # Feasibility score
116
+ feasibility_score = calculate_feasibility(roof_area, open_space, groundwater_level)
117
+
118
+ # Prepare response
119
+ response = {
120
+ "user": {
121
+ "name": "User", # Default name as not provided in input
122
+ "location": {
123
+ "lat": coordinates[0],
124
+ "lon": coordinates[1],
125
+ "address": location
126
+ },
127
+ "roof_area": roof_area,
128
+ "open_space": open_space,
129
+ "dwellers": dwellers
130
+ },
131
+ "reference_data": {
132
+ "rainfall": f"{default_rainfall} mm/year",
133
+ "aquifer": aquifer_type,
134
+ "groundwater_level": f"{groundwater_level} m bgl",
135
+ "soil_type": soil_type,
136
+ "runoff_coefficient": default_runoff_coefficient
137
+ },
138
+ "calculations": {
139
+ "runoff_volume": f"{int(runoff_volume)} liters/year",
140
+ "harvestable_water": f"{harvestable_water} liters/year",
141
+ "recharge_potential": f"{recharge_potential} liters/year",
142
+ "structure_suggestion": structure_suggestion,
143
+ "recommended_dimensions": dimensions,
144
+ "capacity": f"{int(capacity)} liters"
145
+ },
146
+ "cost_analysis": {
147
+ "estimated_cost": f"₹{estimated_cost:,}",
148
+ "water_saved_value": f"₹{int(water_saved_value):,}/year",
149
+ "roi": f"{roi_years} years"
150
+ },
151
+ "gis_data": {
152
+ "map_coordinates": coordinates,
153
+ "feasibility_score": feasibility_score
154
+ },
155
+ "support": {
156
+ "regional_language": get_regional_language(location),
157
+ "faq_link": "https://cgwb.gov.in/rtrwh-faqs"
158
+ }
159
+ }
160
+
161
+ return response
162
+
163
+ def get_coordinates(location):
164
+ """Get coordinates for a location (simplified - would use geocoding service in production)"""
165
+ location_coordinates = {
166
+ "karur": [10.9601, 78.0766],
167
+ "new delhi": [28.6139, 77.2090],
168
+ "delhi": [28.6139, 77.2090],
169
+ "mumbai": [19.0760, 72.8777],
170
+ "bangalore": [12.9716, 77.5946],
171
+ "chennai": [13.0827, 80.2707],
172
+ "hyderabad": [17.3850, 78.4867],
173
+ "pune": [18.5204, 73.8567],
174
+ "kolkata": [22.5726, 88.3639],
175
+ "ahmedabad": [23.0225, 72.5714],
176
+ "jaipur": [26.9124, 75.7873]
177
+ }
178
+
179
+ location_lower = location.lower()
180
+ return location_coordinates.get(location_lower, [28.6139, 77.2090]) # Default to Delhi
181
+
182
+ def determine_structure(open_space, groundwater_level, roof_area):
183
+ """Determine the best rainwater harvesting structure"""
184
+ if open_space >= 100 and groundwater_level > 10:
185
+ return "Recharge Pit"
186
+ elif open_space >= 50 and groundwater_level > 5:
187
+ return "Percolation Tank"
188
+ elif roof_area >= 100:
189
+ return "Storage Tank"
190
+ else:
191
+ return "Rain Barrel"
192
+
193
+ def calculate_dimensions(structure_type, harvestable_water):
194
+ """Calculate recommended dimensions based on structure type"""
195
+ if structure_type == "Recharge Pit":
196
+ # Calculate based on recharge requirements
197
+ volume_needed = harvestable_water / 1000 # Convert to cubic meters
198
+ depth = min(3, max(2, volume_needed / 4)) # Depth between 2-3m
199
+ area_needed = volume_needed / depth
200
+ side = math.sqrt(area_needed)
201
+ return {
202
+ "length": round(side, 1),
203
+ "width": round(side, 1),
204
+ "depth": round(depth, 1)
205
+ }
206
+ elif structure_type == "Percolation Tank":
207
+ return {"length": 3.0, "width": 3.0, "depth": 2.0}
208
+ elif structure_type == "Storage Tank":
209
+ return {"length": 2.0, "width": 2.0, "depth": 2.5}
210
+ else: # Rain Barrel
211
+ return {"length": 1.0, "width": 1.0, "depth": 1.5}
212
+
213
+ def calculate_cost(structure_type, dimensions, roof_area):
214
+ """Calculate estimated cost in INR"""
215
+ base_costs = {
216
+ "Recharge Pit": 15000,
217
+ "Percolation Tank": 25000,
218
+ "Storage Tank": 20000,
219
+ "Rain Barrel": 5000
220
+ }
221
+
222
+ base_cost = base_costs.get(structure_type, 15000)
223
+ volume = dimensions['length'] * dimensions['width'] * dimensions['depth']
224
+
225
+ # Additional cost based on volume and roof area
226
+ additional_cost = (volume * 2000) + (roof_area * 50)
227
+
228
+ return int(base_cost + additional_cost)
229
+
230
+ def calculate_water_savings(harvestable_water):
231
+ """Calculate annual water savings value in INR"""
232
+ # Assuming water cost of ₹12 per 1000 liters
233
+ water_cost_per_1000_liters = 12
234
+ annual_savings = (harvestable_water / 1000) * water_cost_per_1000_liters
235
+ return annual_savings
236
+
237
+ def calculate_feasibility(roof_area, open_space, groundwater_level):
238
+ """Calculate feasibility score"""
239
+ score = 0
240
+
241
+ if roof_area >= 100:
242
+ score += 30
243
+ elif roof_area >= 50:
244
+ score += 20
245
+ else:
246
+ score += 10
247
+
248
+ if open_space >= 100:
249
+ score += 30
250
+ elif open_space >= 50:
251
+ score += 20
252
+ else:
253
+ score += 10
254
+
255
+ if groundwater_level > 10:
256
+ score += 40
257
+ elif groundwater_level > 5:
258
+ score += 30
259
+ else:
260
+ score += 20
261
+
262
+ if score >= 80:
263
+ return "High"
264
+ elif score >= 60:
265
+ return "Medium"
266
+ else:
267
+ return "Low"
268
+
269
+ def get_regional_language(location):
270
+ """Get regional language based on location"""
271
+ language_map = {
272
+ "karur": "Tamil",
273
+ "new delhi": "Hindi",
274
+ "delhi": "Hindi",
275
+ "mumbai": "Marathi",
276
+ "bangalore": "Kannada",
277
+ "chennai": "Tamil",
278
+ "hyderabad": "Telugu",
279
+ "pune": "Marathi",
280
+ "kolkata": "Bengali",
281
+ "ahmedabad": "Gujarati",
282
+ "jaipur": "Hindi"
283
+ }
284
+
285
+ return language_map.get(location.lower(), "Hindi")
app.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+
3
+ # from flask import Flask,request,jsonify
4
+ # from flask_cors import CORS
5
+ # app = Flask(__name__)
6
+ # cors = CORS(app, resources={r"*": {"origins": "*"}})
7
+ from fastapi import FastAPI
8
+ import uvicorn
9
+
10
+
11
+ # loading the data from the csv file to apandas dataframe
12
+ app = FastAPI()
13
+ from huggingface_hub import login
14
+
15
+ from RoofTopCalculation import RooftTopCalculation
16
+ from RainFallModel import calculate_rainfall
17
+
18
+ import os
19
+ cache_dir = '/tmp/hf_cache'
20
+ os.makedirs(cache_dir, exist_ok=True)
21
+
22
+ @app.post('/api/roofTopCalculation')
23
+ def roof_top_calculation(data: dict):
24
+ RainFallData = calculate_rainfall()
25
+ try:
26
+ if not data:
27
+ return {"error": "No data provided"}, 400
28
+
29
+ # Perform roof top calculation logic
30
+ result = RooftTopCalculation(data,RainFallData)
31
+ return result
32
+
33
+ except Exception as e:
34
+ return {"error": str(e)}, 500
35
+
36
+ # Run the app if the script is executed directly
37
+ # if __name__ == '__main__':
38
+ # app.run(host='0.0.0.0', port=8000, debug=True)
39
+ if __name__ == "__main__":
40
+ uvicorn.run(app, port=10000)
requirements.txt ADDED
Binary file (1.32 kB). View file
 
vercel.json ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "version": 2,
3
+ "builds": [
4
+ {
5
+ "src": "./main.py",
6
+ "use": "@vercel/python"
7
+ }
8
+ ],
9
+ "routes": [
10
+ {
11
+ "src": "/(.*)",
12
+ "dest": "/"
13
+ }
14
+ ]
15
+ }