Skip to content

mhadaily/ADME-FABRIC-ControlPlane

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

8 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

ADME-Fabric Control Plane

License: MIT Python 3.11+

A Streamlit-based dashboard for orchestrating data synchronization between Azure Data Manager for Energy (ADME) instances through Microsoft Fabric Lakehouses.

ADME-Fabric Control Plane Dashboard

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                            ADME-Fabric Control Plane                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”               β”‚
β”‚  β”‚    SOURCE ENVIRONMENT   β”‚         β”‚   TARGET ENVIRONMENT    β”‚               β”‚
β”‚  β”‚                         β”‚         β”‚                         β”‚               β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚         β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚               β”‚
β”‚  β”‚  β”‚   Source ADME   β”‚    β”‚         β”‚    β”‚   Target ADME   β”‚  β”‚               β”‚
β”‚  β”‚  β”‚  (Azure Data    β”‚    β”‚         β”‚    β”‚  (Azure Data    β”‚  β”‚               β”‚
β”‚  β”‚  β”‚   Manager for   β”‚    β”‚         β”‚    β”‚   Manager for   β”‚  β”‚               β”‚
β”‚  β”‚  β”‚    Energy)      β”‚    β”‚         β”‚    β”‚    Energy)      β”‚  β”‚               β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚         β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β–²β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚               β”‚
β”‚  β”‚           β”‚             β”‚         β”‚             β”‚           β”‚               β”‚
β”‚  β”‚           β”‚ Search &    β”‚         β”‚    Storage  β”‚           β”‚               β”‚
β”‚  β”‚           β”‚ Storage API β”‚         β”‚    API PUT  β”‚           β”‚               β”‚
β”‚  β”‚           β–Ό             β”‚         β”‚             β”‚           β”‚               β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚         β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚               β”‚
β”‚  β”‚  β”‚  Fabric         β”‚    β”‚  Sync   β”‚    β”‚  Fabric         β”‚  β”‚               β”‚
β”‚  β”‚  β”‚  Lakehouse      │────┼────────────▢│  Lakehouse      β”‚  β”‚               β”‚
β”‚  β”‚  β”‚  (Delta Tables) β”‚    β”‚  (EDS)  β”‚    β”‚  (Delta Tables) β”‚  β”‚               β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚         β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚               β”‚
β”‚  β”‚                         β”‚         β”‚                         β”‚               β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β”‚
β”‚                                                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚                         CONTROL PLANE (This App)                         β”‚  β”‚
β”‚  β”‚                                                                          β”‚  β”‚
β”‚  β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚  β”‚
β”‚  β”‚   β”‚  Streamlit   β”‚   β”‚   SQLite /   β”‚   β”‚   Fabric REST API        β”‚    β”‚  β”‚
β”‚  β”‚   β”‚  Dashboard   │◀─▢│   Azure SQL  β”‚   β”‚   (Notebook Triggers)    β”‚    β”‚  β”‚
β”‚  β”‚   β”‚              β”‚   β”‚   Database   β”‚   β”‚                          β”‚    β”‚  β”‚
β”‚  β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚  β”‚
β”‚  β”‚                                                                          β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Data Flow:
  1. Export: Source ADME ──▢ Source Lakehouse (via Export Notebook)
  2. Sync:   Source Lakehouse ──▢ Target Lakehouse (via External Data Share)
  3. Ingest: Target Lakehouse ──▢ Target ADME (via Ingest Notebook)
πŸ“Š View Interactive Mermaid Diagrams
flowchart TB
    subgraph SourceEnv["Source Environment"]
        ADME_S[("Source ADME<br/>Azure Data Manager<br/>for Energy")]
        subgraph FabricS["Source Fabric Workspace"]
            LH_S[("Source Lakehouse<br/>Delta Tables")]
            NB_Export["Export Notebook<br/>(ADME β†’ Fabric)"]
        end
    end

    subgraph TargetEnv["Target Environment"]
        subgraph FabricT["Target Fabric Workspace"]
            LH_T[("Target Lakehouse<br/>Delta Tables")]
            NB_Ingest["Ingest Notebook<br/>(Fabric β†’ ADME)"]
        end
        ADME_T[("Target ADME<br/>Azure Data Manager<br/>for Energy")]
    end

    subgraph ControlPlane["Control Plane Dashboard"]
        UI["Streamlit UI"]
        DB[("SQLite<br/>Jobs & Connections")]
        API["Fabric REST API<br/>Notebook Trigger"]
    end

    ADME_S -->|"1. Search & Storage API"| NB_Export
    NB_Export -->|"2. Write Delta"| LH_S
    LH_S -->|"3. EDS Sync"| LH_T
    LH_T -->|"4. Read Delta"| NB_Ingest
    NB_Ingest -->|"5. Storage API PUT"| ADME_T

    UI -->|"Configure & Monitor"| DB
    UI -->|"Trigger Jobs"| API
    API -->|"Execute"| NB_Export
    API -->|"Execute"| NB_Ingest
