wrenai 0.7.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 (101) hide show
  1. wrenai-0.7.0/.claude/CLAUDE.md +76 -0
  2. wrenai-0.7.0/.gitignore +73 -0
  3. wrenai-0.7.0/CHANGELOG.md +76 -0
  4. wrenai-0.7.0/PKG-INFO +364 -0
  5. wrenai-0.7.0/README.md +258 -0
  6. wrenai-0.7.0/docs/cli.md +188 -0
  7. wrenai-0.7.0/docs/connections.md +127 -0
  8. wrenai-0.7.0/justfile +95 -0
  9. wrenai-0.7.0/pyproject.toml +98 -0
  10. wrenai-0.7.0/scripts/publish.sh +117 -0
  11. wrenai-0.7.0/src/wren/__init__.py +15 -0
  12. wrenai-0.7.0/src/wren/cli.py +661 -0
  13. wrenai-0.7.0/src/wren/config.py +74 -0
  14. wrenai-0.7.0/src/wren/connector/__init__.py +4 -0
  15. wrenai-0.7.0/src/wren/connector/athena.py +338 -0
  16. wrenai-0.7.0/src/wren/connector/base.py +95 -0
  17. wrenai-0.7.0/src/wren/connector/bigquery.py +57 -0
  18. wrenai-0.7.0/src/wren/connector/canner.py +302 -0
  19. wrenai-0.7.0/src/wren/connector/clickhouse.py +383 -0
  20. wrenai-0.7.0/src/wren/connector/databricks.py +63 -0
  21. wrenai-0.7.0/src/wren/connector/datafusion.py +88 -0
  22. wrenai-0.7.0/src/wren/connector/duckdb.py +123 -0
  23. wrenai-0.7.0/src/wren/connector/factory.py +66 -0
  24. wrenai-0.7.0/src/wren/connector/mssql.py +293 -0
  25. wrenai-0.7.0/src/wren/connector/mysql.py +553 -0
  26. wrenai-0.7.0/src/wren/connector/oracle.py +171 -0
  27. wrenai-0.7.0/src/wren/connector/postgres.py +286 -0
  28. wrenai-0.7.0/src/wren/connector/redshift.py +68 -0
  29. wrenai-0.7.0/src/wren/connector/snowflake.py +93 -0
  30. wrenai-0.7.0/src/wren/connector/spark.py +52 -0
  31. wrenai-0.7.0/src/wren/connector/trino.py +442 -0
  32. wrenai-0.7.0/src/wren/context.py +1345 -0
  33. wrenai-0.7.0/src/wren/context_cli.py +742 -0
  34. wrenai-0.7.0/src/wren/cube_cli.py +317 -0
  35. wrenai-0.7.0/src/wren/docs.py +256 -0
  36. wrenai-0.7.0/src/wren/engine.py +221 -0
  37. wrenai-0.7.0/src/wren/mdl/__init__.py +44 -0
  38. wrenai-0.7.0/src/wren/mdl/cte_rewriter.py +288 -0
  39. wrenai-0.7.0/src/wren/mdl/wren_dialect.py +19 -0
  40. wrenai-0.7.0/src/wren/memory/__init__.py +112 -0
  41. wrenai-0.7.0/src/wren/memory/cli.py +684 -0
  42. wrenai-0.7.0/src/wren/memory/embeddings.py +56 -0
  43. wrenai-0.7.0/src/wren/memory/schema_indexer.py +456 -0
  44. wrenai-0.7.0/src/wren/memory/seed_queries.py +109 -0
  45. wrenai-0.7.0/src/wren/memory/store.py +538 -0
  46. wrenai-0.7.0/src/wren/model/__init__.py +318 -0
  47. wrenai-0.7.0/src/wren/model/data_source.py +630 -0
  48. wrenai-0.7.0/src/wren/model/error.py +89 -0
  49. wrenai-0.7.0/src/wren/model/field_registry.py +393 -0
  50. wrenai-0.7.0/src/wren/policy.py +120 -0
  51. wrenai-0.7.0/src/wren/profile.py +358 -0
  52. wrenai-0.7.0/src/wren/profile_cli.py +475 -0
  53. wrenai-0.7.0/src/wren/profile_web.py +250 -0
  54. wrenai-0.7.0/src/wren/sql_classify.py +41 -0
  55. wrenai-0.7.0/src/wren/templates/_profile_fields.html +47 -0
  56. wrenai-0.7.0/src/wren/templates/profile_form.html +68 -0
  57. wrenai-0.7.0/src/wren/type_mapping.py +62 -0
  58. wrenai-0.7.0/src/wren/utils_cli.py +62 -0
  59. wrenai-0.7.0/tests/__init__.py +0 -0
  60. wrenai-0.7.0/tests/conftest.py +29 -0
  61. wrenai-0.7.0/tests/connectors/__init__.py +0 -0
  62. wrenai-0.7.0/tests/connectors/test_canner.py +332 -0
  63. wrenai-0.7.0/tests/connectors/test_clickhouse.py +291 -0
  64. wrenai-0.7.0/tests/connectors/test_datafusion.py +52 -0
  65. wrenai-0.7.0/tests/connectors/test_duckdb.py +49 -0
  66. wrenai-0.7.0/tests/connectors/test_mssql.py +305 -0
  67. wrenai-0.7.0/tests/connectors/test_mysql.py +92 -0
  68. wrenai-0.7.0/tests/connectors/test_mysql_connector.py +335 -0
  69. wrenai-0.7.0/tests/connectors/test_postgres.py +252 -0
  70. wrenai-0.7.0/tests/connectors/test_snowflake.py +233 -0
  71. wrenai-0.7.0/tests/connectors/test_trino.py +370 -0
  72. wrenai-0.7.0/tests/suite/__init__.py +0 -0
  73. wrenai-0.7.0/tests/suite/manifests.py +70 -0
  74. wrenai-0.7.0/tests/suite/query.py +213 -0
  75. wrenai-0.7.0/tests/suite/test_ref_sql.py +188 -0
  76. wrenai-0.7.0/tests/test_field_registry.py +249 -0
  77. wrenai-0.7.0/tests/test_profile.py +300 -0
  78. wrenai-0.7.0/tests/test_profile_cli.py +445 -0
  79. wrenai-0.7.0/tests/test_profile_web.py +300 -0
  80. wrenai-0.7.0/tests/unit/__init__.py +0 -0
  81. wrenai-0.7.0/tests/unit/test_athena_connector.py +335 -0
  82. wrenai-0.7.0/tests/unit/test_cli_profile_resolve.py +196 -0
  83. wrenai-0.7.0/tests/unit/test_cli_store_tip.py +130 -0
  84. wrenai-0.7.0/tests/unit/test_clickhouse_helpers.py +157 -0
  85. wrenai-0.7.0/tests/unit/test_config.py +104 -0
  86. wrenai-0.7.0/tests/unit/test_context.py +1221 -0
  87. wrenai-0.7.0/tests/unit/test_context_cli.py +837 -0
  88. wrenai-0.7.0/tests/unit/test_convert_mdl.py +384 -0
  89. wrenai-0.7.0/tests/unit/test_cte_rewriter.py +346 -0
  90. wrenai-0.7.0/tests/unit/test_cube_cli.py +337 -0
  91. wrenai-0.7.0/tests/unit/test_engine.py +170 -0
  92. wrenai-0.7.0/tests/unit/test_memory.py +811 -0
  93. wrenai-0.7.0/tests/unit/test_mssql_connection.py +280 -0
  94. wrenai-0.7.0/tests/unit/test_mysql_helpers.py +204 -0
  95. wrenai-0.7.0/tests/unit/test_policy.py +208 -0
  96. wrenai-0.7.0/tests/unit/test_profile_env_expansion.py +182 -0
  97. wrenai-0.7.0/tests/unit/test_seed_queries.py +292 -0
  98. wrenai-0.7.0/tests/unit/test_sql_classify.py +49 -0
  99. wrenai-0.7.0/tests/unit/test_type_mapping.py +144 -0
  100. wrenai-0.7.0/tests/unit/test_version.py +43 -0
  101. wrenai-0.7.0/uv.lock +3676 -0
