scripts.validate_env
Reference › scripts › validate_env
scripts/validate_env.py is an environment-contract preflight: it fails fast when required infrastructure keys are missing, before any test-infrastructure work starts. A human or a launcher runs it; it has no internal imports. See check_env_contract for the static gate on the same contract.
validate_required returns the names of required keys that are absent from the environment, missing_optional returns the optional ones, and _report prints the findings. _resolve_env reads the real process environment unless a mapping is passed, which the tests use. The only option is --quiet, which suppresses the report. The exit code is 1 when any required key is missing and 0 otherwise.
At a glance
| Source | scripts/validate_env.py |
| Lines of code | 143 |
| Classes | 0 |
| Functions | 5 |
| Imports (internal) | none |
| Imported by | none |
| Tests that import it | none |
Class diagram
No classes; see Functions.
Dependency diagram
No internal imports and no importers.
API
Constants
| Name | Type | Value |
|---|---|---|
REQUIRED_KEYS |
tuple[str, ...] |
('REDIS_HOST', 'REDIS_PORT', 'KG_ROUTING_URI', 'KG_DATABASE', 'MEMGRAPH_URI', '… |
OPTIONAL_KEYS |
tuple[str, ...] |
('REDIS_DB', 'KG_URI', 'KG_ENGINE', 'KG_WORKER_COUNT', 'MEMGRAPH_URIS', 'MEMGRA… |
Functions
| Function | Signature | Summary |
|---|---|---|
_resolve_env |
_resolve_env(env: Mapping[str, str] | None) -> Mapping[str, str] |
|
validate_required |
validate_required(env: Mapping[str, str] | None = None) -> list[str] |
Return the REQUIRED keys that are missing or empty in env. |
missing_optional |
missing_optional(env: Mapping[str, str] | None = None) -> list[str] |
Return the OPTIONAL keys that are missing or empty in env (report-only). |
_report |
_report(env: Mapping[str, str] | None, *, quiet: bool) -> list[str] |
|
main |
main(argv: list[str] | None = None, *, env: Mapping[str, str] | None = None) -> int |
CLI entry point. |
Source
Permalink: https://gitlab.com/MSamy/orchestrata-ultimate-architecture/-/blob/a4cbc2bdf/scripts/validate_env.py
#!/usr/bin/env python3
"""Environment-contract preflight — fail fast on missing REQUIRED infra keys.
Part of the reproducibility plan Phase R2 (plans/reproducibility-plan.md):
`.env.example` documents every key the code reads; this script gates on the
subset that blocks test-infra work if unset (Redis/graph(orchgraph)/Memgraph/
CXP/KG connection keys). Everything else (tuning knobs, API keys) is OPTIONAL and
only produces a warning. Values are read at CALL TIME via an injectable
``env`` mapping (defaults to ``os.environ``) — no bare ``os.environ["X"]``,
no monkeypatch.
Usage:
python scripts/validate_env.py # print report, exit 0/1
python scripts/validate_env.py --quiet # exit code only, no report
"""
from __future__ import annotations
import argparse
import os
import sys
from collections.abc import Mapping
# REQUIRED: infra-connection keys with no safe default that would silently
# leave the suite pointed at nothing (or localhost, which has no service on
# this fleet). Kept in sync with .env.example's REQUIRED section.
REQUIRED_KEYS: tuple[str, ...] = (
"REDIS_HOST",
"REDIS_PORT",
# KG_ROUTING_URI/KG_DATABASE, not NEO4J_*: those keys were retired with
# the Neo4j containers on 2026-07-27 (migration plan Step 5.1).
"KG_ROUTING_URI",
"KG_DATABASE",
"MEMGRAPH_URI",
"CXP_GRPC_PORT",
"KG_GRPC_PORT",
)
# OPTIONAL: tuning knobs + API keys/secrets with safe code-level defaults.
# Documented here (rather than exhaustively re-listing .env.example) so the
# report can name what it checked; missing/empty entries only warn.
#
# KG_ENGINE/KG_URI/KG_WORKER_COUNT are the rest of the operational-KG seam
# (KG_ROUTING_URI/KG_DATABASE are REQUIRED above, not repeated here — a key
# is gated by exactly one of the two lists, never both).
OPTIONAL_KEYS: tuple[str, ...] = (
"REDIS_DB",
"KG_URI",
"KG_ENGINE",
"KG_WORKER_COUNT",
"MEMGRAPH_URIS",
"MEMGRAPH_USERNAME",
"MEMGRAPH_PASSWORD",
"MEMGRAPH_HA_CONTROLLER_URL",
"MEMGRAPH_CHUNK_LABEL",
"MEMGRAPH_CODESTRAL_CHUNK_LABEL",
"MEMGRAPH_VECTOR_INDEX_NAME",
"CXP_GRPC_HOST",
"CXP_GRPC_ENDPOINT",
"CXP_WS_URI",
"GATEWAY_HOST",
"GATEWAY_PORT",
"GATEWAY_HTTP_PORT",
"GATEWAY_ADMIN_TOKEN",
"JWT_SECRET",
"DEEPSEEK_API_KEY",
"OPENROUTER_API_KEY",
"ANTHROPIC_API_KEY",
"OPENAI_API_KEY",
"GITLAB_TOKEN",
"LOG_LEVEL",
"PROLOG_STACK_LIMIT",
"ORCHESTRATA_WORKSPACE",
)
def _resolve_env(env: Mapping[str, str] | None) -> Mapping[str, str]:
return os.environ if env is None else env
def validate_required(env: Mapping[str, str] | None = None) -> list[str]:
"""Return the REQUIRED keys that are missing or empty in *env*.
An empty string counts as missing (a key set to ``""`` is just as
useless to a connection string as an unset key). Order follows
:data:`REQUIRED_KEYS`.
"""
resolved = _resolve_env(env)
return [key for key in REQUIRED_KEYS if not resolved.get(key, "").strip()]
def missing_optional(env: Mapping[str, str] | None = None) -> list[str]:
"""Return the OPTIONAL keys that are missing or empty in *env* (report-only)."""
resolved = _resolve_env(env)
return [key for key in OPTIONAL_KEYS if not resolved.get(key, "").strip()]
def _report(env: Mapping[str, str] | None, *, quiet: bool) -> list[str]:
missing_required = validate_required(env)
if quiet:
return missing_required
print("=== Environment contract preflight (scripts/validate_env.py) ===")
if missing_required:
print(f"FAIL: {len(missing_required)} REQUIRED key(s) missing/empty:")
for key in missing_required:
print(f" - {key}")
else:
print(f"OK: all {len(REQUIRED_KEYS)} REQUIRED keys present.")
optional_gaps = missing_optional(env)
if optional_gaps:
print(
f"WARN: {len(optional_gaps)} OPTIONAL key(s) unset (using code defaults):"
)
for key in optional_gaps:
print(f" - {key}")
print("See .env.example for the full documented key list.")
return missing_required
def main(argv: list[str] | None = None, *, env: Mapping[str, str] | None = None) -> int:
"""CLI entry point.
``env`` defaults to ``os.environ`` (real process environment) and is
exposed only so tests can exercise the exit-code contract without
mutating the real environment.
"""
parser = argparse.ArgumentParser(
description="Preflight-check REQUIRED environment keys before test infra work."
)
parser.add_argument(
"--quiet", action="store_true", help="Suppress the report; exit code only."
)
args = parser.parse_args(argv)
missing_required = _report(env, quiet=args.quiet)
return 1 if missing_required else 0
if __name__ == "__main__":
sys.exit(main())