fadhelcherif commited on
Commit
bd87ac0
·
1 Parent(s): 11dc829
Files changed (4) hide show
  1. .dockerignore +9 -0
  2. Dockerfile +17 -0
  3. app.py +12 -44
  4. templates/index.html +1 -1
.dockerignore ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ .git
2
+ .venv
3
+ __pycache__
4
+ *.pyc
5
+ *.pyo
6
+ *.pyd
7
+ *.ipynb
8
+ car_model.pth
9
+ static/uploads
Dockerfile ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.11-slim
2
+
3
+ ENV PYTHONDONTWRITEBYTECODE=1 \
4
+ PYTHONUNBUFFERED=1 \
5
+ PIP_NO_CACHE_DIR=1 \
6
+ PORT=7860
7
+
8
+ WORKDIR /app
9
+
10
+ COPY requirements.txt /app/requirements.txt
11
+ RUN pip install --upgrade pip && pip install -r /app/requirements.txt
12
+
13
+ COPY . /app
14
+
15
+ EXPOSE 7860
16
+
17
+ CMD ["gunicorn", "--bind", "0.0.0.0:7860", "--workers", "1", "--threads", "2", "--timeout", "300", "app:app"]
app.py CHANGED
@@ -227,13 +227,6 @@ def load_label_mapping(num_classes: int) -> Dict[int, str]:
227
  return {i: f"class_{i}" for i in range(num_classes)}
228
 
229
 
230
- def _is_generic_label_mapping(idx_to_class: Dict[int, str]) -> bool:
231
- if not idx_to_class:
232
- return True
233
- sample = [idx_to_class[k] for k in sorted(idx_to_class.keys())[: min(10, len(idx_to_class))]]
234
- return all(isinstance(name, str) and name.startswith("class_") for name in sample)
235
-
236
-
237
  def load_model_and_labels() -> Tuple[torch.nn.Module, torch.device, transforms.Compose, Dict[int, str]]:
238
  model_path = ensure_model_available()
239
 
@@ -706,41 +699,17 @@ def index():
706
  raw_results = predict_topk(model, image, eval_transform, idx_to_class, device, k=3)
707
  labels = [label for label, _ in raw_results]
708
 
709
- price_map, ordered_prices, price_warning = fetch_prices_from_n8n(labels)
710
  if price_warning:
711
- sheets_price_map, sheets_ordered_prices, sheets_warning = fetch_prices_from_google_sheets(labels)
712
- if sheets_price_map or sheets_ordered_prices:
713
- price_map, ordered_prices = sheets_price_map, sheets_ordered_prices
714
- price_warning = "n8n failed, using Google Sheets fallback. " + price_warning
715
- else:
716
- json_price_map, json_ordered_prices, json_warning = fetch_prices_from_json(labels)
717
- if json_price_map or json_ordered_prices:
718
- price_map, ordered_prices = json_price_map, json_ordered_prices
719
- base_warning = sheets_warning if sheets_warning else "Google Sheets unavailable."
720
- price_warning = (
721
- "n8n and Google Sheets failed, using JSON fallback. "
722
- + price_warning
723
- + " "
724
- + base_warning
725
- )
726
- elif json_warning:
727
- extra_warning = sheets_warning if sheets_warning else ""
728
- price_warning = (
729
- price_warning
730
- + (" " + extra_warning if extra_warning else "")
731
- + " JSON fallback also failed: "
732
- + json_warning
733
- )
734
-
735
- if _is_generic_label_mapping(idx_to_class):
736
- generic_warning = (
737
- "Class names are generic (class_#). Label metadata is unavailable right now. "
738
- "Predictions still run, but names are less readable."
739
- )
740
- if integration_warning:
741
- integration_warning = integration_warning + " " + generic_warning
742
- else:
743
- integration_warning = generic_warning
744
 
745
  if price_warning:
746
  integration_warning = (
@@ -750,14 +719,13 @@ def index():
750
  )
751
 
752
  results = []
753
- for i, (label, confidence) in enumerate(raw_results, start=1):
754
  price_info = _best_match_price(label, price_map)
755
 
756
  results.append(
757
  {
758
  "pick": i,
759
  "label": label,
760
- "confidence": round(confidence * 100.0, 2),
761
  "price": price_info.get("price"),
762
  "currency": price_info.get("currency", DEFAULT_CURRENCY),
763
  }
@@ -780,4 +748,4 @@ def health() -> Tuple[Dict[str, str], int]:
780
 
781
 
782
  if __name__ == "__main__":
783
- app.run()
 
227
  return {i: f"class_{i}" for i in range(num_classes)}
228
 
229
 
 
 
 
 
 
 
 
230
  def load_model_and_labels() -> Tuple[torch.nn.Module, torch.device, transforms.Compose, Dict[int, str]]:
231
  model_path = ensure_model_available()
232
 
 
699
  raw_results = predict_topk(model, image, eval_transform, idx_to_class, device, k=3)
700
  labels = [label for label, _ in raw_results]
701
 
702
+ price_map, ordered_prices, price_warning = fetch_prices_from_google_sheets(labels)
703
  if price_warning:
704
+ json_price_map, json_ordered_prices, json_warning = fetch_prices_from_json(labels)
705
+ if json_price_map or json_ordered_prices:
706
+ price_map, ordered_prices = json_price_map, json_ordered_prices
707
+ price_warning = (
708
+ "Google Sheets failed, using JSON fallback. "
709
+ + price_warning
710
+ )
711
+ elif json_warning:
712
+ price_warning = price_warning + " JSON fallback also failed: " + json_warning
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
713
 
714
  if price_warning:
715
  integration_warning = (
 
719
  )
720
 
721
  results = []
722
+ for i, (label, _) in enumerate(raw_results, start=1):
723
  price_info = _best_match_price(label, price_map)
724
 
725
  results.append(
726
  {
727
  "pick": i,
728
  "label": label,
 
729
  "price": price_info.get("price"),
730
  "currency": price_info.get("currency", DEFAULT_CURRENCY),
731
  }
 
748
 
749
 
750
  if __name__ == "__main__":
751
+ app.run(host="0.0.0.0", port=int(os.getenv("PORT", "7860")))
templates/index.html CHANGED
@@ -34,7 +34,7 @@
34
  <ol>
35
  {% for item in results %}
36
  <li>
37
- <span class="label">Pick {{ item.pick }}: {{ item.label }} ({{ item.confidence }}%)</span>
38
  <span class="price">
39
  {% if item.price is not none %}
40
  {{ item.currency }} {{ item.price }}
 
34
  <ol>
35
  {% for item in results %}
36
  <li>
37
+ <span class="label">Pick {{ item.pick }}: {{ item.label }}</span>
38
  <span class="price">
39
  {% if item.price is not none %}
40
  {{ item.currency }} {{ item.price }}