Metadata-Version: 2.4
Name: text2sql-lite
Version: 0.3.0
Summary: Convert natural English to SQL (SQLite, Postgres, MySQL) with offline heuristics or optional LLM backends.
Project-URL: Homepage, https://github.com/sriramsreedhar/text2sql-lite
Project-URL: Repository, https://github.com/sriramsreedhar/text2sql-lite
Project-URL: Issues, https://github.com/sriramsreedhar/text2sql-lite/issues
Author: text2sql-lite contributors
License-Expression: MIT
Keywords: gemini,llm,mistral,mysql,nlp,openai,postgres,sql,sqlite,text2sql
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Database
Requires-Python: >=3.10
Provides-Extra: dev
Requires-Dist: mypy>=1.11.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.6.0; extra == 'dev'
Provides-Extra: llm
Requires-Dist: google-generativeai>=0.8.0; extra == 'llm'
Requires-Dist: mistralai>=1.2.0; extra == 'llm'
Requires-Dist: openai>=1.40.0; extra == 'llm'
Provides-Extra: llm-gemini
Requires-Dist: google-generativeai>=0.8.0; extra == 'llm-gemini'
Provides-Extra: llm-mistral
Requires-Dist: mistralai>=1.2.0; extra == 'llm-mistral'
Provides-Extra: llm-openai
Requires-Dist: openai>=1.40.0; extra == 'llm-openai'
Provides-Extra: mysql
Requires-Dist: pymysql>=1.1.0; extra == 'mysql'
Provides-Extra: postgres
Requires-Dist: psycopg[binary]>=3.1.0; extra == 'postgres'
Description-Content-Type: text/markdown

# text2sql-lite

