from fastapi import FastAPI, HTTPException from pydantic import BaseModel import joblib import numpy as np from sentinelhub import SentinelHubRequest, BBox, CRS, DataCollection, MimeType import cv2 import base64 from geopy.geocoders import Nominatim from fastapi.middleware.cors import CORSMiddleware import os # 1) Force config directory and env var before any SHConfig is touched # CONFIG_DIR = "/app/.config/sentinelhub" # CONFIG_FILE = os.path.join(CONFIG_DIR, "config.json") # os.makedirs(CONFIG_DIR, exist_ok=True) # os.environ["SH_CONFIG_HOME"] = CONFIG_DIR # 2) Now import and instantiate SHConfig from sentinelhub import SHConfig if __name__ == "__main__": port = int(os.environ.get("PORT", 7860)) uvicorn.run(app, host="0.0.0.0", port=port) # If you want to point directly to a file: # config = SHConfig(config_location=CONFIG_FILE) config = SHConfig( use_defaults=True, sh_client_id=os.getenv("id"), sh_client_secret=os.getenv("secret") ) app = FastAPI() origins = [ "http://ecoguard-522e.onrender.com", "https://ecoguard-522e.onrender.com", "http://localhost:3000", "https://localhost:3000", "https://eco-guard-ten.vercel.app", "http://eco-guard-ten.vercel.app", "https://arsh1101-defo-detect.hf.space", "https://arsh1101-defo-detect.hf.space" ] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) clf = joblib.load('./deforestation_percentage_model.joblib') # print("Using config dir:", os.getenv("SENTINELHUB_CONFIG_FOLDER")) # CONFIG_PATH = "/app/.config/sentinelhub/config.json" # os.makedirs(os.path.dirname(CONFIG_PATH), exist_ok=True) # # Use a custom config location # config = SHConfig(config_location=CONFIG_PATH) # config.sh_client_id =os.getenv('SENTINENTAL_ID') # config.sh_client_secret =os.getenv('SENTINENTAL_PASS') class DeforestationRequest(BaseModel): area_name: str def geocode_area(area_name): geolocator = Nominatim(user_agent="deforestation_app") location = geolocator.geocode(area_name) if location: return location.latitude, location.longitude else: raise HTTPException(status_code=400, detail="Area not found") def fetch_satellite_image(latitude, longitude): bbox = BBox([longitude - 0.1, latitude - 0.1, longitude + 0.1, latitude + 0.1], CRS.WGS84) evalscript = """ // Returns true color image (RGB) from Sentinel-2 return [B04, B03, B02]; """ request = SentinelHubRequest( evalscript=evalscript, input_data=[SentinelHubRequest.input_data( data_collection=DataCollection.SENTINEL2_L1C, time_interval=('2024-01-01', '2024-01-10'), )], responses=[SentinelHubRequest.output_response('default', MimeType.PNG)], bbox=bbox, size=[1024, 1024], config=config ) image = request.get_data()[0] return image def normalize_image(image_array): min_val = np.min(image_array) max_val = np.max(image_array) normalized_image = (image_array - min_val) * (255.0 / (max_val - min_val)) return normalized_image.astype(np.uint8) def extract_green_density(image_array): hsv = cv2.cvtColor(image_array, cv2.COLOR_RGB2HSV) green_channel = hsv[:, :, 0] green_channel = green_channel[(green_channel >= 40) & (green_channel <= 80)] green_density = np.mean(green_channel) if green_channel.size > 0 else 0 return green_density def calculate_deforestation_percentage(image_array): green_density = extract_green_density(image_array) prediction = clf.predict(np.array([[green_density]]))[0] return max(0, prediction) def encode_image(image_array): _, buffer = cv2.imencode('.png', image_array) return base64.b64encode(buffer).decode('utf-8') @app.get("/") def initialize(): return { "status":"success" } @app.post("/deforestation") def predict_deforestation(request: DeforestationRequest): try: latitude, longitude = geocode_area(request.area_name) satellite_image = fetch_satellite_image(latitude, longitude) satellite_image = normalize_image(satellite_image) deforestation_percentage = calculate_deforestation_percentage(satellite_image) encoded_image = encode_image(satellite_image) if deforestation_percentage > 20: return { "message": "Deforestation detected", "deforestation_percentage": f"{deforestation_percentage:.2f}", "satellite_image": f"data:image/png;base64,{encoded_image}" } else: return { "message": "No deforestation detected", "deforestation_percentage": "0", "satellite_image": f"data:image/png;base64,{encoded_image}" } except Exception as e: raise HTTPException(status_code=500, detail=str(e))