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.
- wrenai-0.7.0/.claude/CLAUDE.md +76 -0
- wrenai-0.7.0/.gitignore +73 -0
- wrenai-0.7.0/CHANGELOG.md +76 -0
- wrenai-0.7.0/PKG-INFO +364 -0
- wrenai-0.7.0/README.md +258 -0
- wrenai-0.7.0/docs/cli.md +188 -0
- wrenai-0.7.0/docs/connections.md +127 -0
- wrenai-0.7.0/justfile +95 -0
- wrenai-0.7.0/pyproject.toml +98 -0
- wrenai-0.7.0/scripts/publish.sh +117 -0
- wrenai-0.7.0/src/wren/__init__.py +15 -0
- wrenai-0.7.0/src/wren/cli.py +661 -0
- wrenai-0.7.0/src/wren/config.py +74 -0
- wrenai-0.7.0/src/wren/connector/__init__.py +4 -0
- wrenai-0.7.0/src/wren/connector/athena.py +338 -0
- wrenai-0.7.0/src/wren/connector/base.py +95 -0
- wrenai-0.7.0/src/wren/connector/bigquery.py +57 -0
- wrenai-0.7.0/src/wren/connector/canner.py +302 -0
- wrenai-0.7.0/src/wren/connector/clickhouse.py +383 -0
- wrenai-0.7.0/src/wren/connector/databricks.py +63 -0
- wrenai-0.7.0/src/wren/connector/datafusion.py +88 -0
- wrenai-0.7.0/src/wren/connector/duckdb.py +123 -0
- wrenai-0.7.0/src/wren/connector/factory.py +66 -0
- wrenai-0.7.0/src/wren/connector/mssql.py +293 -0
- wrenai-0.7.0/src/wren/connector/mysql.py +553 -0
- wrenai-0.7.0/src/wren/connector/oracle.py +171 -0
- wrenai-0.7.0/src/wren/connector/postgres.py +286 -0
- wrenai-0.7.0/src/wren/connector/redshift.py +68 -0
- wrenai-0.7.0/src/wren/connector/snowflake.py +93 -0
- wrenai-0.7.0/src/wren/connector/spark.py +52 -0
- wrenai-0.7.0/src/wren/connector/trino.py +442 -0
- wrenai-0.7.0/src/wren/context.py +1345 -0
- wrenai-0.7.0/src/wren/context_cli.py +742 -0
- wrenai-0.7.0/src/wren/cube_cli.py +317 -0
- wrenai-0.7.0/src/wren/docs.py +256 -0
- wrenai-0.7.0/src/wren/engine.py +221 -0
- wrenai-0.7.0/src/wren/mdl/__init__.py +44 -0
- wrenai-0.7.0/src/wren/mdl/cte_rewriter.py +288 -0
- wrenai-0.7.0/src/wren/mdl/wren_dialect.py +19 -0
- wrenai-0.7.0/src/wren/memory/__init__.py +112 -0
- wrenai-0.7.0/src/wren/memory/cli.py +684 -0
- wrenai-0.7.0/src/wren/memory/embeddings.py +56 -0
- wrenai-0.7.0/src/wren/memory/schema_indexer.py +456 -0
- wrenai-0.7.0/src/wren/memory/seed_queries.py +109 -0
- wrenai-0.7.0/src/wren/memory/store.py +538 -0
- wrenai-0.7.0/src/wren/model/__init__.py +318 -0
- wrenai-0.7.0/src/wren/model/data_source.py +630 -0
- wrenai-0.7.0/src/wren/model/error.py +89 -0
- wrenai-0.7.0/src/wren/model/field_registry.py +393 -0
- wrenai-0.7.0/src/wren/policy.py +120 -0
- wrenai-0.7.0/src/wren/profile.py +358 -0
- wrenai-0.7.0/src/wren/profile_cli.py +475 -0
- wrenai-0.7.0/src/wren/profile_web.py +250 -0
- wrenai-0.7.0/src/wren/sql_classify.py +41 -0
- wrenai-0.7.0/src/wren/templates/_profile_fields.html +47 -0
- wrenai-0.7.0/src/wren/templates/profile_form.html +68 -0
- wrenai-0.7.0/src/wren/type_mapping.py +62 -0
- wrenai-0.7.0/src/wren/utils_cli.py +62 -0
- wrenai-0.7.0/tests/__init__.py +0 -0
- wrenai-0.7.0/tests/conftest.py +29 -0
- wrenai-0.7.0/tests/connectors/__init__.py +0 -0
- wrenai-0.7.0/tests/connectors/test_canner.py +332 -0
- wrenai-0.7.0/tests/connectors/test_clickhouse.py +291 -0
- wrenai-0.7.0/tests/connectors/test_datafusion.py +52 -0
- wrenai-0.7.0/tests/connectors/test_duckdb.py +49 -0
- wrenai-0.7.0/tests/connectors/test_mssql.py +305 -0
- wrenai-0.7.0/tests/connectors/test_mysql.py +92 -0
- wrenai-0.7.0/tests/connectors/test_mysql_connector.py +335 -0
- wrenai-0.7.0/tests/connectors/test_postgres.py +252 -0
- wrenai-0.7.0/tests/connectors/test_snowflake.py +233 -0
- wrenai-0.7.0/tests/connectors/test_trino.py +370 -0
- wrenai-0.7.0/tests/suite/__init__.py +0 -0
- wrenai-0.7.0/tests/suite/manifests.py +70 -0
- wrenai-0.7.0/tests/suite/query.py +213 -0
- wrenai-0.7.0/tests/suite/test_ref_sql.py +188 -0
- wrenai-0.7.0/tests/test_field_registry.py +249 -0
- wrenai-0.7.0/tests/test_profile.py +300 -0
- wrenai-0.7.0/tests/test_profile_cli.py +445 -0
- wrenai-0.7.0/tests/test_profile_web.py +300 -0
- wrenai-0.7.0/tests/unit/__init__.py +0 -0
- wrenai-0.7.0/tests/unit/test_athena_connector.py +335 -0
- wrenai-0.7.0/tests/unit/test_cli_profile_resolve.py +196 -0
- wrenai-0.7.0/tests/unit/test_cli_store_tip.py +130 -0
- wrenai-0.7.0/tests/unit/test_clickhouse_helpers.py +157 -0
- wrenai-0.7.0/tests/unit/test_config.py +104 -0
- wrenai-0.7.0/tests/unit/test_context.py +1221 -0
- wrenai-0.7.0/tests/unit/test_context_cli.py +837 -0
- wrenai-0.7.0/tests/unit/test_convert_mdl.py +384 -0
- wrenai-0.7.0/tests/unit/test_cte_rewriter.py +346 -0
- wrenai-0.7.0/tests/unit/test_cube_cli.py +337 -0
- wrenai-0.7.0/tests/unit/test_engine.py +170 -0
- wrenai-0.7.0/tests/unit/test_memory.py +811 -0
- wrenai-0.7.0/tests/unit/test_mssql_connection.py +280 -0
- wrenai-0.7.0/tests/unit/test_mysql_helpers.py +204 -0
- wrenai-0.7.0/tests/unit/test_policy.py +208 -0
- wrenai-0.7.0/tests/unit/test_profile_env_expansion.py +182 -0
- wrenai-0.7.0/tests/unit/test_seed_queries.py +292 -0
- wrenai-0.7.0/tests/unit/test_sql_classify.py +49 -0
- wrenai-0.7.0/tests/unit/test_type_mapping.py +144 -0
- wrenai-0.7.0/tests/unit/test_version.py +43 -0
- 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.
|
wrenai-0.7.0/.gitignore
ADDED
|
@@ -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
|
+
[](https://pypi.org/project/wrenai/)
|
|
110
|
+
[](https://pypi.org/project/wrenai/)
|
|
111
|
+
[](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
|