Framework for building polished, interactive command-line applications in Python.
Project description
Klix
CLI interfaces that just click.
Klix is a Python framework for building polished, interactive command-line applications. It combines command routing, typed session state, prompt-driven input, rich rendering, middleware, events, and lightweight layout primitives into one developer-facing toolkit.
Why Klix
Klix is built for developers who want more than print() and argparse, but do not want to hand-roll a terminal framework every time they start a new tool.
It is a framework, not a finished app. You define the commands, state, UI, and flow. Klix provides the runtime pieces that make those tools feel deliberate instead of improvised.
Key Features
- Command-first app model with decorators and first-class
Commandobjects - Typed session state for per-run data and persisted workflows
- Prompt-driven input powered by
prompt_toolkit - Rich terminal rendering with sensible fallback behavior
- Reusable UI helpers for tables, panels, spinners, selectors, forms, and streaming
- Middleware and lifecycle events for cross-cutting behavior
- Lightweight layout regions for headers, status lines, and structured screens
- Built-in scaffold CLI via
klix init mytool
Demo
Minimal command flow:
$ python examples/minimal.py
Minimal
Try /help, /deploy staging, /ask, /login, /markdown, or /exit.
> /deploy staging --force
Deploying to staging in forced mode
> /help
/deploy <environment> [--force] Deploy to an environment
/ask Prompt for free-form input
/login Collect credentials interactively
/markdown Render markdown output
> /exit
Chat-style UI example:
$ python examples/chat_ai.py
Klix Assistant
Talk to the demo like a ai chat app. Type normal text to send a message...
You > explain terminal UX
Assistant: terminal UX looks manageable. I would break it into a small core...
You > /theme
Assistant: Theme switched to light.
Installation
For local development:
python -m pip install -e .
This installs:
- the
klixPython package - the
klixscaffold command
After installation:
klix
Expected output:
Usage: klix init <name>
Quickstart
Create a small Klix app:
from dataclasses import dataclass
import klix
@dataclass
class DemoState(klix.SessionState):
runs: int = 0
app = klix.App(
name="demo",
version="0.1.0",
description="Small Klix example",
state_schema=DemoState,
)
@app.on("start")
def on_start(session: klix.Session) -> None:
session.ui.print("Demo is ready. Try /hello or /exit.", color="muted")
@app.command("/hello", help="Say hello")
def hello(session: klix.Session) -> None:
session.state.runs += 1
session.ui.print(f"Hello from Klix. Run #{session.state.runs}", color="success")
if __name__ == "__main__":
app.run()
Run it:
python main.py
Core Concepts
App: the composition root for commands, middleware, events, theme, and persistenceSession: per-run context holding state, metadata, UI, and input historyRouter: parses slash commands and validates typed argumentsInputEngine: prompt handling, input modes, and interactive terminal behaviorRenderer: rich-aware output with fallback modes for simpler terminalsUI: the main application-facing namespace for input, output, layout, and streamingLayout: lightweight persistent regions for header, main output, and status
If you want the deeper architectural walkthrough, start with docs/index.md and then docs/concepts/architecture.md.
Example Command Usage
Typed command with arguments:
from pydantic import BaseModel
class DeployArgs(BaseModel):
environment: str
force: bool = False
@app.command("/deploy", args_schema=DeployArgs, help="Deploy the service")
def deploy(args: DeployArgs, session: klix.Session) -> None:
session.ui.print(
f"Deploying to {args.environment} (force={args.force})",
color="warning",
)
Interactive command with reusable UI components:
@app.command("/release", help="Run a guided release flow")
async def release(session: klix.Session) -> None:
version = await session.ui.input.text("Version", placeholder="1.2.3")
target = await session.ui.input.select(
["staging", "production"],
label="Environment",
)
confirmed = await session.ui.input.confirm(
f"Release {version} to {target}?",
default=False,
)
if not confirmed:
session.ui.print("Release cancelled.", color="warning")
return
session.ui.output.panel(
f"Released {version} to {target}",
title="Release Complete",
border_color="success",
)
Examples In This Repository
examples/minimal.py: compact command-oriented starter appexamples/full_demo.py: broader framework walkthrough with persistence and middlewareexamples/chat_ai.py: Gemini-style conversational UI demoexamples/ui_showcase.py: reusable input and output component showcase
Documentation
The full docs live in docs/.
Recommended starting points:
Contributing
Contributions are welcome. Good issues, focused pull requests, example improvements, and documentation fixes all help.
Start with CONTRIBUTING.md for local setup, project structure, and contribution guidelines.
License
Klix is licensed under the Apache License 2.0.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file klix-0.1.0.tar.gz.
File metadata
- Download URL: klix-0.1.0.tar.gz
- Upload date:
- Size: 37.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
834d16ad37fb8b91d3f26b00e1a24e56b918db219722f5a96c75b8baa0a960b1
|
|
| MD5 |
19fa04d7984671573a237915f21f03aa
|
|
| BLAKE2b-256 |
9d6e8b123e0f325edd5f6db55d6f7c0bbd1d0360fe073c1e0b4d2197f8946412
|
File details
Details for the file klix-0.1.0-py3-none-any.whl.
File metadata
- Download URL: klix-0.1.0-py3-none-any.whl
- Upload date:
- Size: 40.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d8e5314c19d686a9ede13a00ebd314316898af0a3a9efa3aa98b274fefdfb71d
|
|
| MD5 |
34c03ae7cd5242b8cdf6860c0db8d1f5
|
|
| BLAKE2b-256 |
c9e4c4be1d9ed7869ffdbb26b264d08230d207528e60cf5a8d172ae6c75afa69
|