Natural language to any query language, starting with GraphQL
Project description
text2ql
Natural-language to query-language toolkit for GraphQL and SQL.
text2ql is built for practical usage: deterministic generation, LLM-assisted generation, schema/mapping normalization, evaluation utilities, and benchmark adapters (Spider/BIRD).
Current first-class targets are GraphQL and SQL; planned future targets include JSONata, jq-style queries, Cypher, and dialect-focused SQL paths (PostgreSQL, MySQL, and more).
Why teams use it
- Fast path from text -> query for GraphQL and SQL.
- Three generation modes:
deterministic,llm,function_calling. - Schema + mapping aware generation with validation and confidence scoring.
- Built-in dataset ingestion, synthetic rewrites, and evaluation hooks.
- Built-in Spider/BIRD benchmark loaders and runner.
Install
Python: >=3.10
pip install text2ql
Optional extras:
# Streamlit playground
pip install "text2ql[app]"
# SQL execution backend support (SQLAlchemy)
pip install "text2ql[sql]"
# Local development tools
pip install -e ".[dev]"
Quick Start (CLI)
- Deterministic GraphQL:
text2ql "show top 5 client records with mail state enabled" \
--target graphql \
--schema '{"entities":["customers"],"fields":{"customers":["id","email","status"]}}' \
--mapping '{"entities":{"client":"customers"},"fields":{"mail":"email"},"filters":{"state":"status"},"filter_values":{"status":{"enabled":"active"}}}'
- Deterministic SQL:
text2ql "show customers highest total first 5 offset 10" \
--target sql \
--schema '{"entities":["customers"],"fields":{"customers":["id","total","status"]}}'
- LLM mode:
export OPENAI_API_KEY=...
text2ql "show latest 5 orders with status active" \
--target sql \
--mode llm \
--llm-model gpt-4o-mini \
--schema '{"entities":["orders"],"fields":{"orders":["id","status","createdAt"]}}'
- Function-calling / structured output mode:
export OPENAI_API_KEY=...
text2ql "show latest 5 orders with status active" \
--target graphql \
--mode function_calling \
--llm-model gpt-4o-mini \
--schema '{"entities":["orders"],"fields":{"orders":["id","status","createdAt"]},"args":{"orders":["status","limit","orderBy","orderDirection"]}}'
Quick Start (Python API)
from text2ql import Text2QL
service = Text2QL()
result = service.generate(
text="list active customers",
target="graphql",
schema={"entities": ["customers"], "fields": {"customers": ["id", "status", "email"]}},
mapping={"filters": {"state": "status"}, "filter_values": {"status": {"active": "active"}}},
)
print(result.query)
print(result.confidence)
LLM provider wiring:
from text2ql import Text2QL
from text2ql.providers.openai_compatible import OpenAICompatibleProvider
provider = OpenAICompatibleProvider(
api_key="...", # or use OPENAI_API_KEY / TEXT2QL_API_KEY
model="gpt-4o-mini",
use_structured_output=True,
)
service = Text2QL(provider=provider)
Streamlit Playground
Use hosted app: https://text2ql.streamlit.app/
For local/private data: pip install -e ".[app]".
Run locally: python -m streamlit run examples/streamlit_app.py.
Modes at a glance
| Mode | What it does | Best for |
|---|---|---|
deterministic |
Rule/schema-driven generation | Fast, predictable production defaults |
llm |
Direct LLM-assisted generation | Broad language coverage |
function_calling |
Schema-constrained structured intent path | Better output shape control |
Production Setup (brief)
Recommended project files:
project/
schema.json
mapping.json
data.json # optional; used for payload execution checks
expected_query.sql # optional
expected_rows.json # optional
Production checklist:
- Keep
schema.jsonandmapping.jsonin source control. - Start with
--mode deterministicfor baseline reliability. - Enable
--mode llmor--mode function_callingafter baseline tests pass. - Use retry settings for provider calls (
--llm-max-retries,--llm-retry-backoff). - Run evaluation/benchmark checks in CI before releases.
- Use
-vduring rollout/debugging for detailed logs.
Useful CLI operations:
# Generate hybrid mapping (auto baseline + optional overrides)
text2ql --generate-hybrid-mapping \
--schema-file ./schema.json \
--data-file ./data.json \
--mapping-output-file ./mapping.generated.json
# Execute generated query against payload JSON and compare expected output
text2ql "how many qqq do i own" \
--target graphql \
--schema-file ./schema.json \
--mapping-file ./mapping.json \
--data-file ./data.json \
--expected-execution-file ./expected_rows.json
Benchmarking (Spider & BIRD)
text2ql ships with benchmark adapters and runner APIs:
load_spider(...)load_bird(...)run_benchmark(...),arun_benchmark(...)format_report(...)
CLI examples:
# Spider
text2ql --benchmark spider --benchmark-path /path/to/spider --benchmark-mode structural
# BIRD
text2ql --benchmark bird --benchmark-path /path/to/bird-minidev --benchmark-mode execution
Latest LLM benchmark snapshot (synthetic harness)
Using run_llm_benchmark.py (50 Spider-style + 50 BIRD-style synthetic examples, mode=llm, gpt-4o-mini):
| Benchmark | Exact | Structural | Execution | Errors |
|---|---|---|---|---|
| Spider (50) | 62.0% | 64.0% | 84.0% | 0/50 |
| BIRD (50) | 70.0% | 78.0% | 90.0% | 0/50 |
Raw summary:
SUMMARY
====================================================================
Spider Exact=62.0% Structural=64.0% Execution=84.0% Errors=0/50
BIRD Exact=70.0% Structural=78.0% Execution=90.0% Errors=0/50
Reproduce:
OPENAI_API_KEY=... ./venv/bin/python run_llm_benchmark.py
# or
OPENAI_API_KEY=... python3 run_llm_benchmark.py
Evaluation + Synthetic Data Utilities
Public helpers:
ingest_dataset(...)generate_synthetic_examples(...)evaluate_examples(...)aevaluate_examples(...)rewrite_user_utterance(...)
Built-in rewrite plugins include:
generic,portfolio,banking,crm,healthcare,ecommerce
Repo layout (high level)
src/text2ql/
core.py # Text2QL facade
cli.py # CLI entrypoint
engines/ # GraphQL/SQL engines + stage modules
renderers.py # GraphQLIRRenderer / SQLIRRenderer
evaluate.py # exact/structural/backend evaluation
benchmarks/ # Spider/BIRD loaders + runner
mapping.py # hybrid mapping generation
dataset.py # ingestion + synthetic variants
sql_executor.py # SQLAlchemy-backed execution backend
Testing
python3 -m pytest -m unit
python3 -m pytest -m e2e
python3 -m pytest
License
Apache-2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file text2ql-0.2.4.tar.gz.
File metadata
- Download URL: text2ql-0.2.4.tar.gz
- Upload date:
- Size: 111.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
59b39691594fbf300d6f5c7c691537096d7922e043e6afeb0db1e47a9a0d63ac
|
|
| MD5 |
e8b495adaeafe136f3ba8a65f61232c7
|
|
| BLAKE2b-256 |
40e999c52aa9764f3728c18727128640e729ceac3834496237296d6246566f8c
|
Provenance
The following attestation bundles were made for text2ql-0.2.4.tar.gz:
Publisher:
release.yml on riteshakumar/text2ql
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
text2ql-0.2.4.tar.gz -
Subject digest:
59b39691594fbf300d6f5c7c691537096d7922e043e6afeb0db1e47a9a0d63ac - Sigstore transparency entry: 1292915811
- Sigstore integration time:
-
Permalink:
riteshakumar/text2ql@e8c9f9113dd763593be7e1ecf2febfac4031bb03 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/riteshakumar
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e8c9f9113dd763593be7e1ecf2febfac4031bb03 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file text2ql-0.2.4-py3-none-any.whl.
File metadata
- Download URL: text2ql-0.2.4-py3-none-any.whl
- Upload date:
- Size: 124.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
35a2c06d43f665c135f756581a6eb2407cd028bc0129601a907a68096bb4ff5b
|
|
| MD5 |
75b9aa66bd58fc046671ca9c30d09f1f
|
|
| BLAKE2b-256 |
1a7dc364bb9d2375f4f2ad3b7bb3f6869ac1c2ebaed6ef502c6be9210b5ee3a4
|
Provenance
The following attestation bundles were made for text2ql-0.2.4-py3-none-any.whl:
Publisher:
release.yml on riteshakumar/text2ql
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
text2ql-0.2.4-py3-none-any.whl -
Subject digest:
35a2c06d43f665c135f756581a6eb2407cd028bc0129601a907a68096bb4ff5b - Sigstore transparency entry: 1292915856
- Sigstore integration time:
-
Permalink:
riteshakumar/text2ql@e8c9f9113dd763593be7e1ecf2febfac4031bb03 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/riteshakumar
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e8c9f9113dd763593be7e1ecf2febfac4031bb03 -
Trigger Event:
workflow_dispatch
-
Statement type: