Skip to content

Installation and setup

Requirements

Component Version Purpose
Python 3.9+ Runtime
Java 11+ (only for H2) Runs the H2 JDBC driver via JPype

Install

pip install sql2api                     # SQLite only
pip install "sql2api[postgres,mysql]"   # add the drivers you need
pip install "sql2api[all]"              # every driver

Available extras: mysql, postgres, clickhouse, h2, all, server (gunicorn) and dev. Each database driver is imported only when a connection of that type is used, so you never need drivers you do not use.

Database Driver Extra
MySQL mysql-connector-python mysql
PostgreSQL psycopg2-binary postgres
ClickHouse clickhouse-driver clickhouse
SQLite sqlite3 (standard library) -
H2 JayDeBeApi + JPype1 h2

From source

git clone https://github.com/AnanthaRajuC/SQL2API.git && cd SQL2API
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

Set up a data folder

SQL2API keeps its state in one folder - SQL2API_HOME, by default the current directory:

db_connections.json     connection registry
saved_sql/              one JSON file per saved query
mkdir my-api && cd my-api
sql2api init            # writes db_connections.json (all templates inactive) and saved_sql/
# edit db_connections.json, set "active": true on the connections you want
sql2api serve           # http://127.0.0.1:5000

To try it without any database of your own, use the bundled examples: cd examples && cp db_connections.example.json db_connections.json && sql2api serve.

Configuration

Behaviour is controlled by environment variables - see the table in the README (SQL2API_HOME, SQL2API_ALLOW_WRITES, SQL2API_API_KEY, SQL2API_MAX_PAGE_SIZE, SQL2API_QUERY_TIMEOUT, SQL2API_POOL_SIZE, SQL2API_POOL_IDLE_TIMEOUT, SQL2API_CORS_ORIGINS, SQL2API_RATE_LIMIT, SQL2API_TRUST_PROXY, SQL2API_HOST, SQL2API_PORT, SQL2API_DEBUG, SQL2API_H2_JAR).

Running in production

sql2api serve uses Flask's development server. For production use gunicorn with one worker (saved-query and connection files are protected by an in-process lock) and several threads, behind a TLS-terminating reverse proxy:

pip install "sql2api[server]"
SQL2API_API_KEY=change-me gunicorn --bind 127.0.0.1:5000 --workers 1 --threads 8 --timeout 120 "sql2api.app:create_app()"

Behind a reverse proxy or load balancer, also set SQL2API_TRUST_PROXY=1 (the number of proxies) so rate limits and redirects use the real client address and scheme.

Or use the published Docker image (ghcr.io/anantharajuc/sql2api, with a -h2 variant that includes Java) or the Dockerfile - see the README. The image sets gunicorn's worker timeout to 120 seconds; keep it above SQL2API_QUERY_TIMEOUT if you run your own gunicorn.

Verify

curl http://127.0.0.1:5000/health
curl http://127.0.0.1:5000/connections

Running the tests

pip install -e ".[dev]"
ruff check .
python -m unittest discover -s tests -t .

Integration tests against real databases are enabled by setting SQL2API_IT_POSTGRES, SQL2API_IT_MYSQL, SQL2API_IT_CLICKHOUSE and/or SQL2API_IT_H2 to a JSON connection object - see the header of tests/test_integration.py. tests/test_sql_guard_fuzz.py fuzzes the SQL guard and parameter binder with Hypothesis and always runs as part of the suite above.