Loading

Data Flow Sequence

sequenceDiagram
    participant User
    participant Dashboard as Control Plane
    participant SrcADME as Source ADME
    participant SrcFabric as Source Fabric
    participant TgtFabric as Target Fabric
    participant TgtADME as Target ADME

    User->>Dashboard: Configure Sync Job
    User->>Dashboard: Click "Sync Now"

    rect rgb(240, 248, 255)
        Note over Dashboard,SrcFabric: Phase 1: Export
        Dashboard->>SrcFabric: Trigger Export Notebook
        SrcFabric->>SrcADME: Search API (get record IDs)
        SrcADME-->>SrcFabric: Record IDs + Cursor
        SrcFabric->>SrcADME: Storage API (batch records)
        SrcADME-->>SrcFabric: Full Record Data
        SrcFabric->>SrcFabric: Write to Delta Table
        SrcFabric-->>Dashboard: Export Complete (N records)
    end

    rect rgb(255, 248, 240)
        Note over SrcFabric,TgtFabric: Phase 2: Fabric Sync (EDS)
        Dashboard->>SrcFabric: Trigger Sync Notebook
        SrcFabric->>TgtFabric: External Data Share
        TgtFabric-->>Dashboard: Sync Complete
    end

    rect rgb(240, 255, 240)
        Note over TgtFabric,TgtADME: Phase 3: Ingest
        Dashboard->>TgtFabric: Trigger Ingest Notebook
        TgtFabric->>TgtFabric: Read from Delta Table
        TgtFabric->>TgtFabric: Transform Records
        TgtFabric->>TgtADME: Storage API PUT (batch)
        TgtADME-->>TgtFabric: Ingest Response
        TgtFabric-->>Dashboard: Ingest Complete (N records)
    end

    Dashboard-->>User: Job Complete βœ“
Loading

Features

  • Connection Management: Configure ADME-Fabric environment pairs with encrypted secrets
  • Sync Wizard: Multi-step wizard with cascading dropdowns for kind/partition selection
  • Real-time Dashboard: Monitor active jobs with live logs and progress tracking
  • Job History: View past jobs, clone configurations, re-run with identical settings
  • Error Browser: Analyze errors with categorization and full stack traces
  • Comprehensive Logging: Full API request/response tracking for debugging
  • Mock Mode: Develop and test without real ADME/Fabric connections

Tech Stack

Component Technology Version
Frontend/Backend Streamlit 1.40.0
Database SQLite + SQLAlchemy 2.0.25
Authentication MSAL 1.26.0
HTTP Client Requests + urllib3 2.31.0
Encryption Fernet (cryptography) 41.0.7
Validation Pydantic 2.5.3

πŸš€ Getting Started

Prerequisites

  • Python 3.11+ (Download)
  • Git (Download)
  • Azure Service Principal with permissions to:
    • Azure Data Manager for Energy (ADME)
    • Microsoft Fabric workspace
  • Microsoft Fabric workspace with a Lakehouse

Step 1: Clone the Repository

git clone https://github.com/mhadaily/ADME-FABRIC-ControlPlane.git
cd ADME-FABRIC-ControlPlane

Step 2: Create Virtual Environment

Windows (PowerShell):

python -m venv .venv
.\.venv\Scripts\Activate.ps1

Linux/macOS:

python3 -m venv .venv
source .venv/bin/activate

Step 3: Install Dependencies

pip install -r requirements.txt

Step 4: Configure Environment

# Copy the example environment file
copy .env.example .env   # Windows
# cp .env.example .env   # Linux/macOS

Generate an encryption key:

python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

Edit .env and add your encryption key:

ENCRYPTION_KEY=your-generated-key-here
LOG_LEVEL=INFO
MOCK_MODE=false

Step 5: Run the Application

streamlit run app.py

The application will open at http://localhost:8501


πŸ§ͺ Development

Mock Mode (Recommended for Development)

Enable mock mode to develop without real ADME/Fabric connections:

# .env
MOCK_MODE=true

Mock mode provides:

  • Simulated ADME kinds and partitions
  • Fake record counts
  • Delayed responses to simulate network latency
  • No actual API calls

Running with Debug Logging

# .env
LOG_LEVEL=DEBUG
DEBUG=true

