Skip to main content

A Python CLI framework with self-spacing components and Rich theming

Project description

Clicycle

CI codecov PyPI version Python Versions License: MIT

A Python CLI framework with self-spacing components and Rich theming

Clicycle is a modern Python CLI framework that provides a simple functional API and powerful component-based system for building beautiful command-line interfaces.

It features automatic spacing, Rich theming, and an intuitive API that lets you focus on your application's logic instead of its presentation.

Features

  • Simple Functional API - Import and use functions directly (e.g., clicycle.info()).
  • Rich theming - Comprehensive styling with icons, typography, and layout controls.
  • Automatic spacing - Components manage their own spacing like HTML elements.
  • Customizable indentation - Per-component indentation control for perfect alignment.
  • Component-based - Familiar React/HTML-like API with composable components.
  • Type-safe - Full type hints and IDE support.
  • Smart tables - Automatically sized columns with intelligent formatting.
  • Code highlighting - Syntax-highlighted code blocks with line numbers.
  • Progress tracking - Built-in progress bars and spinners.
  • Interactive prompts - Properly spaced input prompts and confirmations.
  • 100% test coverage - Thoroughly tested for reliability.

Installation

pip install clicycle

Quick Start

Get started in seconds with Clicycle's functional API.

import clicycle
import time

# (Optional) Configure the app name and theme once
clicycle.configure(app_name="MyApp")

# Display a header
clicycle.header("Welcome", "Getting started with Clicycle")

# Show different message types
clicycle.info("This is an info message")
clicycle.success("Operation completed successfully!")
clicycle.warning("This is a warning")
clicycle.error("Something went wrong")

# Display a table
data = [
    {"Name": "Alice", "Age": 30, "City": "New York"},
    {"Name": "Bob", "Age": 25, "City": "San Francisco"},
]
clicycle.table(data, title="User Information")

# Show code with syntax highlighting
code_snippet = '''
def hello_world():
    print("Hello, Clicycle!")
'''
clicycle.code(code_snippet, language="python", title="Example Code")

# Use a spinner for long-running operations
with clicycle.spinner("Processing..."):
    time.sleep(2)

# Interactive prompts
name = clicycle.prompt("What's your name?")
if clicycle.confirm("Do you want to continue?"):
    clicycle.success(f"Great, let's proceed, {name}!")

How to Use Clicycle

Clicycle offers two ways to build your CLI: a simple functional API for most use cases and an object-oriented API for advanced scenarios.

1. Functional API (Recommended)

This is the easiest way to use Clicycle. Simply import the functions you need and call them. A global Clicycle instance is managed for you.

Configuration

Call clicycle.configure() at the start of your app to set a global app name or theme.

import clicycle
from clicycle import Theme

# Set a custom app name to appear in headers
clicycle.configure(app_name="My Awesome App")

# Or configure a full theme
custom_theme = Theme() # Fill with your theme options
clicycle.configure(theme=custom_theme)

Usage

import clicycle

clicycle.header("My App")
clicycle.info("Starting process...")

2. Object-Oriented API

For advanced use cases, such as managing multiple, separate CLI outputs with different themes, you can instantiate the Clicycle class directly.

from clicycle import Clicycle, Theme

# Create a custom instance for a specific task
reporter_theme = Theme() # Fill with your theme options
reporter_cli = Clicycle(theme=reporter_theme)

reporter_cli.info("Reporting task status...")

# Use the default API for other tasks
clicycle.info("This uses the default global instance.")

Components

All components are available through the functional API.

Headers and Sections

import clicycle

# Main header with optional app branding
clicycle.header("Main Title", "Optional subtitle")

# Section dividers
clicycle.section("Configuration")

Text Messages

import clicycle

# Different message types with automatic icons
clicycle.info("Information message")
clicycle.success("Success message")
clicycle.warning("Warning message")
clicycle.error("Error message")
clicycle.debug("Debug message")  # Only shown in verbose mode

# List items
clicycle.list_item("First item")
clicycle.list_item("Second item")

Tables

import clicycle

data = [
    {"Name": "Alice", "Score": 95},
    {"Name": "Bob", "Score": 87},
]

# Simple table
clicycle.table(data)

# Table with title
clicycle.table(data, title="Test Results")

Code Display

import clicycle

# Python code with line numbers
clicycle.code('''
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)
''', language="python", title="Fibonacci Function")

# JSON data
clicycle.json({"name": "Alice", "age": 30}, title="User Data")

Progress and Spinners

import clicycle
import time

# Simple spinner
with clicycle.spinner("Loading data..."):
    time.sleep(2)

# Progress bar
with clicycle.progress("Processing files") as p:
    for i in range(100):
        p.update_progress(i, f"Processing file {i}")
        time.sleep(0.02)

Interactive Prompts

import clicycle
from clicycle import select_from_list

# Basic prompts
name = clicycle.prompt("Enter your name")
age = clicycle.prompt("Enter your age", type=int)
confirmed = clicycle.confirm("Are you sure?")

# Selection from a list
option = select_from_list(
    item_name="environment",
    options=["development", "staging", "production"],
    default="development",
)

Grouping with Blocks

