Skip to content

app

Tux application entrypoint and lifecycle management.

This module provides the orchestration necessary to run the Tux Discord bot, including command prefix resolution, signal handling, configuration validation, and structured startup/shutdown flows with Sentry integration.

Classes:

  • TuxApp

    Application wrapper for managing Tux bot lifecycle.

Functions:

  • get_prefix

    Resolve the command prefix for a guild using the prefix manager.

Classes

TuxApp

Python
TuxApp()

Application wrapper for managing Tux bot lifecycle.

This class encapsulates the setup, run, and shutdown phases of the bot, providing consistent signal handling, configuration validation, and graceful startup/shutdown orchestration.

Attributes:

  • bot (Tux | None) –

    The Discord bot instance, initialized in :meth:start.

  • _connect_task (Task[None] | None) –

    Background task for the Discord connection.

  • _shutdown_event (Event | None) –

    Event flag for coordinating graceful shutdown.

  • _in_setup (bool) –

    Flag indicating if we're currently in the setup phase.

  • _bot_connected (bool) –

    Flag indicating if the bot has successfully connected to Discord.

Initialize the application state.

Notes

The bot instance is not created until :meth:start to ensure the event loop and configuration are properly initialized.

Methods:

  • run

    Run the Tux bot application.

  • setup_signals

    Register signal handlers for graceful shutdown.

  • start

    Start the Tux bot with full lifecycle management.

  • shutdown

    Gracefully shut down the bot and flush telemetry.

Functions

run
Python
run() -> int

Run the Tux bot application.

This is the synchronous entrypoint typically invoked by the CLI. Creates a new event loop, runs the bot, and handles shutdown gracefully.

Returns:

  • int

    Exit code: 0 for success, 130 for user-requested shutdown, 1 for errors.

Raises:

  • RuntimeError

    If a critical application error occurs during startup.

Notes

This method handles KeyboardInterrupt gracefully and ensures the event loop is properly closed regardless of how the application exits.

_handle_signal_shutdown
Python
_handle_signal_shutdown(loop: AbstractEventLoop, signum: int) -> None

Handle shutdown signal with different behavior based on bot state.

During startup (before Discord connection), SIGINT uses immediate exit since synchronous operations can't be interrupted gracefully. After connection, uses graceful shutdown with task cancellation.

Parameters:

  • loop (AbstractEventLoop) –

    The event loop to stop (when using graceful shutdown).

  • signum (int) –

    The signal number received (SIGTERM or SIGINT).

setup_signals
Python
setup_signals(loop: AbstractEventLoop) -> None

Register signal handlers for graceful shutdown.

During bot setup (which includes synchronous operations like database migrations), we use traditional signal handlers that can interrupt synchronous code. After setup completes, we switch to asyncio signal handlers for better integration.

Parameters:

_switch_to_asyncio_signals
Python
_switch_to_asyncio_signals(loop: AbstractEventLoop) -> None

Switch from traditional signal handlers to asyncio signal handlers.

This is called after bot setup completes, when we can rely on asyncio signal handlers for better integration with async operations.

Parameters:

start async
Python
start() -> int

Start the Tux bot with full lifecycle management.

This method orchestrates the complete bot startup sequence, including: - Sentry initialization for error tracking - Signal handler registration for graceful shutdown - Configuration validation and owner ID resolution - Bot instance creation and Discord connection - Background task monitoring for shutdown events

Returns:

  • int

    Exit code: 0 for success, 130 for user-requested shutdown, 1 for errors.

Notes

The bot is not created until this method is called to ensure proper event loop and configuration initialization. This method will block until the bot disconnects or a shutdown signal is received.

_resolve_owner_ids
Python
_resolve_owner_ids() -> set[int]

Resolve owner IDs based on configuration and eval permission settings.

Returns:

  • set[int]

    Set of user IDs with owner-level permissions.

Notes

If ALLOW_SYSADMINS_EVAL is enabled, sysadmin IDs are added to the owner set, granting them eval command access.

_create_bot_instance
Python
_create_bot_instance(owner_ids: set[int]) -> Tux

Create and configure the Tux bot instance.

Parameters:

  • owner_ids (set[int]) –

    Set of user IDs with owner-level permissions.

Returns:

  • Tux

    Configured bot instance ready for connection.

_await_bot_setup async
Python
_await_bot_setup() -> None

Wait for bot internal setup to complete before connecting.

Notes

This ensures all database connections, caches, and internal services are ready before attempting to connect to Discord.

_connect_to_gateway async
Python
_connect_to_gateway() -> None

Establish WebSocket connection to Discord gateway with reconnection support.

This method creates background tasks for the Discord connection and shutdown monitoring, waiting for either to complete.

Notes

The bot must already be logged in before calling this method. Uses connect() call with auto-reconnect and proper task coordination for graceful shutdown.

_monitor_shutdown async
Python
_monitor_shutdown() -> None

Monitor for shutdown signals while the bot is running.

This method creates and waits on a shutdown event that is set by signal handlers when a termination signal is received.

Notes

This task runs concurrently with the bot connection task and will trigger shutdown when a signal is received.

shutdown async
Python
shutdown() -> int

Gracefully shut down the bot and flush telemetry.

This method ensures proper cleanup of all bot resources, including closing the Discord connection and flushing any pending Sentry events.

Returns:

  • int

    Exit code: 130 if user requested shutdown, 0 otherwise.

Notes

This method is called automatically in the finally block of :meth:start, ensuring cleanup occurs regardless of how the application exits.

Functions

get_prefix async

Python
get_prefix(bot: Tux, message: Message) -> list[str]

Resolve the command prefix for a guild using the prefix manager.

This function uses the in-memory prefix cache for optimal performance, falling back to the default prefix when the guild is unavailable. If BOT_INFO__PREFIX is set in environment variables, all guilds will use that prefix, ignoring database settings.

Parameters:

  • bot (Tux) –

    The bot instance containing the prefix manager.

  • message (Message) –

    The message object containing guild context.

Returns:

  • list[str]

    A list containing the resolved command prefix.

Notes

Prefix resolution follows this priority order: 1. Environment variable override (BOT_INFO__PREFIX) 2. Guild-specific prefix from prefix manager cache 3. Default prefix from configuration