Spaces:
Sleeping
Sleeping
| import os | |
| # 在任何 heavy import 之前限制執行緒 | |
| os.environ.setdefault("OMP_NUM_THREADS", "1") | |
| os.environ.setdefault("OPENBLAS_NUM_THREADS", "1") | |
| os.environ.setdefault("MKL_NUM_THREADS", "1") | |
| os.environ.setdefault("NUMEXPR_NUM_THREADS", "1") | |
| # Import onnxruntime BEFORE Flask/pandas/torch. On Windows, if another library | |
| # initializes a shared runtime DLL first, importing onnxruntime later fails with: | |
| # "DLL load failed while importing onnxruntime_pybind11_state". | |
| # Loading it first claims its DLLs cleanly (no-op / harmless on Linux & Docker). | |
| try: | |
| import onnxruntime # noqa: F401 | |
| except Exception as e: | |
| print(f"Note: early onnxruntime import skipped: {e}") | |
| try: | |
| from flask import Flask, jsonify, render_template | |
| except Exception as e: | |
| print(f"Error importing Flask: {e}") | |
| try: | |
| from flask_cors import CORS | |
| except Exception as e: | |
| print(f"Error importing Flask-CORS: {e}") | |
| def create_app(): | |
| base_dir = os.getcwd() | |
| template_folder = os.path.join(base_dir, "app", "templates") | |
| static_folder = os.path.join(base_dir, "app", "static") | |
| # 檢查路徑是否存在 | |
| if os.path.exists(template_folder): | |
| try: | |
| template_files = os.listdir(template_folder) | |
| index_path = os.path.join(template_folder, "index.html") | |
| except Exception as e: | |
| print(f" Error listing template files: {e}") | |
| else: | |
| # 嘗試其他可能的路徑 | |
| alternative_paths = [ | |
| os.path.join(base_dir, "templates"), | |
| "app/templates", | |
| "templates" | |
| ] | |
| for alt_path in alternative_paths: | |
| if os.path.exists(alt_path): | |
| template_folder = alt_path | |
| print(f"Found alternative template folder: {alt_path}") | |
| break | |
| if os.path.exists(static_folder): | |
| try: | |
| static_files = os.listdir(static_folder) | |
| except Exception as e: | |
| print(f" Error listing static files: {e}") | |
| else: | |
| # 嘗試其他可能的路徑 | |
| alternative_static_paths = [ | |
| os.path.join(base_dir, "static"), | |
| "app/static", | |
| "static" | |
| ] | |
| for alt_path in alternative_static_paths: | |
| if os.path.exists(alt_path): | |
| static_folder = alt_path | |
| print(f"Found alternative static folder: {alt_path}") | |
| break | |
| try: | |
| # 創建 Flask app | |
| app = Flask( | |
| __name__, | |
| template_folder=template_folder, | |
| static_folder=static_folder, | |
| static_url_path='/static' | |
| ) | |
| except Exception as e: | |
| print(f"Error creating Flask app: {e}") | |
| raise | |
| try: | |
| CORS(app) | |
| except Exception as e: | |
| print(f"Error configuring CORS: {e}") | |
| from app.utils.data_loader import generate_color_shape_dicts | |
| import pandas as pd | |
| # 數據載入 | |
| try: | |
| df = pd.read_excel("data/TESTData.xlsx") | |
| data_status = f"Data loaded: {len(df)} rows" | |
| app.df = df | |
| # 動態生成分類字典 | |
| color_dict, shape_dict, invalid_colors = generate_color_shape_dicts(df) | |
| app.color_dict = color_dict | |
| app.shape_dict = shape_dict | |
| # === Color statistics (per designed buckets) === | |
| COLOR_BUCKETS = ["白色","黃色","黑色","棕色","紅色","透明","皮膚色","橘色","綠色","藍色","紫色","粉紅色","灰色"] | |
| # Count UNIQUE drugs mapped to each color (e.g., unique '用量排序' ids). | |
| color_counts = {c: 0 for c in COLOR_BUCKETS} | |
| try: | |
| for c in COLOR_BUCKETS: | |
| vals = color_dict.get(c, []) | |
| # Use a set to avoid double-counting the same drug if it appears multiple times | |
| color_counts[c] = len(set(vals)) if hasattr(vals, "__iter__") else int(vals) | |
| # expose on app for other routes / debug | |
| app.color_counts = color_counts | |
| # Console summary (always includes zeros) | |
| summary = " | ".join(f"{c}:{int(color_counts[c])}" for c in COLOR_BUCKETS) | |
| print("顏色→藥物數量統計(Excel/字典基準)", summary) | |
| except Exception as e: | |
| print(f"Color counting failed: {e}") | |
| app.color_counts = {c: 0 for c in COLOR_BUCKETS} | |
| except Exception as e: | |
| print(f"✗ Error loading data: {e}") | |
| data_status = f"Data load failed: {str(e)}" | |
| app.df = None | |
| # 註冊路由 | |
| from app.route import register_routes | |
| register_routes(app, data_status) | |
| # 預熱模型(使用「lazy 單例」的 getter,不會重複載) | |
| from app.utils.pill_detection import get_det_model, get_ocr_engine | |
| try: | |
| get_det_model() | |
| get_ocr_engine() | |
| print("Warmed up YOLO & OpenOCR") | |
| except Exception as e: | |
| print(f" Warmup failed: {e}") | |
| return app | |