Project Structure

adme-fabric-control-plane/
β”œβ”€β”€ app.py                          # Streamlit entry point
β”œβ”€β”€ requirements.txt                # Python dependencies
β”œβ”€β”€ Dockerfile                      # Container configuration
β”œβ”€β”€ .env.example                    # Environment template
β”œβ”€β”€ LICENSE                         # MIT License
β”œβ”€β”€ CONTRIBUTING.md                 # Contribution guidelines
β”‚
β”œβ”€β”€ config/
β”‚   β”œβ”€β”€ settings.py                 # Pydantic settings with defaults
β”‚   └── logging_config.py           # Logging configuration
β”‚
β”œβ”€β”€ database/
β”‚   β”œβ”€β”€ models.py                   # SQLAlchemy models
β”‚   └── db.py                       # Database session management
β”‚
β”œβ”€β”€ clients/
β”‚   β”œβ”€β”€ base_client.py              # HTTP client with retry logic
β”‚   β”œβ”€β”€ adme_client.py              # ADME API client
β”‚   └── fabric_client.py            # Fabric API client
β”‚
β”œβ”€β”€ services/
β”‚   β”œβ”€β”€ auth_service.py             # Token management & caching
β”‚   β”œβ”€β”€ connection_service.py       # Environment CRUD operations
β”‚   β”œβ”€β”€ job_service.py              # Job tracking & management
β”‚   β”œβ”€β”€ sync_service.py             # 3-phase sync orchestration
β”‚   β”œβ”€β”€ scheduler_service.py        # Job scheduling
β”‚   └── error_service.py            # Centralized error handling
β”‚
β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ connection_form.py          # Environment configuration form
β”‚   β”œβ”€β”€ sync_wizard.py              # Multi-step sync wizard
β”‚   β”œβ”€β”€ query_builder.py            # LUCENE query builder
β”‚   β”œβ”€β”€ job_card.py                 # Job status card
β”‚   β”œβ”€β”€ log_viewer.py               # Real-time log viewer
β”‚   └── error_display.py            # Error banners & details
β”‚
β”œβ”€β”€ pages/
β”‚   β”œβ”€β”€ 1_πŸ”—_Connections.py         # Connection management
β”‚   β”œβ”€β”€ 2_πŸ“_Data_Product_Definitions.py  # Data product definitions
β”‚   β”œβ”€β”€ 3_πŸš€_Publish.py             # Publish data products
β”‚   β”œβ”€β”€ 4_πŸ“₯_Consume.py             # Consume data products
β”‚   β”œβ”€β”€ 5_πŸ“Š_Dashboard.py           # Real-time monitoring
β”‚   β”œβ”€β”€ 6_πŸ“œ_History.py             # Job history
β”‚   └── 8_⏰_Scheduled_Jobs.py      # Scheduled jobs
β”‚
β”œβ”€β”€ utils/
β”‚   β”œβ”€β”€ exceptions.py               # Custom exception classes
β”‚   β”œβ”€β”€ validators.py               # Input validation
β”‚   β”œβ”€β”€ encryption.py               # Fernet encryption helpers
β”‚   β”œβ”€β”€ keyvault.py                 # Azure Key Vault integration
β”‚   └── secrets_manager.py          # Secrets management
β”‚
β”œβ”€β”€ notebooks/                      # Fabric notebook templates
β”‚   β”œβ”€β”€ README.md                   # Deployment instructions
β”‚   β”œβ”€β”€ adme_export_notebook_v2.py  # ADME β†’ Fabric export
β”‚   └── adme_ingest_notebook_v2.py  # Fabric β†’ ADME ingest
β”‚
β”œβ”€β”€ docs/                           # Additional documentation
β”‚   β”œβ”€β”€ COMPLETE_WORKFLOW_GUIDE.md
β”‚   β”œβ”€β”€ SECRETS_MANAGEMENT.md
β”‚   └── FABRIC_API_VERIFICATION.md
β”‚
└── tests/                          # Test suite
    β”œβ”€β”€ conftest.py
    β”œβ”€β”€ test_encryption.py
    β”œβ”€β”€ test_fabric_api.py
    └── test_validators.py

Code Style

The project uses:

  • Black for code formatting
  • MyPy for type checking
  • Pytest for testing
# Format code
black .

# Type check
mypy .

# Run tests
pytest

Adding a New Page

  1. Create a file in pages/ with emoji prefix (e.g., 6_βš™οΈ_Settings.py)
  2. Add page config at the top:
    import streamlit as st
    st.set_page_config(page_title="Settings", page_icon="βš™οΈ", layout="wide")
  3. Streamlit auto-discovers pages from the pages/ folder

