feat: enterprise readiness + telemetry exports (#14663)
* feat: enterprise readiness + telemetry exports - health_check_router: add /healthz endpoint + _enterprise_readiness_checks registry (empty = no behaviour change); enterprise plugins append an async check callable; any \"error:\" result returns HTTP 503 so the pod goes Unready - telemetry/run_event_store: docstring marks pop_all() and append_run_event() as stable extension points with deprecation-cycle requirement - telemetry/__init__: re-exports both functions at the stable package path (from langflow.services.telemetry import pop_all, append_run_event) Enterprise bridge should update its import to use the stable path once this merges. * fix: dont swallow telemetry hook exceptions Replace contextlib.suppress(Exception) with try/except + logger.awarning in both the sync and streaming finally blocks of workflow_execution.py. Silent suppression prevented enterprise metering (append_run_event) from being reached when get_telemetry_service() or RunPayload() raised before the call — queue depth stayed 0 with no log evidence. Both paths now log a WARNING with full stack trace on failure while still protecting the user workflow from a broken telemetry hook. Also removes the stale `import contextlib as _cl` inside the sync finally block (module-level import already present). Fixes: enterprise metering queue not populated after /api/v2/workflows runs * fix: enforce run_event_store public API contract Add signature and import-path assertions to test_telemetry_reexports so that any rename, removal, or arity change in the two stable extension points (pop_all, append_run_event) breaks CI before enterprise consumers are silently broken: - test_pop_all_takes_no_parameters: fails if a required param is added - test_append_run_event_accepts_single_payload_param: fails if 'payload' is renamed or the required param list changes - test_stable_import_path_resolves: fails if either symbol is dropped from langflow.services.telemetry.__all__ or becomes non-callable * test: add coverage for timeout, chat failure add coverage for timeout, chat failure * test: tighten tests and fix timeout tighten signature contracts and fix timeout test for enterprise readiness checks * fix: remove health_check_router re-export The APIRouter instance shadowed the submodule name, causing unittest.mock.patch to resolve 'langflow.api.health_check_router.get_chat_service' against the router object instead of the module, breaking test_enterprise_readiness_checks. main.py now imports health_check_router directly from the submodule. * fix: catch asyncio.TimeoutError On Python <=3.10 asyncio.wait_for raises asyncio.TimeoutError which does not inherit from the built-in TimeoutError, so the except clause missed it and the broad except Exception swallowed it silently — no 503 was raised. Catching both types covers all supported Python versions (3.10-3.14). * fix: relax roundtrip assertion to semantic equality Replace `drained[0] is payload` with `drained[0].model_dump() == payload.model_dump()` in test_append_then_pop_roundtrip. Preserves the append/pop payload contract while allowing implementations that copy or serialize the payload. * chore: remove unneeded comment remove unneeded comment * chore: fix DRY, magic string, log exposure - Extract DB + chat probe block into _probe_services(session) helper; health_check() and healthz() now delegate to it (fixes DRY violation) - Add _HEALTH_CHECK_PROBE_KEY module constant; remove duplicate UUID literal "da93c2bd-c857-4b10-8c8c-60988103320f" (fixes magic string) - Drop `result` from enterprise readiness error warning to prevent tenant/license detail leakage in logs (fixes log exposure) - Simplify triple-nested getattr to getattr(__qualname__, type.__name__) - Add comment on (TimeoutError, asyncio.TimeoutError) tuple explaining Python 3.10 compatibility rationale
A
Adam-Aghili committed
eb08ae2e3204dbcd09007aa18f41b7633883c47f
Parent: 97ced62
Committed by GitHub <noreply@github.com>
on 8/21/2026, 4:04:37 AM