noria 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. noria-0.1.0/.github/copilot-instructions.md +61 -0
  2. noria-0.1.0/.github/prompts/1_create_task.prompt.md +39 -0
  3. noria-0.1.0/.github/prompts/2_analyse_pipeline.prompt.md +27 -0
  4. noria-0.1.0/.github/prompts/3_debug_erreur.prompt.md +22 -0
  5. noria-0.1.0/.github/prompts/4_migration_etl.prompt.md +148 -0
  6. noria-0.1.0/.github/workflows/ci.yml +67 -0
  7. noria-0.1.0/.gitignore +39 -0
  8. noria-0.1.0/CHANGELOG.md +29 -0
  9. noria-0.1.0/LICENSE +21 -0
  10. noria-0.1.0/Makefile +35 -0
  11. noria-0.1.0/PKG-INFO +361 -0
  12. noria-0.1.0/README.md +306 -0
  13. noria-0.1.0/docs/adapters/bigquery.md +107 -0
  14. noria-0.1.0/docs/adapters/custom.md +70 -0
  15. noria-0.1.0/docs/adapters/duckdb.md +113 -0
  16. noria-0.1.0/docs/adapters/postgres.md +113 -0
  17. noria-0.1.0/docs/advanced/assertions.md +56 -0
  18. noria-0.1.0/docs/advanced/dag.md +124 -0
  19. noria-0.1.0/docs/advanced/freshness.md +95 -0
  20. noria-0.1.0/docs/advanced/notifications.md +56 -0
  21. noria-0.1.0/docs/advanced/scd2.md +51 -0
  22. noria-0.1.0/docs/advanced/seeds.md +43 -0
  23. noria-0.1.0/docs/index.md +60 -0
  24. noria-0.1.0/docs/migration/alteryx.md +104 -0
  25. noria-0.1.0/docs/migration/index.md +30 -0
  26. noria-0.1.0/docs/migration/powercenter.md +93 -0
  27. noria-0.1.0/docs/migration/sas.md +150 -0
  28. noria-0.1.0/docs/na/303/257a/analyse_pipeline.md +111 -0
  29. noria-0.1.0/docs/na/303/257a/create_task.md +128 -0
  30. noria-0.1.0/docs/na/303/257a/debug.md +192 -0
  31. noria-0.1.0/docs/na/303/257a/index.md +68 -0
  32. noria-0.1.0/docs/quickstart.md +109 -0
  33. noria-0.1.0/docs/reference/cli.md +78 -0
  34. noria-0.1.0/docs/reference/config.md +238 -0
  35. noria-0.1.0/docs/reference/loops.md +183 -0
  36. noria-0.1.0/docs/reference/macros.md +207 -0
  37. noria-0.1.0/docs/reference/write_modes.md +82 -0
  38. noria-0.1.0/examples/demo_project/noria.yml +136 -0
  39. noria-0.1.0/examples/demo_project/params/prod.yml +5 -0
  40. noria-0.1.0/examples/demo_project/sql/01_raw_customers.sql +18 -0
  41. noria-0.1.0/examples/demo_project/sql/02_raw_orders.sql +19 -0
  42. noria-0.1.0/examples/demo_project/sql/03_clients_actifs.sql +20 -0
  43. noria-0.1.0/examples/demo_project/sql/04_stats_mensuelles.sql +25 -0
  44. noria-0.1.0/examples/demo_project/sql/05_rapport_final.sql +25 -0
  45. noria-0.1.0/examples/demo_project/sql/06_rapport_par_region.sql +24 -0
  46. noria-0.1.0/examples/demo_project/sql/07_rapport_par_client.sql +21 -0
  47. noria-0.1.0/examples/demo_project/sql/hooks/loop_pre_region.sql +15 -0
  48. noria-0.1.0/examples/demo_project/sql/hooks/post_rapport.sql +15 -0
  49. noria-0.1.0/examples/demo_project/sql/macros/utils.sql.j2 +41 -0
  50. noria-0.1.0/mkdocs.yml +73 -0
  51. noria-0.1.0/pyproject.toml +83 -0
  52. noria-0.1.0/schemas/noria.schema.json +428 -0
  53. noria-0.1.0/site/404.html +1465 -0
  54. noria-0.1.0/site/adapters/bigquery/index.html +1924 -0
  55. noria-0.1.0/site/adapters/custom/index.html +1743 -0
  56. noria-0.1.0/site/adapters/duckdb/index.html +1878 -0
  57. noria-0.1.0/site/adapters/postgres/index.html +1880 -0
  58. noria-0.1.0/site/advanced/assertions/index.html +1706 -0
  59. noria-0.1.0/site/advanced/dag/index.html +1855 -0
  60. noria-0.1.0/site/advanced/freshness/index.html +1816 -0
  61. noria-0.1.0/site/advanced/notifications/index.html +1683 -0
  62. noria-0.1.0/site/advanced/scd2/index.html +1755 -0
  63. noria-0.1.0/site/advanced/seeds/index.html +1681 -0
  64. noria-0.1.0/site/assets/images/favicon.png +0 -0
  65. noria-0.1.0/site/assets/javascripts/bundle.d7400e89.min.js +16 -0
  66. noria-0.1.0/site/assets/javascripts/bundle.d7400e89.min.js.map +7 -0
  67. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.ar.min.js +1 -0
  68. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.da.min.js +18 -0
  69. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.de.min.js +18 -0
  70. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.du.min.js +18 -0
  71. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.el.min.js +1 -0
  72. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.es.min.js +18 -0
  73. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.fi.min.js +18 -0
  74. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.fr.min.js +18 -0
  75. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.he.min.js +1 -0
  76. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.hi.min.js +1 -0
  77. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.hu.min.js +18 -0
  78. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.hy.min.js +1 -0
  79. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.it.min.js +18 -0
  80. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.ja.min.js +1 -0
  81. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.jp.min.js +1 -0
  82. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.kn.min.js +1 -0
  83. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.ko.min.js +1 -0
  84. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.multi.min.js +1 -0
  85. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.nl.min.js +18 -0
  86. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.no.min.js +18 -0
  87. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.pt.min.js +18 -0
  88. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.ro.min.js +18 -0
  89. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.ru.min.js +18 -0
  90. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.sa.min.js +1 -0
  91. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.stemmer.support.min.js +1 -0
  92. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.sv.min.js +18 -0
  93. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.ta.min.js +1 -0
  94. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.te.min.js +1 -0
  95. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.th.min.js +1 -0
  96. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.tr.min.js +18 -0
  97. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.vi.min.js +1 -0
  98. noria-0.1.0/site/assets/javascripts/lunr/min/lunr.zh.min.js +1 -0
  99. noria-0.1.0/site/assets/javascripts/lunr/tinyseg.js +206 -0
  100. noria-0.1.0/site/assets/javascripts/lunr/wordcut.js +6708 -0
  101. noria-0.1.0/site/assets/javascripts/workers/search.2c215733.min.js +42 -0
  102. noria-0.1.0/site/assets/javascripts/workers/search.2c215733.min.js.map +7 -0
  103. noria-0.1.0/site/assets/stylesheets/main.ec1eaa64.min.css +1 -0
  104. noria-0.1.0/site/assets/stylesheets/main.ec1eaa64.min.css.map +1 -0
  105. noria-0.1.0/site/assets/stylesheets/palette.ab4e12ef.min.css +1 -0
  106. noria-0.1.0/site/assets/stylesheets/palette.ab4e12ef.min.css.map +1 -0
  107. noria-0.1.0/site/index.html +1698 -0
  108. noria-0.1.0/site/migration/alteryx/index.html +2040 -0
  109. noria-0.1.0/site/migration/index.html +1694 -0
  110. noria-0.1.0/site/migration/powercenter/index.html +1976 -0
  111. noria-0.1.0/site/migration/sas/index.html +2070 -0
  112. noria-0.1.0/site/na/303/257a/analyse_pipeline/index.html +1890 -0
  113. noria-0.1.0/site/na/303/257a/create_task/index.html +1830 -0
  114. noria-0.1.0/site/na/303/257a/debug/index.html +2066 -0
  115. noria-0.1.0/site/na/303/257a/index.html +1855 -0
  116. noria-0.1.0/site/quickstart/index.html +1795 -0
  117. noria-0.1.0/site/reference/cli/index.html +1828 -0
  118. noria-0.1.0/site/reference/config/index.html +2300 -0
  119. noria-0.1.0/site/reference/loops/index.html +1966 -0
  120. noria-0.1.0/site/reference/macros/index.html +2132 -0
  121. noria-0.1.0/site/reference/write_modes/index.html +1801 -0
  122. noria-0.1.0/site/search/search_index.json +1 -0
  123. noria-0.1.0/site/sitemap.xml +103 -0
  124. noria-0.1.0/site/sitemap.xml.gz +0 -0
  125. noria-0.1.0/src/noria/__init__.py +5 -0
  126. noria-0.1.0/src/noria/_version.py +1 -0
  127. noria-0.1.0/src/noria/adapters/__init__.py +45 -0
  128. noria-0.1.0/src/noria/adapters/base.py +170 -0
  129. noria-0.1.0/src/noria/adapters/bigquery_adapter.py +172 -0
  130. noria-0.1.0/src/noria/adapters/duckdb_adapter.py +221 -0
  131. noria-0.1.0/src/noria/adapters/postgres_adapter.py +202 -0
  132. noria-0.1.0/src/noria/cli/__init__.py +3 -0
  133. noria-0.1.0/src/noria/cli/app.py +570 -0
  134. noria-0.1.0/src/noria/config/__init__.py +14 -0
  135. noria-0.1.0/src/noria/config/loader.py +82 -0
  136. noria-0.1.0/src/noria/config/models.py +220 -0
  137. noria-0.1.0/src/noria/core/__init__.py +24 -0
  138. noria-0.1.0/src/noria/core/compiler.py +167 -0
  139. noria-0.1.0/src/noria/core/connection.py +89 -0
  140. noria-0.1.0/src/noria/core/dag.py +177 -0
  141. noria-0.1.0/src/noria/core/dag_view.py +186 -0
  142. noria-0.1.0/src/noria/core/docs_generator.py +136 -0
  143. noria-0.1.0/src/noria/core/executor.py +323 -0
  144. noria-0.1.0/src/noria/core/freshness.py +57 -0
  145. noria-0.1.0/src/noria/core/lineage.py +69 -0
  146. noria-0.1.0/src/noria/core/node.py +451 -0
  147. noria-0.1.0/src/noria/core/pipeline.py +226 -0
  148. noria-0.1.0/src/noria/core/seeds.py +83 -0
  149. noria-0.1.0/src/noria/core/task.py +8 -0
  150. noria-0.1.0/src/noria/core/tracking.py +243 -0
  151. noria-0.1.0/src/noria/monitoring/__init__.py +3 -0
  152. noria-0.1.0/src/noria/monitoring/server.py +272 -0
  153. noria-0.1.0/src/noria/scaffold/__init__.py +3 -0
  154. noria-0.1.0/src/noria/scaffold/generator.py +210 -0
  155. noria-0.1.0/src/noria/utils/__init__.py +29 -0
  156. noria-0.1.0/src/noria/utils/exceptions.py +39 -0
  157. noria-0.1.0/src/noria/utils/logger.py +70 -0
  158. noria-0.1.0/src/noria/utils/notifications.py +63 -0
  159. noria-0.1.0/src/noria/utils/run_status.py +47 -0
  160. noria-0.1.0/tests/__init__.py +0 -0
  161. noria-0.1.0/tests/conftest.py +82 -0
  162. noria-0.1.0/tests/test_compiler.py +259 -0
  163. noria-0.1.0/tests/test_config.py +76 -0
  164. noria-0.1.0/tests/test_dag.py +101 -0
  165. noria-0.1.0/tests/test_executor.py +276 -0
  166. noria-0.1.0/tests/test_loop.py +295 -0
  167. noria-0.1.0/tests/test_new_features.py +372 -0
  168. noria-0.1.0/tests/test_pipeline.py +82 -0
  169. noria-0.1.0/tests/test_tracking.py +73 -0
  170. noria-0.1.0/uv.lock +2941 -0
