Build Python Apps on Your Business Data with the New CData CLI



The CData CLI is a command-line tool that lets AI coding agents like Claude Code, Cursor, GitHub Copilot, and Gemini CLI reach your business data through CData drivers. Salesforce, NetSuite, Jira, Snowflake, SAP, and hundreds of other SaaS and database sources become queryable right from your terminal, so an agent can explore real schemas and build data-connected apps against them.

This article focuses on using the CLI for building Python applications. AI coding agents are great at writing Python, but they stumble the moment that code has to talk to a real system. The problem isn't code generation; it's that the agent has no grounded picture of your data. The CData CLI fixes that, and a purpose-built skill turns grounded exploration into working Python.


The architecture: one data model, many drivers

The key idea behind the CLI is that CData drivers (JDBC, ADO.NET, ODBC, and the Python Connector) expose the same relational model over the same SQL dialect. A Salesforce org, a Jira project, a Snowflake warehouse: each is presented as tables, columns, and stored procedures, queried with a standard SQL-92-style dialect. The edition you use (a Java jar, a .NET DLL, a system ODBC driver, a Python wheel) changes how your program links to the driver, but the tables, columns, and SQL do not.

The CLI leans on that shared model:

  • cdatacli is a Java tool that runs on the JDBC driver. It requires Java 17+ and discovers driver jars from ./ or ./lib/. Through it you create a connection, list tables and columns, inspect stored procedures, and run real SQL against the live source.
  • Because the model is shared, anything you validate through the CLI transfers verbatim to whatever edition your app uses. The SELECT ... FROM Opportunity you confirm at the command line is the same statement your Python app runs through the Python Connector.

That gives a clean two-phase workflow:

Discovery  -->  cdatacli  (JDBC)              --> connect, list tables/columns, validate SQL
                    |
                    v  (same data model + SQL)
Build      -->  CData Python Connector         --> write the Python app

The payoff for an AI coder is that the two hard parts (what can I query, and how do I express it) are answered once, empirically, before a line of application code is written. The agent then writes idiomatic Python against a schema it has actually seen, not one it guessed.


From workflow to skill

That workflow is codified as agent skills, instruction files an AI coding tool loads on demand:

  • cdata-cli: the discovery skill. Connect to a source, explore schema, validate SQL, and download/activate JDBC drivers. It's the foundation.
  • cdata-cli-python: the Python build skill. It takes over once discovery is done and you're ready to write Python.

The split matters. cdata-cli is language-agnostic and is where the grounding happens. The build skill deliberately doesn't re-explain schema discovery; it focuses on the parts specific to the Python Connector: how to get it and how to connect. These are the details an agent would otherwise get wrong.


What the Python skill handles

npx skills add CDataSoftware/cli-skills --skill cdata-cli-python

cdata-cli-python encodes the non-obvious specifics of the Python Connector so the agent doesn't rediscover them by trial and error:

  • Language to edition mapping. Python 3.x uses the CData Python Connector, imported as cdata.<source> (e.g. cdata.salesforce). It's a compiled DB-API 2.0 module shipped as a platform-specific wheel.
  • Getting the connector. The wheel comes from CData's Python repository (maven.cdata.com/python). This is a distinct step from the CLI: cdatacli downloads JDBC jars only, so the Python wheel is fetched separately.
  • Licensing is separate and per-machine. A working cdatacli connection proves the JDBC edition is licensed, not the Python Connector. The wheel ships an install-license tool (install-license.exe on Windows, install-license.sh on macOS/Linux), run once per machine.

The net effect: the agent installs the right wheel, activates it, and writes correct DB-API code on the first try, reusing the SQL it already validated.


Example: building a real Python app

Here's the whole workflow, start to finish, from a single prompt to an AI coding agent with both skills installed:

"using /cdata-cli, build a python CLI app to connect to my gmail and tell me the most common topics I have been discussing in the past week."

The agent handled it in two phases (discovery with cdata-cli, then build with cdata-cli-python) exactly as the architecture above predicts. Here's each step.

Step 1: Discovery — confirm the driver (via the CLI, on JDBC)

The agent started at the command line, not in code. cdatacli drivers list showed the Gmail driver present and activated, and an existing gmail connection ready to use.

cdatacli drivers list
{
  "drivers": [
    { "name": "Gmail", "product": "CData JDBC Driver For Gmail 2026", "version": "26.0.9655.0", "activated": true }
  ]
}

Step 2: Discovery — explore the schema and validate the query

Still in the CLI, the agent confirmed the Messages table's columns and ran the actual query the app would use (counting and sampling messages from the past week) against live Gmail. This is where what can I query and how get answered empirically:

