Skip to main content

Open-source universal Python connector for APIs - Query any data source with SQL

Project description

WaveQL

WaveQL Logo

The Universal SQL Connector for Modern APIs
Query ServiceNow, Salesforce, Jira, and more using standard SQL.

PyPI License Python Version Async Support


WaveQL transforms the way you interact with SaaS APIs. Instead of wrestling with complex, proprietary REST endpoints and pagination logic, WaveQL lets you query your business data using the language you already know: SQL.

Built for data engineers and developers, it translates your SQL queries into optimized API calls (pushing down predicates like WHERE and ORDER BY), handles authentications, and returns high-performance Arrow or Pandas dataframes.

🚀 Why WaveQL?

  • 🔌 Universal Adapter System: Connect to ServiceNow, Salesforce, Jira, or generic REST APIs with a unified interface.
  • ⚡ Intelligent Query Pushdown: We don't just fetch all data. WHERE clauses are translated into native API filters (e.g., JQL, SOQL) for maximum performance.
  • 🔄 Cross-Source JOINs: Seamlessly join data between your local CSVs, a Jira backlog, and ServiceNow incidents using our DuckDB-powered engine.
  • ⚡ Async Built-in: Built on httpx and anyio for high-concurrency, non-blocking applications.
  • 🐼 Data Science Ready: Native integrations with Pandas, PyArrow, and SQLAlchemy (works with Superset!).

📦 Installation

pip install waveql

Or install from source:

git clone https://github.com/mitayan0/WaveQL.git
cd WaveQL
pip install -e .

⚡ Quick Start

1. Querying ServiceNow

import waveql

# Connect securely
conn = waveql.connect(
    "servicenow://instance.service-now.com",
    username="admin",
    password="your-password"
)

# Execute standard SQL
cursor = conn.cursor()
cursor.execute("""
    SELECT number, short_description, priority 
    FROM incident 
    WHERE state = 1 AND priority <= 2
    ORDER BY number DESC
    LIMIT 10
""")

# Work with results
for row in cursor:
    print(f"[{row.number}] {row.short_description}")

# Or get a Pandas DataFrame instantly
df = cursor.fetchall().to_df()
print(df.head())

2. Async Support

Building a modern FastAPI or async app? We've got you covered.

import asyncio
from waveql import connect_async

async def main():
    conn = await connect_async(
        "jira://your-domain.atlassian.net",
        username="user@example.com",
        password="api-token"
    )
    
    cursor = conn.cursor()
    # Predicates are pushed down to JQL!
    await cursor.execute("SELECT key, summary FROM issues WHERE project = 'PROJ'")
    
    results = await cursor.fetchall()
    print(results)

asyncio.run(main())

3. The Power of Cross-Source Joins

Combine data from anywhere.

conn.execute("""
    SELECT 
        sn.number as ticket_id,
        jira.key as engineering_task,
        sn.short_description
    FROM servicenow.incident sn
    JOIN jira.issues jira ON sn.correlation_id = jira.key
    WHERE sn.priority = 1
""")

🛠 Supported Adapters

Adapter URI Scheme Features
ServiceNow servicenow:// ✅ Table API, ✅ Aggregates, ✅ Write (CRUD)
Salesforce salesforce:// ✅ SOQL Pushdown, ✅ Bulk API support
Jira jira:// ✅ JQL Pushdown, ✅ Pagination
REST rest:// ⚠️ Generic JSON querying
File file:// ✅ CSV, Parquet, JSON (via DuckDB)

📝 SQL Syntax Support

WaveQL supports ANSI SQL with full compatibility for schema-qualified and quoted identifiers:

-- All of these are equivalent and fully supported:
SELECT * FROM incident
SELECT * FROM servicenow.incident
SELECT * FROM "servicenow"."incident"
SELECT * FROM servicenow."incident"

Supports: SELECT, INSERT, UPDATE, DELETE, JOIN, GROUP BY, ORDER BY, LIMIT, OFFSET

🔐 Authentication

WaveQL takes the headache out of auth headers.

  • Basic Auth: Simple username/password.
  • API Key: Custom headers or query params.
  • OAuth2: Full flow support including token refresh.
from waveql.auth import AuthManager

# OAuth2 Example
auth = AuthManager(
    oauth2_token_url="https://login.salesforce.com/services/oauth2/token",
    client_id="your_client_id",
    client_secret="your_client_secret"
)
conn = waveql.connect("salesforce://login.salesforce.com", auth_manager=auth)

🤝 Contributing

We love contributions! Whether it's a new adapter, a bug fix, or a docs improvement, please join us.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

Copyright (c) 2026 Mitayan Chakma.


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

waveql-0.1.1.tar.gz (469.8 kB view details)

Uploaded Source

Built Distribution

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

waveql-0.1.1-py3-none-any.whl (61.3 kB view details)

Uploaded Python 3

File details

Details for the file waveql-0.1.1.tar.gz.

File metadata

  • Download URL: waveql-0.1.1.tar.gz
  • Upload date:
  • Size: 469.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for waveql-0.1.1.tar.gz
Algorithm Hash digest
SHA256 474ebf5e96e1c63e7f5c85dc8c916e85bcdcdeb29acd0d36c19c62d80694690c
MD5 98883a13f50766a6f188a5f22eab4b66
BLAKE2b-256 2da47291a0b8861521fb69b432da477a3211d7be5c53e45a29de46faaa1dd202

See more details on using hashes here.

File details

Details for the file waveql-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: waveql-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 61.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for waveql-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 06fe62c285cea6831c3074fd741de7d89a6a3740165580de4ed2ed3ed6404fe9
MD5 dca2a650ba7322025cd3c9590e81c865
BLAKE2b-256 4becef6983cc5b25f3a9ec70b32fe91e1d6298963523e1033e542963a8a78bbf

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