mvk-sdk-micro 1.0.4
MVK SDK Micro - Ultralight OpenTelemetry-compatible SDK for AI Observability
License: Apache-2.0
Requires Python: >=3.8
Keywords: llm, observability, tracing, ai, ml, opentelemetry-compatible

# MVK Micro SDK

**Ultralight ~450KB • No OpenTelemetry Dependencies • Auto-instrumentation First • W3C TraceContext**

## Overview

MVK Micro SDK is an ultralight observability solution (~450KB) that provides OpenTelemetry-compatible telemetry without any OpenTelemetry dependencies. The SDK automatically instruments AI/ML providers at import time with minimal overhead and full W3C TraceContext support for distributed tracing.

### Key Features

- **Ultralight**: ~450KB total size vs 2MB+ for OpenTelemetry-based solutions
- **No Dependencies**: No OpenTelemetry, just wrapt and zstandard
- **Zero-Code Instrumentation**: Works without any decorators via sitecustomize
- **Unified API**: Single @mvk.track decorator and mvk.context for all use cases
- **Provider Auto-wrapping**: Instruments OpenAI, Anthropic, Bedrock, Vertex AI, Pinecone, Weaviate, HTTPX
- **Tag Validation**: Enforces max 10 tags with strict naming rules
- **Direct Export**: Sends data directly to Mavvrik ingestion with gzip compression
- **Built-in WAL**: File-based Write-Ahead Log for reliability

## Quick Start

### Minimal Setup (Auto-instrumentation only)

```python
import mvk_sdk as mvk

# Initialize with API key and agent name
mvk.instrument(
    api_key="your-api-key",
    agent_name="my-service"
)

# That's it! All provider calls are now traced
import openai
response = openai.ChatCompletion.create(...)  # Automatically traced
```

### With Business Context

```python
import mvk_sdk as mvk

mvk.instrument(
    api_key="your-api-key",
    agent_name="qa-bot"
)

@mvk.track(tier="premium", team="ml")  # Add business context
def answer_question(query: str):
    # All operations inherit the context tags
    embedding = openai.Embedding.create(...)  # Auto-traced as EMBEDDING
    results = pinecone.query(...)              # Auto-traced as RETRIEVER
    answer = openai.ChatCompletion.create(...) # Auto-traced as LLM
    return answer
```

## Architecture

### Context Stack (Precedence: Low → High)

1. **Global** (mvk.instrument): Process-wide defaults
2. **Decorator** (@mvk.track or @mvk.context): Function-scoped
3. **Context Manager** (with mvk.context): Block-scoped
4. **Per-request Headers** (x-mvk-*): Highest precedence, single call only

**Note**: `mvk.context` works as both decorator AND context manager with the same name.

### Span Kinds

- `LLM`: Language model completions
- `EMBEDDING`: Embedding generation
- `RETRIEVER`: Vector/search operations
- `TOOL`: Generic I/O (http, sql, filesystem)
- `MEMORY`: Cache/store operations
- `AGENT_CALL`: Agent orchestration and workflows

### Auto-instrumented Libraries

| Library | Version | Span Kind |
|---------|---------|-----------|
| openai | 1.3-1.25 | LLM/EMBEDDING |
| anthropic | 0.20-0.26 | LLM |
| aws-bedrock-agent | ≥1.0 | LLM/EMBEDDING |
| vertexai | ≥1.45 | LLM/EMBEDDING |
| pinecone-client | 3.x | EMBEDDING/RETRIEVER |
| weaviate-client | 4.x | EMBEDDING/RETRIEVER |
| requests | 2.31-2.32 | TOOL |
| httpx | 0.25-0.26 | TOOL |
| psycopg2 | 2.9.x | TOOL |

## Documentation

- **[Technical Specification](MVK-Micro-SDK-Spec.md)**: Complete API specification, configuration options, and schema definitions
- **[Architecture Design](MVK-Micro-SDK-Architecture.md)**: Internal architecture, component design, and implementation guidelines

## Installation

```bash
pip install mvk-sdk-micro
```

## Configuration

### Basic Configuration

```python
mvk.instrument(
    api_key="mvk_...",           # Required
    agent_name="my-service",      # Required (maps to service.name)
    config={
        "endpoint": "https://api.mavvrik.ai"
    }
)
```

### Advanced Configuration

