Appearance
Session
Session is the per-terminal runtime object in Klix. If App is the application definition, Session is the active instance.
See also:
Why Session Exists
A framework like Klix needs a place to hold runtime state that is not global:
- current application state
- metadata about the terminal
- runtime UI handles
- input history
- background tasks
That is what Session does.
What Lives On A Session
The current implementation exposes these important attributes:
session.idsession.statesession.metadatasession.historysession.uisession.input_engine
session.ui and session.input_engine are attached during startup. They are None until the runtime has been built.
Typed State
The most common reason to use Session is typed state access:
python
from dataclasses import dataclass
import klix
@dataclass
class MyState(klix.SessionState):
logged_in: bool = False
username: str = ""
app = klix.App(name="mytool", state_schema=MyState)
@app.command("/login", help="Log in")
def login(session: klix.Session):
session.state.logged_in = True
session.state.username = "alice"See Working with State.
Terminal Metadata
Klix captures a small TerminalMetadata object on startup. It currently contains:
envwidthheightstart_timeterm_programinteractive
Example:
python
@app.command("/env", help="Show terminal metadata")
def env(session: klix.Session):
session.ui.output.json(
{
"interactive": session.metadata.interactive,
"term_program": session.metadata.term_program,
"size": [session.metadata.width, session.metadata.height],
}
)Background Tasks
Session.create_task() lets you schedule session-scoped async work:
python
import asyncio
@app.command("/watch", help="Run a background watcher")
async def watch(session: klix.Session):
async def worker():
for i in range(3):
await asyncio.sleep(1)
session.ui.print(f"tick {i + 1}", dim=True)
session.create_task(worker())Klix tracks these tasks and waits on them during shutdown.
How It Fits The Architecture
Every handler and middleware function gets a Session because it is the shortest path to the active runtime:
- state
- UI
- metadata
- background tasks
That keeps function signatures simple without forcing global variables.
Common Mistakes
Using session.ui before startup
If you instantiate a Session yourself outside the normal App.run() path, you are responsible for attaching session.ui and session.input_engine.
Putting app definition into session state
State should hold runtime data, not command definitions, renderer objects, or application configuration that already lives on App.
Assuming session.history is fully managed everywhere
session.history is the live per-session command history backing the input engine.
That means:
- Up/Down arrow navigation reads from it
- duplicate consecutive commands are skipped
AppConfig(max_history_size=...)trims it automatically
The field is still just a Python list, so if you mutate it directly, do it deliberately.