Source code for kstlib.ops.models
"""Data models for the kstlib.ops module.
This module defines the core data structures used by the ops module:
- BackendType: Enum for backend selection (tmux, container)
- SessionState: Enum for session state (running, stopped, exited, unknown)
- SessionConfig: Configuration for creating a session
- SessionStatus: Current status of a session
"""
from __future__ import annotations
from dataclasses import dataclass, field
from enum import Enum
from kstlib.ops.validators import (
validate_command,
validate_env,
validate_image_name,
validate_ports,
validate_session_name,
validate_volumes,
)
[docs]
class BackendType(str, Enum):
"""Backend type for session management.
Attributes:
TMUX: Use tmux for session management (dev/local).
CONTAINER: Use Podman/Docker for session management (prod).
"""
TMUX = "tmux"
CONTAINER = "container"
[docs]
class SessionState(str, Enum):
"""State of a session or container.
Attributes:
RUNNING: Session is active and running.
STOPPED: Session was stopped gracefully.
EXITED: Container exited (with exit code).
DEFINED: Session exists in config but has not been started.
UNKNOWN: State cannot be determined.
"""
RUNNING = "running"
STOPPED = "stopped"
EXITED = "exited"
DEFINED = "defined"
UNKNOWN = "unknown"
[docs]
@dataclass(frozen=True, slots=True)
class SessionConfig:
"""Configuration for creating a session.
This dataclass holds all configuration options for both tmux and container
backends. Options that are not applicable to the selected backend are ignored.
Attributes:
name: Unique session name (required).
backend: Backend type (tmux or container).
command: Command to run in the session (tmux) or container.
working_dir: Working directory for the session.
env: Environment variables to set.
image: Container image to use (container backend only).
volumes: Volume mounts in "host:container" format.
ports: Port mappings in "host:container" format.
runtime: Container runtime to use ("podman" or "docker").
log_volume: Log volume mount for persistence (auto-mounted).
Examples:
>>> config = SessionConfig(
... name="astro",
... backend=BackendType.TMUX,
... command="python -m astro.bot",
... )
>>> config = SessionConfig(
... name="astro-prod",
... backend=BackendType.CONTAINER,
... image="astro-bot:latest",
... volumes=["./data:/app/data"],
... log_volume="./logs:/app/logs",
... )
"""
name: str
backend: BackendType = BackendType.TMUX
# Common options
command: str | None = None
working_dir: str | None = None
env: dict[str, str] = field(default_factory=dict)
# Container-specific options
image: str | None = None
volumes: list[str] = field(default_factory=list)
ports: list[str] = field(default_factory=list)
runtime: str | None = None
# Log persistence (post-mortem analysis)
log_volume: str | None = None
[docs]
def __post_init__(self) -> None:
"""Validate configuration values.
Raises:
ValueError: If any configuration value is invalid.
"""
validate_session_name(self.name)
if self.command is not None:
validate_command(self.command)
if self.image is not None:
validate_image_name(self.image)
if self.volumes:
validate_volumes(self.volumes)
if self.ports:
validate_ports(self.ports)
if self.env:
validate_env(self.env)
[docs]
@dataclass(slots=True)
class SessionStatus:
"""Current status of a session or container.
This dataclass holds the runtime status information for a session,
including state, PID, creation time, and backend-specific details.
Attributes:
name: Session name.
state: Current state (running, stopped, exited, unknown).
backend: Backend type used for this session.
pid: Process ID (tmux server PID or container main PID).
created_at: ISO timestamp when the session was created.
window_count: Number of tmux windows (tmux backend only).
socket_name: tmux socket name for custom sockets (tmux backend only).
image: Container image name (container backend only).
exit_code: Container exit code if exited (container backend only).
Examples:
>>> status = SessionStatus(
... name="astro",
... state=SessionState.RUNNING,
... backend=BackendType.TMUX,
... pid=12345,
... window_count=1,
... )
>>> status = SessionStatus(
... name="astro-prod",
... state=SessionState.RUNNING,
... backend=BackendType.CONTAINER,
... pid=67890,
... image="astro-bot:latest",
... )
"""
name: str
state: SessionState
backend: BackendType
pid: int | None = None
created_at: str | None = None
# tmux-specific
window_count: int = 0
socket_name: str | None = None
# container-specific
image: str | None = None
exit_code: int | None = None
__all__ = [
"BackendType",
"SessionConfig",
"SessionState",
"SessionStatus",
]