prshntdxt commited on
Commit
5497b71
·
2 Parent(s): b8d2fae 964b5ae

Resolve merge conflict in requirements.txt

Browse files
Files changed (4) hide show
  1. .dockerignore +0 -1
  2. Dockerfile +12 -27
  3. main.py +12 -2
  4. schemas.py +54 -24
.dockerignore CHANGED
@@ -10,7 +10,6 @@ build/
10
  venv/
11
  env/
12
  server/
13
- .git
14
  .gitignore
15
  .env
16
  .env.local
 
10
  venv/
11
  env/
12
  server/
 
13
  .gitignore
14
  .env
15
  .env.local
Dockerfile CHANGED
@@ -1,11 +1,11 @@
1
- # Use official Python runtime as base image
2
  FROM python:3.11-slim
3
 
4
- # Set working directory in container
5
  WORKDIR /app
6
 
7
- # Install system dependencies (OpenCV, HDF5 support)
8
  RUN apt-get update && apt-get install -y \
 
 
9
  libsm6 \
10
  libxext6 \
11
  libxrender-dev \
@@ -13,35 +13,20 @@ RUN apt-get update && apt-get install -y \
13
  pkg-config \
14
  && rm -rf /var/lib/apt/lists/*
15
 
16
- # Copy requirements file
17
- COPY requirements.txt .
18
 
19
- # Install Python dependencies
20
- RUN pip install --no-cache-dir -r requirements.txt
21
-
22
- # Copy application code
23
- COPY main.py .
24
- COPY model.py .
25
- COPY schemas.py .
26
- COPY inference/ ./inference/
27
 
28
- # Copy pre-trained model (use .keras format only)
29
- COPY models/Forest_Segmentation_Best.keras ./models/
30
 
31
- # Create logs directory
32
- RUN mkdir -p logs
33
 
34
- # Expose port (Hugging Face Spaces default)
35
  EXPOSE 7860
36
-
37
- # Set environment for production
38
  ENV PYTHONUNBUFFERED=1
39
- ENV PORT=7860
40
- ENV HOST=0.0.0.0
41
-
42
- # Health check
43
- HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
44
- CMD python -c "import requests; requests.get('http://localhost:7860/health')" || exit 1
45
 
46
- # Run FastAPI application with uvicorn
47
  CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
 
 
1
  FROM python:3.11-slim
2
 
 
3
  WORKDIR /app
4
 
5
+ # --- System deps ---
6
  RUN apt-get update && apt-get install -y \
7
+ git \
8
+ git-lfs \
9
  libsm6 \
10
  libxext6 \
11
  libxrender-dev \
 
13
  pkg-config \
14
  && rm -rf /var/lib/apt/lists/*
15
 
16
+ # --- Enable Git LFS ---
17
+ RUN git lfs install
18
 
19
+ # --- Copy repo ---
20
+ COPY . .
 
 
 
 
 
 
21
 
22
+ # --- Pull LFS files INSIDE container ---
23
+ RUN git lfs pull
24
 
25
+ # --- Install Python deps ---
26
+ RUN pip install --no-cache-dir -r requirements.txt
27
 
28
+ # --- Runtime ---
29
  EXPOSE 7860
 
 
30
  ENV PYTHONUNBUFFERED=1
 
 
 
 
 
 
31
 
 
32
  CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
main.py CHANGED
@@ -1,5 +1,5 @@
1
  # main.py
2
-
3
  from fastapi import FastAPI, HTTPException, Request
4
  from fastapi.responses import JSONResponse, HTMLResponse
5
  import tensorflow as tf
@@ -207,11 +207,21 @@ def predict(payload: PredictRequest):
207
  # ---------------------------------------------------------------------
208
  # Run model (raw confidence)
209
  # ---------------------------------------------------------------------
 
 
 
 
 
 
 
 
210
  model = tf.keras.models.load_model(
211
- "models/Forest_Segmentation_Best.keras",
212
  compile=False
213
  )
214
 
 
 
215
  confidence_map = model.predict(
216
  input_tensor, verbose=0
217
  )[0, :, :, 0]
 
1
  # main.py
2
+ from huggingface_hub import hf_hub_download
3
  from fastapi import FastAPI, HTTPException, Request
4
  from fastapi.responses import JSONResponse, HTMLResponse
5
  import tensorflow as tf
 
207
  # ---------------------------------------------------------------------
208
  # Run model (raw confidence)
209
  # ---------------------------------------------------------------------
210
+ MODEL_REPO = "prshntdxt/Forest_Segmentation_Best"
211
+ MODEL_FILE = "Forest_Segmentation_Best.keras"
212
+
213
+ MODEL_PATH = hf_hub_download(
214
+ repo_id=MODEL_REPO,
215
+ filename=MODEL_FILE,
216
+ )
217
+
218
  model = tf.keras.models.load_model(
219
+ MODEL_PATH,
220
  compile=False
221
  )
222
 
223
+
224
+
225
  confidence_map = model.predict(
226
  input_tensor, verbose=0
227
  )[0, :, :, 0]
schemas.py CHANGED
@@ -1,41 +1,71 @@
1
  from pydantic import BaseModel
2
- from typing import Dict, List, Optional, Union
 
 
 
 
3
 
4
  class PredictRequest(BaseModel):
5
  """
6
- Forest segmentation prediction request
7
-
8
- Supports Landsat 8 Collection 2 Level 2 data format.
9
- Each band can be provided as:
10
- - Base64-encoded float32 data (for remote API calls)
11
- - Array/list format (for direct server calls)
12
-
13
- Required bands:
14
- - Blue, Green, Red: Optical bands
15
- - NIR, SWIR1, SWIR2: Infrared bands
16
- - NDVI, NDWI, NBR: Spectral indices (or server will compute them)
17
-
18
- Optional special keys:
19
- - _invert_mask: Set to true to invert forest/non-forest in response
20
-
21
- Value range expectations:
22
- - Optical bands: [-0.2, 0.6]
23
- - Indices: [-1, 1]
24
  """
 
25
  model_name: str = "forest_segmentation"
26
  model_version: str = "landsat8_v1"
27
- bands: Dict[str, Union[str, List, int]] # Band data as base64 or array
28
 
 
 
 
 
 
 
 
 
 
29
 
30
- from typing import List, Dict, Any, Optional
31
- from pydantic import BaseModel
 
 
32
 
33
  class PredictResponse(BaseModel):
34
- mask: List[int] # 1D flat list ✓
35
- inverted_mask: List[int] # 1D flat list ✓
 
 
 
 
 
 
 
 
 
 
 
36
  forest_percentage: float
37
  forest_confidence: float
38
  mean_prediction: float
 
 
39
  classes: Dict[str, int]
 
 
40
  model_info: Dict[str, Any]
 
 
41
  debug: Optional[Dict[str, Any]] = None
 
1
  from pydantic import BaseModel
2
+ from typing import Dict, List, Optional, Union, Any
3
+
4
+ # =============================================================================
5
+ # REQUEST SCHEMA
6
+ # =============================================================================
7
 
8
  class PredictRequest(BaseModel):
9
  """
10
+ Forest segmentation prediction request.
11
+
12
+ This schema is intentionally flexible to support:
13
+ - Supabase Edge Functions
14
+ - Hugging Face remote inference
15
+ - Local inference scripts
16
+
17
+ Required:
18
+ - bands: Dict[str, Union[str, List[float]]]
19
+
20
+ Allowed extra fields (sent by Supabase):
21
+ - width, height
22
+ - bbox
23
+ - band_names
24
+ - preprocessing
25
+ - model_name, model_version
 
 
26
  """
27
+
28
  model_name: str = "forest_segmentation"
29
  model_version: str = "landsat8_v1"
 
30
 
31
+ # Band data:
32
+ # - base64-encoded float32 (remote calls)
33
+ # - list/array of floats (local calls)
34
+ bands: Dict[str, Union[str, List[float]]]
35
+
36
+ class Config:
37
+ # 🔑 CRITICAL FIX
38
+ # Allows Supabase to send extra metadata without 422 errors
39
+ extra = "allow"
40
 
41
+
42
+ # =============================================================================
43
+ # RESPONSE SCHEMA
44
+ # =============================================================================
45
 
46
  class PredictResponse(BaseModel):
47
+ """
48
+ Forest segmentation prediction response.
49
+
50
+ Mask values are CONTINUOUS (0–255) — NOT binary.
51
+ """
52
+
53
+ # Flattened mask (length = width * height)
54
+ mask: List[int]
55
+
56
+ # Inverted mask (optional utility)
57
+ inverted_mask: List[int]
58
+
59
+ # Statistics
60
  forest_percentage: float
61
  forest_confidence: float
62
  mean_prediction: float
63
+
64
+ # Class mapping
65
  classes: Dict[str, int]
66
+
67
+ # Model metadata
68
  model_info: Dict[str, Any]
69
+
70
+ # Optional debug block
71
  debug: Optional[Dict[str, Any]] = None