mud_server.admin_gradio.app =========================== .. py:module:: mud_server.admin_gradio.app .. autoapi-nested-parse:: Gradio-based web client for the MUD server. This is the main entry point for the MUD client interface. It creates a multi-tab Gradio interface by composing individual tab modules. The application has been refactored into a modular structure: - api_client.py: All backend API communication - utils.py: Shared utility functions - static/styles.css: Centralized CSS styling - tabs/: Individual tab modules (login, game, settings, etc.) Interface Structure: Tab 1: Login - User authentication Tab 2: Register - New account creation Tab 3: Game - Main gameplay interface with auto-refresh Tab 4: Settings - Password change and server control (admin only) Tab 5: Database - Admin database viewer (admin/superuser only) Tab 6: Ollama - Ollama server management and AI model control (admin/superuser only) Tab 7: Help - Game instructions and command reference Key Features: - Per-user session state using gr.State (prevents cross-user contamination) - Auto-refresh timer (3 seconds) for real-time game updates - Role-based UI elements (admin features hidden for regular players) - Chat system with support for say, yell, and whisper commands - Modular architecture for easy maintenance and extensibility State Management: Each user has their own gr.State dictionary containing: - session_id: UUID from successful login - username: Player's username - role: User role (player, worldbuilder, admin, superuser) - logged_in: Boolean login status API Communication: All game operations communicate with the FastAPI backend via HTTP requests through the api_client module. Port Configuration: --ui-port CLI argument: Specify exact port (no auto-discovery) MUD_UI_PORT env var: Specify preferred port (will auto-discover if in use) Default: 7860 (will auto-discover if in use) Attributes ---------- .. autoapisummary:: mud_server.admin_gradio.app.DEFAULT_UI_PORT mud_server.admin_gradio.app.UI_PORT_RANGE_START mud_server.admin_gradio.app.UI_PORT_RANGE_END Functions --------- .. autoapisummary:: mud_server.admin_gradio.app.login mud_server.admin_gradio.app.logout mud_server.admin_gradio.app.create_interface mud_server.admin_gradio.app.is_port_available mud_server.admin_gradio.app.find_available_port mud_server.admin_gradio.app.launch_client Module Contents --------------- .. py:function:: login(username, password, session_state) Handle user login with password authentication. Sends credentials to backend via AuthAPIClient, stores session data on success, and returns updated UI state for tab visibility and user info display. This function wraps the new AuthAPIClient.login() method and uses UI state builders to maintain compatibility with the Gradio interface. Migration Notes: - Migrated from old api_client.py to new modular structure - Uses AuthAPIClient for authentication - Uses state builders (build_logged_in_state, build_login_failed_state) - Updates session_state using update_session_state helper - Returns tuple matching Gradio output expectations :param username: Username to login with :param password: Plain text password :param session_state: User's session state dictionary :returns: Tuple of (session_state, login_result, clear_username, clear_password, login_tab, register_tab, game_tab, settings_tab, db_tab, ollama_tab, help_tab) .. admonition:: Examples >>> session = {} >>> result = login("alice", "password123", session) >>> isinstance(result, tuple) and len(result) == 11 True .. py:function:: logout(session_state) Handle user logout and clean up session state. Sends logout request to backend via AuthAPIClient, clears session data, and returns updated UI state to hide game tabs and show login tabs. This function wraps the new AuthAPIClient.logout() method and uses UI state builders to maintain compatibility with the Gradio interface. Migration Notes: - Migrated from old api_client.py to new modular structure - Uses AuthAPIClient for logout - Uses clear_session_state helper to reset session - Uses build_logged_out_state (via manual construction) for UI updates - Returns tuple matching Gradio output expectations :param session_state: User's session state dictionary :returns: Tuple of (session_state, message, blank, login_tab, register_tab, game_tab, settings_tab, db_tab, ollama_tab, help_tab) .. admonition:: Examples >>> session = {"session_id": "abc123", "logged_in": True} >>> result = logout(session) >>> isinstance(result, tuple) and len(result) == 10 True .. py:function:: create_interface() Create and configure the complete Gradio web interface. Builds the entire multi-tab UI by composing individual tab modules. Each tab module is responsible for its own layout, components, and event handlers. This function handles only top-level integration and tab visibility control based on authentication state. :returns: Configured Gradio interface ready to launch :rtype: gr.Blocks .. py:data:: DEFAULT_UI_PORT :value: 7860 .. py:data:: UI_PORT_RANGE_START :value: 7860 .. py:data:: UI_PORT_RANGE_END :value: 7899 .. py:function:: is_port_available(port, host = '0.0.0.0') Check if a TCP port is available for binding on the specified host. This function is identical to the one in server.py but kept separate to maintain module independence. The Gradio UI client should be able to function without depending on the API server module. Technical Details: - Uses a TCP socket (SOCK_STREAM) for the availability check - Socket is automatically closed via context manager - Handles various OSError conditions (EADDRINUSE, EACCES, etc.) :param port: TCP port number to check (1-65535) :param host: Host interface to check. Common values: - "0.0.0.0": All interfaces (default) - "127.0.0.1": Localhost only :returns: True if the port is available for binding, False otherwise .. admonition:: Example >>> is_port_available(7860) True # Port 7860 is free for Gradio .. py:function:: find_available_port(preferred_port = DEFAULT_UI_PORT, host = '0.0.0.0', range_start = UI_PORT_RANGE_START, range_end = UI_PORT_RANGE_END) Find an available TCP port for the Gradio UI, starting with preferred port. Implements sequential port scanning to find an available port: 1. Try the preferred port first (usually 7860) 2. If unavailable, scan 7860-7899 sequentially 3. Return None if no ports available (caller handles error) :param preferred_port: The first port to try. Defaults to 7860 (Gradio default). :param host: Host interface to check availability on. Defaults to "0.0.0.0". :param range_start: First port in scan range (inclusive). Defaults to 7860. :param range_end: Last port in scan range (inclusive). Defaults to 7899. :returns: An available port number within the range None: If no ports are available (all 40 ports in use) :rtype: int .. admonition:: Example >>> find_available_port(7860) 7860 # Normal case - default port available >>> find_available_port(7860) # 7860 in use 7861 # Returns next available port .. py:function:: launch_client(host = None, port = None, auto_discover = True) Launch the Gradio web client with configurable host and port. This is the main entry point for running the Gradio-based web interface. It handles configuration resolution and implements automatic port discovery to avoid "address already in use" errors. Configuration Resolution Order: For both host and port, configuration is resolved in this priority: 1. Explicit function parameter (highest priority) 2. Environment variable (MUD_UI_HOST, MUD_UI_PORT) 3. Default value (0.0.0.0:7860) Auto-Discovery Behavior: When auto_discover=True (default): - If port 7860 is in use, scans 7860-7899 for an available port - Prints a message when using an alternate port - Raises RuntimeError only if ALL ports in range are unavailable When auto_discover=False: - Fails immediately if the specified port is unavailable - Useful when port must match external configuration (proxy, etc.) :param host: Network interface to bind to. Common values: - None: Use MUD_UI_HOST env var, or "0.0.0.0" (all interfaces) - "0.0.0.0": Accept connections from any network interface - "127.0.0.1": Accept only local connections (localhost) :param port: TCP port number for the web UI. Values: - None: Use MUD_UI_PORT env var, or 7860 (Gradio default) - Integer: Use this specific port (subject to auto_discover) :param auto_discover: Enable automatic port discovery. Defaults to True. :raises RuntimeError: When auto_discover=True but no port is available in the 7860-7899 range. :raises OSError: When auto_discover=False and the specified port is in use. .. admonition:: Example # Default configuration launch_client() # Uses 0.0.0.0:7860 with auto-discovery # Custom port for development launch_client(port=8080) # Local development only launch_client(host="127.0.0.1") .. note:: This function blocks until the Gradio server is stopped. The interface is accessible at http://{host}:{port} once started.