CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-cement

Advanced Application Framework for Python with a focus on Command Line Interfaces

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

foundation.mddocs/

Application Foundation

The foundation system provides the core application framework classes that serve as the entry point and container for all cement-based applications. The App class manages the complete application lifecycle, while TestApp provides specialized functionality for testing.

Capabilities

App Class

The main application framework class that serves as the central container for all application components and functionality.

class App:
    """
    Main application class that handles the entire application lifecycle.
    
    The App class manages setup, execution, and cleanup of cement applications.
    It serves as the central container for all handlers, interfaces, extensions,
    and configuration management.
    """
    
    def __init__(self, label: str = None, **kw: Any) -> None:
        """
        Initialize the application.
        
        Args:
            label: Application label/name
            **kw: Additional keyword arguments passed to Meta
        """
    
    def setup(self) -> None:
        """
        Initialize and setup the application for execution.
        
        This method handles:
        - Loading configuration files
        - Setting up logging
        - Loading extensions and plugins  
        - Registering handlers
        - Running pre_setup and post_setup hooks
        """
    
    def run(self) -> None:
        """
        Execute the application.
        
        This method handles:
        - Parsing command-line arguments
        - Running pre_run hooks
        - Executing the appropriate controller/command
        - Running post_run hooks
        - Exception handling and signal management
        """
    
    def close(self) -> None:
        """
        Cleanup and shutdown the application.
        
        This method handles:
        - Running pre_close and post_close hooks
        - Cleaning up resources
        - Proper application shutdown
        """
    
    def render(self, data: Dict[str, Any], template: str = None) -> str:
        """
        Render data using the configured output handler.
        
        Args:
            data: Dictionary of data to render
            template: Optional template name for template-based output
            
        Returns:
            Rendered output string
        """
    
    def extend(self, extension: str, app: 'App') -> None:
        """
        Register a framework extension.
        
        Args:
            extension: Extension name/identifier
            app: Application instance to extend
        """
    
    @property
    def _meta(self) -> Any:
        """Application meta-data configuration object."""

TestApp Class

Specialized application class designed for unit testing cement applications with additional testing utilities and simplified configuration options.

class TestApp(App):
    """
    Application class designed specifically for testing cement applications.
    
    Inherits all functionality from App but provides additional testing
    conveniences and simplified configuration for test environments.
    """
    
    def __init__(self, label: str = None, **kw: Any) -> None:
        """
        Initialize the test application.
        
        Args:
            label: Application label/name  
            **kw: Additional keyword arguments passed to Meta
        """

Meta Configuration

Application behavior is controlled through the Meta class which can be defined as a nested class or passed as keyword arguments during initialization.

class Meta:
    """
    Application meta-data configuration.
    
    Controls application behavior including handler selection,
    configuration options, and framework settings.
    """
    
    label: str = None
    """Application label/name"""
    
    debug: bool = False
    """Debug mode flag"""
    
    config_handler: str = 'configparser'
    """Configuration handler to use"""
    
    config_file_suffix: str = '.conf'
    """Configuration file suffix"""
    
    config_files: List[str] = []
    """List of configuration files to load"""
    
    config_dirs: List[str] = []
    """List of configuration directories to search"""
    
    config_defaults: Dict[str, Any] = {}
    """Default configuration values"""
    
    argv: List[str] = None
    """Override sys.argv for argument parsing"""
    
    catch_signals: List[int] = [signal.SIGTERM, signal.SIGINT]
    """List of signals to catch and handle"""
    
    signal_handler: str = 'signal'
    """Signal handler to use"""
    
    pre_setup_hooks: List[Callable] = []
    """List of pre-setup hook functions"""
    
    post_setup_hooks: List[Callable] = []
    """List of post-setup hook functions"""
    
    pre_run_hooks: List[Callable] = []
    """List of pre-run hook functions"""
    
    post_run_hooks: List[Callable] = []
    """List of post-run hook functions"""
    
    pre_close_hooks: List[Callable] = []
    """List of pre-close hook functions"""
    
    post_close_hooks: List[Callable] = []
    """List of post-close hook functions"""
    
    handlers: List[Handler] = []
    """List of handler classes to register"""
    
    extensions: List[str] = []
    """List of extensions to load"""
    
    plugins: List[str] = []
    """List of plugins to load"""
    
    plugin_config_dirs: List[str] = []
    """List of plugin configuration directories"""
    
    plugin_dirs: List[str] = []
    """List of plugin directories to search"""
    
    template_handler: str = 'dummy'
    """Template handler to use"""
    
    template_dirs: List[str] = []
    """List of template directories"""
    
    output_handler: str = 'dummy'
    """Output handler to use"""
    
    log_handler: str = 'logging'
    """Log handler to use"""
    
    cache_handler: str = 'dummy'
    """Cache handler to use"""
    
    mail_handler: str = 'dummy'
    """Mail handler to use"""
    
    argument_handler: str = 'argparse'
    """Argument handler to use"""
    
    base_controller: str = None
    """Base controller class name"""

Usage Examples

Basic Application

from cement import App, Controller, ex

class BaseController(Controller):
    class Meta:
        label = 'base'
    
    @ex(help='say hello')
    def hello(self):
        print('Hello World!')

class MyApp(App):
    class Meta:
        label = 'myapp'
        base_controller = 'base'
        handlers = [BaseController]

def main():
    with MyApp() as app:
        app.run()

if __name__ == '__main__':
    main()

Application with Configuration

from cement import App, init_defaults

CONFIG = init_defaults('myapp')
CONFIG['myapp']['debug'] = False
CONFIG['myapp']['some_option'] = 'default_value'

class MyApp(App):
    class Meta:
        label = 'myapp'
        config_defaults = CONFIG
        config_files = ['/etc/myapp.conf', '~/.myapp.conf']

with MyApp() as app:
    app.setup()
    print(f"Debug mode: {app.config.get('myapp', 'debug')}")
    print(f"Option value: {app.config.get('myapp', 'some_option')}")
    app.run()

Testing Application

from cement import TestApp

def test_myapp():
    with TestApp() as app:
        app.setup()
        # Test application functionality
        assert app.config.get('myapp', 'debug') == True
        app.run()

Application with Extensions

from cement import App

class MyApp(App):
    class Meta:
        label = 'myapp'
        extensions = ['colorlog', 'jinja2', 'yaml']
        config_handler = 'yaml'
        template_handler = 'jinja2'
        log_handler = 'colorlog'

with MyApp() as app:
    app.setup()
    app.log.info('Application started with extensions')
    app.run()

Context Manager Usage

The recommended pattern is to use applications as context managers to ensure proper setup and cleanup:

from cement import App

# Recommended approach - automatic setup/cleanup
with MyApp() as app:
    app.run()

# Manual approach - requires explicit calls
app = MyApp()
try:
    app.setup()
    app.run()
finally:
    app.close()

Install with Tessl CLI

npx tessl i tessl/pypi-cement

docs

arguments.md

caching.md

configuration.md

controllers.md

extensions.md

foundation.md

hooks.md

index.md

interface-handler.md

logging.md

mail.md

output.md

plugins.md

templates.md

utilities.md

tile.json