Skip to main content

A framework for building production-ready CLI apps and Terminal UIs with minimal code.

Project description

clidev

clidev is a Python framework for building production-ready Command Line Applications (CLI) and Terminal User Interfaces (TUI) with minimal code.

Unlike traditional CLI libraries that only parse arguments, clidev gives you a complete framework for interactive terminal apps — menus, forms, workflows, dashboards, state management, command execution, navigation, and event-driven logic — so you don't have to hand-write input loops, menu rendering, or terminal state machines.

Think of it as the Flutter/React of terminal applications: you describe what your app looks like and does, clidev handles the rendering loop.

Built on top of rich for terminal rendering and questionary for interactive prompts.


Installation

pip install -e .

(This installs clidev from this repo in editable mode, along with its dependencies: rich, questionary, pydantic, click, PyYAML, toml.)

Quick start

from clidev import App

app = App("My App")

home = app.menu("Home")
home.option("Say Hello", lambda: app.success("Hello!"))
home.option("Exit", app.exit)

app.run()

Or scaffold a brand-new project with the bundled CLI:

clidev new myproject
cd myproject
python app.py

Module guide

App (clidev/app.py)

The core object. Wires together state, storage, routing, events, plugins, theming, and every UI widget factory.

from clidev import App

app = App("Developer Toolkit", theme="dark", storage_backend="json")

State (clidev/state.py)

Global, dict-like state, accessible anywhere in your app.

app.state["username"] = "Vrushabh"
print(app.state["username"])

app.state.on_change(lambda key, old, new: print(f"{key}: {old} -> {new}"))

Storage (clidev/storage.py)

Every form (or any code) can persist data through a pluggable backend: memory, json, sqlite, yaml, or toml.

app.storage.save("user", {"name": "Bob"})
user = app.storage.load("user")
app = App("My App", storage_backend="sqlite")

Forms (clidev/forms.py, inputs.py, validators.py)

Chainable form builder with automatic validation.

form = app.form("User")
form.text("Name")
form.email("Email")
form.password("Password")
form.number("Age")

data = form.run()
# {"Name": "Vrushabh", "Email": "abc@gmail.com", "Password": "******", "Age": 17}

Supported field types: text, email, password, number, url, file, folder, date, time, checkbox, toggle, radio, select/dropdown, multiselect, searchable.

Custom validators can be attached per-field via extra_validators=[...] using anything from clidev.validators (min_length, max_length, min_value, max_value, is_date, etc.).

Menus (clidev/menus.py)

menu = app.menu("Main Menu")
menu.option("Create Project", create_project)
menu.option("Deploy", deploy)
menu.option("Exit", app.exit)

Nested menus:

main = app.menu("Main")
settings = app.menu("Settings")
main.link("Settings", settings)

Page routing (clidev/router.py, pages.py)

@app.page("home")
def home():
    ...

app.goto("settings")
app.back()

Conditional navigation (clidev/actions.py)

@app.when(lambda data: data["Role"] == "Admin")
def admin():
    app.goto("admin_menu")

or:

app.if_value("Role", equals="Admin").goto("admin_menu")
app.if_value("Age", greater_than=18).goto("adult_menu")

Supported comparisons: equals, not_equals, greater_than, less_than, greater_equal, less_equal, contains, in_list.

Workflow engine (clidev/workflow.py)

workflow = app.workflow()
workflow.step(login)
workflow.step(select_project)
workflow.step(build)
workflow.step(deploy)
result = workflow.start()

Each step can accept a shared context dict; whatever a step returns (as a dict) is merged into that context for subsequent steps.

Events (clidev/events.py)

@app.on_start
def startup():
    ...

@app.on_exit
def shutdown():
    ...

@app.on_submit(some_form)
def save(data):
    ...

@app.on_error
def on_error(e):
    ...

Command execution (clidev/shell.py)

app.cmd("git init")

result = app.cmd("git status", capture=True)
print(result.stdout, result.ok)

app.cmd("pip install -r requirements.txt", background=True)

Progress & tasks (clidev/progress.py, spinner.py, tasks.py, scheduler.py)

with app.progress("Installing"):
    app.cmd("pip install numpy")
    app.cmd("pip install pandas")

@app.task
def build():
    ...

app.run_task("build")

Plugins (clidev/plugins.py)

from clidev.plugins import Plugin

class GitPlugin(Plugin):
    name = "git"

    def on_install(self, app):
        ...

    def on_start(self, app):
        ...

app.use(GitPlugin())

Themes (clidev/themes.py, colors.py)

app = App("My App", theme="dark")

theme = Theme()
theme.primary("blue")
theme.success("green")

Logging (clidev/logger.py)

app.logger.info("Started")
app.logger.warning("Warning")
app.logger.error("Failed")

