Skip to content

Eager gateway_host import in praisonai/integration/__init__.py drags the bot gateway stack into every UI/dashboard startup #5392

Description

@MervinPraison

Summary

The praisonai.integration package __init__ eagerly imports both host_app and gateway_host at module load. Because importing any praisonai.integration.* submodule first executes this __init__, every consumer that only wants host_app also force-loads the gateway_host shim — and, through it, the whole praisonai_bot.integration.gateway_host stack. This is structural import bloat, not a feature; the fix is a lazy re-export that keeps the public import surface byte-for-byte identical.

Current behaviour

src/praisonai/praisonai/integration/__init__.py:3-10:

from .host_app import (
    build_host_app, configure_host, create_host_app, is_legacy_host, setup_bridges,
)
from .gateway_host import run_integrated_gateway   # line 10 — eager

gateway_host.py is a compat shim that calls ensure_praisonai_bot() and then import praisonai_bot.integration.gateway_host at import time (integration/gateway_host.py:6-9).

The UI/dashboard/bot presets import host_app at module top level, which triggers the __init__ above and therefore the eager gateway_host load:

  • ui_bot/default_app.py:10 — from praisonai.integration.host_app import UIPreset, build_ui_app
  • ui_chat/default_app.py:14 — same
  • (also reachable from ui_dashboard/ui_agents host-app usage)

Measured with python -X importtime -c "import praisonai.integration": importing praisonai.integration.gateway_host / praisonai_bot.integration.gateway_host costs ~24 ms of the ~58 ms total, and it is pulled in even when the launched path never serves an integrated gateway.

Why it matters

Import cost / startup latency on the UI, dashboard and bot launch paths: ~24 ms of gateway-stack import is paid unconditionally to satisfy a symbol (run_integrated_gateway) those paths do not use. It is also inconsistent with the wrapper's own established pattern — praisonai/__init__.py:152-160 already lazy-loads build_host_app, configure_host and run_integrated_gateway via __getattr__, so only the sub-package __init__ is out of step.

Category

Import bloat

Capability preserved

  • from praisonai.integration import run_integrated_gateway continues to work unchanged.
  • from praisonai.integration import build_host_app, configure_host, create_host_app, is_legacy_host, setup_bridges unchanged.
  • from praisonai.integration.gateway_host import run_integrated_gateway (direct submodule import) unchanged.
  • No change to gateway/bot behaviour, reliability, session handling, rate limits or approval flows — the praisonai_bot implementation is untouched; it is simply loaded on first use of the gateway symbol instead of at package import.

Proposed approach

Defer the gateway_host import behind a module-level __getattr__ in integration/__init__.py, mirroring the lazy hook already used in praisonai/__init__.py. host_app can stay eager (it is what the UI presets actually need) or be made lazy too for symmetry.

Resolution sketch

# Before (integration/__init__.py)
from .host_app import (
    build_host_app, configure_host, create_host_app, is_legacy_host, setup_bridges,
)
from .gateway_host import run_integrated_gateway

__all__ = [
    "build_host_app", "configure_host", "create_host_app",
    "is_legacy_host", "setup_bridges", "run_integrated_gateway",
]

# After (same public surface; gateway stack loaded only on first use)
from .host_app import (
    build_host_app, configure_host, create_host_app, is_legacy_host, setup_bridges,
)

__all__ = [
    "build_host_app", "configure_host", "create_host_app",
    "is_legacy_host", "setup_bridges", "run_integrated_gateway",
]

def __getattr__(name):
    if name == "run_integrated_gateway":
        from .gateway_host import run_integrated_gateway
        return run_integrated_gateway
    raise AttributeError(f"module {__name__!r} has no attribute {name!r}")

Layer placement

  • Primary layer: wrapper (praisonai/integration/)
  • Touches core/tools/plugins: none — praisonai_bot implementation unchanged; only the wrapper re-export becomes lazy.
  • 3-way surface (CLI + YAML + Python): preserved — Python import paths are identical; no CLI/YAML surface involved.

Severity

Low — a real, measurable (~24 ms) eager-import on UI/dashboard/bot startup with a trivial, fully backward-compatible fix. Not on the main praisonai / praisonai.cli CLI dispatch hot path (that path is already clean).

Validation

  • praisonai/__init__.py, praisonai.cli and __main__ dispatch traced clean — no gateway/bot import on the core CLI hot path; this is scoped to UI/dashboard/bot startup only.
  • Eager load reproduced: import praisonai.integration.host_app leaves praisonai_bot.integration.gateway_host present in sys.modules.
  • Not intentional robustness: the shims carry no import-time registration side effect beyond aliasing to praisonai_bot; the eager line exists only to populate __all__, which __getattr__ covers identically.

Keep unchanged

  • All praisonai_bot gateway/bot reliability logic (sessions, rate limits, reconnection, approval flows).
  • The compat shims themselves (host_app.py, gateway_host.py) and their sys.modules aliasing — intentional package-extraction surface.
  • The five ui_*/default_app.py presets and the praisonai ui* commands.
  • The already-lazy run_integrated_gateway / build_host_app hooks in praisonai/__init__.py.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    claudeAuto-trigger Claude analysis

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions