CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-cyclopts

Intuitive, easy CLIs based on type hints.

Pending
Overview
Eval results
Files

configuration.mddocs/

Configuration System

File-based configuration loading system supporting JSON, TOML, YAML formats and environment variable integration.

Capabilities

Base Configuration Class

Abstract base class for all configuration loaders.

class ConfigFromFile:
    def __init__(self, file: Path):
        """
        Base configuration loader from file.
        
        Parameters
        ----------
        file
            Path to configuration file
        """
        
    def load(self) -> dict[str, Any]:
        """
        Load configuration from file.
        
        Returns
        -------
        dict[str, Any]
            Configuration data as dictionary
        """

JSON Configuration

Load configuration from JSON files.

class Json(ConfigFromFile):
    def __init__(self, file: Path):
        """
        JSON configuration loader.
        
        Parameters
        ----------
        file
            Path to JSON configuration file
        """
        
    def load(self) -> dict[str, Any]:
        """
        Load configuration from JSON file.
        
        Returns
        -------
        dict[str, Any]
            Parsed JSON configuration
            
        Raises
        ------
        FileNotFoundError
            If configuration file doesn't exist
        json.JSONDecodeError
            If JSON is malformed
        """

TOML Configuration

Load configuration from TOML files.

class Toml(ConfigFromFile):
    def __init__(self, file: Path):
        """
        TOML configuration loader.
        
        Parameters
        ----------
        file
            Path to TOML configuration file
        """
        
    def load(self) -> dict[str, Any]:
        """
        Load configuration from TOML file.
        
        Returns
        -------
        dict[str, Any]
            Parsed TOML configuration
            
        Raises
        ------
        FileNotFoundError
            If configuration file doesn't exist
        tomllib.TOMLDecodeError
            If TOML is malformed
        """

YAML Configuration

Load configuration from YAML files.

class Yaml(ConfigFromFile):
    def __init__(self, file: Path):
        """
        YAML configuration loader.
        
        Parameters
        ----------
        file
            Path to YAML configuration file
        """
        
    def load(self) -> dict[str, Any]:
        """
        Load configuration from YAML file.
        
        Returns
        -------
        dict[str, Any]
            Parsed YAML configuration
            
        Raises
        ------
        FileNotFoundError
            If configuration file doesn't exist
        yaml.YAMLError
            If YAML is malformed
        """

Environment Variable Configuration

Load configuration from environment variables.

class Env:
    def __init__(
        self,
        prefix: str = "",
        case_sensitive: bool = False,
        nested_separator: str = "__"
    ):
        """
        Environment variable configuration loader.
        
        Parameters
        ----------
        prefix
            Prefix for environment variable names
        case_sensitive
            Whether environment variable names are case sensitive
        nested_separator
            Separator for nested configuration keys
        """
        
    def load(self) -> dict[str, Any]:
        """
        Load configuration from environment variables.
        
        Returns
        -------
        dict[str, Any]
            Configuration from environment variables
        """

Configuration Protocol

Protocol that configuration loaders must implement.

class ConfigProtocol:
    def load(self) -> dict[str, Any]:
        """
        Load configuration data.
        
        Returns
        -------
        dict[str, Any]
            Configuration as dictionary
        """

Usage Examples

JSON Configuration

from cyclopts import App
from cyclopts.config import Json
from pathlib import Path

# config.json:
# {
#   "database": {
#     "host": "localhost",
#     "port": 5432
#   },
#   "verbose": true
# }

app = App(config=[Json(Path("config.json"))])

@app.command
def connect(
    host: str = "127.0.0.1",
    port: int = 3306,
    verbose: bool = False
):
    """Connect to database with config file support."""
    if verbose:
        print(f"Connecting to {host}:{port}")

TOML Configuration

from cyclopts import App
from cyclopts.config import Toml
from pathlib import Path

# config.toml:
# [server]
# host = "0.0.0.0"
# port = 8080
# debug = true

app = App(config=[Toml(Path("config.toml"))])

@app.command
def start_server(
    host: str = "localhost",
    port: int = 8000,
    debug: bool = False
):
    """Start server with TOML configuration."""
    print(f"Starting server on {host}:{port} (debug={debug})")

Environment Variable Configuration

from cyclopts import App
from cyclopts.config import Env

# Environment variables:
# MYAPP_DATABASE__HOST=prod-db.example.com
# MYAPP_DATABASE__PORT=5432
# MYAPP_VERBOSE=true

app = App(config=[Env(prefix="MYAPP_", nested_separator="__")])

@app.command
def deploy(
    database_host: str = "localhost",
    database_port: int = 5432,
    verbose: bool = False
):
    """Deploy with environment configuration."""
    if verbose:
        print(f"Deploying to database at {database_host}:{database_port}")

Multiple Configuration Sources

from cyclopts import App
from cyclopts.config import Json, Env
from pathlib import Path

# Configuration precedence: CLI args > environment > config file
app = App(config=[
    Json(Path("app.json")),  # Loaded first (lowest priority)
    Env(prefix="APP_")       # Loaded second (higher priority)
])

@app.command
def run_job(
    worker_count: int = 1,
    timeout: float = 30.0,
    output_dir: str = "./output"
):
    """Run job with multiple configuration sources."""
    print(f"Running job with {worker_count} workers")
    print(f"Timeout: {timeout}s, Output: {output_dir}")

YAML Configuration with Nested Structure

from cyclopts import App
from cyclopts.config import Yaml
from pathlib import Path

# config.yaml:
# logging:
#   level: INFO
#   file: app.log
# processing:
#   batch_size: 100
#   parallel: true

app = App(config=[Yaml(Path("config.yaml"))])

@app.command
def process_data(
    logging_level: str = "WARNING",
    logging_file: str = "default.log",
    processing_batch_size: int = 50,
    processing_parallel: bool = False
):
    """Process data with YAML configuration."""
    print(f"Logging: {logging_level} -> {logging_file}")
    print(f"Processing: batch_size={processing_batch_size}, parallel={processing_parallel}")

Custom Configuration Loader

from cyclopts import App
from cyclopts.config import ConfigFromFile
from pathlib import Path
import configparser

class IniConfig(ConfigFromFile):
    """Custom INI file configuration loader."""
    
    def load(self) -> dict[str, Any]:
        config = configparser.ConfigParser()
        config.read(self.file)
        
        result = {}
        for section_name in config.sections():
            section = {}
            for key, value in config[section_name].items():
                # Try to convert to appropriate types
                if value.lower() in ('true', 'false'):
                    section[key] = value.lower() == 'true'
                elif value.isdigit():
                    section[key] = int(value)
                else:
                    section[key] = value
            result[section_name] = section
        return result

app = App(config=[IniConfig(Path("config.ini"))])

@app.command
def example(setting: str = "default"):
    """Example command with custom INI config."""
    print(f"Setting: {setting}")

Install with Tessl CLI

npx tessl i tessl/pypi-cyclopts

docs

advanced-features.md

arguments-parameters.md

configuration.md

core-app.md

exceptions.md

index.md

types-validation.md

tile.json