Skip to main content

An IDE/harness-agnostic and database-agnostic Text-to-SQL Python library.

Project description

Harness-Agnostic Text-to-SQL

A production-grade, IDE/agent-harness agnostic, and database-agnostic Python library that translates natural language queries into safe SQL statements and executes them against a database.

Features

  • Database/IDE-Agnostic: Works out of the box with standard SQLite databases and any major database supported by SQLAlchemy (including MS SQL Server, PostgreSQL, MySQL, Oracle, etc.) by simply providing a connection string. No hardcoded credentials or specific IDE environment setup required.
  • Model-Agnostic: Decouples prompt formulation from specific LLM vendors (OpenAI, Gemini, Anthropic, etc.). You simply pass a callback function that handles the model text completion.
  • Strict Safety Layer: Enforces query rules (such as read-only SELECT constraints), sanitizes markdown blocks, scrubs comments, and protects against DDL/DML injection keywords (e.g. DROP, DELETE, UPDATE, ALTER).

Installation

You can install the stable release directly from PyPI:

# Standard install (SQLite, standard SQLAlchemy, etc.)
pip install harness-agnostic-text-to-sql

# Install with Azure Active Directory and pyodbc dependencies
pip install harness-agnostic-text-to-sql[azure]

For local development or installing from source:

# Clone the repository
git clone https://github.com/adnanahmaddev/model-agnostic-text-to-sql.git
cd model-agnostic-text-to-sql

# Install in editable mode
pip install -e .

Getting Started

1. Basic SQLite Example (Direct DB Connection String)

import sqlite3
from text_to_sql import TextToSQL

# Initialize a demo database
conn = sqlite3.connect("demo.db")
conn.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, role TEXT);")
conn.execute("INSERT INTO users VALUES (1, 'Alice', 'Admin'), (2, 'Bob', 'User');")
conn.commit()
conn.close()

# 1. Define your custom LLM callback
def gemini_or_openai_callback(prompt: str) -> str:
    # Connect to your preferred model SDK here (e.g. Gemini, OpenAI, Claude)
    # response = client.generate_content(prompt)
    # return response.text
    return "SELECT name FROM users WHERE role = 'Admin';"

# 2. Instantiate TextToSQL with connection string and query
translator = TextToSQL(db_uri="sqlite:///demo.db", llm_callback=gemini_or_openai_callback)

result = translator.query("Get the names of all admin users")
print(result)
# Output:
# {
#     'success': True,
#     'sql': 'SELECT name FROM users WHERE role = \'Admin\';',
#     'columns': ['name'],
#     'data': [{'name': 'Alice'}]
# }

2. Live Database Connection Example (SQLAlchemy URI)

You can pass any SQLAlchemy database connection string (e.g., PostgreSQL, MS SQL, MySQL):

from text_to_sql import TextToSQL

# 1. Define LLM callback
def llm_callback(prompt: str) -> str:
    return "SELECT TOP 3 * FROM awo.Asset;"

# 2. Connect directly via DB URI (e.g. MS SQL Server)
# Specify target schema using the 'schema' parameter
translator = TextToSQL(
    db_uri="mssql+pyodbc:///?odbc_connect=DRIVER={ODBC Driver 17 for SQL Server};SERVER=localhost;DATABASE=testdb;UID=sa;PWD=password;",
    schema="awo",
    llm_callback=llm_callback
)

result = translator.query("Get first 3 assets")
result = translator.query("Get first 3 assets")
print(result)

3. Database connection string configuration via CLI or .env

For command-line interface (CLI) execution, the connection string can be provided in three ways:

  1. Explicit command argument: --db-uri "your_connection_string"
  2. Environment Variable: DATABASE_URL set in your shell environment.
  3. Local .env File: A DATABASE_URL variable set inside a .env file in the current working directory. The tool will automatically look for and load a .env file when executed.

Security & Safety

The SafetyValidator intercepts query executions and validates safety constraints:

  • By default, it operates in read_only=True mode, blocking any modification queries (INSERT, UPDATE, DELETE, DROP, ALTER, TRUNCATE, REPLACE, GRANT, REVOKE, SCHEMA, RENAME).
  • Regular expression keyword validation uses word boundaries (\b) to ensure column names containing keywords (e.g. created_at or update_flag) are not false-positives.
  • Comments (single-line -- and multi-line /* */) are cleaned from the returned statement, and searched for keywords to prevent injection bypasses.

Running Tests

Tests are written using pytest. To run the test suite:

# Install test requirements
pip install -e ".[test]"

# Execute tests
PYTHONPATH=. pytest -v

Antigravity Agent Plugin Integration

This repository includes a custom Plugin & Skill wrapper for Antigravity-supported IDE environments.

1. Global Installation (IDE-wide)

To expose this skill to all local workspace agents globally:

  1. Clone this repository:
    git clone https://github.com/adnanahmaddev/model-agnostic-text-to-sql.git
    
  2. Copy or symlink the plugins/text-to-sql-plugin directory to your local configuration folder:
    ln -s "$(pwd)/plugins/text-to-sql-plugin" ~/.gemini/config/plugins/text-to-sql-plugin
    

2. Repository-level Installation (Recommended for Teams)

If you want to commit the skill configuration directly into your project repository:

  1. Create a directory .agents/skills/text-to-sql/ inside your target project repository.
  2. Download or copy the SKILL.md file directly into that directory:
    mkdir -p .agents/skills/text-to-sql
    curl -o .agents/skills/text-to-sql/SKILL.md https://raw.githubusercontent.com/adnanahmaddev/harness-agnostic-text-to-sql/main/plugins/text-to-sql-plugin/skills/text-to-sql/SKILL.md
    
  3. Register it in your repository's local AGENTS.md file:
    | Skill | Path | When To Use |
    |---|---|---|
    | `text-to-sql` | `.agents/skills/text-to-sql/` | Translate natural language queries into SQL and query the database |
    

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

harness_agnostic_text_to_sql-0.1.6.tar.gz (16.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

harness_agnostic_text_to_sql-0.1.6-py3-none-any.whl (16.0 kB view details)

Uploaded Python 3

File details

Details for the file harness_agnostic_text_to_sql-0.1.6.tar.gz.

File metadata

File hashes

Hashes for harness_agnostic_text_to_sql-0.1.6.tar.gz
Algorithm Hash digest
SHA256 65836c24f412698c107d027e89bb3a77bded71ab0bec3b422a86fa661b893282
MD5 4620f29c8ac51746669135adddcaf8b9
BLAKE2b-256 69801237bd3eb2d5a06ed8629c8bd66e02ffc4d7b196acb5675ae8d1c09041fe

See more details on using hashes here.

File details

Details for the file harness_agnostic_text_to_sql-0.1.6-py3-none-any.whl.

File metadata

File hashes

Hashes for harness_agnostic_text_to_sql-0.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 d6df8a31b31dd75fbf77d9ffb448c3e00247599c72ec9cf08859caddd2882044
MD5 a776aca9f31245f7417cde9b5adf57b0
BLAKE2b-256 8a26a20680f7ca6473f70f1998f6ffc5fa72bd99ba7d34373d3de7b7b69acf31

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page