πŸ§ͺ Testing

Run All Tests

pytest

Run with Coverage

pytest --cov=. --cov-report=html
# Open htmlcov/index.html to view report

Test Categories

# Unit tests only
pytest tests/unit/

# Integration tests
pytest tests/integration/

# Specific test file
pytest tests/unit/test_validators.py

Manual Testing Checklist

  1. Connections Page

    • Add new environment
    • Test ADME connection
    • Test Fabric connection
    • Edit existing environment
    • Delete environment
  2. Sync Page

    • Select source environment
    • Select data partition
    • Select kind (record type)
    • Configure filters
    • Select target environment
    • Execute sync job
  3. Dashboard

    • View active jobs
    • View job progress
    • Cancel running job
    • View logs
  4. History

    • View completed jobs
    • Clone job configuration
    • Re-run job
    • Export job logs

🐳 Docker

Build Image

docker build -t adme-fabric-control-plane .

Run Container

docker run -d \
  --name adme-control-plane \
  -p 8501:8501 \
  -e ENCRYPTION_KEY=your-fernet-key \
  -e LOG_LEVEL=INFO \
  -v $(pwd)/data:/app/data \
  adme-fabric-control-plane

Docker Compose

Create docker-compose.yml:

version: '3.8'
services:
  control-plane:
    build: .
    ports:
      - '8501:8501'
    environment:
      - ENCRYPTION_KEY=${ENCRYPTION_KEY}
      - LOG_LEVEL=INFO
      - MOCK_MODE=false
    volumes:
      - ./data:/app/data
    restart: unless-stopped

Run:

docker-compose up -d

☁️ Deployment

Recommended: Deploy with PowerShell Script

The easiest way to deploy to Azure Container Apps is using the included deployment script:

# Deploy to Azure (creates all resources automatically)
./deploy.ps1

# Or with custom parameters
./deploy.ps1 -ResourceGroup "my-rg" -Location "eastus" -AppName "my-control-plane"

The script automatically:

  • Creates Azure Container Registry
  • Builds and pushes the Docker image
  • Creates Azure Container Apps environment
  • Configures managed identity for Key Vault access
  • Sets up Azure Key Vault for secrets storage
  • Deploys the application

Alternative: Azure App Service

Option 1: Deploy from Container Registry

  1. Push to Azure Container Registry:

    az acr login --name <your-acr>
    docker tag adme-fabric-control-plane <your-acr>.azurecr.io/adme-control-plane:latest
    docker push <your-acr>.azurecr.io/adme-control-plane:latest
  2. Create App Service:

    az webapp create \
      --resource-group <rg-name> \
      --plan <plan-name> \
      --name <app-name> \
      --deployment-container-image-name <your-acr>.azurecr.io/adme-control-plane:latest
  3. Configure Environment:

    az webapp config appsettings set \
      --resource-group <rg-name> \
      --name <app-name> \
      --settings \
        ENCRYPTION_KEY="your-fernet-key" \
        LOG_LEVEL="INFO" \
        WEBSITES_PORT="8501"

Option 2: Deploy from Source

  1. Create App Service (Python 3.11):

    az webapp create \
      --resource-group <rg-name> \
      --plan <plan-name> \
      --name <app-name> \
      --runtime "PYTHON:3.11"
  2. Configure Startup Command:

    az webapp config set \
      --resource-group <rg-name> \
      --name <app-name> \
      --startup-file "streamlit run app.py --server.port 8000 --server.address 0.0.0.0 --server.headless true"
  3. Deploy Code:

    az webapp deployment source config-local-git \
      --resource-group <rg-name> \
      --name <app-name>
    
    git remote add azure <git-url-from-output>
    git push azure main

Environment Variables for Production

Variable Description Required
ENCRYPTION_KEY Fernet encryption key βœ… Yes
DATABASE_PATH SQLite path (use persistent storage) βœ… Yes
LOG_LEVEL INFO or WARNING for production No
MOCK_MODE Must be false No
WEBSITES_PORT Set to 8501 for Azure βœ… Yes (Azure)

Persistent Storage (Azure)

For production, mount Azure Files for SQLite persistence:

az webapp config storage-account add \
  --resource-group <rg-name> \
  --name <app-name> \
  --custom-id data \
  --storage-type AzureFiles \
  --share-name <share-name> \
  --account-name <storage-account> \
  --mount-path /app/data \
  --access-key <access-key>

πŸ“’ Fabric Notebooks