@@ -0,0 +1,61 @@
1
+ # Instructions NAÏA (Noria AI Assistant) — Framework Noria
2
+
3
+ ## Contexte
4
+
5
+ Ce projet utilise le framework **Noria**, un pipeline SQL-first basé sur Jinja2, DuckDB, SQLAlchemy et Typer.
6
+
7
+ ## Structure d'un projet Noria
8
+
9
+ ```
10
+ mon_projet/
11
+ ├── noria.yml # configuration principale
12
+ ├── sql/
13
+ │ ├── macros/ # macros Jinja2 auto-chargées
14
+ │ ├── seeds/ # fichiers CSV/Parquet (task_type: seed)
15
+ │ └── *.sql # requêtes des tâches
16
+ └── .noria/
17
+ ├── .env # secrets (auto-chargé)
18
+ └── tracking.db # historique des exécutions
19
+ ```
20
+
21
+ ## Règles importantes
22
+
23
+ 1. **Macros cross-DB** : utiliser `{{ cast() }}`, `{{ date_trunc() }}`, `{{ safe_divide() }}` plutôt que SQL dialectal.
24
+ 2. **Paramètres** : accéder via `{{ params.nom }}` dans le SQL.
25
+ 3. **Macros utilisateur** : définies dans `sql/macros/*.sql` ou `*.sql.j2`, auto-importées.
26
+ 4. **Cible dynamique** : `target: "{{ params.schema }}.{{ params.table }}"` est compilé par tâche.
27
+ 5. **Types de tâches** : `sql` (défaut), `assert` (qualité — échoue si SELECT retourne des lignes), `seed` (chargement fichier).
28
+ 6. **Boucles** : `loop:` (liste statique), `loop_from_query:` (SQL), contexte `{{ loop.index }}`, `{{ loop.first }}`, `{{ loop.last }}`.
29
+
30
+ ## Commandes utiles
31
+
32
+ ```bash
33
+ noria validate # valider la config
34
+ noria compile --task nom # prévisualiser le SQL compilé
35
+ noria run --dry-run # simuler sans exécuter
36
+ noria dag # cartographie visuelle
37
+ noria docs # documentation HTML
38
+ noria run --only-tags daily # filtrer par tag
39
+ ```
40
+
41
+ ## Réécriture ETL → Noria
42
+
43
+ L'architecture Noria (tâches SQL, modes d'écriture, boucles, dépendances, paramètres) couvre nativement les mêmes besoins que les outils ETL graphiques. Un développeur peut réécrire un traitement existant en Noria sans changer de paradigme.
44
+
45
+ | Concept ETL | Équivalent Noria |
46
+ |---|---|
47
+ | Mapping / Workflow | Tâche SQL + `depends_on:` |
48
+ | Update Strategy (I/U/D) | `write_mode: replace / merge / update / scd2` |
49
+ | Parameter File | `params:` + `--params-file` |
50
+ | Boucle / Batch Macro | `loop:` ou `loop_from_query:` |
51
+ | Pre/Post SQL | `pre_hook:` / `post_hook:` |
52
+ | Reprise sur erreur | `retry: N` + `retry_delay_s: N` |
53
+
54
+ Pour réécrire un traitement, utilise le prompt NAÏA : `.github/prompts/4_migration_etl.prompt.md`
55
+ Documentation complète : `docs/migration/`
56
+
57
+ ## Ne pas faire
58
+
59
+ - Ne pas utiliser `CAST(col AS TYPE)` directement — utiliser `{{ cast('col', 'TYPE') }}`.
60
+ - Ne pas hardcoder les noms de schéma — utiliser `{{ params.schema }}`.
61
+ - Ne pas créer de tâche sans `description:` (bonne pratique).
@@ -0,0 +1,39 @@
1
+ # NAÏA — Créer une tâche Noria
2
+
3
+ Tu es NAÏA (Noria AI Assistant), un assistant expert du framework Noria. Aide l'utilisateur à créer une nouvelle tâche dans `noria.yml`.
4
+
5
+ ## Contexte Noria
6
+
7
+ - Chaque tâche a un nom unique, un fichier SQL (`sql:`), une table cible (`target:`), et un mode d'écriture (`write_mode:`).
8
+ - Les modes d'écriture disponibles : `replace`, `append`, `truncate`, `merge`, `create_if_not_exists`, `safe_replace`, `incremental`, `scd2`, `update`.
9
+ - Les types de tâches : `sql` (défaut), `assert` (qualité), `seed` (load_orders fichier), `snapshot`.
10
+ - Les macros SQL cross-DB : `{{ cast('col', 'TYPE') }}`, `{{ date_trunc('month', 'col') }}`, `{{ safe_divide(a, b) }}`, `{{ current_timestamp() }}`.
11
+ - Les boucles permettent de répéter une tâche sur une liste ou une requête SQL (`loop:` / `loop_from_query:`).
12
+ - Les dépendances s'expriment avec `depends_on: [tâche1, tâche2]`.
13
+
14
+ ## Instruction
15
+
16
+ L'utilisateur va décrire ce qu'il veut faire. Tu dois :
17
+ 1. Poser les questions nécessaires pour compléter la configuration.
18
+ 2. Générer le bloc YAML de la tâche.
19
+ 3. Générer le fichier SQL associé avec les macros appropriées.
20
+
21
+ ## Format de réponse
22
+
23
+ ```yaml
24
+ # noria.yml — section tasks
25
+ tasks:
26
+ nom_de_la_tache:
27
+ sql: sql/nom_de_la_tache.sql
28
+ target: "{{ params.schema }}.nom_de_la_tache"
29
+ write_mode: replace
30
+ description: "Description claire de ce que fait la tâche"
31
+ tags: [tag1, tag2]
32
+ depends_on: []
33
+ ```
34
+
35
+ ```sql
36
+ -- sql/nom_de_la_tache.sql
37
+ SELECT ...
38
+ FROM {{ params.schema }}.table_source
39
+ ```
@@ -0,0 +1,27 @@
1
+ # NAÏA — Analyser un pipeline Noria
2
+
3
+ Tu es NAÏA (Noria AI Assistant), un assistant expert du framework Noria. Analyse le pipeline décrit par l'utilisateur.
4
+
5
+ ## Ce que tu peux analyser
6
+
7
+ 1. **DAG et dépendances** : identifier les tâches racines, les chemins critiques, les tâches orphelines.
8
+ 2. **Modes d'écriture** : vérifier la cohérence (ex: merge sans merge_key, incremental sans incremental_key).
9
+ 3. **SQL qualité** : repérer les JOINs sans condition, les SELECT *, les divisions sans protection.
10
+ 4. **Performance** : tâches pouvant être parallélisées, loops qui pourraient bénéficier de `loop_parallel: true`.
11
+ 5. **Robustesse** : tâches sans retry, sans timeout, sans ignore_on_error sur des tâches non critiques.
12
+
13
+ ## Instructions
14
+
15
+ 1. Lis le `noria.yml` fourni.
16
+ 2. Pour chaque problème trouvé, donne : la tâche concernée, le problème, et la correction proposée.
17
+ 3. Propose les améliorations en priorité : critique > important > suggestion.
18
+
19
+ ## Format de réponse
20
+
21
+ ### Analyse du pipeline `{nom}`
22
+
23
+ | Priorité | Tâche | Problème | Correction |
24
+ |----------|-------|----------|------------|
25
+ | 🔴 Critique | ... | ... | ... |
26
+ | 🟡 Important | ... | ... | ... |
27
+ | 🟢 Suggestion | ... | ... | ... |
@@ -0,0 +1,22 @@
1
+ # NAÏA — Déboguer une erreur Noria
2
+
3
+ Tu es NAÏA (Noria AI Assistant), un assistant expert du framework Noria. Aide l'utilisateur à diagnostiquer et résoudre une erreur.
4
+
5
+ ## Erreurs fréquentes et solutions
6
+
7
+ | Erreur | Cause probable | Solution |
8
+ |--------|---------------|----------|
9
+ | `CompilationError: undefined variable` | Variable Jinja2 non définie | Ajouter la variable dans `params:` ou vérifier le nom |
10
+ | `ExecutionError: safe_replace guard` | SELECT renvoie moins de lignes que `safe_replace_min_rows` | Vérifier la requête ou baisser `safe_replace_min_rows` |
11
+ | `DependencyError: cycle detected` | Cycle dans `depends_on` | Visualiser avec `noria dag` et corriger |
12
+ | `TaskError: timed out` | Tâche dépasse `timeout:` secondes | Augmenter `timeout:` ou optimiser la requête |
13
+ | `ExecutionError: assert FAILED` | Assertion qualité échouée | Vérifier les données — des violations ont été trouvées |
14
+ | `ConfigError: merge_key required` | `write_mode: merge` sans `merge_key` | Ajouter `merge_key: [col1]` |
15
+ | `Seed file not found` | `seed_file:` pointe vers un fichier absent | Vérifier le chemin relatif depuis la racine du projet |
16
+
17
+ ## Instructions
18
+
19
+ 1. Demande à l'utilisateur de coller le message d'erreur complet.
20
+ 2. Identifie la cause dans le tableau ci-dessus ou par analyse.
21
+ 3. Propose une solution concrète avec le code corrigé.
22
+ 4. Si le problème est dans le SQL, propose de vérifier avec `noria compile --task nom_tache`.
@@ -0,0 +1,148 @@
1
+ # NAÏA — Réécrire un traitement ETL en Noria
2
+
3
+ Tu es NAÏA (Noria AI Assistant). Tu aides le développeur à **réécrire** un traitement ETL existant (PowerCenter, Alteryx, SAS, Talend) en tâches Noria.
4
+
5
+ > **Principe** : Noria ne migre pas automatiquement. C'est son architecture (tâches SQL, modes d'écriture, boucles, dépendances, paramètres) qui est conçue pour couvrir nativement les mêmes besoins que les outils ETL graphiques. Le développeur garde le contrôle du SQL — il remplace les boîtes graphiques par des requêtes lisibles et versionnables.
6
+
7
+ ---
8
+
9
+ ## Correspondances PowerCenter → Noria
10
+
11
+ | Concept PowerCenter | Équivalent Noria | Notes |
12
+ |---------------------|-----------------|-------|
13
+ | Mapping | Fichier SQL + tâche `sql:` | 1 mapping = 1 à N tâches selon la complexité |
14
+ | Session | Tâche avec `write_mode:` | La stratégie de load_orders est dans `write_mode` |
15
+ | Workflow | Pipeline (`noria.yml`) | L'ordonnancement = `depends_on:` |
16
+ | Source Qualifier | `FROM {{ params.schema }}.table` | Le filtre source va dans `WHERE` |
17
+ | Expression Transformation | Colonnes calculées dans `SELECT` | Utiliser `{{ cast() }}`, `{{ safe_divide() }}` |
18
+ | Aggregator | `GROUP BY` | Direct en SQL |
19
+ | Lookup Transformation | `LEFT JOIN` ou sous-requête | Pas de cache lookup séparé |
20
+ | Router | Plusieurs tâches avec `WHERE` différents | 1 branche = 1 tâche |
21
+ | Joiner | `JOIN` | Standard SQL |
22
+ | Filter | `WHERE` | Standard SQL |
23
+ | Union | `UNION ALL` | Standard SQL |
24
+ | Sorter | `ORDER BY` | Standard SQL |
25
+ | Update Strategy (Insert only) | `write_mode: replace` ou `append` | |
26
+ | Update Strategy (Update) | `write_mode: update` + `update_key:` | |
27
+ | Update Strategy (Upsert) | `write_mode: merge` + `merge_key:` | |
28
+ | Update Strategy (Delete+Insert) | `write_mode: incremental` + `incremental_key:` | |
29
+ | SCD Type 2 | `write_mode: scd2` + `scd2_key:` | Colonnes _valid_from/_valid_to/_is_current gérées |
30
+ | Sequence Generator | `ROW_NUMBER() OVER (...)` en SQL | |
31
+ | Parameter ($Param) | `{{ params.nom }}` dans le SQL | |
32
+ | Parameter File | `--params-file prod.yml` en CLI | |
33
+ | Mapping Parameter | `params:` dans la tâche | |
34
+ | Pre/Post SQL | `pre_hook:` / `post_hook:` | |
35
+ | Worklet | Groupe de tâches avec `depends_on:` | |
36
+ | Concurrent sessions | `loop_parallel: true` ou DAG parallèle | |
37
+
38
+ ---
39
+
40
+ ## Correspondances Alteryx → Noria
41
+
42
+ | Outil Alteryx | Équivalent Noria | Notes |
43
+ |---------------|-----------------|-------|
44
+ | Input Data Tool | `FROM {{ params.schema }}.table` | |
45
+ | Select Tool | Colonnes dans `SELECT`, alias | |
46
+ | Filter Tool | `WHERE` | |
47
+ | Join Tool | `INNER JOIN` / `LEFT JOIN` | |
48
+ | Union Tool | `UNION ALL` | |
49
+ | Summarize Tool | `GROUP BY` + fonctions d'agrégat | |
50
+ | Formula Tool | Colonnes calculées | `{{ cast() }}`, `CASE WHEN`, etc. |
51
+ | Multi-Row Formula | `LAG()`, `LEAD()`, `ROW_NUMBER() OVER (...)` | |
52
+ | Running Total | `SUM() OVER (ORDER BY ...)` | |
53
+ | Sort Tool | `ORDER BY` | |
54
+ | Sample Tool | `LIMIT N` ou `{{ limit(n) }}` | |
55
+ | Unique Tool | `SELECT DISTINCT` | |
56
+ | Transpose | `UNPIVOT` (DuckDB) | |
57
+ | Cross Tab | `PIVOT` (DuckDB) | |
58
+ | Output Data Tool | `target:` + `write_mode:` | |
59
+ | Macro (Standard) | Macro Jinja2 dans `sql/macros/` | |
60
+ | App Parameter | `{{ params.nom }}` | |
61
+ | Batch Macro | `loop:` ou `loop_from_query:` | |
62
+ | Container (groupement) | Tags (`tags:`) + `depends_on:` | |
63
+ | Test Tool | `task_type: assert` | |
64
+
65
+ ---
66
+
67
+ ## Correspondances SAS → Noria
68
+
69
+ | Concept SAS | Équivalent Noria | Notes |
70
+ |-------------|-----------------|-------|
71
+ | LIBNAME | `{{ params.schema }}.` | |
72
+ | DATA step (SET) | `SELECT * FROM source` | |
73
+ | DATA step (calculs) | Colonnes calculées dans `SELECT` | |
74
+ | DATA step (IF/THEN) | `CASE WHEN` | |
75
+ | DATA step (RETAIN) | Fonctions fenêtre `SUM() OVER (...)` | |
76
+ | PROC SQL | SQL direct (natif dans Noria) | |
77
+ | PROC SORT | `ORDER BY` | |
78
+ | PROC MEANS | `SELECT AVG(), MIN(), MAX(), ...` + `GROUP BY` | |
79
+ | PROC FREQ | `SELECT col, COUNT(*) GROUP BY col` | |
80
+ | PROC TRANSPOSE | `PIVOT` (DuckDB) ou CASE WHEN | |
81
+ | PROC APPEND | `write_mode: append` | |
82
+ | PROC DELETE | `write_mode: replace` (vide puis recharge) | |
83
+ | Macro variable (&param) | `{{ params.nom }}` | |
84
+ | %LET / %GLOBAL | `params:` dans noria.yml | |
85
+ | %INCLUDE | Macro Jinja2 ou `{% include %}` | |
86
+ | %DO %TO (boucle) | `loop:` (liste) ou `loop_from_query:` | |
87
+ | Formats | `CASE WHEN` ou macro utilisateur | |
88
+ | BY group processing | `PARTITION BY` dans les fonctions fenêtre | |
89
+
90
+ ---
91
+
92
+ ## Instructions pour la réécriture
93
+
94
+ 1. L'utilisateur décrit ou colle le traitement source (pseudocode, description métier, ou extrait du code/mapping).
95
+ 2. Tu identifies :
96
+ - Les **sources** (tables, fichiers)
97
+ - Les **transformations** (calculs, jointures, agrégations, filtres)
98
+ - La **stratégie de load_orders** (insert, update, upsert, historisation)
99
+ - Le **séquencement** (étapes dépendantes ou parallélisables)
100
+ 3. Tu génères :
101
+ - Le bloc YAML des tâches dans `noria.yml`
102
+ - Les fichiers SQL avec macros cross-DB
103
+ - Les macros métier réutilisables dans `sql/macros/` si pertinent
104
+ 4. Tu signales ce qui nécessite attention (logique métier complexe, connecteurs propriétaires non reproductibles en SQL pur).
105
+
106
+ ---
107
+
108
+ ## Format de réponse
109
+
110
+ ### Analyse du traitement source
111
+
112
+ **Outil d'origine :** PowerCenter / Alteryx / SAS
113
+ **Sources :** liste des tables/fichiers en entrée
114
+ **Cible :** table résultat
115
+ **Stratégie de load_orders :** replace / merge / scd2 / etc.
116
+ **Étapes identifiées :** N
117
+
118
+ ### Tâches Noria
119
+
120
+ ```yaml
121
+ tasks:
122
+ etape_1:
123
+ sql: sql/etape_1.sql
124
+ target: "{{ params.schema }}.etape_1"
125
+ write_mode: replace
126
+ description: "..."
127
+
128
+ resultat_final:
129
+ sql: sql/resultat_final.sql
130
+ target: "{{ params.schema }}.resultat"
131
+ write_mode: merge
132
+ merge_key: [id]
133
+ depends_on: [etape_1]
134
+ ```
135
+
136
+ ```sql
137
+ -- sql/etape_1.sql
138
+ SELECT
139
+ id,
140
+ {{ cast('montant', 'DECIMAL(18,2)') }} AS montant,
141
+ {{ date_trunc('month', 'date_op') }} AS mois
142
+ FROM {{ params.schema }}.source_brute
143
+ WHERE statut = 'actif'
144
+ ```
145
+
146
+ ### Points d'attention
147
+ - Ce qui a été simplifié ou adapté par rapport à l'original
148
+ - Ce qui nécessite une vérification manuelle (règles métier complexes, etc.)
@@ -0,0 +1,67 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main, develop]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ name: Tests (${{ matrix.python-version }})
12
+ runs-on: ubuntu-latest
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ python-version: ["3.10", "3.11", "3.12"]
17
+
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - name: Set up Python ${{ matrix.python-version }}
22
+ uses: actions/setup-python@v5
23
+ with:
24
+ python-version: ${{ matrix.python-version }}
25
+
26
+ - name: Install uv
27
+ run: pip install uv
28
+
29
+ - name: Install dependencies
30
+ run: uv pip install -e ".[dev]" --system
31
+
32
+ - name: Lint (ruff)
33
+ run: ruff check src/ tests/
34
+
35
+ - name: Run tests
36
+ run: pytest -q --cov=src/noria --cov-report=xml
37
+
38
+ - name: Upload coverage
39
+ if: matrix.python-version == '3.12'
40
+ uses: codecov/codecov-action@v4
41
+ with:
42
+ file: coverage.xml
43
+
44
+ publish:
45
+ name: Publish to PyPI
46
+ runs-on: ubuntu-latest
47
+ needs: test
48
+ if: github.ref == 'refs/heads/main' && startsWith(github.event.head_commit.message, 'release:')
49
+ permissions:
50
+ id-token: write
51
+
52
+ steps:
53
+ - uses: actions/checkout@v4
54
+
55
+ - name: Set up Python
56
+ uses: actions/setup-python@v5
57
+ with:
58
+ python-version: "3.12"
59
+
60
+ - name: Install build tools
61
+ run: pip install build
62
+
63
+ - name: Build package
64
+ run: python -m build
65
+
66
+ - name: Publish to PyPI
67
+ uses: pypa/gh-action-pypi-publish@release/v1
noria-0.1.0/.gitignore ADDED
@@ -0,0 +1,39 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.pyo
5
+ *.pyd
6
+ .Python
7
+ build/
8
+ dist/
9
+ *.egg-info/
10
+ .eggs/
11
+ *.egg
12
+ .venv/
13
+ venv/
14
+ env/
15
+
16
+ # Noria runtime
17
+ .noria/
18
+ *.db
19
+
20
+ # Tests
21
+ .pytest_cache/
22
+ .coverage
23
+ htmlcov/
24
+ .ruff_cache/
25
+ .mypy_cache/
26
+
27
+ # Editors
28
+ .idea/
29
+ .vscode/
30
+ *.swp
31
+ *.swo
32
+
33
+ # OS
34
+ .DS_Store
35
+ Thumbs.db
36
+
37
+ # Env
38
+ .env
39
+ .env.*
@@ -0,0 +1,29 @@
1
+ # Changelog
2
+
3
+ All notable changes to Noria are documented here.
4
+
5
+ Format: [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
6
+ Versioning: [Semantic Versioning](https://semver.org/)
7
+
8
+ ---
9
+
10
+ ## [0.1.0] — 2026-09-19
11
+
12
+ ### Added
13
+ - Initial release of the Noria framework
14
+ - **SQL-first pipeline engine** — Jinja2 templating in `.sql` files
15
+ - **Multi-database adapters** — DuckDB (default) and PostgreSQL
16
+ - **Cross-DB macro system** — `cast`, `date_trunc`, `current_timestamp`, `concat`, `coalesce`, `safe_divide`, `to_char`, `limit`, `schema_table`
17
+ - **DAG orchestrator** — topological sort, parallel task execution (configurable thread pool)
18
+ - **Write modes** — `replace`, `append`, `truncate`, `merge`, `create_if_not_exists`
19
+ - **Pre/post hooks** — SQL files executed before/after each task
20
+ - **Built-in monitoring dashboard** — FastAPI + HTMX, auto-refresh, run history
21
+ - **SQLite run tracker** — embedded, zero-config execution history
22
+ - **Pydantic v2 config** — strict validation of `noria.yml`
23
+ - **CLI** (`typer`) — `init`, `validate`, `compile`, `run`, `run-task`, `tasks`, `status`, `monitor`
24
+ - **Project scaffolding** — `noria init <name>` generates a ready-to-use project
25
+ - **Parameter system** — global params, task-level overrides, CLI overrides, env vars
26
+ - **Comprehensive test suite** — pytest, 40+ tests covering all components
27
+ - **Demo project** — e-commerce pipeline with 5 tasks and macros examples
28
+
29
+ [0.1.0]: https://github.com/your-org/noria/releases/tag/v0.1.0
noria-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Noria Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
noria-0.1.0/Makefile ADDED
@@ -0,0 +1,35 @@
1
+ .PHONY: install install-dev test lint format typecheck demo clean
2
+
3
+ install:
4
+ pip install -e .
5
+
6
+ install-dev:
7
+ pip install -e ".[dev]"
8
+ pre-commit install
9
+
10
+ test:
11
+ pytest tests/ -v
12
+
13
+ test-cov:
14
+ pytest tests/ --cov=src/noria --cov-report=html --cov-report=term-missing
15
+
16
+ lint:
17
+ ruff check src/ tests/
18
+
19
+ format:
20
+ ruff format src/ tests/
21
+
22
+ typecheck:
23
+ mypy src/noria/
24
+
25
+ demo:
26
+ cd examples/demo_project && noria run --verbose
27
+
28
+ demo-monitor:
29
+ cd examples/demo_project && noria monitor --open
30
+
31
+ clean:
32
+ find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
33
+ find . -type d -name .noria -exec rm -rf {} + 2>/dev/null || true
34
+ find . -name "*.db" -delete 2>/dev/null || true
35
+ rm -rf build/ dist/ *.egg-info/ .coverage htmlcov/