UI widgets

  • app.table(title, columns=[...]) — data tables (clidev/table.py)
  • app.tree(label) — tree views (clidev/tree.py)
  • app.card(title, content) — bordered content cards (clidev/cards.py)
  • app.dashboard(title) — multi-panel grid overview (clidev/dashboard.py)
  • app.dialog.confirm(...), app.dialog.prompt(...), app.dialog.alert(...) (clidev/dialogs.py)
  • app.notify.success/error/warning/info(...) (clidev/notifications.py)
  • app.statusbar.set(...).render() (clidev/statusbar.py)

Project generator (clidev/generators/, cli.py)

clidev new myproject

Creates:

myproject/
│
├── app.py
├── routes.py
├── menus.py
├── forms.py
├── workflows.py
├── commands.py
├── storage.py
├── settings.py
└── assets/

Full example

See examples/basic_app.py for the complete "Developer Toolkit" example (menus, page routing, forms, storage, conditional navigation, and shell commands), and examples/workflow_app.py for a workflow + plugin + dashboard example.

from clidev import App

app = App("Developer Toolkit")

home = app.menu("Home")
home.option("Create Project", "project_form")
home.option("Settings", "settings")
home.option("Exit", app.exit)


@app.page("project_form")
def project_form_page():
    project = app.form("Project")
    project.text("Project Name")
    project.select("Language", ["Python", "Rust", "Go"])
    data = project.run()

    if not data:
        return

    app.storage.save("project", data)
    app._last_form_data = data

    if data["Language"] == "Python":
        app.goto("python_setup")
    else:
        app.success(f"Project '{data['Project Name']}' created ({data['Language']}).")


@app.page("python_setup")
def python_setup():
    with app.progress("Setting up Python project"):
        app.cmd("python -m venv .venv_demo")
        app.cmd("git init")
    app.success("Project Created")


if __name__ == "__main__":
    app.run()

Running the tests

pip install -e ".[dev]"
pytest tests/ -v

The test suite (in tests/) covers global state, all storage backends, form field validation, the shell command wrapper, routing/history, the workflow engine, conditional navigation, the event dispatcher, theming, the project generator, and full App integration — 85 tests in total.


Project layout

clidev/
├── __init__.py
├── app.py                 # Main application
├── router.py               # Navigation
├── pages.py                # Pages
├── menus.py                 # Menu engine
├── forms.py                  # Forms
├── inputs.py                  # Input widgets
├── validators.py
│
├── state.py                   # Global state
├── storage.py                  # JSON/SQLite/YAML/TOML storage
├── workflow.py                  # Workflow engine
├── events.py                     # Event dispatcher
├── actions.py                     # Conditional navigation
│
├── shell.py                        # Execute commands
├── tasks.py                          # Background tasks
├── scheduler.py
│
├── progress.py
├── spinner.py
├── dashboard.py
├── table.py
├── tree.py
├── cards.py
├── dialogs.py
├── notifications.py
├── statusbar.py
│
├── themes.py
├── colors.py
├── icons.py
│
├── logger.py
├── config.py
├── plugins.py
├── utils.py
├── exceptions.py
│
├── generators/
│   ├── project.py
│   ├── menu.py
│   ├── form.py
│   └── workflow.py
│
├── templates/
├── builtins/                        # Example plugins (GitPlugin, DatabasePlugin)
└── cli.py                            # "clidev" terminal command

Roadmap

  • Additional storage backends: PostgreSQL, MongoDB, Redis
  • clidev-auth, clidev-cloud, clidev-testing, clidev-plugins as separate installable packages
  • Richer dashboard layout options and live-updating widgets

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

clidevkit-0.1.0.tar.gz (32.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

clidevkit-0.1.0-py3-none-any.whl (33.5 kB view details)

Uploaded Python 3

File details

Details for the file clidevkit-0.1.0.tar.gz.

File metadata

  • Download URL: clidevkit-0.1.0.tar.gz
  • Upload date:
  • Size: 32.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for clidevkit-0.1.0.tar.gz
Algorithm Hash digest
SHA256 1a0437e173f76aae1e55b8b0a99e7a7333cdd3d31ad786cc255e4be4868ef4a2
MD5 2fb64e3410c634394399a9ef8da531b0
BLAKE2b-256 f2e10ecbe592502e20b031039f710fba7c3cb63e6d375a6da52482797b38b976

See more details on using hashes here.

File details

Details for the file clidevkit-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: clidevkit-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 33.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for clidevkit-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b91e1d781c3062f51d81b49e4b201df2696781237506097d04bf471934b98711
MD5 1994070737e56a848e6a45bf5feb70df
BLAKE2b-256 77ee841d3126f8da515c42563e08fdcae39b6edacf08a641d312a82a424a65b4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page