Spaces:
Sleeping
Sleeping
fadhelcherif commited on
Commit ·
bd87ac0
1
Parent(s): 11dc829
Docker
Browse files- .dockerignore +9 -0
- Dockerfile +17 -0
- app.py +12 -44
- 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 =
|
| 710 |
if price_warning:
|
| 711 |
-
|
| 712 |
-
if
|
| 713 |
-
price_map, ordered_prices =
|
| 714 |
-
price_warning =
|
| 715 |
-
|
| 716 |
-
|
| 717 |
-
|
| 718 |
-
|
| 719 |
-
|
| 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,
|
| 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 }}
|
| 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 }}
|