hm_ai_qc_report_tool/config.py
nickviljoen a500d7b088 Six tooling fixes from Dev test pass
Video QC:
* _extract_locale_from_filename now also handles the suffix form
  ..._XX-yy.ext (case-insensitive both sides), so DOOH/OOH-style
  adapt filenames like ..._ES-es.mp4 unblock the price_currency
  check instead of skipping with "could not extract locale".
* Batch results page expires the SQLAlchemy session at the top of
  the route so the post-completion reload sees committed reports
  even when it lands on a different gunicorn worker than the one
  that wrote them. Reload delay bumped 1s → 2s for margin.
* visual_quality prompt now passes the filename's market+language
  to the LLM and tells it the on-screen copy should be in the
  localized language, not the source-language guideline copy.
  Stops Spanish-market videos being flagged as "language mismatch
  with English campaign guidelines".

Printer Check:
* regions.json rewritten to cover all 10 H&M regions (AME, CEU,
  NEU, GCN, IND, SHE, SEU, EEU, EAS, Franchise) with default-all
  groups. Two judgement calls vs the screenshot: kept TR for
  Turkey (TK is Tokelau in ISO and would break filename matching)
  and BR for Brazil (every other code is 2-letter ISO).

Campaign codes:
* New core/utils/campaign_code.py is the single source of truth.
  Matches both the legacy 4-digits-plus-optional-letter (1013A,
  4116) and the new 11-char alphanumeric with year at positions
  5-6 (CFUL263C01D). All four prior parser sites now import from
  this helper.

Video Master:
* BOX_CAMPAIGNS_FOLDER_ID switched 156182880490 → 133295752718
  (same root the Reporting tool uses). Updated config.py default
  and all three .env example files.
* Match page now shows which Box folder the search runs against
  (with a clickable link), and on a not-found error explains what
  was searched for so missing-campaign cases are self-diagnosable.
2026-05-09 18:32:23 +02:00

76 lines
2.8 KiB
Python

"""Application configuration."""
import os
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
class Config:
"""Base configuration."""
# Flask
SECRET_KEY = os.environ.get('SECRET_KEY', 'dev-secret-key-change-in-production')
# Authentication (simple username:password_hash pairs, comma-separated)
AUTH_USERS = os.environ.get('AUTH_USERS', '')
# Box
BOX_CONFIG_PATH = os.environ.get('BOX_CONFIG_PATH', 'config/box_config.json')
BOX_REPORT_FOLDER_ID = os.environ.get('BOX_REPORT_FOLDER_ID', '133295752718')
# Same Box folder as REPORT — the Reporting and Video Master tools both
# search inside this root for campaign-named subfolders.
BOX_CAMPAIGNS_FOLDER_ID = os.environ.get('BOX_CAMPAIGNS_FOLDER_ID', '133295752718')
# Server
HOST = os.environ.get('HOST', '0.0.0.0')
PORT = int(os.environ.get('PORT', 5000))
# Database
# Use absolute path for SQLite database
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
SQLALCHEMY_DATABASE_URI = os.environ.get(
'DATABASE_URI',
f'sqlite:///{os.path.join(BASE_DIR, "database", "qc_platform.db")}'
)
SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_ECHO = os.environ.get('FLASK_ENV') == 'development'
# Session Configuration
SESSION_COOKIE_SECURE = os.environ.get('FLASK_ENV') == 'production'
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = 'Lax'
SESSION_COOKIE_PATH = os.environ.get('SESSION_COOKIE_PATH', '/')
# File Upload Configuration
MAX_CONTENT_LENGTH = 500 * 1024 * 1024 # 500 MB max file size
UPLOAD_FOLDER = 'uploads'
STORAGE_FOLDER = 'storage'
# Module-specific paths
HM_QC_UPLOAD_PATH = 'uploads/hm_qc'
VIDEO_QC_UPLOAD_PATH = 'uploads/video_qc'
VIDEO_MASTER_UPLOAD_PATH = 'uploads/video_master'
HM_QC_STORAGE_PATH = 'storage/reports/hm_qc'
CONSOLIDATED_STORAGE_PATH = 'storage/reports/consolidated'
# Campaign presentation storage
CAMPAIGN_STORAGE_PATH = 'storage/campaigns'
# Pricing reference storage (per-row, selectable at configure time)
PRICING_REF_STORAGE_PATH = 'storage/pricing_references'
# Legacy global pricing (auto-imported into PricingReference on first run)
GLOBAL_PRICING_PDF_PATH = 'storage/reference/global_pricing.pdf'
GLOBAL_PRICING_JSON_PATH = 'storage/reference/global_pricing.json'
# LLM Configuration
OPENAI_API_KEY = os.environ.get('OPENAI_API_KEY')
ANTHROPIC_API_KEY = os.environ.get('ANTHROPIC_API_KEY')
AZURE_OPENAI_API_KEY = os.environ.get('AZURE_OPENAI_API_KEY')
AZURE_OPENAI_ENDPOINT = os.environ.get('AZURE_OPENAI_ENDPOINT')
GOOGLE_API_KEY = os.environ.get('GOOGLE_API_KEY')
# Application
MAX_REPORTS_PER_JOB = 100 # Limit reports fetched per job number
CACHE_TIMEOUT = 300 # 5 minutes cache for Box searches