Source code for pynenc.cli.monitor_cli
import argparse
import importlib.util
import sys
from typing import TYPE_CHECKING
from pynenc.cli.namespace import PynencCLINamespace
if TYPE_CHECKING:
from pynenc.app import AppInfo, Pynenc
[docs]
def add_monitor_subparser(subparsers: argparse._SubParsersAction) -> None:
"""Add the monitor subparser to the main pynenc CLI."""
monitor_parser = subparsers.add_parser(
"monitor", help="Start the web monitoring interface"
)
monitor_parser.add_argument(
"--host",
default="127.0.0.1",
help="Host to bind the server (default: 127.0.0.1)",
)
monitor_parser.add_argument(
"--port", type=int, default=8000, help="Port to bind the server (default: 8000)"
)
monitor_parser.add_argument(
"--log-level",
default=None,
choices=["debug", "info", "warning", "error", "critical"],
help="Log level for pynmon (default: info, or PYNMON_LOG_LEVEL env var)",
)
monitor_parser.set_defaults(func=start_monitor_command)
[docs]
def start_monitor_command(args: PynencCLINamespace) -> None:
"""Execute the monitor command, starting the web interface."""
# Check Python version compatibility
if sys.version_info >= (3, 13):
print("Error: Pynmon monitoring UI requires Python <3.13")
print("Reason: FastAPI/Pydantic v2 dependencies do not support Python 3.13+")
print("Note: Core pynenc functionality supports Python 3.13+")
print("Solution: Use Python 3.11 or 3.12 for monitoring features")
sys.exit(1)
# Check if the monitor dependencies are installed
if not _check_monitor_dependencies():
print(
"Monitor dependencies not installed. Please install with: "
"pip install pynenc[monitor]"
)
sys.exit(1)
# Import the app module only when dependencies are confirmed to exist
try:
from pynmon.app import start_monitor
except ImportError:
print(
"Error: Monitoring features are not available. Please install pynenc with monitoring extras:"
)
print("pip install pynenc[monitor]")
sys.exit(1)
# Start the monitor with the provided app instance
apps: dict[str, AppInfo] = get_all_available_apps(args)
if not apps:
print("Error: No Pynenc app instance available.")
sys.exit(1)
selected_app: Pynenc | None = None
if hasattr(args, "app_instance") and args.app_instance:
selected_app = args.app_instance
print(
f"Starting monitoring for app: {selected_app.app_id if selected_app else 'None'}"
)
start_monitor(
apps=apps,
selected_app=selected_app,
host=args.host,
port=args.port,
log_level=getattr(args, "log_level", None),
)
[docs]
def _check_monitor_dependencies() -> bool:
"""Check if required monitoring dependencies are installed."""
dependencies = ["fastapi", "jinja2", "uvicorn"]
for dep in dependencies:
if importlib.util.find_spec(dep) is None:
return False
return True
[docs]
def get_all_available_apps(args: PynencCLINamespace) -> dict[str, "AppInfo"]:
"""Get all available apps in the current environment."""
if not args.app_instance:
from pynenc.app import Pynenc
return Pynenc().state_backend.discover_app_infos()
return args.app_instance.state_backend.discover_app_infos()