IntegrationsLangChain

LangChain

LangChain tools for Hotdata — give your chains and agents SQL execution and instant database access.

Install

pip install hotdata-langchain

Authentication

Set HOTDATA_API_KEY in your environment. Optionally set HOTDATA_WORKSPACE to pin a specific workspace.

Quickstart

from hotdata_framework import from_env
from hotdata_langchain import make_hotdata_tools
from langchain.agents import create_agent

client = from_env()
tools = make_hotdata_tools(client, database_id="dbid...")

agent = create_agent(
    model="openai:gpt-4o",
    tools=tools,
    system_prompt="You are a data analyst.",
)
result = agent.invoke(
    {"messages": [{"role": "user", "content": "How many orders are in the database?"}]}
)
print(result["messages"][-1].content)

Queries run against a database scope, so pass database_id= (an instant database id). from_env().list_managed_databases() shows what is available in the workspace, with the id of each.

Tools

make_hotdata_tools returns a list of StructuredTool objects ready to pass to any LangChain agent. By default it returns five tools — hotdata_describe_tables is registered unless you pass describe_tables=False — plus hotdata_search_text when you configure full-text search:

ToolDescription
hotdata_execute_sqlRun SQL and return JSON rows
hotdata_list_managed_databasesList Hotdata instant databases, with the id of each
hotdata_create_managed_databaseCreate a database and declare tables
hotdata_load_managed_tableLoad a local parquet file into a table
hotdata_describe_tablesList tables, or one table's columns and types
hotdata_search_textFull-text search an indexed column, ranked by relevance (opt-in)
tools = make_hotdata_tools(
    client,
    max_rows=50,           # rows returned to the agent per query (default 100)
    database_id="dbid...", # scope queries to a specific database id (optional)
)

Run SQL directly

from hotdata_langchain import execute_sql_json, result_rows_for_llm
from hotdata_langchain.databases import resolve_database_by_id

# Queries are database-scoped, and these take a resolved database — not an id
# string — under the keyword `database`.
database = resolve_database_by_id(client, "dbid...")

# Returns a JSON string — useful for custom tool wrappers
json_str = execute_sql_json(client, "SELECT * FROM orders LIMIT 5", database=database)

# Returns list[dict] from a QueryResult, trimmed to max_rows
result = client.execute_sql("SELECT * FROM orders LIMIT 100", database=database)
rows = result_rows_for_llm(result, max_rows=20)

Three things to carry over from that example. The keyword is database here, while make_hotdata_tools above takes database_idhotdata-langchain#81 tracks reconciling the two. execute_sql_json takes the resolved database only and rejects a bare id string, so resolve_database_by_id is a required step rather than a convenience; it accepts an already-resolved database unchanged, so it is safe to call either way. And while client.execute_sql does accept a string, that path falls back to matching a database's display label, which is not unique — passing the resolved database is the dependable form for both.

Instant databases

from hotdata_langchain.databases import (
    create_managed_database,
    list_managed_databases_json,
    load_managed_table,
)

# Create a database and declare tables
db = create_managed_database(
    client,
    name="sales",
    schema="public",
    tables=["orders", "customers"],
)

# Load a local parquet file into a table
loaded = load_managed_table(
    client,
    database_id=db.id,
    table="orders",
    file="orders.parquet",
)
print(f"Loaded {loaded.row_count} rows → {loaded.full_name}")

# What the workspace holds — one entry per database
print(list_managed_databases_json(client))

A listing entry carries the database's id and its description, which is where the label passed as name at creation currently comes back. Address a database by its id — the label is a display string and is not unique. The spelling of that label field is still settling, so read it off a live listing rather than assuming a name for it.

See also