add
This commit is contained in:
104
scripts/validate_setup.py
Normal file
104
scripts/validate_setup.py
Normal file
@@ -0,0 +1,104 @@
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
# Ensure project root is on PYTHONPATH when running from scripts/
|
||||
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
if project_root not in sys.path:
|
||||
sys.path.insert(0, project_root)
|
||||
|
||||
from app_core.config.settings import AppSettings
|
||||
from app_core.db.database import engine
|
||||
from sqlalchemy import text
|
||||
|
||||
|
||||
def check_env(settings: AppSettings) -> list[str]:
|
||||
missing: list[str] = []
|
||||
required = [
|
||||
("DATABASE_URL", settings.database_url or os.getenv("DATABASE_URL")),
|
||||
("SMTP_HOST", settings.smtp_host),
|
||||
("SMTP_PORT", settings.smtp_port),
|
||||
("SMTP_USER", settings.smtp_user),
|
||||
("SMTP_PASSWORD", settings.smtp_password),
|
||||
("SMTP_FROM_EMAIL", settings.smtp_from_email),
|
||||
("REPORT_RECIPIENTS", settings.report_recipients or os.getenv("REPORT_RECIPIENTS")),
|
||||
]
|
||||
for key, val in required:
|
||||
if not val:
|
||||
missing.append(key)
|
||||
return missing
|
||||
|
||||
|
||||
def check_db_connection() -> tuple[bool, str | None]:
|
||||
try:
|
||||
with engine.connect() as conn:
|
||||
# SQLAlchemy 2.0: wrap SQL in text() or use exec_driver_sql
|
||||
conn.execute(text("SELECT 1"))
|
||||
return True, None
|
||||
except Exception as e:
|
||||
return False, str(e)
|
||||
|
||||
|
||||
def check_smtp_login(s: AppSettings) -> tuple[bool, str | None]:
|
||||
import smtplib
|
||||
|
||||
try:
|
||||
server = smtplib.SMTP(s.smtp_host, s.smtp_port, timeout=20)
|
||||
if s.smtp_use_tls:
|
||||
server.starttls()
|
||||
if s.smtp_user and s.smtp_password:
|
||||
server.login(s.smtp_user, s.smtp_password)
|
||||
# Probe NOOP and quit without sending
|
||||
server.noop()
|
||||
server.quit()
|
||||
return True, None
|
||||
except Exception as e:
|
||||
return False, str(e)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
print("=== Workolik Production Validation ===")
|
||||
settings = AppSettings()
|
||||
|
||||
# 1) Environment variables
|
||||
missing = check_env(settings)
|
||||
if missing:
|
||||
print("❌ Missing required env vars:", ", ".join(sorted(set(missing))))
|
||||
else:
|
||||
print("✅ Required env vars present")
|
||||
|
||||
# Optional BCC
|
||||
bcc = os.getenv("BCC_RECIPIENTS", "").strip()
|
||||
if bcc:
|
||||
print(f"✅ BCC_RECIPIENTS set: {bcc}")
|
||||
else:
|
||||
print("ℹ️ BCC_RECIPIENTS not set (no BCC will be added)")
|
||||
|
||||
# 2) Database connectivity
|
||||
ok_db, err_db = check_db_connection()
|
||||
if ok_db:
|
||||
print("✅ Database connectivity OK")
|
||||
else:
|
||||
print(f"❌ Database connectivity FAILED: {err_db}")
|
||||
|
||||
# 3) SMTP connectivity (no email will be sent)
|
||||
ok_smtp, err_smtp = check_smtp_login(settings)
|
||||
if ok_smtp:
|
||||
print("✅ SMTP login OK (no email sent)")
|
||||
else:
|
||||
print(f"❌ SMTP login FAILED: {err_smtp}")
|
||||
|
||||
# 4) Scheduler subject check (ensure dedupe matches)
|
||||
today_str = datetime.now().date().strftime('%Y-%m-%d')
|
||||
expected_subject = f"Daily Digest - {today_str}"
|
||||
print(f"✅ Scheduler dedupe subject pattern: {expected_subject}")
|
||||
|
||||
failures = (1 if missing else 0) + (0 if ok_db else 1) + (0 if ok_smtp else 1)
|
||||
print("=== Validation Complete ===")
|
||||
return 0 if failures == 0 else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
||||
|
||||
Reference in New Issue
Block a user