whyml

WhyML Core

PyPI version Python Support License WhyML Ecosystem

๐ŸŽฏ Core functionality for the WhyML ecosystem - validation, loading, processing, and manifest manipulation

WhyML Core provides the foundational infrastructure for the WhyML ecosystem, offering robust tools for YAML manifest processing, template inheritance, dependency resolution, and async operations. Built with modern Python patterns and comprehensive error handling.

๐Ÿ”ง Recent Core Updates (2025)

โœ… EXCEPTION SYSTEM: Enhanced exception classes with improved constructors:

โœ… VALIDATION FRAMEWORK: Added ValidationResult class to whyml-core validation module for structured validation reporting and compatibility with existing test suites.

โœ… LOADEDMANIFEST HANDLING: Improved LoadedManifest dataclass structure with proper .content attribute extraction patterns throughout the ecosystem.

โœ… BACKWARDS COMPATIBILITY: Maintained full backwards compatibility while adding new functionality and fixing critical CLI conversion issues.

๐Ÿš€ Key Features

๐Ÿ“ฆ Installation

pip install whyml-core

For development dependencies:

pip install whyml-core[dev]

๐Ÿ— Architecture

WhyML Core is organized into focused modules:

Core Modules

Module Details

whyml_core/
โ”œโ”€โ”€ exceptions/          # Exception handling
โ”‚   โ”œโ”€โ”€ base_exceptions.py      # Base exception classes
โ”‚   โ”œโ”€โ”€ validation_exceptions.py   # Validation-specific exceptions
โ”‚   โ””โ”€โ”€ processing_exceptions.py   # Processing-specific exceptions
โ”œโ”€โ”€ validation/          # Validation framework
โ”‚   โ”œโ”€โ”€ manifest_validator.py     # Core manifest validation
โ”‚   โ”œโ”€โ”€ schema_loader.py          # JSON schema management
โ”‚   โ””โ”€โ”€ field_validators.py       # Specialized field validators
โ”œโ”€โ”€ loading/            # Loading and dependency management
โ”‚   โ”œโ”€โ”€ manifest_loader.py       # Async manifest loading
โ”‚   โ”œโ”€โ”€ cache_manager.py         # Advanced caching system
โ”‚   โ””โ”€โ”€ dependency_resolver.py    # Dependency graph resolution
โ”œโ”€โ”€ processing/         # Template processing
โ”‚   โ”œโ”€โ”€ template_processor.py    # Jinja2 template engine
โ”‚   โ”œโ”€โ”€ inheritance_resolver.py  # Template inheritance
โ”‚   โ””โ”€โ”€ variable_substitution.py # Variable substitution
โ””โ”€โ”€ utils/             # Utilities
    โ”œโ”€โ”€ yaml_utils.py         # YAML processing utilities
    โ”œโ”€โ”€ async_utils.py        # Async operation helpers
    โ”œโ”€โ”€ path_utils.py         # Path manipulation
    โ””โ”€โ”€ string_utils.py       # String processing

๐Ÿ”ง Quick Start

Basic Manifest Validation

from whyml_core.validation import ManifestValidator

validator = ManifestValidator()

# Validate a manifest
manifest = {
    'metadata': {'title': 'My App', 'version': '1.0.0'},
    'structure': {'body': {'content': 'Hello World'}}
}

try:
    is_valid = await validator.validate_manifest(manifest)
    print(f"Manifest is valid: {is_valid}")
except ValidationError as e:
    print(f"Validation error: {e.message}")

Async Manifest Loading

from whyml_core.loading import ManifestLoader

loader = ManifestLoader()

# Load manifest with dependencies
async def load_example():
    manifest = await loader.load_manifest('manifest.yaml')
    return manifest

# With dependency resolution
manifest = await loader.load_with_dependencies('main-manifest.yaml')

Template Processing

from whyml_core.processing import TemplateProcessor

processor = TemplateProcessor()

# Process templates with variables
template_vars = {
    'app_name': 'MyApp',
    'version': '1.0.0'
}

processed = processor.substitute_template_variables(
    'Welcome to  v',
    template_vars
)

Advanced Processing Pipeline

from whyml_core import (
    ManifestLoader, 
    ManifestValidator, 
    TemplateProcessor,
    InheritanceResolver
)

async def process_manifest(manifest_path: str):
    # Load manifest
    loader = ManifestLoader()
    manifest = await loader.load_manifest(manifest_path)
    
    # Validate
    validator = ManifestValidator()
    await validator.validate_manifest(manifest)
    
    # Process inheritance
    resolver = InheritanceResolver()
    resolved = await resolver.resolve_inheritance(manifest)
    
    # Process templates
    processor = TemplateProcessor()
    final_manifest = processor.substitute_template_vars(resolved)
    
    return final_manifest

๐Ÿ›  Advanced Features

Custom Validation Schemas

from whyml_core.validation import SchemaLoader

schema_loader = SchemaLoader()

# Load custom schema
custom_schema = await schema_loader.load_schema('custom-schema.json')

# Use with validator
validator = ManifestValidator(schema_loader=schema_loader)

Caching and Performance

from whyml_core.loading import CacheManager

# Configure caching
cache_manager = CacheManager(max_size=1000, ttl=3600)

# Use with loader
loader = ManifestLoader(cache_manager=cache_manager)

Async File Operations

from whyml_core.utils import AsyncFileManager

async def example():
    file_manager = AsyncFileManager()
    
    # Read file with caching
    content = await file_manager.read_file('data.yaml')
    
    # Write file with directory creation
    await file_manager.write_file('output/result.yaml', content)

YAML Processing

from whyml_core.utils import YAMLUtils, YAMLProcessor

# Basic operations
data = YAMLUtils.load_file('manifest.yaml')
YAMLUtils.save_file(data, 'output.yaml')

# Advanced processing
processor = YAMLProcessor()
normalized = processor.normalize_manifest(manifest)
excerpt = processor.extract_sections(manifest, ['metadata', 'structure'])

๐Ÿ” Error Handling

WhyML Core provides comprehensive error handling:

from whyml_core.exceptions import (
    WhyMLError,
    ValidationError,
    TemplateError,
    ManifestError
)

try:
    result = await some_operation()
except ValidationError as e:
    print(f"Validation failed: {e.message}")
    print(f"Details: {e.details}")
except TemplateError as e:
    print(f"Template processing error: {e.message}")
    print(f"Context: {e.context}")
except WhyMLError as e:
    # Base class catches all WhyML-specific errors
    print(f"WhyML error: {e}")

๐Ÿงช Testing

Run the test suite:

# Install test dependencies
pip install whyml-core[test]

# Run tests
pytest

# Run with coverage
pytest --cov=whyml_core --cov-report=html

๐Ÿค Contributing

WhyML Core is part of the larger WhyML ecosystem. Contributions are welcome!

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Run the test suite
  6. Submit a pull request

๐Ÿ“‹ Requirements

WhyML Core is designed to work with other WhyML packages:

๐Ÿ“„ License

Licensed under the Apache License, Version 2.0. See LICENSE for details.


WhyML Core - Empowering modular manifest processing with robust, async-first architecture.