@@ -0,0 +1,76 @@
1
+ # CLAUDE.md — wren package
2
+
3
+ Python SDK and CLI for Wren Engine. Wraps `wren-core-py` (PyO3 bindings) + Ibis connectors into a single installable package with YAML-based MDL project management, named connection profiles, and optional semantic memory.
4
+
5
+ ## Build & Development
6
+
7
+ ```bash
8
+ cd wren
9
+ just install # build wren-core-py wheel + uv sync
10
+ just install-all # with all optional extras (including memory)
11
+ just install-extra <extra> # e.g. just install-extra postgres
12
+ just install-memory # install memory extra (lancedb + sentence-transformers)
13
+ just dev # run `wren` CLI
14
+ just test # pytest tests/
15
+ just test-memory # memory-specific tests
16
+ just lint # ruff format --check + ruff check
17
+ just format # ruff auto-fix (also aliased as `just fmt`)
18
+ just build # uv build (produces wheel)
19
+ ```
20
+
21
+ Uses `uv` (not Poetry). `pyproject.toml` uses `hatchling` as build backend.
22
+
23
+ ## CLI Command Groups
24
+
25
+ - `wren query` / `wren dry-plan` / `wren validate` — Core query operations
26
+ - `wren context init|build|validate|show` — YAML MDL project management
27
+ - `wren profile add|list|show|remove|activate` — Named connection profiles
28
+ - `wren docs connection-info` — Generate connection field docs
29
+ - `wren utils parse-type` — SQL type normalization
30
+ - `wren memory index|fetch|store|recall` — Semantic memory (when `wren[memory]` installed)
31
+
32
+ ## Key Design Points
33
+
34
+ - **WrenEngine** is the main entry point. It accepts a base64-encoded MDL JSON string, a `DataSource`, and a connection dict.
35
+ - **Query flow**: `_plan()` → wren-core `SessionContext.transform_sql()` → `_transpile()` via sqlglot → connector `.query()`.
36
+ - **Manifest extraction**: `_plan()` tries to extract a minimal sub-manifest scoped to the query's referenced tables before calling wren-core — this reduces planning overhead. Falls back to the full manifest on error.
37
+ - **`get_session_context` is `@cache`-decorated** — same `(manifest_str, function_path, properties, data_source)` tuple reuses the same SessionContext. Avoid mutating session state.
38
+ - **Write dialect mapping**: `canner` → `trino`; file sources (`local_file`, `s3_file`, `minio_file`, `gcs_file`) → `duckdb`. All others use `data_source.name` directly.
39
+ - **WrenEngine is a context manager** (`__enter__` / `__exit__` call `close()`).
40
+ - **Profile-based workflow**: When no explicit `--connection-*` flags are given, the CLI auto-discovers the active profile from `~/.wren/profiles.yml`. Profiles store datasource type + connection fields.
41
+ - **YAML MDL project**: `wren context build` compiles YAML model/view/relationship files from a project directory into `target/mdl.json`. `_require_mdl()` auto-discovers this target file.
42
+ - **Config system**: `~/.wren/config.json` with `strict_mode` (reject queries referencing non-MDL tables) and `denied_functions` (block specific SQL functions).
43
+ - **Field registry** (`model/field_registry.py`): Single source of truth for per-datasource connection fields, derived from Pydantic models. Used by CLI interactive prompts, MCP web UI forms, and documentation generation.
44
+
45
+ ## Connectors
46
+
47
+ `connector/factory.py` dispatches on `DataSource` to return the right connector. Each connector wraps an Ibis backend and exposes `.query(sql, limit)` and `.dry_run(sql)`. Base class in `connector/base.py`; Ibis-backed connectors share `connector/ibis.py`.
48
+
49
+ - **Dedicated modules**: `postgres.py`, `mysql.py`, `mssql.py`, `bigquery.py`, `duckdb.py`, `oracle.py` (native oracledb, not Ibis), `redshift.py`, `spark.py`, `databricks.py`, `canner.py`
50
+ - **Shared Ibis module** (`ibis.py`): trino, clickhouse, snowflake, athena
51
+ - **File connectors**: `local_file`, `s3_file`, `minio_file`, `gcs_file` all map to duckdb
52
+ - **doris** maps to mysql connector (MySQL-compatible protocol)
53
+ - **canner** maps to postgres connector
54
+
55
+ ## Memory Module (Optional)
56
+
57
+ `wren/src/wren/memory/` — LanceDB-backed semantic memory for schema and query retrieval. Install via `wren[memory]`.
58
+
59
+ - **`WrenMemory`** — Main API: `index_manifest()`, `get_context()`, `store_query()`, `recall_queries()`, `describe_schema()`, `schema_is_current()`, `status()`, `reset()`
60
+ - Uses sentence-transformers for embedding MDL schema items and NL↔SQL query pairs
61
+ - **Seed queries** (`seed_queries.py`): On index, generates canonical NL-SQL pairs from the MDL manifest to bootstrap the query history
62
+ - CLI: `wren memory index|fetch|store|recall` subcommands (auto-registered when extras installed)
63
+ - Backing store: LanceDB (local or remote via opendal)
64
+
65
+ ## Optional Extras
66
+
67
+ Install per data-source extras: `postgres`, `mysql`, `bigquery`, `snowflake`, `clickhouse`, `trino`, `mssql`, `databricks`, `redshift`, `spark`, `athena`, `oracle`, `memory`, `all`, `dev`.
68
+
69
+ On macOS, `mysql` extra needs:
70
+ ```bash
71
+ PKG_CONFIG_PATH="$(brew --prefix mysql-client)/lib/pkgconfig" just install-extra mysql
72
+ ```
73
+
74
+ ## Dependency on wren-core-py
75
+
76
+ `wren-core-py` wheel is built locally from `../wren-core-py/` and installed via `--find-links`. Run `just build-core` (or `just install`) to rebuild after Rust changes.
@@ -0,0 +1,73 @@
1
+ # ---- IDE & editors ----
2
+ .idea/
3
+ .vscode/
4
+ *.iml
5
+ *.ipr
6
+ *.iws
7
+ *.swp
8
+ *~
9
+ .run/
10
+
11
+ # ---- OS ----
12
+ .DS_Store
13
+ __MACOSX/
14
+
15
+ # ---- Environment files (templates kept) ----
16
+ **/.env
17
+ **/.env.*
18
+ !**/.env.example
19
+ !**/.env.*.example
20
+
21
+ # ---- Secrets / credentials ----
22
+ *.pem
23
+
24
+ # ---- Python ----
25
+ __pycache__/
26
+ *.py[cod]
27
+ *$py.class
28
+ *.so
29
+ *.egg
30
+ *.egg-info/
31
+ .eggs/
32
+ build/
33
+ dist/
34
+ .python-version
35
+ .tox/
36
+ .coverage
37
+ .coverage.*
38
+ htmlcov/
39
+ .mypy_cache/
40
+ .ruff_cache/
41
+ .pytest_cache/
42
+ .hypothesis/
43
+ venv/
44
+ .venv/
45
+
46
+ # ---- Rust ----
47
+ target/
48
+ **/*.rs.bk
49
+ *.pdb
50
+
51
+ # ---- WebAssembly (wasm-pack) ----
52
+ pkg/
53
+
54
+ # ---- Node / TypeScript (skills, sdks, wasm consumers) ----
55
+ node_modules/
56
+ .pnp
57
+ .pnp.js
58
+ npm-debug.log*
59
+ yarn-debug.log*
60
+ yarn-error.log*
61
+ *.tsbuildinfo
62
+
63
+ # ---- SQLite (memory layer caches) ----
64
+ *.sqlite
65
+ *.sqlite3
66
+
67
+ # ---- Local caches & temporary files ----
68
+ local_cache/
69
+ .tmp/
70
+ .tmp
71
+
72
+ # ---- Claude Code worktrees (local dev only) ----
73
+ **/.claude/worktrees/
@@ -0,0 +1,76 @@
1
+ # Changelog
2
+
3
+ ## [0.7.0](https://github.com/Canner/WrenAI/compare/wren-v0.6.0...wren-v0.7.0) (2026-05-22)
4
+
5
+
6
+ ### ⚠ BREAKING CHANGES
7
+
8
+ * **wren:** rename PyPI package from wren-engine to wrenai ([#2315](https://github.com/Canner/WrenAI/issues/2315))
9
+
10
+ ### Features
11
+
12
+ * **wasm:** full Cube support — validate, translate, PyO3, CLI, WASM, docs ([#2282](https://github.com/Canner/WrenAI/issues/2282)) ([026111e](https://github.com/Canner/WrenAI/commit/026111e54ec31e7165f9fd79c5c998070e66626c))
13
+
14
+
15
+ ### Documentation
16
+
17
+ * **wren:** rebrand README to Wren AI and expand rename migration note ([#2316](https://github.com/Canner/WrenAI/issues/2316)) ([f3a00eb](https://github.com/Canner/WrenAI/commit/f3a00eb971a27186824954eff64b32f7e290db3c))
18
+
19
+
20
+ ### Miscellaneous Chores
21
+
22
+ * **wren:** rename PyPI package from wren-engine to wrenai ([#2315](https://github.com/Canner/WrenAI/issues/2315)) ([20cffa9](https://github.com/Canner/WrenAI/commit/20cffa904f2d47c048c9247a77687b3fdfe24416))
23
+
24
+ ## [0.6.0](https://github.com/Canner/WrenAI/compare/wren-v0.5.0...wren-v0.6.0) (2026-05-13)
25
+
26
+
27
+ ### Features
28
+
29
+ * **context:** bind a connection profile to a project ([#2251](https://github.com/Canner/WrenAI/issues/2251)) ([41fbe41](https://github.com/Canner/WrenAI/commit/41fbe411fd1f1bb7a4080fbcedc7c886678276d1))
30
+
31
+ ## [0.5.0](https://github.com/Canner/WrenAI/compare/wren-v0.4.0...wren-v0.5.0) (2026-05-05)
32
+
33
+
34
+ ### Features
35
+
36
+ * **core:** import wren-engine into core/ ([cc9b67f](https://github.com/Canner/WrenAI/commit/cc9b67f593bf94c7418e0abb0ed46aa4a21613c3))
37
+ * **core:** import wren-engine into core/ ([#2209](https://github.com/Canner/WrenAI/issues/2209)) ([8b8a1a3](https://github.com/Canner/WrenAI/commit/8b8a1a3c5bf2a43d56ea1587782a0d5d853803b2))
38
+
39
+ ## [0.4.0](https://github.com/Canner/wren-engine/compare/wren-v0.3.0...wren-v0.4.0) (2026-04-30)
40
+
41
+
42
+ ### Features
43
+
44
+ * **wren:** .env-driven profile secrets, auto connection validation, and wren-install-guide skill ([#1588](https://github.com/Canner/wren-engine/issues/1588)) ([38ceaf1](https://github.com/Canner/wren-engine/commit/38ceaf1f73a91bf123e609aa6e402d5b971d3340))
45
+
46
+ ## [0.3.0](https://github.com/Canner/wren-engine/compare/wren-v0.2.0...wren-v0.3.0) (2026-04-20)
47
+
48
+
49
+ ### Features
50
+
51
+ * add MDL layout versioning and dialect field on Model and View ([#1556](https://github.com/Canner/wren-engine/issues/1556)) ([0384931](https://github.com/Canner/wren-engine/commit/03849312d5934c606c0e43d0bd41d091892b4454))
52
+ * add wren-core-wasm module with browser WASM support ([#1568](https://github.com/Canner/wren-engine/issues/1568)) ([4f9201b](https://github.com/Canner/wren-engine/commit/4f9201b7f98ce34fba9069b10da7a52b2c338b8b))
53
+ * **wren-core:** add refSql model support ([#1555](https://github.com/Canner/wren-engine/issues/1555)) ([bdaddf2](https://github.com/Canner/wren-engine/commit/bdaddf25bb9c10287b7f2062e727c26ac0e76303))
54
+ * **wren:** add `wren docs connection-info` CLI command ([#1507](https://github.com/Canner/wren-engine/issues/1507)) ([87efbfd](https://github.com/Canner/wren-engine/commit/87efbfdb91aece1c46999a3cc1bae72b77de778b))
55
+ * **wren:** add LanceDB-backed memory layer for schema and query retrieval ([#1494](https://github.com/Canner/wren-engine/issues/1494)) ([dfdff01](https://github.com/Canner/wren-engine/commit/dfdff010371f649abfa999b9fd08a729b81b15f2))
56
+ * **wren:** add memory list, forget, dump & load commands ([#1531](https://github.com/Canner/wren-engine/issues/1531)) ([de424e8](https://github.com/Canner/wren-engine/commit/de424e8b08d4125456895935e99dfd79ddd21f3f))
57
+ * **wren:** add profile management for named connection profiles ([#1509](https://github.com/Canner/wren-engine/issues/1509)) ([b086576](https://github.com/Canner/wren-engine/commit/b086576fbc0ead4ce46af915403a5c7268eac525))
58
+ * **wren:** add standalone wren Python SDK package ([#1471](https://github.com/Canner/wren-engine/issues/1471)) ([41f3f21](https://github.com/Canner/wren-engine/commit/41f3f21f97aba6418b087c1d6437183fdd30f2b3))
59
+ * **wren:** CLI 0.2.0 — context management, profiles, strict mode & memory ([#1522](https://github.com/Canner/wren-engine/issues/1522)) ([fbec650](https://github.com/Canner/wren-engine/commit/fbec650d4e44a62a3ed7fa3a943c74af83d63402))
60
+ * **wren:** CTE-based SQL planning with per-model expansion ([#1479](https://github.com/Canner/wren-engine/issues/1479)) ([fca2b11](https://github.com/Canner/wren-engine/commit/fca2b11bb4d2d45d883803f75605f0b84571188f))
61
+ * **wren:** extend standalone CLI with MySQL support and auto-discovery ([#1476](https://github.com/Canner/wren-engine/issues/1476)) ([6a78c12](https://github.com/Canner/wren-engine/commit/6a78c1210e0bd36e34984f85ae7e240a70b5ef0f))
62
+ * **wren:** generate AGENTS.md during `wren context init` ([#1526](https://github.com/Canner/wren-engine/issues/1526)) ([40bf46f](https://github.com/Canner/wren-engine/commit/40bf46f636d38f39f01fc005583d71c1679a2507))
63
+ * **wren:** preserve SELECT * in CTE rewriter ([#1536](https://github.com/Canner/wren-engine/issues/1536)) ([ed03388](https://github.com/Canner/wren-engine/commit/ed03388f7534a4f85b85a4fd3b6fc8a36179425e))
64
+
65
+
66
+ ### Bug Fixes
67
+
68
+ * **oracle:** replace ibis[oracle] with native oracledb cursor connector ([#1495](https://github.com/Canner/wren-engine/issues/1495)) ([2e3c1de](https://github.com/Canner/wren-engine/commit/2e3c1def9645dcab3e0105bfa7053e740d162f83))
69
+ * **wren:** address CodeRabbit review feedback ([9c46f55](https://github.com/Canner/wren-engine/commit/9c46f554d0e25ce1000be11a496718289092e81d))
70
+ * **wren:** fix CLI 0.2.0 docs — description placement, install extras, CLI flags ([#1523](https://github.com/Canner/wren-engine/issues/1523)) ([536988e](https://github.com/Canner/wren-engine/commit/536988edeb1055620e0204f25243cbc70ee25f8a))
71
+ * **wren:** suppress model-loading noise and improve memory CLI error message ([#1529](https://github.com/Canner/wren-engine/issues/1529)) ([bd20444](https://github.com/Canner/wren-engine/commit/bd204445d81805e3b54cb9f441177f06c5e45eb8))
72
+
73
+
74
+ ### Dependencies
75
+
76
+ * **wren:** bump transitive deps for security patches ([53c16c4](https://github.com/Canner/wren-engine/commit/53c16c4a36eb7dbe1bb467c4cb05b0b64b6ec902))
wrenai-0.7.0/PKG-INFO ADDED
@@ -0,0 +1,364 @@
1
+ Metadata-Version: 2.4
2
+ Name: wrenai
3
+ Version: 0.7.0
4
+ Summary: Wren Engine CLI and Python SDK — semantic SQL layer for 20+ data sources
5
+ Project-URL: Homepage, https://getwren.ai
6
+ Project-URL: Repository, https://github.com/Canner/WrenAI
7
+ Project-URL: Issues, https://github.com/Canner/WrenAI/issues
8
+ Author-email: Wren AI <contact@getwren.ai>
9
+ License: Apache-2.0
10
+ Keywords: analytics,cli,data-modeling,database,datafusion,mdl,python,sdk,semantic,semantic-layer,sql,wren,wrenai
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: Apache Software License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Requires-Python: >=3.11
18
+ Requires-Dist: boto3>=1.26
19
+ Requires-Dist: duckdb>=1.0
20
+ Requires-Dist: ibis-framework>=10
21
+ Requires-Dist: loguru>=0.7
22
+ Requires-Dist: opendal>=0.45
23
+ Requires-Dist: pandas>=2
24
+ Requires-Dist: pyarrow-hotfix>=0.6
25
+ Requires-Dist: pyarrow>=14
26
+ Requires-Dist: pyasn1>=0.6.3
27
+ Requires-Dist: pydantic>=2
28
+ Requires-Dist: pyopenssl>=26.0.0
29
+ Requires-Dist: python-dotenv>=1.0
30
+ Requires-Dist: pyyaml>=6.0
31
+ Requires-Dist: requests>=2.33.0
32
+ Requires-Dist: sqlglot>=27
33
+ Requires-Dist: typer>=0.12
34
+ Requires-Dist: wren-core-py>=0.1
35
+ Provides-Extra: all
36
+ Requires-Dist: clickhouse-connect>=0.8; extra == 'all'
37
+ Requires-Dist: databricks-sdk; extra == 'all'
38
+ Requires-Dist: databricks-sql-connector; extra == 'all'
39
+ Requires-Dist: google-auth; extra == 'all'
40
+ Requires-Dist: ibis-framework[bigquery]; extra == 'all'
41
+ Requires-Dist: inquirerpy>=0.3.4; extra == 'all'
42
+ Requires-Dist: jinja2>=3.1; extra == 'all'
43
+ Requires-Dist: lancedb>=0.6; extra == 'all'
44
+ Requires-Dist: mysqlclient>=2.2; extra == 'all'
45
+ Requires-Dist: oracledb>=2; extra == 'all'
46
+ Requires-Dist: psycopg[binary]>=3; extra == 'all'
47
+ Requires-Dist: pyathena[pandas]>=3; extra == 'all'
48
+ Requires-Dist: pyodbc<6,>=5; extra == 'all'
49
+ Requires-Dist: pyspark>=3.5; extra == 'all'
50
+ Requires-Dist: python-multipart>=0.0.9; extra == 'all'
51
+ Requires-Dist: redshift-connector; extra == 'all'
52
+ Requires-Dist: sentence-transformers>=2.2; extra == 'all'
53
+ Requires-Dist: snowflake-connector-python[pandas]>=3.10; extra == 'all'
54
+ Requires-Dist: starlette>=0.37; extra == 'all'
55
+ Requires-Dist: trino<1,>=0.333; extra == 'all'
56
+ Requires-Dist: uvicorn>=0.29; extra == 'all'
57
+ Provides-Extra: athena
58
+ Requires-Dist: pyathena[pandas]>=3; extra == 'athena'
59
+ Provides-Extra: bigquery
60
+ Requires-Dist: google-auth; extra == 'bigquery'
61
+ Requires-Dist: ibis-framework[bigquery]; extra == 'bigquery'
62
+ Provides-Extra: clickhouse
63
+ Requires-Dist: clickhouse-connect>=0.8; extra == 'clickhouse'
64
+ Provides-Extra: databricks
65
+ Requires-Dist: databricks-sdk; extra == 'databricks'
66
+ Requires-Dist: databricks-sql-connector; extra == 'databricks'
67
+ Provides-Extra: dev
68
+ Requires-Dist: httpx>=0.27; extra == 'dev'
69
+ Requires-Dist: orjson>=3; extra == 'dev'
70
+ Requires-Dist: pytest>=8; extra == 'dev'
71
+ Requires-Dist: ruff>=0.4; extra == 'dev'
72
+ Requires-Dist: testcontainers[mysql,postgres]>=4; extra == 'dev'
73
+ Provides-Extra: interactive
74
+ Requires-Dist: inquirerpy>=0.3.4; extra == 'interactive'
75
+ Provides-Extra: main
76
+ Requires-Dist: inquirerpy>=0.3.4; extra == 'main'
77
+ Requires-Dist: jinja2>=3.1; extra == 'main'
78
+ Requires-Dist: python-multipart>=0.0.9; extra == 'main'
79
+ Requires-Dist: starlette>=0.37; extra == 'main'
80
+ Requires-Dist: uvicorn>=0.29; extra == 'main'
81
+ Provides-Extra: memory
82
+ Requires-Dist: lancedb>=0.6; extra == 'memory'
83
+ Requires-Dist: sentence-transformers>=2.2; extra == 'memory'
84
+ Provides-Extra: mssql
85
+ Requires-Dist: pyodbc<6,>=5; extra == 'mssql'
86
+ Provides-Extra: mysql
87
+ Requires-Dist: mysqlclient>=2.2; extra == 'mysql'
88
+ Provides-Extra: oracle
89
+ Requires-Dist: oracledb>=2; extra == 'oracle'
90
+ Provides-Extra: postgres
91
+ Requires-Dist: psycopg[binary]>=3; extra == 'postgres'
92
+ Provides-Extra: redshift
93
+ Requires-Dist: redshift-connector; extra == 'redshift'
94
+ Provides-Extra: snowflake
95
+ Requires-Dist: snowflake-connector-python[pandas]>=3.10; extra == 'snowflake'
96
+ Provides-Extra: spark
97
+ Requires-Dist: pyspark>=3.5; extra == 'spark'
98
+ Provides-Extra: trino
99
+ Requires-Dist: trino<1,>=0.333; extra == 'trino'
100
+ Provides-Extra: ui
101
+ Requires-Dist: jinja2>=3.1; extra == 'ui'
102
+ Requires-Dist: python-multipart>=0.0.9; extra == 'ui'
103
+ Requires-Dist: starlette>=0.37; extra == 'ui'
104
+ Requires-Dist: uvicorn>=0.29; extra == 'ui'
105
+ Description-Content-Type: text/markdown
106
+
107
+ # wrenai
108
+
109
+ [![PyPI version](https://img.shields.io/pypi/v/wrenai.svg)](https://pypi.org/project/wrenai/)
110
+ [![Python](https://img.shields.io/pypi/pyversions/wrenai.svg)](https://pypi.org/project/wrenai/)
111
+ [![License](https://img.shields.io/pypi/l/wrenai.svg)](https://github.com/Canner/WrenAI/blob/main/LICENSE)
112
+
113
+ Wren AI CLI and Python SDK — semantic SQL layer for 20+ data sources.
114
+
115
+ Translate natural SQL queries through an [MDL (Modeling Definition Language)](https://docs.getwren.ai/) semantic layer and execute them against your database. Powered by [Apache DataFusion](https://datafusion.apache.org/).
116
+
117
+ ## Installation
118
+
119
+ ```bash
120
+ pip install wrenai # Core (DuckDB included)
121
+ pip install wrenai[postgres] # PostgreSQL
122
+ pip install wrenai[mysql] # MySQL
123
+ pip install wrenai[bigquery] # BigQuery
124
+ pip install wrenai[snowflake] # Snowflake
125
+ pip install wrenai[clickhouse] # ClickHouse
126
+ pip install wrenai[trino] # Trino
127
+ pip install wrenai[mssql] # SQL Server
128
+ pip install wrenai[databricks] # Databricks
129
+ pip install wrenai[redshift] # Redshift
130
+ pip install wrenai[spark] # Spark
131
+ pip install wrenai[athena] # Athena
132
+ pip install wrenai[oracle] # Oracle
133
+ pip install 'wrenai[memory]' # Schema & query memory (LanceDB)
134
+ pip install 'wrenai[ui]' # Browser-based profile form (starlette + uvicorn)
135
+ pip install 'wrenai[main]' # memory + interactive prompts + ui
136
+ pip install 'wrenai[all]' # All connectors + main
137
+ ```
138
+
139
+ Requires Python 3.11+.
140
+
141
+ ## Quick start
142
+
143
+ **1. Initialize a project** — scaffolds a YAML-based MDL project:
144
+
145
+ ```bash
146
+ mkdir my-project && cd my-project
147
+ wren context init
148
+ ```
149
+
150
+ This creates `wren_project.yml`, `models/`, and `views/`. Edit `wren_project.yml` to set your `data_source` and add models under `models/`:
151
+
152
+ ```yaml
153
+ # wren_project.yml
154
+ schema_version: 2
155
+ name: my_project
156
+ catalog: wren
157
+ schema: public
158
+ data_source: postgres
159
+ ```
160
+
161
+ ```yaml
162
+ # models/orders/metadata.yml
163
+ name: orders
164
+ table_reference:
165
+ schema: mydb
166
+ table: orders
167
+ columns:
168
+ - name: order_id
169
+ type: integer
170
+ - name: customer_id
171
+ type: integer
172
+ - name: total
173
+ type: double
174
+ - name: status
175
+ type: varchar
176
+ primary_key: order_id
177
+ ```
178
+
179
+ > **Already have an MDL JSON?** Import it directly:
180
+ > `wren context init --from-mdl path/to/mdl.json`
181
+
182
+ **2. Configure a connection profile:**
183
+
184
+ ```bash
185
+ # Browser form (recommended, requires wrenai[ui])
186
+ wren profile add my-db --ui
187
+
188
+ # Interactive terminal prompts
189
+ wren profile add my-db --interactive
190
+
191
+ # Import from an existing connection file
192
+ wren profile add my-db --from-file connection_info.json
193
+ ```
194
+
195
+ **3. Build the manifest:**
196
+
197
+ ```bash
198
+ wren context build
199
+ ```
200
+
201
+ This compiles YAML files into `target/mdl.json`. The CLI auto-discovers this file when you run queries from within the project directory.
202
+
203
+ **4. Run queries:**
204
+
205
+ ```bash
206
+ wren --sql 'SELECT order_id FROM "orders" LIMIT 10'
207
+ ```
208
+
209
+ `wren` walks up from the current directory to find `wren_project.yml` and uses `target/mdl.json`. You can also pass `--mdl path/to/mdl.json` explicitly.
210
+
211
+ For the full CLI reference and per-datasource connection field reference, see [`docs/cli.md`](docs/cli.md) and [`docs/connections.md`](docs/connections.md).
212
+
213
+ **4a. (Optional) Aggregation queries with cubes** — define cubes under `cubes/`,
214
+ then query them with a structured input instead of writing `GROUP BY` SQL by hand:
215
+
216
+ ```bash
217
+ wren cube list
218
+ wren cube describe order_metrics
219
+ wren cube query --cube order_metrics --measures revenue --time-dimension "created_at:month"
220
+ ```
221
+
222
+ The translator produces `DATE_TRUNC` / `GROUP BY` / `WHERE` clauses for you and
223
+ runs them through the same engine path as `wren --sql`. See the
224
+ [Cube guide](../../docs/core/guides/modeling/cube.md) for full YAML structure
225
+ and the [CLI reference](../../docs/core/reference/cli.md#wren-cube--pre-aggregation-queries) for all
226
+ flags.
227
+
228
+ **5. (Optional) Configure security policy** — create `~/.wren/config.json`:
229
+
230
+ ```json
231
+ {
232
+ "strict_mode": true,
233
+ "denied_functions": ["pg_read_file", "dblink", "lo_import"]
234
+ }
235
+ ```
236
+
237
+ | Key | Default | Description |
238
+ |-----|---------|-------------|
239
+ | `strict_mode` | `false` | When `true`, every table in a query must be defined in the MDL. Queries referencing undeclared tables are rejected before execution. |
240
+ | `denied_functions` | `[]` | List of function names (case-insensitive) that are forbidden in queries. |
241
+
242
+ **6. (Optional) Index schema for semantic search** (requires `wrenai[memory]`):
243
+
244
+ ```bash
245
+ wren memory index # index MDL schema
246
+ wren memory fetch -q "customer order price" # fetch relevant schema context
247
+ wren memory store --nl "top customers" --sql "SELECT ..." # store NL→SQL pair
248
+ wren memory recall -q "best customers" # retrieve similar past queries
249
+ ```
250
+
251
+ ---
252
+
253
+ ## Connection profiles
254
+
255
+ Profiles let you store named connection configurations in `~/.wren/profiles.yml` and switch between them easily — useful when working across multiple databases or environments.
256
+
257
+ ```bash
258
+ # Add a profile (browser form, interactive prompts, or file import)
259
+ wren profile add prod --ui # opens http://localhost:<port>
260
+ wren profile add staging --interactive # terminal prompts
261
+ wren profile add local --from-file conn.json # import existing file
262
+
263
+ # List and switch profiles
264
+ wren profile list # * marks the active profile
265
+ wren profile switch prod
266
+
267
+ # Inspect a profile (sensitive fields masked)
268
+ wren profile debug prod
269
+
270
+ # Remove a profile
271
+ wren profile rm old-profile --force
272
+ ```
273
+
274
+ The `--ui` flag opens a browser-based form that auto-derives fields from each datasource's schema — including file upload for BigQuery credentials, variant selection for Databricks/Redshift, and sensible defaults for all 20+ supported sources. Requires `pip install 'wrenai[ui]'`.
275
+
276
+ Once a profile is active, `wren` uses it automatically:
277
+
278
+ ```bash
279
+ wren profile switch prod
280
+ wren --sql 'SELECT COUNT(*) FROM "orders"' # connects using prod profile
281
+ ```
282
+
283
+ ---
284
+
285
+ ## Python SDK
286
+
287
+ ```python
288
+ import base64, orjson
289
+ from wren import WrenEngine, DataSource
290
+
291
+ manifest = { ... } # your MDL dict
292
+ manifest_str = base64.b64encode(orjson.dumps(manifest)).decode()
293
+
294
+ with WrenEngine(manifest_str, DataSource.mysql, {"host": "...", ...}) as engine:
295
+ result = engine.query('SELECT * FROM "orders" LIMIT 10')
296
+ print(result.to_pandas())
297
+ ```
298
+
299
+ ---
300
+
301
+ ## Development
302
+
303
+ ```bash
304
+ just install-dev # Install with dev dependencies
305
+ just lint # Ruff format check + lint
306
+ just format # Auto-fix
307
+ ```
308
+
309
+ | Command | What it runs | Docker needed |
310
+ |---------|-------------|---------------|
311
+ | `just test-unit` | Unit tests (engine, CTE rewriter, field registry, profiles) | No |
312
+ | `just test-duckdb` | DuckDB connector tests | No |
313
+ | `just test-postgres` | PostgreSQL connector tests | Yes |
314
+ | `just test-mysql` | MySQL connector tests | Yes |
315
+ | `just test` | All tests | Yes |
316
+
317
+ Profile web tests (`test_profile_web.py`) require `wrenai[ui]`:
318
+
319
+ ```bash
320
+ uv sync --extra dev --extra ui --find-links ../wren-core-py/target/wheels/
321
+ uv run pytest tests/test_profile_web.py -v
322
+ ```
323
+
324
+ ## Publishing
325
+
326
+ ```bash
327
+ ./scripts/publish.sh # Build + publish to PyPI
328
+ ./scripts/publish.sh --test # Build + publish to TestPyPI
329
+ ./scripts/publish.sh --build # Build only
330
+ ```
331
+
332
+ ## Package rename: `wren-engine` → `wrenai`
333
+
334
+ Starting with the 0.7.0 release, this PyPI distribution is renamed from
335
+ [`wren-engine`](https://pypi.org/project/wren-engine/) to
336
+ [`wrenai`](https://pypi.org/project/wrenai/) to align with the **Wren AI**
337
+ brand. The legacy `wren-engine` project on PyPI is frozen at 0.6.x and
338
+ will not receive further updates.
339
+
340
+ ### What stays the same
341
+
342
+ - The Python import path: `import wren` (and submodules under `wren.*`)
343
+ - The `wren` CLI entrypoint and every subcommand (`wren query`,
344
+ `wren context`, `wren profile`, `wren memory`, …)
345
+ - All extras (`postgres`, `mysql`, `bigquery`, …, `memory`, `ui`, `main`,
346
+ `all`)
347
+ - Configuration files under `~/.wren/` (profiles, memory, config)
348
+
349
+ Only the name you type after `pip install` is different.
350
+
351
+ ### Migration
352
+
353
+ ```bash
354
+ pip uninstall wren-engine
355
+ pip install wrenai # or: pip install "wrenai[<extras>]"
356
+ wren --version # should print: wrenai X.Y.Z
357
+ ```
358
+
359
+ If your project pinned `wren-engine` in a `requirements.txt`,
360
+ `pyproject.toml`, or lockfile, replace it with `wrenai` and re-lock.
361
+
362
+ ## License
363
+
364
+ Apache-2.0