import clicycle

# Group related content
clicycle.section("User Information")
with clicycle.block():
    clicycle.info("Processing user data...")
    clicycle.success("User validated")
    clicycle.info("Creating profile...")

Summary Data

import clicycle

# Key-value summaries
summary_data = [
    {"label": "Total Files", "value": 1250},
    {"label": "Success Rate", "value": "96%"},
]
clicycle.summary(summary_data)

Theming

Clicycle's theming is highly customizable. You can pass a Theme object to clicycle.configure() or a Clicycle instance.

from clicycle import Theme, Icons, Typography, ComponentIndentation, configure

# Create a custom theme
custom_theme = Theme(
    icons=Icons(
        success="✅",
        error="❌",
    ),
    typography=Typography(
        header_style="bold magenta",
        info_style="bold blue",
    ),
    indentation=ComponentIndentation(
        list=4,      # 4 spaces for list items
        success=2,   # 2 spaces for success messages
        error=0,     # No indentation for errors
    )
)

# Apply the theme globally
configure(theme=custom_theme)

# Now all functional calls will use the new theme
clicycle.success("Theme updated successfully!")
clicycle.list_item("This will be indented 4 spaces")

Advanced Usage

Integration with Click

Clicycle works seamlessly with Click. The debug function automatically respects Click's verbose flag.

import click
import clicycle

@click.command()
@click.option('--verbose', '-v', is_flag=True, help="Enable verbose output.")
def main(verbose):
    # This is a basic example. For robust integration,
    # you might pass the verbose flag through the click context object.
    if verbose:
        # A simple way to let clicycle know about verbosity
        # is to configure it or handle it in your logic.
        # For this example, we'll just print a warning message.
        clicycle.warning("Verbose mode enabled.")

    clicycle.configure(app_name="MyApp")
    clicycle.header("My Application", "Version 1.0")
    clicycle.info("Application started")
    clicycle.debug("This will only show if --verbose is used.")

if __name__ == '__main__':
    main()

You can access the verbose flag in your Click command by using the click.get_current_context() function.

import click

@click.command()
@click.option('--verbose', '-v', is_flag=True, help="Enable verbose output.")
def main(verbose):
    context = click.get_current_context()
    if context.params.get('verbose'):
        clicycle.warning("Verbose mode enabled.")
        # more logic here

API Reference

Top-Level Functions

These functions are available for direct import from clicycle.

  • configure(app_name: str, theme: Theme) - Configure the global instance.
  • header(title: str, subtitle: str, app_name: str) - Display header.
  • section(title: str) - Display section divider.
  • info/success/warning/error/debug(message: str) - Display styled messages.
  • table(data: list[dict], title: str) - Display data table.
  • code(code: str, language: str, title: str) - Display code.
  • json(data: dict, title: str) - Display JSON data.
  • summary(data: list[dict]) - Display key-value summary.
  • list_item(item: str) - Display list item.
  • prompt(text: str, **kwargs) - Interactive prompt.
  • confirm(text: str, **kwargs) - Interactive confirmation.
  • spinner(message: str) - Context manager for spinner.
  • progress(description: str) - Context manager for progress bar.
  • block() - Context manager for grouping components.
  • clear() - Clear terminal and reset.

Clicycle Class

For advanced use, you can create separate instances.

from clicycle import Clicycle

cli = Clicycle(width: int = 100, theme: Theme | None = None, app_name: str | None = None)

The methods on the Clicycle class instance mirror the top-level functions.

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

clicycle-1.1.2.tar.gz (29.6 kB view details)

Uploaded Source

Built Distribution

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

clicycle-1.1.2-py3-none-any.whl (15.9 kB view details)

Uploaded Python 3

File details

Details for the file clicycle-1.1.2.tar.gz.

File metadata

  • Download URL: clicycle-1.1.2.tar.gz
  • Upload date:
  • Size: 29.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for clicycle-1.1.2.tar.gz
Algorithm Hash digest
SHA256 bb8adf683e2cfde39341b6ff78c8417b96f48dbd659b51e3151311f5ed766f2a
MD5 835b1410ab737883cedf21e8e9275065
BLAKE2b-256 903e195441be53fb38accf43edcdafbe77f491e3f50d98efbaf1610c50670b8b

See more details on using hashes here.

Provenance

The following attestation bundles were made for clicycle-1.1.2.tar.gz:

Publisher: publish.yml on Living-Content/clicycle

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file clicycle-1.1.2-py3-none-any.whl.

File metadata

  • Download URL: clicycle-1.1.2-py3-none-any.whl
  • Upload date:
  • Size: 15.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for clicycle-1.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 c98e899886e6b8d3d5893b7d5bfbc80e6fca5e8b5bcfddc46d32162e0be63790
MD5 c9e76a5fa024d8fea9fff3c3025c3492
BLAKE2b-256 1eee39c6be7a9d5de8f433de38d9c1e33f18fc1f4ae80a08e9b8fbd004bc089d

See more details on using hashes here.

Provenance

The following attestation bundles were made for clicycle-1.1.2-py3-none-any.whl:

Publisher: publish.yml on Living-Content/clicycle

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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