```python
mvk.instrument(
    api_key="mvk_...",
    agent_name="my-service",
    config={
        "wal": {
            "type": "disk",              # "disk" or "memory"
            "path": "/var/log/mvk",      # WAL directory
            "batch_size": 250,           # Spans per batch
            "flush_interval_secs": 2,    # Flush interval
            "max_age_hours": 12,         # Span retention before dropping
            "max_retry_hours": 4.0,      # Keep retrying exports for up to 4 hours
            "max_retry_interval_secs": 300,  # Max wait between retries (5 minutes)
            "initial_retry_interval_secs": 1.0,  # Initial retry interval (OTEL standard)
            "max_fast_retries": 10,      # Fast retries before switching to long-term
        },
        "endpoint": "https://api.mavvrik.ai",
        "strict_validation": True,       # Raise on schema violations
        "patches": {                     # Enable/disable wrappers
            "openai": True,
            "anthropic": True,
            "pinecone": True
        }
    },
    tags={"env": "prod"}  # Global context tags
)
```

## Manual Instrumentation

### Track Decorator

```python
@mvk.track(kind="LLM", model="gpt-4", tier="premium")
def generate_response(prompt: str):
    # Manual tracking for custom operations
    return custom_llm_call(prompt)
```

### Context Manager

```python
def process_batch(items):
    for i, item in enumerate(items):
        with mvk.context(batch_index=i, item_id=item.id):
            # Tags scoped to this block only
            process_item(item)
```

### Combined Usage

```python
# Use as decorator
@mvk.context(feature="search")
def search_handler():
    # All operations inherit feature="search"
    pass

# Use as context manager - same function!
with mvk.context(feature="search"):
    search_handler()
```

### Usage Metrics

```python
# Add custom metrics to current span
mvk.add_metered_usage(
    metric="tokens.prompt",
    value=150,
    uom="tokens",
    model_name="gpt-4"
)
```

## Context Inheritance Examples

```python
# Global level
mvk.instrument(api_key="...", agent_name="api", tags={"env": "prod"})

@mvk.track(team="backend")  # Decorator level
def api_handler():
    # Has: env="prod", team="backend"
    
    with mvk.context(user_id="123"):  # Context manager level
        # Has: env="prod", team="backend", user_id="123"
        
        # Per-call header (if x-mvk-priority="high" in request)
        llm_call()  # Has all above + priority="high" for this call only
```

## Tag Validation

Tags must follow strict rules:
- Maximum 10 tags per span
- Keys and values must match regex: `[a-z0-9_-]{1,32}`
- UTF-8 strings only
- Validation errors are logged (or raised if `strict_validation=True`)

```python
# Validate tags before use
valid_tags, errors = mvk.validate_tags({
    "user_id": "123",
    "tier": "premium",
    "INVALID!": "will-be-dropped"
})
```

## Testing

### Setup for Testing

```bash
# Clone the repository
git clone https://github.com/mavvrik/mvk-sdk.git
cd mvk-sdk/components/python-sdk

# Create a virtual environment (recommended)
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install the package in development mode with test dependencies
pip install -e ".[dev]"
```

### Running Tests

```bash
# Run all tests
PYTHONPATH=src pytest

# Run unit tests only
PYTHONPATH=src pytest tests/unit

# Run integration tests only
PYTHONPATH=src pytest tests/integration

# Run specific test file
PYTHONPATH=src pytest tests/unit/test_decorators.py

# Run specific test class or method
PYTHONPATH=src pytest tests/unit/test_decorators.py::TestTrackDecorator
PYTHONPATH=src pytest tests/unit/test_decorators.py::TestTrackDecorator::test_track_decorator_basic

# Run tests with verbose output
PYTHONPATH=src pytest -v

# Run tests and stop on first failure
PYTHONPATH=src pytest -x

# Run tests matching a pattern
PYTHONPATH=src pytest -k "test_context"
```

### Test Coverage

```bash
# Run tests with coverage report
PYTHONPATH=src pytest --cov=src/mvk_sdk --cov-report=term

# Generate HTML coverage report
PYTHONPATH=src pytest --cov=src/mvk_sdk --cov-report=html
# Open htmlcov/index.html in your browser

# Show missing lines in terminal
PYTHONPATH=src pytest --cov=src/mvk_sdk --cov-report=term-missing

# Generate multiple report formats
PYTHONPATH=src pytest --cov=src/mvk_sdk --cov-report=term --cov-report=html --cov-report=xml

# Run tests with coverage for specific modules
PYTHONPATH=src pytest tests/unit/test_decorators.py --cov=src/mvk_sdk/decorators --cov-report=term-missing
```

### Test Categories

Tests are organized into categories using pytest markers:

