DagSmith — wizualny edytor DAG-ów dla Apache Airflow 3

Pisanie DAG-ów w Airflow to w praktyce Python — co dobre dla inżynierów danych, ale jest barierą wejścia dla analityków, mniej technicznych członków zespołu czy osób, które po prostu chcą szybko poskładać prosty pipeline bez grzebania w kodzie. Jednocześnie żadne narzędzie wizualne nie może być kolejnym silosem — jeśli edytor generuje kod, który nie da się potem normalnie utrzymywać w Git, code review i CI, to nie ma sensu.
DagSmith to plugin do Apache Airflow ≥ 3.1, który dokłada do standardowego Airflow UI pełny edytor DAG-ów — canvas z blokami operatorów obok edytora kodu, z założeniem, że kod jest źródłem prawdy, a canvas jest tylko jego wizualną reprezentacją.
Wyzwanie
Głównym problemem przy budowie takiego narzędzia nie jest samo rysowanie grafu zależności — to rozwiązany problem (React Flow). Trudność leży gdzie indziej:
- Jak edytować istniejące, ręcznie pisane DAG-i (z DAG(...), @dag, @task, >>, chain(), zagnieżdżonymi TaskGroups) bez nadpisywania formatowania i komentarzy, których edytor nie dotknął?
- Jak obsłużyć dynamiczne konstrukcje (pętle generujące taski, .partial().expand()), które z natury nie mają jednej, statycznej reprezentacji graficznej?
- Jak zbudować paletę operatorów bez ręcznego katalogowania setek klas z providerów Airflow, które wciąż się zmieniają między wersjami?
- Jak dopuścić edycję w UI bez ryzyka, że scheduler zobaczy niedokończony, niewalidowalny plik .py w trakcie pracy nad nim?
Rozwiązanie
Dwukierunkowa synchronizacja przez libcst
Zamiast generować plik .py od zera przy każdej zmianie na canvasie, DagSmith parsuje istniejący kod przez libcst i nanosi na niego minimalne, chirurgiczne zmiany. Efekt: fragmenty kodu, których użytkownik nie ruszył na canvasie, zostają bajt w bajt identyczne — łącznie z komentarzami i formatowaniem. Edycja w drugą stronę (w kodzie) automatycznie aktualizuje canvas. Konstrukcje dynamiczne, których nie da się bezpiecznie odwzorować graficznie, pojawiają się jako bloki "tylko kod" zamiast psuć parser.
Auto-generowana paleta operatorów
Zainstalowane pakiety providerów są introspekowane w runtime — DagSmith analizuje operatory, sensory i sygnatury ich `__init__` w całej hierarchii klas. Dzięki temu setki bloków z typowanymi formularzami parametrów pojawiają się w palecie bez jakiejkolwiek ręcznej definicji, a paleta jest zawsze zgodna z faktycznie zainstalowaną wersją providerów.
Drafty i kontrolowany deploy
Praca w toku nie trafia od razu do plików DAG-ów. Zmiany są zapisywane jako wersjonowane drafty w bazie metadanych Airflow (autosave, historia, diffy, przywracanie do wcześniejszej wersji). Dopiero kliknięcie Deploy — po walidacji — zapisuje realny plik .py, z backupem i wykrywaniem konfliktów. Scheduler nigdy nie widzi niedokończonej pracy.
Praca zespołowa
Każdy zespół może mieć własny katalog w ramach DAG bundle i własne repozytorium git: edycja ograniczona do członków zespołu, reassignment DAG-ów przez adminów, tagowanie DAG-ów zespołami oraz przycisk Commit & push (GitHub/GitLab), z opcjonalnym pushem przy każdym deployu.
Architektura
DagSmith jest wtyczką rejestrowaną przez entry point `airflow.plugins` — nic nie trzeba kopiować ręcznie do katalogu pluginów. Frontend to jeden bundle UMD (React Flow + CodeMirror), zgodny z kontraktem react-plugin z AIP-68 — host (Airflow) dostarcza Reacta, wszystko inne jest zapakowane w bundlu, bez ładowania z CDN. Backend to aplikacja FastAPI działająca wewnątrz api-servera Airflow, komunikująca się z frontem przez REST (`/dagsmith/api/v1`), autoryzowana tym samym JWT co reszta Airflow UI.
Airflow UI ─▶ react_app "DagSmith" (React Flow canvas + CodeMirror)
│ REST /dagsmith/api/v1 (Airflow JWT)
▼
FastAPI app inside the api-server
│ parse (libcst) / codegen / validation (subprocess)
┌────────────┴────────────┐
Save / autosave Deploy (validated)
▼ ▼
Airflow metadata DB .py files in the DAG bundle
(draft versions, (atomic write, backup,
canvas layout) conflict detection, git)Istniejący kod jest obsługiwany na trzech poziomach: DAG-i stworzone w DagSmith mają pełną edycję wizualną z zapamiętanym układem; typowe, ręcznie pisane DAG-i (DAG(...), @dag, @task, >>, chain(), zagnieżdżone TaskGroups, etykiety krawędzi) też są w pełni edytowalne wizualnie, bez naruszania formatowania; konstrukcje dynamiczne (pętle generujące taski, .expand()) są pokazywane jako bloki tylko-do-odczytu na canvasie, edytowalne w widoku kodu.
Bezpieczeństwo
Deploy jest domyślnie wyłączony — bez jego świadomego włączenia DagSmith działa wyłącznie w trybie odczytu i draftów. Wszystkie endpointy są autoryzowane przez Airflow Auth Manager, kod użytkownika jest wykonywany wyłącznie w izolowanym, ograniczonym czasowo subprocessie, każda ścieżka plikowa jest ograniczona do katalogu bundla, a każdy deploy jest logowany do audytu.
Deployowanie DAG-ów z poziomu UI jest równoważne wykonywaniu dowolnego kodu w środowisku Airflow — dokładnie tak samo jak wgranie pliku DAG-a jakąkolwiek inną drogą. `deploy_enabled` warto włączać dopiero po ustawieniu odpowiedniej kontroli dostępu w Airflow UI.
Konfiguracja
[dagsmith]
deploy_enabled = True
# opcjonalny podział ról / zespołów:
# editors = data-platform-team # kto może tworzyć i edytować drafty
# deployers = admin # kto może zapisywać pliki .py
# admins = admin # kto zarządza zespołami
# git_commit = True # commit do checkoutu bundla przy deployuWymagania
| Komponent | Wymagana wersja |
|---|---|
| Apache Airflow | ≥ 3.1 (wymagane API react_apps + fastapi_apps, brak wsparcia dla Airflow 2.x) |
| Python | ≥ 3.10 |
| Baza metadanych | PostgreSQL zalecany (własne tabele dagsmith_*) |
| Dostęp do plików | api-server potrzebuje zapisu do katalogu bundla tylko przy deployu; praca na draftach nie wymaga dostępu do plików |
Efekty (potencjał wdrożenia)
DagSmith jest narzędziem open-source rozwijanym poza konkretnym wdrożeniem klienckim, więc poniższe liczby to realistyczne oszacowania korzyści wynikających z architektury narzędzia, a nie zmierzone dane produkcyjne.
- Skrócenie czasu potrzebnego mniej technicznym użytkownikom na złożenie prostego DAG-a — dzięki gotowej palecie operatorów i typowanym formularzom zamiast pisania Pythona od zera.
- Zerowe ryzyko "zepsucia" ręcznie utrzymywanego kodu DAG-a — edycja surowa przez libcst zamiast pełnej regeneracji pliku zachowuje formatowanie i komentarze.
- Mniej wypadków w produkcji dzięki modelowi draft → walidacja → deploy, który uniemożliwia schedulerowi zobaczenie niedokończonego pliku.