ZenML is a unified MLOps framework that extends battle-tested machine learning operations principles to support the entire AI stack, from classical machine learning models to advanced AI agents.
Custom type definitions for specialized content. ZenML provides string subclasses for structured content types that preserve semantic meaning and enable automatic visualization.
class HTMLString(str):
"""
String subclass for HTML content.
Used to mark strings as HTML for proper rendering and visualization
in the ZenML dashboard.
Example:
```python
from zenml import step
from zenml.types import HTMLString
@step
def generate_report() -> HTMLString:
html = '''
<html>
<body>
<h1>Model Performance Report</h1>
<p>Accuracy: 95%</p>
<table>
<tr><th>Metric</th><th>Value</th></tr>
<tr><td>Precision</td><td>0.93</td></tr>
<tr><td>Recall</td><td>0.97</td></tr>
</table>
</body>
</html>
'''
return HTMLString(html)
```
"""Import from:
from zenml.types import HTMLStringclass MarkdownString(str):
"""
String subclass for Markdown content.
Used to mark strings as Markdown for proper rendering and visualization.
Example:
```python
from zenml import step
from zenml.types import MarkdownString
@step
def generate_documentation() -> MarkdownString:
md = '''
# Model Documentation
## Overview
This model performs sentiment analysis on text data.
## Metrics
- **Accuracy**: 95%
- **Precision**: 93%
- **Recall**: 97%
## Usage
```python
model.predict("This is a great product!")
```
'''
return MarkdownString(md)
```
"""Import from:
from zenml.types import MarkdownStringclass CSVString(str):
"""
String subclass for CSV content.
Used to mark strings as CSV for proper visualization and export.
Example:
```python
from zenml import step
from zenml.types import CSVString
@step
def export_results() -> CSVString:
csv = '''name,accuracy,precision,recall
model_v1,0.90,0.88,0.92
model_v2,0.93,0.91,0.95
model_v3,0.95,0.93,0.97
'''
return CSVString(csv)
```
"""Import from:
from zenml.types import CSVStringclass JSONString(str):
"""
String subclass for JSON content.
Used to mark strings as JSON for proper visualization and validation.
Example:
```python
from zenml import step
from zenml.types import JSONString
import json
@step
def export_config() -> JSONString:
config = {
"model": {
"type": "transformer",
"layers": 12,
"hidden_size": 768
},
"training": {
"learning_rate": 0.001,
"batch_size": 32,
"epochs": 10
}
}
return JSONString(json.dumps(config, indent=2))
```
"""Import from:
from zenml.types import JSONStringfrom zenml import step, pipeline
from zenml.types import HTMLString
@step
def train_model(data: list) -> dict:
"""Train model."""
return {
"accuracy": 0.95,
"precision": 0.93,
"recall": 0.97,
"f1": 0.95
}
@step
def generate_html_report(metrics: dict) -> HTMLString:
"""Generate HTML performance report."""
html = f'''
<!DOCTYPE html>
<html>
<head>
<style>
body {{ font-family: Arial, sans-serif; margin: 20px; }}
h1 {{ color: #333; }}
table {{ border-collapse: collapse; width: 100%; }}
th, td {{ border: 1px solid #ddd; padding: 8px; text-align: left; }}
th {{ background-color: #4CAF50; color: white; }}
</style>
</head>
<body>
<h1>Model Performance Report</h1>
<table>
<tr>
<th>Metric</th>
<th>Value</th>
</tr>
<tr>
<td>Accuracy</td>
<td>{metrics["accuracy"]:.2%}</td>
</tr>
<tr>
<td>Precision</td>
<td>{metrics["precision"]:.2%}</td>
</tr>
<tr>
<td>Recall</td>
<td>{metrics["recall"]:.2%}</td>
</tr>
<tr>
<td>F1 Score</td>
<td>{metrics["f1"]:.2%}</td>
</tr>
</table>
</body>
</html>
'''
return HTMLString(html)
@pipeline
def reporting_pipeline():
"""Pipeline generating HTML report."""
metrics = train_model([1, 2, 3])
report = generate_html_report(metrics)
return reportfrom zenml import step
from zenml.types import MarkdownString
@step
def generate_model_card(
model: dict,
metrics: dict,
training_info: dict
) -> MarkdownString:
"""Generate model card in Markdown."""
md = f'''
# Model Card: {model.get("name", "Untitled Model")}
## Model Details
- **Type**: {model.get("type", "Unknown")}
- **Version**: {model.get("version", "1.0")}
- **Framework**: {model.get("framework", "N/A")}
## Performance Metrics
| Metric | Value |
|--------|-------|
| Accuracy | {metrics.get("accuracy", 0):.2%} |
| Precision | {metrics.get("precision", 0):.2%} |
| Recall | {metrics.get("recall", 0):.2%} |
| F1 Score | {metrics.get("f1", 0):.2%} |
## Training Information
- **Training Samples**: {training_info.get("samples", "N/A")}
- **Training Duration**: {training_info.get("duration", "N/A")}
- **Learning Rate**: {training_info.get("learning_rate", "N/A")}
## Intended Use
This model is intended for sentiment analysis on customer reviews.
## Limitations
- English language only
- Maximum sequence length: 512 tokens
- Performance degrades on domain-specific jargon
## Ethical Considerations
Model may exhibit bias on certain demographic groups. Regular monitoring recommended.
'''
return MarkdownString(md.strip())from zenml import step
from zenml.types import CSVString
@step
def export_experiment_results(experiments: list) -> CSVString:
"""Export experiment results as CSV."""
# Header
csv_lines = ["experiment_id,model_type,accuracy,precision,recall,f1_score"]
# Data rows
for exp in experiments:
csv_lines.append(
f"{exp['id']},"
f"{exp['model_type']},"
f"{exp['accuracy']},"
f"{exp['precision']},"
f"{exp['recall']},"
f"{exp['f1']}"
)
csv = "\n".join(csv_lines)
return CSVString(csv)
# Usage
experiments = [
{"id": "exp1", "model_type": "rf", "accuracy": 0.90, "precision": 0.88, "recall": 0.92, "f1": 0.90},
{"id": "exp2", "model_type": "xgb", "accuracy": 0.93, "precision": 0.91, "recall": 0.95, "f1": 0.93},
{"id": "exp3", "model_type": "lgbm", "accuracy": 0.95, "precision": 0.93, "recall": 0.97, "f1": 0.95},
]
csv_result = export_experiment_results(experiments)from zenml import step
from zenml.types import JSONString
import json
@step
def export_model_config(model: dict) -> JSONString:
"""Export model configuration as JSON."""
config = {
"model_architecture": {
"type": model.get("type", "transformer"),
"layers": model.get("layers", 12),
"hidden_size": model.get("hidden_size", 768),
"attention_heads": model.get("attention_heads", 12)
},
"training_config": {
"optimizer": "AdamW",
"learning_rate": 0.001,
"batch_size": 32,
"epochs": 10,
"warmup_steps": 1000
},
"preprocessing": {
"max_length": 512,
"tokenizer": "bert-base-uncased",
"lowercase": True
},
"inference": {
"batch_size": 64,
"temperature": 1.0,
"top_k": 50,
"top_p": 0.9
}
}
return JSONString(json.dumps(config, indent=2))from zenml import step, pipeline
from zenml.types import HTMLString, MarkdownString, CSVString
from typing import Tuple
@step
def generate_comprehensive_report(
metrics: dict
) -> Tuple[HTMLString, MarkdownString, CSVString]:
"""Generate report in multiple formats."""
# HTML report
html = HTMLString(f'''
<html><body>
<h1>Report</h1>
<p>Accuracy: {metrics["accuracy"]}</p>
</body></html>
''')
# Markdown report
md = MarkdownString(f'''
# Report
**Accuracy**: {metrics["accuracy"]}
''')
# CSV export
csv = CSVString(f'''metric,value
accuracy,{metrics["accuracy"]}
''')
return html, md, csv
@pipeline
def multi_format_pipeline():
"""Pipeline generating reports in multiple formats."""
metrics = {"accuracy": 0.95}
html, md, csv = generate_comprehensive_report(metrics)
return html, md, csvAll structured string types (HTMLString, MarkdownString, CSVString, JSONString) are automatically rendered appropriately in the ZenML dashboard:
These types enable rich, automatically-visualized outputs from pipeline steps without requiring custom visualization code.
Install with Tessl CLI
npx tessl i tessl/pypi-zenml