```bash
# Run fast tests only (< 1 second)
PYTHONPATH=src pytest -m "not slow"

# Run slow tests only (integration, E2E)
PYTHONPATH=src pytest -m slow

# Run tests that don't require external services
PYTHONPATH=src pytest -m "not requires_external"

# List all available markers
PYTHONPATH=src pytest --markers
```

### Performance Testing

```bash
# Run performance benchmarks
PYTHONPATH=src pytest tests/unit/test_performance_benchmarks.py -v

# Run with profiling (requires pytest-profiling)
PYTHONPATH=src pytest --profile

# Run with memory profiling (requires pytest-memray)
PYTHONPATH=src pytest --memray
```

### Debugging Tests

```bash
# Run tests with Python debugger on failures
PYTHONPATH=src pytest --pdb

# Run tests with detailed traceback
PYTHONPATH=src pytest --tb=long

# Run tests without capturing output (see print statements)
PYTHONPATH=src pytest -s

# Run tests with logging output
PYTHONPATH=src pytest --log-cli-level=DEBUG
```

### Writing Tests

When writing new tests:

1. **Unit tests** go in `tests/unit/` - test individual functions/classes in isolation
2. **Integration tests** go in `tests/integration/` - test interactions between components
3. **E2E tests** go in `tests/e2e/` - test complete workflows

Example test structure:

```python
# tests/unit/test_my_module.py
import pytest
from mvk_sdk.my_module import my_function

class TestMyFunction:
    def test_basic_functionality(self):
        result = my_function("input")
        assert result == "expected_output"
    
    def test_error_handling(self):
        with pytest.raises(ValueError):
            my_function(None)
    
    @pytest.mark.slow
    def test_performance(self):
        # Performance test that takes > 1 second
        pass
```

### Continuous Integration

Tests run automatically on pull requests. To run the same checks locally:

```bash
# Run linting
flake8 src tests

# Run type checking
mypy src

# Run all checks (tests + linting + type checking)
make check  # If Makefile is available
```

## Migration from v2.1

### Key Changes

1. **Package Update**:
   ```bash
   # Old
   pip install mvk-auto[openai,anthropic]
   
   # New
   pip install mvk-sdk-micro
   ```

2. **Import Changes**:
   ```python
   # Old
   import mvk_auto
   
   # New
   import mvk_sdk as mvk
   ```

3. **Initialization**:
   ```python
   # Old
   mvk_auto.instrument(resource={"service.name": "my-service"})
   
   # New
   mvk.instrument(api_key="key", agent_name="my-service")
   ```

4. **Decorators**:
   ```python
   # Old
   @mvk_agent(agent_id="123", agent_name="bot")
   @mvk_track(kind="LLM")
   
   # New
   @mvk.track(kind="LLM")  # agent_name set in instrument()
   ```

5. **Context**:
   ```python
   # Old
   with mvk_track_context(user_id="123"):
   
   # New
   with mvk.context(user_id="123"):
   ```

## Development

See [MVK-Micro-SDK-Architecture-v3.0.md](MVK-Micro-SDK-Architecture-v3.0.md) for the complete architecture documentation.

### Project Structure

```
python-sdk/
├── README.md                        # This file
├── MVK-Micro-SDK-Spec-v3.0.md      # Technical specification
├── MVK-Micro-SDK-Architecture-v3.0.md  # Architecture overview
├── CLAUDE.md                        # AI development guidelines
├── pyproject.toml                   # Package configuration
├── src/
│   └── mvk_sdk/                    # Main package
│       ├── __init__.py             # Public API
│       ├── instrument.py           # SDK initialization
│       ├── decorators.py           # @mvk.track, mvk.context
│       ├── context.py              # Context management
│       ├── schema.py               # Span validation
│       ├── tracer.py               # Ultralight tracer
│       ├── metrics.py              # Metered usage
│       ├── sitecustomize.py        # Auto-instrumentation
│       ├── wrappers/               # Provider wrappers
│       │   ├── openai.py
│       │   ├── anthropic.py
│       │   ├── bedrock.py
│       │   ├── vertexai.py
│       │   └── ...
│       └── wal/                    # Write-ahead log
│           ├── disk.py
│           └── memory.py
├── tests/
│   ├── unit/
│   ├── integration/
│   └── e2e/
└── examples/
    ├── quickstart.py               # Basic usage
    ├── openai_example.py           # OpenAI integration
    └── advanced_features.py        # All features demo
```

## Support

- GitHub Issues: [github.com/mavvrik/mvk-sdk](https://github.com/mavvrik/mvk-sdk)
- Documentation: [docs.mavvrik.ai](https://docs.mavvrik.ai)
- Email: support@mavvrik.ai