Skip to content

feat!: merge Python node folders into python/ - #850

Merged
kvlonge merged 9 commits into
mainfrom
feat/python-node-root
Sep 27, 2026
Merged

kvlonge merged 9 commits into
mainfrom
feat/python-node-root

Conversation

@kvlonge

@kvlonge kvlonge commented Sep 27, 2026

Copy link
Copy Markdown
Contributor

Why

Python nodes were split across tasks/, assets/, checks/, loaders/, factories/ and libs/, with folder-kind rules that added errors without adding meaning. Orchestrator code (dagster/, rivers_pipeline/, root definitions.py) also lived inside the SQLBuild project, although nothing in SQLBuild reads it.

Changes

  • Python nodes and their helpers live under one python/ root, discovered recursively. The decorator decides the node kind, and helper modules without decorators are imported but never become nodes.
  • Modules are imported under their python.* package names, bound to the project's own python/ directory, so relative imports work and helpers initialise once per discovery pass. An unrelated installed python package is restored afterwards.
  • A factory that returns an already-registered node registers it once. Distinct nodes with the same name still conflict.
  • Allowed project Python roots: adapters, materializations, providers, python, rules, sinks, root adapter.py. The removed roots fail with D016. D010 is removed; loader import failures report D011.
  • Path selectors, sqb init, playground templates, examples and docs use python/. The Dagster and Rivers playgrounds generate a wrapper directory with definitions.py, and the SQLBuild project nested in waffle_shop/ along with its skill files.

BREAKING CHANGE: move Python node files into python/, and move orchestrator code out of the SQLBuild project.

Verification

  • make test: 7,848 passed. make check-ci passed.
  • New unit tests and DuckDB E2E tests (real CLI) for: nested python/ layouts, relative-import helpers, single initialisation, helper edits changing node identity, factory de-duplication, an unrelated python package on PYTHONPATH, D016 for each removed root, sqb init, and the Dagster and Rivers wrapper playgrounds.
  • One independent review plus a follow-up pass; all findings fixed.

Discover loaders, tasks, assets, checks, factories, and audit factories
anywhere under a single python/ root. The decorator defines each node
kind, so folder-based kind validation is gone and undecorated helper
modules under python/ are importable without becoming nodes.

Remove the tasks/, assets/, checks/, loaders/, factories/, libs/,
dagster/, and rivers_pipeline/ Python roots and the root definitions.py
allowance. The Dagster and Rivers playgrounds now generate an
orchestrator directory with definitions.py next to a nested waffle_shop/
SQLBuild project. Path selectors for Python nodes use the python/ root.

BREAKING CHANGE: Python nodes and their helper modules must live under
python/ (for example python/tasks/orders.py, imported as
python.tasks.orders). Python under tasks/, assets/, checks/, loaders/,
factories/, libs/, dagster/, rivers_pipeline/, or a root definitions.py
now fails compilation with D016. Python path selectors use python/...
instead of tasks/, assets/, checks/, or loaders/.
Update the Python nodes, project Python, selector, init, playground, quickstart, dlt, Dagster, and Rivers pages for the single python/ root and for orchestrator definitions that live outside the SQLBuild project, then regenerate the bundled skill references.
Discovery imports every python/ module as python.<dotted.path> through the normal import system, so helper packages can use relative imports and each module initializes once per discovery pass. python.* entries are evicted at the start of each pass so sequential projects and edited files are imported afresh.
A factory may return a decorated node that direct discovery already registers from its own python/ module. Skip that identical callable in factory output while keeping the duplicate-name error for distinct nodes.
Dagster and Rivers playgrounds nest the SQLBuild project under waffle_shop/. Install the scaffolded agent skills there, where sqb skills and stale-skill maintenance resolve them, and document the location.
Check node decorators directly when de-duplicating factory output, split the factory E2E into success and conflict tests, and use expected_ fields and the shared repo-file fixture in the new regressions.
…entity

Discovery installs an explicit python package whose __path__ is the
project's python/ folder, so project imports never resolve to an
unrelated python package elsewhere on sys.path. Unrelated python.*
modules displaced during discovery are restored afterwards.

Discovery now imports every python/ module and registers direct nodes
before running factories, then skips factory results that are the same
callable direct discovery registered. A factory that binds a generated
node to a module global registers it once instead of dropping it.
@kvlonge
kvlonge enabled auto-merge (squash) September 27, 2026 04:51
@kvlonge
kvlonge merged commit cbaa787 into main Sep 27, 2026
30 checks passed
@kvlonge
kvlonge deleted the feat/python-node-root branch September 27, 2026 05:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant