Skip to main content
Version: 0.0.41

Manage Datasources

This use case covers the full datasource lifecycle via API: create a connection, validate it, trigger semantic extraction, and bind the datasource to a Custom Model — so it is ready for analytical queries.

Sequence Overview​

1. Create datasource  →  datasource_id
2. Validate connection → confirm reachability
3. Trigger semantic extraction → wait for completion
4. Bind to a Custom Model → ready for chat

Each step is required in order. Skipping semantic extraction means the AI has no knowledge of the tables and columns.

1. Create a Datasource​

curl -X POST "$LHC_SEMANTIC/api/v1/semantic/datasources" \
-H "Authorization: Bearer $LHC_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Sales Database",
"type": "postgresql",
"connection_uri": "postgresql://readonly_user:secret@db.example.com:5432/sales"
}'
ds = requests.post(
f"{SEMANTIC}/api/v1/semantic/datasources",
headers=HEADERS,
json={
"name": "Sales Database",
"type": "postgresql",
"connection_uri": "postgresql://readonly_user:secret@db.example.com:5432/sales",
},
).json()

datasource_id = ds["id"]
print(f"Created datasource: {datasource_id}")

For the full list of supported type values and the required connection fields per type, see Datasource Types.

2. Validate the Connection​

Before triggering extraction, verify that the database is reachable:

curl -X PUT "$LHC_SEMANTIC/api/v1/semantic/datasources/id/$DATASOURCE_ID/operations" \
-H "Authorization: Bearer $LHC_TOKEN" \
-H "Content-Type: application/json" \
-d '{"test_connection": true}'
result = requests.put(
f"{SEMANTIC}/api/v1/semantic/datasources/id/{datasource_id}/operations",
headers=HEADERS,
json={"test_connection": True},
).json()

print(result) # {"success": true} or error detail

3. Trigger Semantic Extraction​

Semantic extraction reads the database schema and generates descriptions for all tables and columns. This step is required before any analytical queries can run.

curl -X PUT "$LHC_SEMANTIC/api/v1/semantic/datasources/id/$DATASOURCE_ID/operations" \
-H "Authorization: Bearer $LHC_TOKEN" \
-H "Content-Type: application/json" \
-d '{"create": true}'
requests.put(
f"{SEMANTIC}/api/v1/semantic/datasources/id/{datasource_id}/operations",
headers=HEADERS,
json={"create": True},
)

Extraction runs asynchronously. It typically completes within seconds to a few minutes depending on the schema size. You can poll the datasource status to confirm completion:

import time

while True:
status = requests.get(
f"{SEMANTIC}/api/v1/semantic/datasources/id/{datasource_id}",
headers=HEADERS,
).json()
if status.get("is_ready"):
print("Semantic extraction complete")
break
time.sleep(5)

4. Bind Datasource to a Custom Model​

Once extraction is complete, bind the datasource to an existing Custom Model:

curl -X POST "$LHC_SEMANTIC/api/v1/semantic/datasourcemodels" \
-H "Authorization: Bearer $LHC_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"datasource_id\": \"$DATASOURCE_ID\", \"model_id\": \"$MODEL_ID\"}"
requests.post(
f"{SEMANTIC}/api/v1/semantic/datasourcemodels",
headers=HEADERS,
json={"datasource_id": datasource_id, "model_id": model_id},
)

The model is now ready to answer questions about this datasource. See Chat with Data.

List Datasources​

datasources = requests.get(
f"{SEMANTIC}/api/v1/semantic/datasources",
headers=HEADERS,
).json()

for ds in datasources:
print(ds["id"], ds["name"], ds["type"], ds.get("is_ready"))