Native Python CLI UI library with CSS-like styling
Project description
Casca
Casca is a lightweight, native Python TUI (Terminal User Interface) framework with a DOM-like widget tree, CSS-style theming, and modern features.
โจ Features
Core Features
- Zero core dependencies (standard library runtime only)
- DOM-like widget tree with declarative syntax
- CSS-style theming with cascade and specificity
- Flexbox layouts (row/column) with percentage sizing
- Named themes with CSS variables (
var(--primary),var(--surface), ...) - Full type hints with strict mypy configuration
- Comprehensive logging with configurable levels
Widgets (20+)
Basic: Container, Label, Button, Card, Header, ScrollView
Forms: Input, TextArea, Select, RadioGroup, Checkbox
Data: ListView, DataGrid, Table, TreeView
Visual: ProgressBar, Spinner, Tabs, Slider, Menu
Layout: Grid, VirtualScrollView (for 10,000+ items)
Data Visualization
BarChart,Sparkline,Gauge,Heatmap,ScatterPlot
Advanced Features
- Virtual Scrolling - Render 10,000+ items with O(1) performance
- Grid Layout - CSS Grid-like 2D layout system
- Accessibility - Focus management, keyboard navigation, screen reader support
- Hot Reload - Automatic UI refresh on CSS changes (optional watchdog)
- Image Widget - Terminal images with multiple render modes
- Screenshot Capture - Export
.ansi,.txt,.svgscreenshots - Studio Mode - Live inspection (focus path, computed style, box model)
- Plugin Architecture - Community widgets via entry points
- Redux-like Store - Unidirectional state management
Developer Experience
- casca-doctor - Diagnostic CLI tool
- Debug overlay - Layout visualization, style warnings
- Type hints - 100% type coverage on core modules
- Tested - 450+ tests with comprehensive coverage
- CI/CD - GitHub Actions with test matrix
- Documentation - API reference, troubleshooting, contributing guides
๐ Quick Start
Installation
# Basic installation
pip install casca
# With hot reload support
pip install casca[hotreload]
# All features
pip install casca[all]
Hello World
from casca import Container, Label, run_app
CSS = """
#root {
padding: 1;
border: solid;
}
"""
ui_tree = Container(
Label("Hello from Casca"),
id="root",
)
if __name__ == "__main__":
run_app(ui_tree, css=CSS)
With Logging
from casca import Container, Label, run_app, setup_logging
import logging
# Enable debug logging
setup_logging(level=logging.DEBUG)
ui_tree = Container(Label("Hello with logging"), id="root")
run_app(ui_tree)
Load Styles from File
from casca import Container, Label, run_app
ui_tree = Container(
Label("Styled from file.css"),
id="root",
)
if __name__ == "__main__":
run_app(ui_tree, css_path="styles.css")
๐ Examples
Run Use Cases
# Nomeda CLI - Modern AI Chatbot
PYTHONPATH=. python3 use_cases/nomeda_cli.py
# Login screen demo
PYTHONPATH=. python3 use_cases/login_screen.py
# Dashboard with widgets
PYTHONPATH=. python3 use_cases/dashboard.py
# File selector
PYTHONPATH=. python3 use_cases/file_selector.py
# Terminal browser
PYTHONPATH=. python3 use_cases/cli_browser.py
Widget Examples
# Menu widget
PYTHONPATH=. python3 examples/30_menu_example.py
# Slider widget
PYTHONPATH=. python3 examples/31_slider_example.py
# Virtual scrolling (10,000 items)
PYTHONPATH=. python3 examples/32_virtual_scroll_example.py
# Image rendering
PYTHONPATH=. python3 examples/25_image.py
๐จ Styling
CSS Variables
:root {
--primary: #007bff;
--surface: #1a1a1a;
--border: #333;
}
#root {
background: var(--surface);
border-color: var(--primary);
}
Border Styles
#widget {
border: solid; /* or: ascii, rounded, double, thick, dashed */
border-color: cyan;
}
Flexbox Layouts
#container {
flex-direction: row; /* or: column */
gap: 1;
}
Grid Layout
from casca.components.widgets.grid import Grid
grid = Grid(
columns="1fr 1fr 1fr",
rows="auto auto",
gap=1
)
grid.add(Label("Header"), grid_column="1 / span 3", grid_row="1")
grid.add(Label("Sidebar"), grid_column="1", grid_row="2")
grid.add(Label("Content"), grid_column="2 / span 2", grid_row="2")
๐ Debugging
Enable Debug Mode
from casca import App
class MyApp(App):
debug = True # Detailed error messages
debug_layout = True # Layout visualization
studio_mode = True # Live inspection
Enable Logging
from casca import setup_logging
import logging
# Debug to stderr
setup_logging(level=logging.DEBUG)
# Or log to file
setup_logging(level=logging.INFO, log_file="casca.log")
Studio Mode
Press F2 in any running Casca app to toggle the studio overlay:
- Focused widget path
- Computed style display
- Box model visualization
- Layout debugging
Run Diagnostic Tool
casca-doctor
casca-doctor --json
๐ช State Management
Casca includes an optional Redux-like store:
from casca import App, create_store
def reducer(state, action):
state = dict(state or {})
if action["type"] == "inc":
state["count"] = state.get("count", 0) + 1
return state
class CounterApp(App):
def __init__(self):
super().__init__()
self.set_store(create_store(reducer, {"count": 0}))
def build_ui(self):
state = self.get_state() or {}
count = state.get("count", 0)
return Container(
Label(f"Count: {count}"),
id="root"
)
Combine Reducers
from casca import combine_reducers
root_reducer = combine_reducers({
"counter": counter_reducer,
"user": user_reducer,
"posts": posts_reducer
})
๐ฅ Hot Reload (Development)
Enable automatic UI refresh on CSS changes:
from casca import App, run_app
from casca.core.hot_reload import enable_hot_reload
class MyApp(App):
css_path = "styles.css"
app = MyApp()
# Enable hot reload (watch CSS files)
# Watchdog optional - falls back to polling
reloader = enable_hot_reload(app, ["styles/"])
run_app(app)
โฟ Accessibility
Focus Management
from casca.core.accessibility import get_accessibility
accessibility = get_accessibility()
# Set tab order
accessibility.focus_manager.set_focus_order(["input1", "input2", "submit"])
# Enable focus trap for modals
accessibility.focus_manager.enable_focus_trap(modal_dialog)
# Screen reader announcements
accessibility.announce("Form submitted successfully")
Keyboard Shortcuts
accessibility.register_keybinding("Ctrl+S", save_handler)
accessibility.register_keybinding("F1", help_handler)
๐ Testing
Run Tests
# All tests
pytest tests/ -v
# With coverage
pytest tests/ --cov=casca --cov-report=term-missing
# Specific test file
pytest tests/test_app_comprehensive.py -v
# Fast tests only
pytest tests/ -v -m "not slow"
Write Tests
import pytest
from casca import Container, Label
def test_container_layout():
container = Container(Label("Test"), id="root")
container.resolve_styles({})
w, h = container.calculate_layout(80, 24)
assert w > 0
assert h > 0
๐ Project Layout
casca/
โโโ casca/ # Core library
โ โโโ core/ # App, events, terminal, store, logging
โ โโโ dom/ # Widget base class (DOM node)
โ โโโ components/ # Widgets (organized by category)
โ โโโ style/ # CSS parsing and validation
โ โโโ plugins/ # Plugin registration
โโโ tests/ # Test suite (450+ tests)
โโโ examples/ # Small demos
โโโ use_cases/ # Real applications
โโโ docs/ # Documentation
โ โโโ API_REFERENCE.md # Complete API docs
โ โโโ TROUBLESHOOTING.md # Common issues
โ โโโ CONTRIBUTING.md # Contribution guide
โโโ benchmarks/ # Performance benchmarks
๐ ๏ธ Development
Install Development Dependencies
pip install -e ".[dev]"
Run Linting
ruff check casca/ tests/
ruff format casca/ tests/ --check
Run Type Checking
mypy casca/ --ignore-missing-imports
Run All Tests
pytest tests/ -v --tb=short
Makefile Commands
# Serve website locally
make serve
# Deploy website to GitHub Pages
make deploy-website
# Run all checks
make all
Website Deployment
The Casca website is deployed to GitHub Pages at https://abdallah4z.github.io/Casca/
Automatic Deployment:
- Push to
mainbranch โ Auto-deploys via GitHub Actions - Visit the site to see latest documentation
Manual Deployment:
# Using the deployment script
./scripts/deploy-website.sh
# Or using Make
make deploy-website
Serve Locally:
# Using Make
make serve
# Or manually
cd retro_website
python3 -m http.server 8000
See retro_website/README.md for detailed deployment instructions.
Build Documentation
pip install -e ".[docs]"
mkdocs serve
๐ Documentation
- API Reference - Complete API documentation
- Troubleshooting - Common issues and solutions
- Contributing - How to contribute
- Architecture - System design and internals
- Getting Started - Installation and basics
- Components - Widget reference
- Style Reference - CSS properties
๐ง Configuration
mypy
Strict type checking enabled:
# mypy.ini
[mypy]
python_version = 3.10
disallow_untyped_defs = True
check_untyped_defs = True
Ruff
Code formatting and linting:
# pyproject.toml
[tool.ruff]
target-version = "py310"
line-length = 100
Coverage
# pyproject.toml
[tool.coverage.report]
fail_under = 60
show_missing = true
๐ค Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Guidelines
- Add tests for new features
- Maintain type hints (100% on core modules)
- Follow existing code style (ruff format)
- Update documentation
- Read CONTRIBUTING.md
๐ License
MIT License - See LICENSE for details.
๐ Acknowledgments
Inspired by:
๐ Roadmap
v1.1.0 (Next)
- Improved CSS pseudo-selector support
- Better Windows terminal support
- Performance optimizations
- More widget themes
Future
- Async/await support
- Plugin marketplace
- Visual designer tool
- Mobile terminal support
Built with โค๏ธ in Python
Need help? Check out:
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 casca-1.0.1.tar.gz.
File metadata
- Download URL: casca-1.0.1.tar.gz
- Upload date:
- Size: 136.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
050a0813e69cfdd0782c162948a7ecae7d8d1051ac695b4b39bb3eba956b3715
|
|
| MD5 |
12e3ab16d02476d2283a35874f7c4b92
|
|
| BLAKE2b-256 |
cc1a0d7009956d0726b5409f3c165593624d1fec0df7d3aad9e5112f8102670d
|
File details
Details for the file casca-1.0.1-py3-none-any.whl.
File metadata
- Download URL: casca-1.0.1-py3-none-any.whl
- Upload date:
- Size: 121.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8dfc7d3b4900fb4a9a5e93ff553409a77ec503bc6b28f221e4ce96ee887d1cd0
|
|
| MD5 |
142b2e89d53560522e2b68fb74b6eb39
|
|
| BLAKE2b-256 |
859a39fa2a8b9df619603618bdb6c9be4062ed75d90c3cc53ff4c9a7fd44e99b
|