Spaces:
Sleeping
Sleeping
Commit History
-
fix: pass ruff lint+format, clean README, remove stray script
Priya Monishafa0ce5b -
fix: production audit — security hardening + observability + code quality
Priya MonishaC-1 api/routes/classify.py: add missing logger (was NameError on unknown class) M-1 src/models/base_classifier.py: remove print() — logger.info already covers epoch progress m-1 src/data/dataset.py: assert -> ValueError for invalid split param SEC config.py + redis_cache.py + api/main.py: Redis password support (REDIS_PASSWORD env) SEC docker-compose.yml: conditional Redis auth (no-op when REDIS_PASSWORD empty) SEC docker-compose.airflow.yml: replace hardcoded airflow:airflow/admin:admin with env vars OBS api/prometheus_metrics.py: add http_errors Counter + models_loaded Gauge OBS api/main.py: middleware counts 4xx/5xx; models_loaded.set(1) on successful startup DOC .env.example: document REDIS_PASSWORD, AIRFLOW_DB_PASSWORD, AIRFLOW_ADMIN_PASSWORD6319415 -
section-12: CI + Tests + HuggingFace Deployment
Priya Monisha- pytest suite: 57 tests, 0 failures across health/classify/detect/drift/redis - RedisCache: _client= kwarg (keyword-only) for fakeredis injection in tests - conftest.py: MockClassificationModel (real nn.Module), synthetic confidence baseline, raise_server_exceptions=False, session-scoped test_image_bytes - pytest.ini: pythonpath=., coverage xml+term, strict-markers - .github/workflows/ci.yml: ruff lint+format → pytest, pip cache, coverage artifact - spaces.yaml: streamlit sdk, python_version=3.11, cpu-basic, 5 CV tags - packages.txt: libgl1, libglib2.0-0 for HF Spaces build - requirements.txt: fakeredis>=2.23.0 added to Testing section4d14020
-
section-9: KS drift detection + Prometheus -- DriftDetector, /drift/status, alert rules
Priya Monisha- src/monitoring/drift_detector.py: DriftDetector class Double-gate KS alert (stat > 0.10 AND p < 0.05) -- stat alone has ~95% FP rate at n=30 baseline Rate-limited KS_RUN_EVERY_N=10 -- prevents blocking asyncio event loop at 100 req/s Redis list buffer sv:drift:live:{class} with deque fallback (Rule 23) All 22 Gauge series initialized at startup -- Prometheus has time series from day 1 Redis buffer restoration on restart: reversed(get_list) preserves chronological order _safe_float() guards nan/inf from degenerate KS inputs (zero-variance live data) - api/routes/drift.py: GET /drift/status -- Pydantic DriftStatusResponse model - api/main.py: DriftDetector in lifespan after Redis init; drift router registered - api/routes/classify.py: record(top1, confidence) after inference; unknown_predictions Counter - api/prometheus_metrics.py: unknown_predictions Counter (surfaces invisible model failures) - src/inference/redis_cache.py: push_to_list (LPUSH+LTRIM pipeline) + get_list m…dacce7e -
section-8: FastAPI + Redis -- classify, detect, health, metrics endpoints
Priya Monisha- api/main.py: FastAPI lifespan (Rule 32), get_running_loop (Rule 31), non-blocking load_all_models via run_in_executor, eval_transform built once - api/routes/classify.py: POST /classify -- UploadFile+Form, Redis cache-aside, cached-key-pop fix (prevents TypeError on cache hit), Prometheus labels - api/routes/detect.py: POST /detect -- np.array(PIL) YOLO input, results[0].names, graceful 503 if YOLO unavailable - api/routes/health.py: GET /health -- 503 when loading (Docker healthcheck waits) - api/routes/metrics.py: GET /metrics -- CONTENT_TYPE_LATEST text/plain (Rule 30) - api/prometheus_metrics.py: Counter/Histogram singletons, class_name cardinality guard - api/schemas.py: ClassifyResponse, DetectResponse, HealthResponse Pydantic models - src/inference/model_loader.py: local-first weight resolution, HF Hub fallback with 120s ThreadPoolExecutor timeout, chunked MD5 hash, 3-pass warmup, FAST_MODE support - src/inference/redis_cache.py: socket_connect_timeout=1s (Rule 23), 32…9cb1db0