Deployment Steps

  1. Navigate to your Fabric workspace
  2. Create a new Notebook for each:
    • adme_export_notebook.py β†’ Export Notebook
    • fabric_sync_notebook.py β†’ Sync Notebook
    • adme_ingest_notebook.py β†’ Ingest Notebook
  3. Copy the content from notebooks/ into each Fabric notebook
  4. Update environment configuration in your Control Plane with the notebook IDs

Notebook Parameters

The notebooks accept parameters via the Fabric REST API when triggered from the Control Plane:

Notebook Key Parameters
Export dataPartitionId, admeServerUrl, searchApiKind, credentials
Sync source_workspace_id, target_workspace_id, sync_mode
Ingest osduEndpoint, dataPartitionId, batch_size, credentials

See notebooks/README.md for detailed deployment instructions.


πŸ”’ Security

Secrets Management

  • All secrets (client secrets) are encrypted using Fernet symmetric encryption
  • The encryption key is stored as an environment variable (never in code)
  • Secrets are decrypted only when needed for API calls

Generate Encryption Key

from cryptography.fernet import Fernet
print(Fernet.generate_key().decode())

Best Practices

  • βœ… Never commit .env files
  • βœ… Use Azure Key Vault for production secrets
  • βœ… Rotate encryption keys periodically
  • βœ… Enable HTTPS at the load balancer/App Service level
  • βœ… Restrict network access to the App Service

πŸ› Troubleshooting

Common Issues

"ENCRYPTION_KEY not set"

Make sure .env file exists and contains ENCRYPTION_KEY

Database locked error

SQLite doesn't support concurrent writes. This usually resolves itself.
For production, consider using PostgreSQL.

"Connection refused" to ADME

1. Check ADME server URL (must be HTTPS)
2. Verify Service Principal has permissions
3. Check firewall rules

Streamlit "AxiosError"

Usually a browser cache issue. Clear cache or try incognito mode.

Logs

View application logs:

# Local development
streamlit run app.py 2>&1 | tee app.log

# Docker
docker logs adme-control-plane

# Azure App Service
az webapp log tail --name <app-name> --resource-group <rg-name>

πŸ“ License

This project is licensed under the MIT License - see the LICENSE file for details.

🀝 Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit changes (git commit -m 'Add amazing feature')
  4. Push to branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“š References

Data Product Flow

Steps & APIs

  1. Create Data Product

    • User selects source environment, partition, kinds, and query.
    • APIs:
      • GET /api/partition/v1/partitions (ADME): List partitions
      • POST /api/search/v2/query (ADME): Aggregate kinds with counts
      • POST /api/search/v2/query (ADME): Preview/filter records
    • Result: Data product definition is saved.
  2. Publish Data Product

    • User triggers export/publish for a data product.
    • APIs:
      • POST /notebooks/{export_notebook_id}/execute (Fabric): Start export
      • GET /notebooks/{export_notebook_id}/status (Fabric): Poll for export
      • POST /notebooks/{sync_notebook_id}/execute (Fabric): (Optional) Sync
      • POST /notebooks/{ingest_notebook_id}/execute (Fabric): Start ingest
      • GET /notebooks/{ingest_notebook_id}/status (Fabric): Poll for ingest
    • Result: Data is exported from ADME, processed in Fabric, and ready for sharing.
  3. Consume Data Product

    • User selects a published data product to ingest into their own ADME.
    • APIs:
      • GET /api/data-products (Fabric/Custom): List data products
      • POST /api/consume (Fabric/Custom): Trigger ingestion
    • Result: Data product is ingested into the consumer’s ADME environment.

Mermaid Diagram

flowchart TD
    A[User: Create Data Product] -->|Selects Source, Partition, Kind| B[ADME API: /partitions, /query]
    B -->|Save Config| C[Control Plane: Save Data Product]
    C -->|User Publishes| D[Fabric API: Execute Export Notebook]
    D -->|Exported Data| E[Fabric Lakehouse]
    E -->|Execute Ingest Notebook| F[Fabric API: Ingest to Target ADME]
    F -->|Data Ready| G[Data Product Published]
    G -->|User Consumes| H[Fabric API: List/Consume Data Product]
    H -->|Ingested| I[Target ADME]
Loading

Text Summary

  1. Create Data Product: The user defines a data product by selecting the source ADME, partition, and kinds. The app calls ADME APIs to list partitions and kinds, and saves the configuration.

  2. Publish Data Product: When the user publishes, the app triggers Fabric notebooks via the Fabric API to export data from ADME, process it in Fabric, and prepare it for sharing.

  3. Consume Data Product: Users will be able to browse and subscribe to published data products, triggering ingestion into their own ADME environment.

About

No description, website, or topics provided.

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors