Metadata-Version: 2.5
Name: vibedata-dlt-fabric-warehouse-studio
Version: 0.4.0
Summary: VibeData dlt runtime — Fabric Warehouse execution unit (runs targeting a Fabric Warehouse over TDS, in the Studio intent venv or as a published Fabric notebook): audience-bound token auth for dlt's fabric destination plus OneLake staging in the bridge Lakehouse.
Author-email: Vibedata <eng@acceleratedata.ai>
License: MIT
Requires-Python: >=3.11
Requires-Dist: adlfs>=2026.8.0
Requires-Dist: azure-core>=1.30.0
Requires-Dist: dlt[fabric,filesystem]<1.31,>=1.30
Requires-Dist: requests>=2.31.0
Requires-Dist: vibedata-dlt-fabric-core
Requires-Dist: vibedata-dlt-studio-secrets
Requires-Dist: vibedata-studio-azure-cred-broker>=0.1.4
Provides-Extra: dev
Requires-Dist: pytest-mock>=3.12; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Description-Content-Type: text/markdown

# vibedata-dlt-fabric-warehouse-studio

Fabric **Warehouse** Studio execution unit for the VibeData dlt runtime — the installed distribution for Domains whose Fabric data platform is a Warehouse rather than a Lakehouse. dlt's own `fabric` destination does the loading; this unit supplies the two things it cannot get by itself: an audience-bound access token in place of a client secret, and a credential for the OneLake staging area the run is configured with, holding the parquet that `COPY INTO` reads back.

The same pipeline runs in the Studio-local intent venv and, once published, as a Fabric notebook. Only where the token and the Domain's Key Vault come from differs, and the unit resolves that from the environment.

Import this unit **before** dlt. In a Fabric notebook it has to stand the kernel's preloaded storage stack aside, and `import dlt` binds that stack at module scope; the wrong order raises rather than loading silently against two different copies.

```python
from vibedata.dlt.fabric_warehouse import setup_environment, finalize, onelake_staging
import dlt

setup_environment()
pipeline = dlt.pipeline(pipeline_name="<name>", destination="fabric",
                        staging=onelake_staging(), dataset_name="<schema>")
try:
    pipeline.run(source)
except Exception as e:
    finalize(pipeline, error_message=str(e)); raise
finalize(pipeline)
```

`setup_environment()` and `finalize()` are the whole API — the same pair every execution unit exposes. `setup_environment()` asserts dlt's `fabric` destination is patched for token auth, registers the venue's token provider and secret provider, and resolves the staging location. `finalize()` persists the audit tables and stops there: dlt performs the load itself, so unlike the Lakehouse unit there is nothing left to sync.

The staging location is read from dlt config as `[destination.filesystem] bucket_url`, overridable through `DESTINATION__FILESYSTEM__BUCKET_URL`. It must be an `abfss://` URL on OneLake naming its workspace by GUID: Fabric's OneLake endpoints reject display names, so a non-GUID is refused at setup. Absent the key there is no staging location and the load goes row by row.

## The dlt pin

`dlt>=1.30,<1.31`. The `fabric` destination arrived in 1.30 and only speaks client-secret service-principal auth, so this unit patches five of its private seams: the destination's config spec, `FabricCredentials.on_partial`, `FabricCredentials.get_odbc_dsn_dict`, `FabricSqlClient.open_connection`, and `FabricCopyFileLoadJob._ensure_fabric_token_initialized`. None of those is public API, so a minor bump can move them and the upper bound is a correctness fence rather than caution. `mssql` and `synapse` are never touched.

Upstream support for an access token on the Fabric credentials — an `access_token` field and `attrs_before` on the connection — would make `_spec.py` and `_patch.py` deletable, leaving only staging and bootstrap.
