Metadata-Version: 2.4
Name: modelmirror
Version: 0.1.3
Summary: Model Mirror
License-Expression: MIT
License-File: LICENSE
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.10
Requires-Dist: pydantic>=2.0.0
Description-Content-Type: text/markdown

# ModelMirror

A Python library for dependency injection and configuration management using JSON files. ModelMirror allows you to define object instances and their dependencies in JSON configuration files, then automatically instantiate and wire them together at runtime.

## Quick Example

```python
from modelmirror.mirror import Mirror
from modelmirror.class_provider.class_register import ClassRegister
from modelmirror.class_provider.class_reference import ClassReference

# Define your classes
class DatabaseService:
    def __init__(self, host: str, port: int):
        self.host = host
        self.port = port

class UserService:
    def __init__(self, db: DatabaseService, cache_enabled: bool):
        self.db = db
        self.cache_enabled = cache_enabled

# Register classes - schema and version must match the $reference in JSON config
class DatabaseServiceRegister(ClassRegister,
    reference=ClassReference(
        schema="database",
        version="1.0.0",
        cls=DatabaseService
    )):
    pass

class UserServiceRegister(ClassRegister,
    reference=ClassReference(
        schema="user_service",
        version="1.0.0",
        cls=UserService
    )):
    pass

# Define configuration in JSON
config = {
    "database": {
        "$reference": {"registry": {"schema": "database", "version": "1.0.0"}},
        "params": {"host": "localhost", "port": 5432}
    },
    "user_service": {
        "$reference": {"registry": {"schema": "user_service", "version": "1.0.0"}},
        "params": {"db": "$database", "cache_enabled": True}
    }
}

# Load and instantiate
mirror = Mirror('myapp')
instances = mirror.reflect_raw('config.json')
user_service = instances.get(UserService)
```

## Features

- **JSON-based Configuration**: Define object instances and dependencies in JSON files
- **Automatic Dependency Injection**: Reference instances using `$instance_name` syntax
- **Non-Intrusive**: Works with existing classes without modification - no need to change your code
- **Simple Registration**: Register any class by creating a simple registry entry
- **Type Safety**: Integration with Pydantic for validation and type checking
- **Class Registration**: Register classes with schema and version
- **Dependency Resolution**: Automatic topological sorting of dependencies
- **Multiple Instance Types**: Support for single instances, lists, and dictionaries

## Installation

```bash
pip install modelmirror
```

## Usage

### 1. Register Your Classes

Create class registers that define how your classes should be instantiated:

```python
from modelmirror.class_provider.class_register import ClassRegister
from modelmirror.class_provider.class_reference import ClassReference

class DatabaseServiceRegister(ClassRegister,
    reference=ClassReference(
        schema="database",
        version="1.0.0",
        cls=DatabaseService
    )):
    pass

class UserServiceRegister(ClassRegister,
    reference=ClassReference(
        schema="user_service",
        version="1.0.0",
        cls=UserService
    )):
    pass
```

### 2. Create JSON Configuration

Define your instances and their dependencies in a JSON file:

```json
{
    "database": {
        "$reference": {
            "registry": {
                "schema": "database",
                "version": "1.0.0"
            }
        },
        "params": {
            "host": "localhost",
            "port": 5432
        }
    },
    "user_service": {
        "$reference": {
            "registry": {
                "schema": "user_service",
                "version": "1.0.0"
            }
        },
        "params": {
            "db": "$database",
            "cache_enabled": true
        }
    }
}
```

### 3. Load Configuration

Use the Mirror class to load and instantiate your objects:

```python
from modelmirror.mirror import Mirror

# Load configuration and get instances
mirror = Mirror('myapp')  # Package name where registers are defined
instances = mirror.reflect_raw('config.json')

# Get specific instances
database = instances.get(DatabaseService)
user_service = instances.get(UserService)

# Get instance by ID
database = instances.get(DatabaseService, 'database')
```

### 4. Type-Safe Configuration with Pydantic

Define a Pydantic model for type-safe configuration loading:

```python
from pydantic import BaseModel

class AppConfig(BaseModel):
    database: DatabaseService
    user_service: UserService

# Load with type validation
config = mirror.reflect_typed('config.json', AppConfig)
print(config.database.host)  # Type-safe access
```

## Advanced Features

### Lists and Collections

```json
{
    "services": [
        {
            "$reference": {
                "instance": "service1",
                "registry": {"schema": "service", "version": "1.0.0"}
            },
            "params": {"name": "Service 1"}
        },
        "$service2"
    ]
}
```

### Instance References

Reference other instances using the `$` prefix:

```json
{
    "cache": {
        "$reference": {"registry": {"schema": "cache", "version": "1.0.0"}},
        "params": {"size": 1000}
    },
    "service": {
        "$reference": {"registry": {"schema": "service", "version": "1.0.0"}},
        "params": {
            "cache": "$cache",
            "timeout": 30
        }
    }
}
```

## Requirements

- Python >= 3.10
- Pydantic >= 2.0.0

## Development

```bash
# Install development dependencies
pip install -e ".[dev]"

# Run tests
python -m pytest tests/

# Run pre-commit hooks
pre-commit run --all-files
```

## License

MIT License - see LICENSE file for details.
