verifile-x-api / scripts /production_check.py
abinazebinoy's picture
feat(ops): add production readiness checklist script
aad2686
Raw
History Blame Contribute Delete
3.09 kB
"""
Production Readiness Checklist for VeriFile-X.
Usage:
python scripts/production_check.py
python scripts/production_check.py --strict
"""
import sys, json, logging, argparse, importlib
from pathlib import Path
logging.basicConfig(level=logging.INFO, format="%(levelname)-8s %(message)s")
logger = logging.getLogger(__name__)
ROOT = Path(__file__).parents[1]
PASSED, WARNED, FAILED = [], [], []
def check(name, cond, msg, warn=False):
if cond:
logger.info("PASS %s", name); PASSED.append(name)
elif warn:
logger.warning("WARN %s β€” %s", name, msg); WARNED.append((name, msg))
else:
logger.error("FAIL %s β€” %s", name, msg); FAILED.append((name, msg))
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--strict", action="store_true")
args = parser.parse_args()
logger.info("VeriFile-X Production Readiness Check\n" + "=" * 50)
logger.info("\n--- Reference Files ---")
for fname, script in [
("data/reference/clip_database.pkl", "scripts/build_clip_database.py"),
("data/reference/ensemble_xgb.pkl", "scripts/train_ensemble.py"),
("data/reference/own_embedding_model.pt", "scripts/train_embedding.py"),
("data/reference/own_centroids.pkl", "scripts/build_centroids.py"),
]:
p = ROOT / fname
check(fname, p.exists() and p.stat().st_size > 100, f"Run {script}", warn=True)
logger.info("\n--- Ensemble Sanity ---")
rf = ROOT / "data" / "reference" / "ensemble_results.json"
if rf.exists():
r = json.loads(rf.read_text())
check("cv_auc_not_perfect", r.get("cv_auc_mean", 0) < 0.99,
f"CV AUC={r.get('cv_auc_mean',0):.4f} β€” likely data leakage")
check("test_auc_present", "test_auc" in r, "Re-run train_ensemble.py", warn=True)
else:
check("ensemble_results.json", False, "Not found", warn=True)
logger.info("\n--- Imports ---")
sys.path.insert(0, str(ROOT))
for svc in ["backend.main", "backend.core.config",
"backend.services.image_forensics",
"backend.utils.image_quality"]:
try: importlib.import_module(svc); check(svc, True, "")
except Exception as e: check(svc, False, str(e))
logger.info("\n--- Config ---")
try:
from backend.core.config import settings
check("VERSION_set", settings.VERSION != "0.0.0", "")
check("CORS_set", len(settings.cors_origins_list) >= 1, "No CORS origins")
check("DEBUG_false", not settings.DEBUG, "Set DEBUG=False", warn=True)
except Exception as e:
check("config", False, str(e))
logger.info("\n--- Security ---")
for fname in (".env", "api_keys.jsonl", "cases.jsonl"):
check(f"{fname}_not_committed", not (ROOT / fname).exists(),
f"{fname} should not be in repo", warn=True)
logger.info("\n" + "=" * 50)
logger.info("PASSED: %d | WARNED: %d | FAILED: %d", len(PASSED), len(WARNED), len(FAILED))
if FAILED or (WARNED and args.strict): sys.exit(1)
if __name__ == "__main__":
main()