Skip to main content

A CLI tool to hydrate Microsoft Fabric Lakehouse metadata from Delta Lake schemas

Project description

Fabric Lakehouse Metadata Hydrator

CI PyPI version Python 3.10+ License: MIT

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:

  1. Reading Delta Lake schemas directly from OneLake/ADLS storage
  2. Generating Fabric-compatible metadata JSON for documentation and validation
  3. Comparing schemas between source Delta tables and target Fabric workspaces
  4. 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fabric_hydrate-1.0.1.tar.gz (44.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fabric_hydrate-1.0.1-py3-none-any.whl (25.3 kB view details)

Uploaded Python 3

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

Hashes for fabric_hydrate-1.0.1.tar.gz
Algorithm Hash digest
SHA256 d68bdb548ddb9545956963379f1f56907857b96679b4ddf1d9b17ce0bea8c7bc
MD5 59aea3155e591ba030eb329dc9aa7a06
BLAKE2b-256 e41397804ac6fc9d32222ee82226dfa3b6105c0a7cc6628601e7e7b4cab47ae3

See more details on using hashes here.

Provenance

The following attestation bundles were made for fabric_hydrate-1.0.1.tar.gz:

Publisher: publish.yml on mjtpena/fabric-hydrate

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for fabric_hydrate-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 efa91af9045f25806bf249c61b813e6faefbdd002eae043d99a0fce1cf751881
MD5 5b6dc2df5f6f51cc5b97f542cfe1f5d8
BLAKE2b-256 78342d8627fd9684b90b6ca812237164966792d4a9fc86255f070864eb4d9be9

See more details on using hashes here.

Provenance

The following attestation bundles were made for fabric_hydrate-1.0.1-py3-none-any.whl:

Publisher: publish.yml on mjtpena/fabric-hydrate

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page