Source: [github.com/sriramsreedhar/text2sql-lite](https://github.com/sriramsreedhar/text2sql-lite)

Turn short English requests into **SQLite**, **PostgreSQL**, or **MySQL** SQL using **offline heuristics** by default. You can optionally add **OpenAI**, **Google Gemini**, or **Mistral** via small install extras so `translate()` can call a model when you want broader coverage or when heuristics fail.

---

## LLM (optional)

Install **one** provider you use, or **all** of them:

```bash
pip install "text2sql-lite[llm]"              # OpenAI + Gemini + Mistral (all SDKs)
pip install "text2sql-lite[llm_openai]"       # OpenAI only
pip install "text2sql-lite[llm_gemini]"      # Google Gemini only
pip install "text2sql-lite[llm_mistral]"     # Mistral only
```

**How `translate()` uses an LLM**

- Pass **`llm_client=<wrapper>`** (see below). If the **heuristic** parser cannot handle the phrase, the model is used instead of raising `ValueError`.
- Pass **`prefer_llm=True`** to call the **model first**; if the model fails (network error, etc.), the library **falls back** to heuristics when possible.

Set API keys the usual way (environment variables or your provider’s docs). Always **review** model-generated SQL before running it.

### OpenAI

```python
import os
from text2sql_lite import translate, Dialect, OpenAIChatClient
from text2sql_lite.schema import Table, Column, TableSchema

schema = TableSchema((Table("users", (Column("email"), Column("state"))),))
client = OpenAIChatClient(api_key=os.environ.get("OPENAI_API_KEY"), model="gpt-4o-mini")

result = translate(
    "emails of users in TX ordered by signup",
    dialect=Dialect.POSTGRES,
    schema=schema,
    llm_client=client,
)
print(result.sql)
```

### Google Gemini

Uses the `google-generativeai` SDK (`llm_gemini` extra). Set `GOOGLE_API_KEY` or pass `api_key=` into the client.

```python
import os
from text2sql_lite import translate, Dialect, GeminiChatClient
from text2sql_lite.schema import Table, Column, TableSchema

schema = TableSchema((Table("users", (Column("email"), Column("state"))),))
client = GeminiChatClient(api_key=os.environ.get("GOOGLE_API_KEY"), model="gemini-1.5-flash")

result = translate(
    "emails of users in TX ordered by signup",
    dialect=Dialect.POSTGRES,
    schema=schema,
    llm_client=client,
)
print(result.sql)
```

### Mistral

```python
import os
from text2sql_lite import translate, Dialect, MistralChatClient
from text2sql_lite.schema import Table, Column, TableSchema

schema = TableSchema((Table("users", (Column("email"), Column("state"))),))
client = MistralChatClient(api_key=os.environ.get("MISTRAL_API_KEY"), model="mistral-small-latest")

result = translate(
    "emails of users in TX ordered by signup",
    dialect=Dialect.POSTGRES,
    schema=schema,
    llm_client=client,
)
print(result.sql)
```

---

## SQLite

**Install** — base package only (no extra dependencies):

```bash
pip install text2sql-lite
```

**Generate SQL** — use `Dialect.SQLITE` (backtick identifiers; `LIKE` for place-style filters):

```python
from text2sql_lite import translate, Dialect
from text2sql_lite.schema import Table, Column, TableSchema

schema = TableSchema(
    (Table("users", (Column("id"), Column("email"), Column("state"))),),
)

result = translate(
    "show users from texas",
    dialect=Dialect.SQLITE,
    schema=schema,
)
print(result.sql)
```

**Optional: load schema from a `.db` file** — uses the standard library (`sqlite3`); no extra install:

```python
from text2sql_lite.introspect import introspect_sqlite

schema = introspect_sqlite("/path/to/app.db")
```

---

## PostgreSQL

**Install** — include the Postgres extra so schema introspection can use `psycopg`:

```bash
pip install "text2sql-lite[postgres]"
```

**Generate SQL** — use `Dialect.POSTGRES` (double-quoted identifiers when needed; `ILIKE` for place-style filters):

```python
from text2sql_lite import translate, Dialect
from text2sql_lite.schema import Table, Column, TableSchema

schema = TableSchema(
    (Table("users", (Column("id"), Column("email"), Column("state"))),),
)

result = translate(
    "show users from texas",
    dialect=Dialect.POSTGRES,
    schema=schema,
)
print(result.sql)
```

**Optional: load schema from a live database** — pass a **psycopg** connection (v3):

```python
import psycopg
from text2sql_lite.introspect import introspect_postgres

conn = psycopg.connect("postgresql://user:pass@localhost:5432/dbname")
schema = introspect_postgres(conn)
conn.close()
```

---

## MySQL

**Install** — include the MySQL extra for **PyMySQL** (used by `introspect_mysql`):

```bash
pip install "text2sql-lite[mysql]"
```

**Generate SQL** — use `Dialect.MYSQL` (backtick identifiers; place-style filters use `LOWER` / `LIKE` / `CONCAT`):

```python
from text2sql_lite import translate, Dialect
from text2sql_lite.schema import Table, Column, TableSchema

schema = TableSchema(
    (Table("users", (Column("id"), Column("email"), Column("state"))),),
)

result = translate(
    "show users from texas",
    dialect=Dialect.MYSQL,
    schema=schema,
)
print(result.sql)
```

**Optional: load schema from a live database** — pass a **PyMySQL** connection to the current database:

```python
import pymysql
from text2sql_lite.introspect import introspect_mysql

conn = pymysql.connect(host="localhost", user="u", password="p", database="mydb")
schema = introspect_mysql(conn)
conn.close()
```

---

## API highlights

- **`translate(...)`** — pattern-based English → SQL; raises `ValueError` if neither heuristics nor an LLM can handle the request (when no `llm_client` is passed). Use **`llm_client=`** and optionally **`prefer_llm=True`**.
- **`Dialect.SQLITE` / `Dialect.POSTGRES` / `Dialect.MYSQL`** — quoting and string matching tuned per engine.
- **`introspect_sqlite(path)`** — stdlib only; **`introspect_postgres(conn)`** — needs `[postgres]`; **`introspect_mysql(conn)`** — needs `[mysql]`.

## Limits

Heuristics cover a **narrow** set of shapes (list rows, optional “from &lt;place&gt;” filters, simple `WHERE col op value`, `LIMIT`). LLMs can handle richer language but may still hallucinate—always **review** generated SQL before execution.

## Development

```bash
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest
```