cdatacli query sql --connection gmail --sql "SELECT COUNT(*) AS c FROM Messages WHERE [Date] >= '2026-07-20'"
cdatacli query sql --connection gmail --sql "SELECT Subject, [From], [Date] FROM Messages WHERE [Date] >= '2026-07-20' ORDER BY [Date] DESC LIMIT 10"
{ "resultset": [ { "c": 6 } ] }
{ "resultset": [
  { "Subject": "Justin, review your Google Account settings", "From": "Google &lt;[email protected]>",            "Date": "2026-07-27 09:06:02.0" },
  { "Subject": "Important Updates to Legal Terms for Salesforce APIs", "From": "Salesforce &lt;[email protected]>", "Date": "2026-07-23 09:12:45.0" },
  { "Subject": "How does Agentforce work?",                   "From": "Salesforce Agentforce &lt;[email protected]>", "Date": "2026-07-22 13:26:48.0" },
  { "Subject": "Real ROI for your business starts at Dreamforce.", "From": "Dreamforce &lt;[email protected]>",   "Date": "2026-07-20 13:47:25.0" }
] }

The query returned real subjects (Google account notices, Salesforce/Dreamforce mail) confirming the Subject, Date, and Snippet columns the app would read.

This is the key architectural moment. The SQL was validated here through the JDBC-backed CLI, and because every CData edition shares one data model, the exact same statement runs unchanged through the Python Connector in the app.

Step 3: Handoff to the Python build skill

With the connection and query proven, the agent invoked cdata-cli-python and set up the Python side: it fetched the Gmail Python Connector wheel from CData's Python repository and installed it into a virtual environment. The skill's import self-check returned exactly what it predicts:

python -m pip install cdata_gmail_connector-26.0.9655-cp310-abi3-win_amd64.whl
python -c "import cdata.gmail as m; print('paramstyle:', m.paramstyle, '| apilevel:', m.apilevel)"
Successfully installed cdata-gmail-connector-26.0.9655
paramstyle: qmark | apilevel: 2.0

A separate driver edition. The Python Connector isn't the JDBC driver the CLI used. It's the Python edition of the same driver, obtained from CData's Python repository and licensed independently. Same data model, different runtime.

Step 4: The build — write the CLI app

The agent wrote a small CLI, gmail_topics.py, using the connector through DB-API 2.0 exactly as the skill describes: cdata.gmail.connect(...), ? (qmark) placeholders, and try/finally (the connector doesn't support with). It reused the connection from discovery, so there was no new sign-in. The core is just the validated query plus a bit of keyword and phrase counting:

import cdata.gmail as gmail

def fetch_recent_text(days: int) -> list[str]:
    cutoff = (datetime.now() - timedelta(days=days)).strftime("%Y-%m-%d")
    sql = ("SELECT Subject, Snippet FROM Messages "
           "WHERE [Date] >= ? AND Labels LIKE '%INBOX%' ORDER BY [Date] DESC")
    conn = gmail.connect(CONNECTION_STRING)
    try:
        cur = conn.cursor()
        cur.execute(sql, [cutoff])          # ? qmark params, validated in discovery
        return [" ".join(str(c) for c in row if c) for row in cur.fetchall()]
    finally:
        conn.close()

Step 5: Run it against real Gmail

python gmail_topics.py --days 7 --top 10
Analyzed 6 message(s) from the past 7 day(s).

Top 10 keywords
------------------------------
    5  salesforce
    4  dreamforce
    4  register
    3  google
    3  september
    3  important
    3  agent
    3  free
    2  started

Top 10 phrases
------------------------------
    3  dreamforce register
    2  september san
    2  san francisco
    2  register free
    1  google settings
    1  review google
    ...

The topics are real and coherent: the past week's inbox was dominated by Salesforce/Dreamforce (registration, September, San Francisco), with a few Google account notices. From "connect to my Gmail and tell me what I've been discussing" to a working Python CLI came out of one prompt, because the agent grounded itself with the CLI before writing a line of Python, then built against the same data model through the Python Connector.


Get started

The CData CLI turns any AI coding agent into one that can build real, data-connected Python apps grounded in your actual schema. Validate your connection and SQL with the CLI first, then add the Python skill and let the agent write against Salesforce, Jira, or any of the hundreds of supported sources.

Download the CLI

macOS:

curl -fsSL https://downloads.cdata.com/cdatabuilds/builds/free/cdatacli/install-cdatacli-macos.sh | bash

Windows:

irm https://downloads.cdata.com/cdatabuilds/builds/free/cdatacli/install-cdatacli-windows.ps1 | iex

Linux:

curl -fsSL https://downloads.cdata.com/cdatabuilds/builds/free/cdatacli/install-cdatacli-linux.sh | bash

Download all CLI skills:

npx skills add CDataSoftware/cli-skills

Download the Python CLI skill only:

npx skills add CDataSoftware/cli-skills --skill cdata-cli-python

Need assistance? Contact our support team.