A CLI tool to hydrate Microsoft Fabric Lakehouse metadata from Delta Lake schemas
Project description
Fabric Lakehouse Metadata Hydrator
A production-ready CLI tool to extract, compare, and hydrate Microsoft Fabric Lakehouse metadata from Delta Lake table schemas.
🎯 Purpose
Microsoft Fabric's REST API provides table-level metadata but doesn't expose column-level schema information. This tool bridges that gap by:
- Reading Delta Lake schemas directly from OneLake/ADLS storage
- Generating Fabric-compatible metadata JSON for documentation and validation
- Comparing schemas between source Delta tables and target Fabric workspaces
- Enabling CI/CD workflows via GitHub Actions integration
✨ Features
- Delta Lake Schema Extraction - Read schemas from local paths or OneLake (ABFSS)
- Fabric Metadata Generation - Convert Delta schemas to Fabric-compatible format
- Schema Diff Engine - Compare schemas and detect additions, removals, type changes
- REST API Client - Full async support with retry logic and rate limiting
- Production Ready - Comprehensive error handling, logging, and retry mechanisms
- GitHub Actions - Ready-to-use action for CI/CD pipelines
- Type Safety - Full type hints with PEP 561 py.typed marker
📦 Installation
pip install fabric-hydrate
For development:
pip install -e ".[dev]"
🚀 Quick Start
Extract Schema from Local Delta Table
fabric-hydrate schema extract ./path/to/delta/table
Extract Schema from OneLake
fabric-hydrate schema extract "abfss://workspace@onelake.dfs.fabric.microsoft.com/lakehouse.Lakehouse/Tables/my_table"
Compare Schemas (Diff)
fabric-hydrate diff ./local/table --workspace-id <id> --lakehouse-id <id>
Validate Configuration
fabric-hydrate validate config.yaml
⚙️ Configuration
Create a fabric-hydrate.yaml configuration file:
# fabric-hydrate.yaml
workspace_id: "your-workspace-guid"
lakehouse_id: "your-lakehouse-guid"
tables:
- name: customers
source: "./data/customers"
- name: orders
source: "abfss://workspace@onelake.dfs.fabric.microsoft.com/lakehouse.Lakehouse/Tables/orders"
output:
format: json # or yaml
path: "./metadata"
🔐 Authentication
Interactive (Development)
az login
fabric-hydrate schema extract <path>
Service Principal (CI/CD)
Set environment variables:
export AZURE_CLIENT_ID="your-client-id"
export AZURE_CLIENT_SECRET="your-client-secret"
export AZURE_TENANT_ID="your-tenant-id"
Then run commands as usual - the tool will automatically use service principal authentication.
🔧 CI/CD Integration
GitHub Actions
- name: Hydrate Fabric Metadata
uses: mjtpena/fabric-hydrate@v1
with:
workspace-id: ${{ secrets.FABRIC_WORKSPACE_ID }}
lakehouse-id: ${{ secrets.FABRIC_LAKEHOUSE_ID }}
config-path: ./fabric-hydrate.yaml
dry-run: true
Azure DevOps Pipelines
Use the reusable template or run directly:
# azure-pipelines.yml
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '3.11'
- script: |
pip install fabric-hydrate
fabric-hydrate hydrate --config fabric-hydrate.yaml --output ./metadata
displayName: 'Run Fabric Hydrate'
env:
AZURE_CLIENT_ID: $(AZURE_CLIENT_ID)
AZURE_CLIENT_SECRET: $(AZURE_CLIENT_SECRET)
AZURE_TENANT_ID: $(AZURE_TENANT_ID)
- publish: ./metadata
artifact: 'fabric-metadata'
Or use the provided template from azure-devops/templates/fabric-hydrate.yml:
steps:
- template: azure-devops/templates/fabric-hydrate.yml
parameters:
command: 'hydrate'
configPath: 'fabric-hydrate.yaml'
workspaceId: '$(FABRIC_WORKSPACE_ID)'
lakehouseId: '$(FABRIC_LAKEHOUSE_ID)'
See Azure DevOps README for full documentation including the Azure DevOps Marketplace extension.
🏭 Production Features
Logging
Enable verbose or debug logging:
# Verbose output
fabric-hydrate --verbose schema extract ./data/table
# Debug logging
fabric-hydrate --debug schema extract ./data/table
JSON Logging (for log aggregation)
from fabric_hydrate.logging import setup_logging
# Enable JSON logging for production
logger = setup_logging(level="INFO", json_format=True)
Retry Logic
The Fabric API client includes automatic retry with exponential backoff:
from fabric_hydrate.retry import RetryConfig, retry
from fabric_hydrate.fabric_client import FabricAPIClient
# Custom retry configuration
config = RetryConfig(
max_retries=5,
base_delay=1.0,
max_delay=60.0,
jitter=True
)
Async Support
For high-performance workloads:
from fabric_hydrate.fabric_client import FabricAPIClient
async with FabricAPIClient(workspace_id="...", lakehouse_id="...") as client:
tables = await client.async_list_tables()
for table in tables:
metadata = await client.async_get_table_metadata(table.name)
Custom Exception Handling
from fabric_hydrate.exceptions import (
FabricAPIError,
RateLimitError,
AuthenticationError,
DeltaTableError,
)
try:
schema = reader.read_schema("./path/to/table")
except DeltaTableError as e:
logger.error(f"Failed to read Delta table: {e}")
except FabricAPIError as e:
if e.status_code == 429:
logger.warning(f"Rate limited, retry after {e.retry_after}s")
�📊 Output Example
{
"table_name": "customers",
"schema": {
"fields": [
{
"name": "customer_id",
"type": "long",
"nullable": false,
"metadata": {}
},
{
"name": "email",
"type": "string",
"nullable": true,
"metadata": {}
}
]
},
"partition_columns": ["region"],
"properties": {
"delta.minReaderVersion": "1",
"delta.minWriterVersion": "2"
}
}
🛠️ Development
Setup
git clone https://github.com/mjtpena/fabric-hydrate.git
cd fabric-hydrate
pip install -e ".[dev]"
pre-commit install
Run Tests
pytest
Linting
ruff check .
ruff format .
mypy src/
� Architecture
src/fabric_hydrate/
├── __init__.py # Package exports
├── cli.py # Typer CLI commands
├── delta_reader.py # Delta Lake schema extraction
├── diff_engine.py # Schema comparison engine
├── exceptions.py # Custom exception hierarchy
├── fabric_client.py # Fabric REST API client (async + sync)
├── logging.py # Structured logging configuration
├── metadata_generator.py # Fabric metadata conversion
├── models.py # Pydantic data models
├── retry.py # Retry with exponential backoff
└── py.typed # PEP 561 type marker
🔒 Security
- Supports Azure CLI, Service Principal, and Managed Identity authentication
- Never logs sensitive credentials
- Uses httpx with secure defaults
�📝 License
MIT License - see LICENSE for details.
🤝 Contributing
Contributions are welcome! Please read our Contributing Guide for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fabric_hydrate-1.0.1.tar.gz.
File metadata
- Download URL: fabric_hydrate-1.0.1.tar.gz
- Upload date:
- Size: 44.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d68bdb548ddb9545956963379f1f56907857b96679b4ddf1d9b17ce0bea8c7bc
|
|
| MD5 |
59aea3155e591ba030eb329dc9aa7a06
|
|
| BLAKE2b-256 |
e41397804ac6fc9d32222ee82226dfa3b6105c0a7cc6628601e7e7b4cab47ae3
|
Provenance
The following attestation bundles were made for fabric_hydrate-1.0.1.tar.gz:
Publisher:
publish.yml on mjtpena/fabric-hydrate
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fabric_hydrate-1.0.1.tar.gz -
Subject digest:
d68bdb548ddb9545956963379f1f56907857b96679b4ddf1d9b17ce0bea8c7bc - Sigstore transparency entry: 829765636
- Sigstore integration time:
-
Permalink:
mjtpena/fabric-hydrate@ca70550d18b4c6878e572733de5deb56e8fd780c -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/mjtpena
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ca70550d18b4c6878e572733de5deb56e8fd780c -
Trigger Event:
release
-
Statement type:
File details
Details for the file fabric_hydrate-1.0.1-py3-none-any.whl.
File metadata
- Download URL: fabric_hydrate-1.0.1-py3-none-any.whl
- Upload date:
- Size: 25.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
efa91af9045f25806bf249c61b813e6faefbdd002eae043d99a0fce1cf751881
|
|
| MD5 |
5b6dc2df5f6f51cc5b97f542cfe1f5d8
|
|
| BLAKE2b-256 |
78342d8627fd9684b90b6ca812237164966792d4a9fc86255f070864eb4d9be9
|
Provenance
The following attestation bundles were made for fabric_hydrate-1.0.1-py3-none-any.whl:
Publisher:
publish.yml on mjtpena/fabric-hydrate
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fabric_hydrate-1.0.1-py3-none-any.whl -
Subject digest:
efa91af9045f25806bf249c61b813e6faefbdd002eae043d99a0fce1cf751881 - Sigstore transparency entry: 829765647
- Sigstore integration time:
-
Permalink:
mjtpena/fabric-hydrate@ca70550d18b4c6878e572733de5deb56e8fd780c -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/mjtpena
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ca70550d18b4c6878e572733de5deb56e8fd780c -
Trigger Event:
release
-
Statement type: