From f738ca8c525f965d4e8e48a35c20d4f5ced01c00 Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Fri, 13 Mar 2026 09:46:52 +0100 Subject: [PATCH] fix: make compliance router imports resilient to individual module failures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced bare imports with safe_import_router pattern — if one sub-router fails to import (e.g. missing dependency), other routers still load. Co-Authored-By: Claude Opus 4.6 --- backend-compliance/compliance/api/__init__.py | 165 +++++++----------- 1 file changed, 61 insertions(+), 104 deletions(-) diff --git a/backend-compliance/compliance/api/__init__.py b/backend-compliance/compliance/api/__init__.py index 98fb9b0..0ba0f4b 100644 --- a/backend-compliance/compliance/api/__init__.py +++ b/backend-compliance/compliance/api/__init__.py @@ -1,110 +1,67 @@ """API routes for Compliance module.""" +import logging + from .routes import router -from .audit_routes import router as audit_router -from .ai_routes import router as ai_router -from .evidence_routes import router as evidence_router -from .risk_routes import router as risk_router -from .dashboard_routes import router as dashboard_router -from .scraper_routes import router as scraper_router -from .module_routes import router as module_router -from .isms_routes import router as isms_router -from .vvt_routes import router as vvt_router -from .legal_document_routes import router as legal_document_router -from .einwilligungen_routes import router as einwilligungen_router -from .escalation_routes import router as escalation_router -from .consent_template_routes import router as consent_template_router -from .notfallplan_routes import router as notfallplan_router -from .obligation_routes import router as obligation_router -from .security_backlog_routes import router as security_backlog_router -from .quality_routes import router as quality_router -from .loeschfristen_routes import router as loeschfristen_router -from .legal_template_routes import router as legal_template_router -from .compliance_scope_routes import router as compliance_scope_router -from .dsfa_routes import router as dsfa_router -from .dsr_routes import router as dsr_router -from .email_template_routes import router as email_template_router -from .banner_routes import router as banner_router -from .extraction_routes import router as extraction_router -from .tom_routes import router as tom_router -from .vendor_compliance_routes import router as vendor_compliance_router -from .incident_routes import router as incident_router -from .change_request_routes import router as change_request_router -from .generation_routes import router as generation_router -from .project_routes import router as project_router -from .wiki_routes import router as wiki_router -from .canonical_control_routes import router as canonical_control_router -from .control_generator_routes import router as control_generator_router -# Include sub-routers -router.include_router(audit_router) -router.include_router(ai_router) -router.include_router(evidence_router) -router.include_router(risk_router) -router.include_router(dashboard_router) -router.include_router(scraper_router) -router.include_router(module_router) -router.include_router(isms_router) -router.include_router(vvt_router) -router.include_router(legal_document_router) -router.include_router(einwilligungen_router) -router.include_router(escalation_router) -router.include_router(consent_template_router) -router.include_router(notfallplan_router) -router.include_router(obligation_router) -router.include_router(security_backlog_router) -router.include_router(quality_router) -router.include_router(loeschfristen_router) -router.include_router(legal_template_router) -router.include_router(compliance_scope_router) -router.include_router(dsfa_router) -router.include_router(dsr_router) -router.include_router(email_template_router) -router.include_router(banner_router) -router.include_router(extraction_router) -router.include_router(tom_router) -router.include_router(vendor_compliance_router) -router.include_router(incident_router) -router.include_router(change_request_router) -router.include_router(generation_router) -router.include_router(project_router) -router.include_router(wiki_router) -router.include_router(canonical_control_router) -router.include_router(control_generator_router) +logger = logging.getLogger(__name__) -__all__ = [ - "router", - "audit_router", - "ai_router", - "evidence_router", - "risk_router", - "dashboard_router", - "scraper_router", - "module_router", - "isms_router", - "vvt_router", - "legal_document_router", - "einwilligungen_router", - "escalation_router", - "consent_template_router", - "notfallplan_router", - "obligation_router", - "security_backlog_router", - "quality_router", - "loeschfristen_router", - "legal_template_router", - "compliance_scope_router", - "dsfa_router", - "dsr_router", - "email_template_router", - "banner_router", - "tom_router", - "vendor_compliance_router", - "incident_router", - "change_request_router", - "generation_router", - "project_router", - "wiki_router", - "canonical_control_router", - "control_generator_router", + +def _safe_import_router(module_name: str, attr: str = "router"): + """Import a router module safely — log error but don't crash the whole app.""" + try: + mod = __import__(f"compliance.api.{module_name}", fromlist=[attr]) + return getattr(mod, attr) + except Exception as e: + logger.error("Failed to import %s: %s", module_name, e) + return None + + +# Import all sub-routers (safe — failure of one doesn't block others) +_ROUTER_MODULES = [ + "audit_routes", + "ai_routes", + "evidence_routes", + "risk_routes", + "dashboard_routes", + "scraper_routes", + "module_routes", + "isms_routes", + "vvt_routes", + "legal_document_routes", + "einwilligungen_routes", + "escalation_routes", + "consent_template_routes", + "notfallplan_routes", + "obligation_routes", + "security_backlog_routes", + "quality_routes", + "loeschfristen_routes", + "legal_template_routes", + "compliance_scope_routes", + "dsfa_routes", + "dsr_routes", + "email_template_routes", + "banner_routes", + "extraction_routes", + "tom_routes", + "vendor_compliance_routes", + "incident_routes", + "change_request_routes", + "generation_routes", + "project_routes", + "wiki_routes", + "canonical_control_routes", + "control_generator_routes", ] + +_loaded_count = 0 +for _mod_name in _ROUTER_MODULES: + _sub_router = _safe_import_router(_mod_name) + if _sub_router is not None: + router.include_router(_sub_router) + _loaded_count += 1 + +logger.info("Loaded %d/%d compliance sub-routers", _loaded_count, len(_ROUTER_MODULES)) + +__all__ = ["router"]