Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
a3ec5bf
fix(dashboard): remove `pandas` deps, use `pyarrow` (#3157)
zilto Oct 2, 2025
d63abaa
add custom header generation to ArrowToCsvWriter with quoting style h…
burnash Oct 6, 2025
4c8fac8
[Databricks destination] Feat/2863 databricks table optimization (#3137)
bayees Oct 6, 2025
d3b87a5
feat:3162 add resource name to incremental extract duplicate checks l…
and2reak Oct 8, 2025
0169875
Feat/adds workspace (#3171)
rudolfix Oct 8, 2025
caf1028
Fix: make store_decimal_as_integer patching conditional on pyiceberg …
ivasio Oct 10, 2025
352b053
documents vault provider (#3160)
rudolfix Oct 10, 2025
b2ed341
QoL: accept destination name as shorthand form of destination (#3122)
anuunchin Oct 10, 2025
5ca7c95
Minor docs fix (#3197)
anuunchin Oct 14, 2025
71ffcad
removes cluster on create table test and allows only partition (#3191)
rudolfix Oct 14, 2025
bc2706b
renames `dlt_plus` plugin to `dlthub` (#3192)
rudolfix Oct 14, 2025
036aab3
skips dlthub tests properly
rudolfix Oct 15, 2025
8855732
Add redirect from dlt-plus pages to hub (#3195)
VioletM Oct 16, 2025
8a46409
repo(pytest): migrate to `pyproject.toml` and reduce verbosity (#3205)
zilto Oct 16, 2025
6f1b0b9
feat: unify `dlt.Relation` API and create bound Ibis tables (#3179)
zilto Oct 18, 2025
fe56741
chore/moves cli to `_workspace` module (#3215)
rudolfix Oct 19, 2025
e2ef7c1
feat/3103: Ensure consistency in HexBytes coercion (#3200)
alkaline-0 Oct 20, 2025
f4c4752
Update Databricks init scipt documentation (#3202)
AndreiBondarenko Oct 20, 2025
3298b40
Feat: workspace file selector, package builder (#3207)
anuunchin Oct 20, 2025
563c764
Feat/adds workspace configuration (#3221)
rudolfix Oct 20, 2025
9070650
Add new dlthub structure for docs (#3199)
VioletM Oct 21, 2025
e552606
fix: it should be destination (#3217)
Magicbeanbuyer Oct 22, 2025
986978d
adds pokemon table count consts (#3232)
rudolfix Oct 22, 2025
773a649
Feat/3154 convert script preprocess docs to python and add destinatio…
alkaline-0 Oct 22, 2025
7848c91
renames mcp pipeline tools (#3238)
rudolfix Oct 22, 2025
0dcdcf0
ignores native config values if config spec does not implement those …
rudolfix Oct 22, 2025
91dc3d9
avoids passing naming conventions as modules (#3229)
rudolfix Oct 23, 2025
4d629cc
feat: extend `TTableReference` (#3093)
zilto Oct 23, 2025
66da0e1
Feat: dlt.destination as named destination factory (#3204)
anuunchin Oct 23, 2025
f14eca1
Initial commit with add_metrics (#3240)
anuunchin Oct 23, 2025
98c8146
Feature: Introduce support of http based resources for fs source (#3029)
TheLazzziest Oct 23, 2025
a3d73a5
Fixes docs on schema file naming convention (#3244)
willi-mueller Oct 23, 2025
26d0cfa
Fix: add support for yield_map in rest resource (#3211)
ivasio Oct 23, 2025
76823c3
Skip `cluster by` in bigquery on alter statements (#3239)
adrian-173 Oct 23, 2025
84de711
Re-enable python 3.14 common tests (#3242)
sh-rp Oct 24, 2025
a94f5c7
graceful signal handler (#3234)
rudolfix Oct 24, 2025
b879236
init pipeline in three ways page (#3222)
AstrakhantsevaAA Oct 24, 2025
73e861f
add profiles (#3252)
AstrakhantsevaAA Oct 25, 2025
335aea8
Fix: workspace package manifest has sorted files (#3251)
anuunchin Oct 27, 2025
38b0dec
Add dlthub intro docs (#3241)
VioletM Oct 27, 2025
718b636
fix: `.to_ibis()` query normalization + docs update (#3225)
zilto Oct 27, 2025
449d914
Fix: Empty columns that were previously flattened into compound ones …
anuunchin Oct 27, 2025
e56f617
adds more signal options (#3248)
rudolfix Oct 28, 2025
df8ccec
fixes flaky signal tests in pipelines
rudolfix Oct 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
36 changes: 36 additions & 0 deletions .github/workflows/build_docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: docs | build docs

on:
workflow_call:
workflow_dispatch:

jobs:
build_docs:
name: docs | build docs
runs-on: ubuntu-latest

steps:
- name: Check out
uses: actions/checkout@master

- uses: pnpm/action-setup@v2
with:
version: 9.13.2

- uses: actions/setup-node@v5
with:
node-version: '22'

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install node dependencies
run: cd docs/website && npm install

- name: Install python dependencies
run: cd docs/website && pip install -r requirements.txt

- name: Build docs
run: cd docs/website && npm run build:cloudflare
13 changes: 9 additions & 4 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ jobs:
test_docs_snippets:
name: test snippets in docs
uses: ./.github/workflows/test_docs_snippets.yml

# NOTE: we build docs the same way as on cloudflare, so we can catch problems early
build_docs:
name: build docs
uses: ./.github/workflows/build_docs.yml

lint:
name: lint on all python versions
Expand Down Expand Up @@ -61,10 +66,10 @@ jobs:
needs: test_common
uses: ./.github/workflows/test_sources_local.yml

test_hub:
name: test dlthub features
needs: lint
uses: ./.github/workflows/test_hub.yml
# test_hub:
# name: test dlthub features
# needs: lint
# uses: ./.github/workflows/test_hub.yml

test_tools_airflow:
name: test airflow helpers
Expand Down
35 changes: 22 additions & 13 deletions .github/workflows/test_common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ jobs:
python-version: "3.13"
shell: bash

# - os: ubuntu-latest
# python-version: "3.14.0-beta.4"
# shell: bash
- os: "macos-14"
python-version: "3.14"
shell: bash

# linux test with minimal dependencies
- os: ubuntu-latest
Expand All @@ -63,11 +63,11 @@ jobs:
- os: windows-latest
python-version: "3.11"
shell: cmd
pytest_args: '-m "not forked"'
pytest_args: '-m "not forked and not rfam"'
- os: windows-latest
python-version: "3.13"
shell: cmd
pytest_args: '-m "not forked"'
pytest_args: '-m "not forked and not rfam"'

defaults:
run:
Expand Down Expand Up @@ -114,31 +114,40 @@ jobs:

- name: Install pyarrow
run: uv sync ${{ matrix.uv_sync_args }} --extra duckdb --extra cli --extra parquet --group sentry-sdk
if: matrix.python-version != '3.14.0-beta.4'
if: matrix.python-version != '3.14'

- name: Run pipeline tests with pyarrow but no pandas installed
run: |
pytest tests/pipeline/test_pipeline_extra.py -k arrow ${{ matrix.pytest_args }}
if: matrix.python-version != '3.14.0-beta.4'
if: matrix.python-version != '3.14'

- name: Install workspace dependencies
run: uv sync ${{ matrix.uv_sync_args }} --extra workspace --extra cli --group sentry-sdk
if: matrix.python-version != '3.14'

- name: Run workspace tests
run: |
pytest tests/workspace ${{ matrix.pytest_args }}
if: matrix.python-version != '3.14'

- name: Install pipeline and sources dependencies
run: uv sync ${{ matrix.uv_sync_args }} --extra duckdb --extra cli --extra parquet --extra deltalake --extra sql_database --group sentry-sdk --group pipeline --group sources --group ibis
if: matrix.python-version != '3.14.0-beta.4'
run: uv sync ${{ matrix.uv_sync_args }} --extra http --extra duckdb --extra cli --extra parquet --extra deltalake --extra sql_database --group sentry-sdk --group pipeline --group sources --group ibis
if: matrix.python-version != '3.14'

- name: Run extract and pipeline tests
run: |
pytest tests/extract tests/pipeline tests/libs tests/cli/common tests/destinations tests/sources ${{ matrix.pytest_args }}
if: matrix.python-version != '3.14.0-beta.4'
pytest tests/extract tests/pipeline tests/libs tests/destinations tests/sources ${{ matrix.pytest_args }}
if: matrix.python-version != '3.14'

# here we upgrade sql alchemy to 2 an run the sql_database tests again
- name: Upgrade sql alchemy
run: uv run pip install sqlalchemy==2.0.32
if: matrix.python-version != '3.14.0-beta.4'
if: matrix.python-version != '3.14'

- name: Run extract and pipeline tests
run: |
pytest tests/sources/sql_database
if: matrix.python-version != '3.14.0-beta.4'
if: matrix.python-version != '3.14'
matrix_job_required_check:
name: common | common tests
needs: run_common
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/test_destinations_local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,11 @@ jobs:
post_install_commands: "uv run pip install sqlalchemy==2.0.18" # minimum version required by `pyiceberg`

# TODO: also test ducklake in remote mode with a buckets and remote postgres
- name: postgres, duckdb, ducklake, and dummy with cli commands
- name: postgres, duckdb, ducklake, and dummy
destinations: "[\"postgres\", \"duckdb\", \"ducklake\", \"dummy\"]"
filesystem_drivers: "[\"memory\", \"file\"]"
extras: "--group adbc --extra postgres --extra postgis --extra parquet --extra duckdb --extra cli --extra filesystem"
needs_postgres: true
additional_tests: "pytest tests/cli"


# Clickhouse OSS (TODO: test with minio s3)
- name: clickhouse
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test_docs_snippets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ jobs:
- name: Install dependencies
run: uv sync --extra duckdb --extra weaviate --extra parquet --extra qdrant --extra bigquery --extra postgres --extra lancedb --extra s3 --extra workspace --group docs --group sentry-sdk --group ibis --group providers

- name: Install dlt-plus incl alpha releases
run: uv run pip install --pre dlt-plus
# - name: Install dlthub incl alpha releases
# run: uv run pip install --pre dlthub

- name: run docs preprocessor
run: make preprocess-docs
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test_examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ jobs:
- name: Install dependencies
run: uv sync --extra duckdb --extra weaviate --extra parquet --extra qdrant --extra bigquery --extra postgres --extra lancedb --extra s3 --extra workspace --group docs --group sentry-sdk --group ibis --group providers

- name: Install dlt-plus incl alpha releases
run: uv run pip install --pre dlt-plus
# - name: Install dlthub incl alpha releases
# run: uv run pip install --pre dlthub

- name: create secrets.toml for examples
run: pwd && echo "$DLT_SECRETS_TOML" > docs/examples/.dlt/secrets.toml
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/test_hub.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: hub | dlthub features

#
# dlt-plus smoke tests against the nightly build.
# dlthub smoke tests against the nightly build.
#

on:
Expand All @@ -19,7 +19,7 @@ jobs:
matrix:
os: ["ubuntu-latest", "macos-latest", "windows-latest"]
python-version: ["3.10", "3.11", "3.12"]
plus_dep: ["dlt-plus", "https://dlt-packages.fra1.digitaloceanspaces.com/dlt-plus/dlt_plus-0.0.0+nightly-py3-none-any.whl"]
dlthub_dep: ["dlthub", "https://dlt-packages.fra1.digitaloceanspaces.com/dlthub/dlthub-0.0.0+nightly-py3-none-any.whl"]
# Test all python versions on ubuntu only
exclude:
- os: "macos-latest"
Expand Down Expand Up @@ -61,8 +61,8 @@ jobs:
- name: Install all dependencies
run: make dev

- name: Install dlt-plus nightly devel build without cache
run: uv run pip install --upgrade --force-reinstall --no-cache-dir ${{ matrix.plus_dep }}
- name: Install dlthub nightly devel build without cache
run: uv run pip install --upgrade --force-reinstall --no-cache-dir ${{ matrix.dlthub_dep }}

- name: Run tests
run: pytest tests/hub
Expand Down
11 changes: 6 additions & 5 deletions .github/workflows/test_tools_dashboard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,18 +102,19 @@ jobs:
# Run pipeline dashboard unit tests
- name: Run pipeline dashboard unit tests
run: |
pytest tests/helpers/dashboard
pytest tests/workspace/helpers/dashboard

# Run pipeline dashboard e2e tests (does not pass with python 3.9, does not pass on windows (playwright does not work somehow), does not pass on python 3.13 (ibis not available))
# Mac is also disabled for the time being
# Run pipeline dashboard e2e tests (does not pass with python 3.9
- name: Run dashboard e2e
run: |
marimo run --headless dlt/helpers/dashboard/dlt_dashboard.py -- -- --pipelines-dir _storage/.dlt/pipelines/ --with_test_identifiers true & pytest --browser chromium tests/e2e
marimo run --headless dlt/_workspace/helpers/dashboard/dlt_dashboard.py -- -- --pipelines-dir _storage/.dlt/pipelines/ --with_test_identifiers true & pytest --browser chromium tests/e2e
if: matrix.python-version != '3.9' && matrix.python-version != '3.14.0-beta.4' && matrix.os != 'windows-latest'

# note that this test will pass only when running from cmd shell (_storage\.dlt\pipelines\ must stay)
- name: Run dashboard e2e windows
run: |
start marimo run --headless dlt/helpers/dashboard/dlt_dashboard.py -- -- --pipelines-dir _storage\.dlt\pipelines\ --with_test_identifiers true
start marimo run --headless dlt/_workspace/helpers/dashboard/dlt_dashboard.py -- -- --pipelines-dir _storage\.dlt\pipelines\ --with_test_identifiers true
timeout /t 6 /nobreak
pytest --browser chromium tests/e2e
if: matrix.python-version != '3.9' && matrix.python-version != '3.14.0-beta.4' && matrix.os == 'windows-latest'

Expand Down
20 changes: 0 additions & 20 deletions .github/workflows/tools_deploy_docs.yml

This file was deleted.

29 changes: 12 additions & 17 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@ dev: has-uv

dev-airflow: has-uv
uv sync --all-extras --group docs --group providers --group pipeline --group sources --group sentry-sdk --group ibis --group airflow

lint:

lint: lint-core lint-security lint-docstrings

lint-core:
uv run mypy --config-file mypy.ini dlt tests
# NOTE: we need to make sure docstring_parser_fork is the only version of docstring_parser installed
uv pip uninstall docstring_parser
Expand All @@ -59,22 +61,20 @@ lint:
uv run flake8 --extend-ignore=D --max-line-length=200 dlt
uv run flake8 --extend-ignore=D --max-line-length=200 tests --exclude tests/reflection/module_cases,tests/common/reflection/cases/modules/
uv run black dlt docs tests --check --diff --color --extend-exclude=".*syntax_error.py"
$(MAKE) lint-security
$(MAKE) lint-docstrings

format:
uv run black dlt docs tests --extend-exclude='.*syntax_error.py|_storage/.*'
uv run black docs/education --ipynb --extend-exclude='.*syntax_error.py|_storage/.*'

lint-snippets:
cd docs/tools && uv run python check_embedded_snippets.py full

lint-and-test-snippets: lint-snippets
# TODO: re-enable transformation snippets tests
# TODO: re-enable transformation snippets tests when dlthub dep is available
uv pip install docstring_parser_fork --reinstall
uv run mypy --config-file mypy.ini docs/website docs/tools --exclude docs/tools/lint_setup --exclude docs/website/docs_processed --exclude docs/website/versioned_docs/ --exclude docs/website/docs/general-usage/transformations/transformation-snippets.py
uv run mypy --config-file mypy.ini docs/website docs/tools --exclude docs/tools/lint_setup --exclude docs/website/docs_processed --exclude docs/website/versioned_docs/
uv run ruff check
uv run flake8 --max-line-length=200 docs/website docs/tools --exclude docs/website/.dlt-repo --exclude docs/website/docs/hub/features/transformations/transformation-snippets.py
uv run flake8 --max-line-length=200 docs/website docs/tools --exclude docs/website/.dlt-repo,docs/website/node_modules

lint-and-test-snippets: lint-snippets
cd docs/website/docs && uv run pytest --ignore=node_modules --ignore hub/features/transformations/transformation-snippets.py

lint-and-test-examples:
Expand Down Expand Up @@ -123,12 +123,7 @@ test-load-local-postgres:
DESTINATION__POSTGRES__CREDENTIALS=postgresql://loader:loader@localhost:5432/dlt_data ACTIVE_DESTINATIONS='["postgres"]' ALL_FILESYSTEM_DRIVERS='["memory"]' uv run pytest tests/load

test-common:
uv run pytest tests/common tests/normalize tests/extract tests/pipeline tests/reflection tests/sources tests/cli/common tests/load/test_dummy_client.py tests/libs tests/destinations

reset-test-storage:
-rm -r _storage
mkdir _storage
python3 tests/tools/create_storages.py
uv run pytest tests/common tests/normalize tests/extract tests/pipeline tests/reflection tests/sources tests/workspace tests/load/test_dummy_client.py tests/libs tests/destinations

build-library: dev
uv version
Expand Down Expand Up @@ -180,8 +175,8 @@ test-e2e-dashboard-headed:
uv run pytest --headed --browser chromium tests/e2e

start-dlt-dashboard-e2e:
uv run marimo run --headless dlt/helpers/dashboard/dlt_dashboard.py -- -- --pipelines-dir _storage/.dlt/pipelines --with_test_identifiers true
uv run marimo run --headless dlt/_workspace/helpers/dashboard/dlt_dashboard.py -- -- --pipelines-dir _storage/.dlt/pipelines --with_test_identifiers true

# creates the dashboard test pipelines globally for manual testing of the dashboard app and cli
create-test-pipelines:
uv run python tests/helpers/dashboard/example_pipelines.py
uv run python tests/workspace/helpers/dashboard/example_pipelines.py
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Be it a Google Colab notebook, AWS Lambda function, an Airflow DAG, your local l

## Installation

dlt supports Python 3.9 through Python 3.14 (beta 4). Note that some optional extras are not yet available for Python 3.14, so support for this version is considered experimental.
dlt supports Python 3.9 through Python 3.14. Note that some optional extras are not yet available for Python 3.14, so support for this version is considered experimental.

```sh
pip install dlt
Expand Down
1 change: 1 addition & 0 deletions dlt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"attach",
"Pipeline",
"dbt",
"hub",
"progress",
"current",
"mark",
Expand Down
2 changes: 1 addition & 1 deletion dlt/__main__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from dlt.cli._dlt import main
from dlt._workspace.cli._dlt import main

if __name__ == "__main__":
main()
18 changes: 18 additions & 0 deletions dlt/__plugins__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""A module that imports all pluggy plugins implementations to work with pyproject entrypoint"""
from typing import Any, Dict, Optional

from dlt.common.configuration import plugins as _plugins
from dlt.common.configuration.specs.pluggable_run_context import RunContextBase
from dlt.common.runtime.run_context import RunContext

# import workspace plugins before core plugin
from dlt._workspace._plugins import * # noqa
from dlt._workspace.cli._plugins import * # noqa


# make sure OSS context is tried last
@_plugins.hookimpl(specname="plug_run_context", trylast=True)
def plug_run_context_impl(
run_dir: Optional[str], runtime_kwargs: Optional[Dict[str, Any]]
) -> Optional[RunContextBase]:
return RunContext(run_dir)
File renamed without changes.
35 changes: 35 additions & 0 deletions dlt/_workspace/_plugins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import os
from typing import Any, Dict, Optional

from dlt._workspace.exceptions import WorkspaceRunContextNotAvailable
from dlt._workspace.profile import DEFAULT_PROFILE, read_profile_pin
from dlt.common.configuration import plugins as _plugins
from dlt.common.configuration.specs.pluggable_run_context import RunContextBase
from dlt.common.runtime.run_context import RunContext

from dlt._workspace.run_context import default_name
from dlt._workspace._workspace_context import (
WorkspaceRunContext,
is_workspace_dir,
)

__all__ = ["plug_workspace_context_impl"]


@_plugins.hookimpl(specname="plug_run_context", trylast=False)
def plug_workspace_context_impl(
run_dir: Optional[str], runtime_kwargs: Optional[Dict[str, Any]]
) -> Optional[RunContextBase]:
# TODO: if recursive search was requested
# if runtime_kwargs.get("_look_recursive")
run_dir = os.path.abspath(run_dir or ".")
if is_workspace_dir(run_dir):
profile: str = None
if runtime_kwargs:
profile = runtime_kwargs.get("profile")
profile = profile or read_profile_pin(RunContext(run_dir)) or DEFAULT_PROFILE
return WorkspaceRunContext(default_name(run_dir), run_dir, profile)
elif runtime_kwargs and runtime_kwargs.get("_required") == "WorkspaceRunContext":
raise WorkspaceRunContextNotAvailable(run_dir)

return None
Loading
Loading