mud_server.admin_tui.api.client =============================== .. py:module:: mud_server.admin_tui.api.client .. autoapi-nested-parse:: HTTP API client for PipeWorks MUD Server. This module provides an async HTTP client for communicating with the MUD server's REST API. It handles authentication, session management, and all administrative operations. The client is designed to be used as an async context manager to ensure proper resource cleanup: async with AdminAPIClient(config) as client: await client.login("admin", "password") health = await client.get_health() Key Features: - Async HTTP requests using httpx - Automatic session management - Custom exceptions for error handling - Type hints for all public methods Exceptions ---------- .. autoapisummary:: mud_server.admin_tui.api.client.APIError mud_server.admin_tui.api.client.AuthenticationError Classes ------- .. autoapisummary:: mud_server.admin_tui.api.client.SessionState mud_server.admin_tui.api.client.AdminAPIClient Module Contents --------------- .. py:exception:: APIError Bases: :py:obj:`Exception` Exception raised when an API request fails. This exception is raised for any non-2xx response from the server, except for authentication-specific errors which raise AuthenticationError. .. attribute:: message Human-readable error message. .. attribute:: status_code HTTP status code from the response. .. attribute:: detail Additional detail from the server response, if available. .. admonition:: Example try: await client.get_health() except APIError as e: print(f"API error {e.status_code}: {e.message}") Initialize self. See help(type(self)) for accurate signature. .. py:attribute:: message :type: str .. py:attribute:: status_code :type: int :value: 0 .. py:attribute:: detail :type: str :value: '' .. py:exception:: AuthenticationError Bases: :py:obj:`APIError` Exception raised for authentication-related failures. This includes: - Invalid credentials (401) - Permission denied (403) - Session expired - Not authenticated when required .. admonition:: Example try: await client.login("admin", "wrong_password") except AuthenticationError as e: print(f"Login failed: {e.detail}") Initialize self. See help(type(self)) for accurate signature. .. py:class:: SessionState Tracks the current authentication session state. This dataclass maintains information about the current user session, including authentication status and user role. It is updated automatically by the AdminAPIClient during login/logout operations. .. attribute:: session_id The session ID returned by the server after login. None if not authenticated. .. attribute:: username The authenticated username. None if not authenticated. .. attribute:: role The user's role (e.g., "admin", "superuser", "player"). None if not authenticated. Properties: is_authenticated: True if currently logged in with a valid session. is_admin: True if the user has admin or superuser role. is_superuser: True if the user has superuser role. .. admonition:: Example state = SessionState() print(state.is_authenticated) # False state.session_id = "abc123" state.username = "admin" state.role = "admin" print(state.is_authenticated) # True print(state.is_admin) # True .. py:attribute:: session_id :type: str | None :value: None .. py:attribute:: username :type: str | None :value: None .. py:attribute:: role :type: str | None :value: None .. py:property:: is_authenticated :type: bool Check if we have an active session. .. py:property:: is_admin :type: bool Check if the user has admin privileges. .. py:property:: is_superuser :type: bool Check if the user has superuser privileges. .. py:method:: clear() Clear all session state (logout). .. py:class:: AdminAPIClient Async HTTP client for the MUD server admin API. This client handles all communication with the MUD server's REST API. It must be used as an async context manager to properly manage the underlying HTTP connection pool. .. attribute:: config Configuration object with server URL and timeout settings. .. attribute:: session Current authentication session state. .. admonition:: Example config = Config(server_url="http://localhost:8000", timeout=30.0) async with AdminAPIClient(config) as client: # Login await client.login("admin", "password123") # Check server health health = await client.get_health() print(f"Active players: {health['active_players']}") # Get list of players (requires admin) players = await client.get_players() # Logout await client.logout() .. py:attribute:: config :type: mud_server.admin_tui.config.Config .. py:attribute:: session :type: SessionState .. py:property:: http_client :type: httpx.AsyncClient Get the HTTP client, ensuring it's been initialized. :raises RuntimeError: If accessed outside of async context manager. :returns: The underlying httpx.AsyncClient. .. py:method:: login(username, password) :async: Authenticate with the MUD server. Sends credentials to the server and stores the session information on successful authentication. :param username: The username to authenticate with. :param password: The user's password. :returns: The server response containing session_id, role, and message. :rtype: dict :raises AuthenticationError: If credentials are invalid (401). :raises APIError: If the server returns any other error. .. admonition:: Example try: result = await client.login("admin", "password123") print(f"Logged in as {result['role']}") except AuthenticationError: print("Invalid credentials") .. py:method:: logout() :async: End the current session. Notifies the server of logout and clears local session state. The local state is always cleared, even if the server request fails. :returns: True if logout was performed, False if not authenticated. :rtype: bool .. admonition:: Example if await client.logout(): print("Logged out successfully") else: print("Was not logged in") .. py:method:: get_health() :async: Get server health status. This endpoint is public and does not require authentication. :returns: Server health information including: - status: "ok" if healthy - active_players: Number of currently connected players :rtype: dict :raises APIError: If the server returns an error. .. admonition:: Example health = await client.get_health() if health["status"] == "ok": print(f"{health['active_players']} players online") .. py:method:: get_players() :async: Get list of all players in the database. Requires admin privileges. :returns: List of player dictionaries with username, role, etc. :rtype: list :raises AuthenticationError: If not authenticated or lacks permission. :raises APIError: If the server returns an error. .. admonition:: Example players = await client.get_players() for player in players: print(f"{player['username']} ({player['role']})") .. py:method:: get_sessions() :async: Get list of active sessions. Requires admin privileges. :returns: List of session dictionaries with username, created_at, etc. :rtype: list :raises AuthenticationError: If not authenticated or lacks permission. :raises APIError: If the server returns an error. .. admonition:: Example sessions = await client.get_sessions() print(f"{len(sessions)} active sessions") .. py:method:: get_chat_messages(limit = 100) :async: Get recent chat messages from the database. Requires admin privileges. :param limit: Maximum number of messages to return (default 100). :returns: List of chat message dictionaries with username, message, etc. :rtype: list :raises AuthenticationError: If not authenticated or lacks permission. :raises APIError: If the server returns an error. .. admonition:: Example messages = await client.get_chat_messages(limit=50) for msg in messages: print(f"{msg['username']}: {msg['message']}") .. py:method:: get_tables() :async: Get list of database tables with schema metadata. Requires admin privileges. :returns: List of table metadata dictionaries with name, columns, row_count. :rtype: list :raises AuthenticationError: If not authenticated or lacks permission. :raises APIError: If the server returns an error. .. py:method:: get_table_rows(table_name, limit = 100) :async: Get rows and columns for a specific database table. Requires admin privileges. :param table_name: Table name to query. :param limit: Max number of rows to return. :returns: Contains table, columns, and rows. :rtype: dict :raises AuthenticationError: If not authenticated or lacks permission. :raises APIError: If the server returns an error. .. py:method:: get_player_locations() :async: Get player locations with zone context for admin display. Requires admin privileges. :returns: List of player location dictionaries. :rtype: list :raises AuthenticationError: If not authenticated or lacks permission. :raises APIError: If the server returns an error. .. py:method:: get_connections() :async: Get active session connections with activity age. Requires admin privileges. :returns: List of connection dictionaries. :rtype: list :raises AuthenticationError: If not authenticated or lacks permission. :raises APIError: If the server returns an error. .. py:method:: kick_session(target_session_id, reason = None) :async: Force-disconnect a session (admin/superuser only). :param target_session_id: Session id to disconnect. :param reason: Optional reason for the action. :returns: Response payload with success/message. :rtype: dict .. py:method:: manage_user(target_username, action, *, new_role = None, new_password = None) :async: Perform a user management action via the admin API. :param target_username: Username to manage. :param action: Action string (change_role, ban, unban, delete, change_password). :param new_role: Required when action is change_role. :param new_password: Required when action is change_password. :returns: Response payload with success/message. :rtype: dict .. py:method:: create_user(username, password, password_confirm, role) :async: Create a new user account (admin/superuser only). :param username: Username for the new account. :param password: Initial password for the account. :param password_confirm: Confirmation of the password. :param role: Role to assign to the new account. :returns: Response payload with success/message. :rtype: dict :raises AuthenticationError: If the current session lacks permissions. :raises APIError: If validation fails or the server rejects the request.