Amazon Q Basics
Stand up a minimal Q Business application over a data source via SDK.
Busca en todas las páginas de la documentación
Stand up a minimal Q Business application over a data source via SDK.
This page is a hands-on tour of the qbusiness service: create an application, create an index, attach a data source, run a sync, and ask your first question. Each resource depends on the one before it, and the two long-running steps - application and index creation, and the sync job - are asynchronous, so this page also shows the poll-for-status pattern you will reuse throughout the section.
pip install boto3 (boto3 1.43.x, Python 3.10+). TypeScript: npm install @aws-sdk/client-qbusiness (Node.js 18+).aws configure, environment variables, or an IAM role. Your identity needs qbusiness:CreateApplication, qbusiness:CreateIndex, qbusiness:CreateDataSource, qbusiness:StartDataSourceSyncJob, and qbusiness:ChatSync.CreateDataSource.us-east-1. Verify current regional availability before relying on it.An application is the top-level container for an index, data sources, and chat.
# --- Python (boto3) ---
import boto3
qbiz = boto3.client("qbusiness", region_name="us-east-1")
resp = qbiz.create_application(
displayName="internal-kb-demo",
identityCenterInstanceArn="arn:aws:sso:::instance/ssoins-exampleid",
)
application_id = resp["applicationId"]
print("application:", application_id, "-", resp["status"])// --- TypeScript (AWS SDK v3) ---
import { QBusinessClient, CreateApplicationCommand } from "@aws-sdk/client-qbusiness";
const qbiz = new QBusinessClient({ region: "us-east-1" });
const resp = await qbiz.send(new CreateApplicationCommand({
displayName: "internal-kb-demo",
identityCenterInstanceArn: "arn:aws:sso:::instance/ssoins-exampleid",
}));
const applicationId = resp.applicationId;
console.log("application:", applicationId, "-", resp.status);identityCenterInstanceArn ties the application to your organization's IAM Identity Center instance for user identity.CreateApplication returns immediately with a status like CREATING - the application is not ready to use yet.applicationId - every later call in this page needs it.The index is where crawled content is embedded and made searchable.
# --- Python (boto3) ---
resp = qbiz.create_index(
applicationId=application_id,
displayName="internal-kb-index",
capacityConfiguration={"units": 1},
)
index_id = resp["indexId"]
print("index:", index_id, "-", resp["status"])// --- TypeScript (AWS SDK v3) ---
import { CreateIndexCommand } from "@aws-sdk/client-qbusiness";
const resp = await qbiz.send(new CreateIndexCommand({
applicationId,
displayName: "internal-kb-index",
capacityConfiguration: { units: 1 },
}));
const indexId = resp.indexId;
console.log("index:", indexId, "-", resp.status);applicationId.capacityConfiguration.units controls index capacity - start at 1 and raise it only if you outgrow it.A data source describes where content comes from and how to connect to it.
# --- Python (boto3) ---
resp = qbiz.create_data_source(
applicationId=application_id,
indexId=index_id,
displayName="internal-kb-s3",
configuration={
"type": "S3",
"syncMode": "FULL_CRAWL",
"connectionConfiguration": {
"repositoryEndpointMetadata": {"BucketName": "my-internal-kb-bucket"}
},
},
roleArn="arn:aws:iam::123456789012:role/QBusinessS3ReaderRole",
)
data_source_id = resp["dataSourceId"]
print("data source:", data_source_id, "-", resp["status"])// --- TypeScript (AWS SDK v3) ---
import { CreateDataSourceCommand } from "@aws-sdk/client-qbusiness";
const resp = await qbiz.send(new CreateDataSourceCommand({
applicationId,
indexId,
displayName: "internal-kb-s3",
configuration: {
type: "S3",
syncMode: "FULL_CRAWL",
connectionConfiguration: {
repositoryEndpointMetadata: { BucketName: "my-internal-kb-bucket" },
},
},
roleArn: "arn:aws:iam::123456789012:role/QBusinessS3ReaderRole",
}));
const dataSourceId = resp.dataSourceId;
console.log("data source:", dataSourceId, "-", resp.status);configuration is connector-specific - S3 here, but SharePoint, Confluence, and a web crawler use their own shapes.roleArn must be a role Q Business can assume with read access to the source and write access to the index.qbusiness API reference.Related: Q Business: Data Sources & Indexing - connector types and sync options in depth.
Nothing is queryable until a sync job crawls and embeds the content.
# --- Python (boto3) ---
import time
qbiz.start_data_source_sync_job(
applicationId=application_id, indexId=index_id, dataSourceId=data_source_id,
)
while True:
jobs = qbiz.list_data_source_sync_jobs(
applicationId=application_id, indexId=index_id, dataSourceId=data_source_id,
)["history"]
status = jobs[0]["status"] if jobs else "UNKNOWN"
print("sync status:", status)
if status in ("SUCCEEDED", "FAILED"):
break
time.sleep(15)// --- TypeScript (AWS SDK v3) ---
import { StartDataSourceSyncJobCommand, ListDataSourceSyncJobsCommand } from "@aws-sdk/client-qbusiness";
await qbiz.send(new StartDataSourceSyncJobCommand({ applicationId, indexId, dataSourceId }));
let status = "UNKNOWN";
while (status !== "SUCCEEDED" && status !== "FAILED") {
const jobs = await qbiz.send(new ListDataSourceSyncJobsCommand({ applicationId, indexId, dataSourceId }));
status = jobs.history?.[0]?.status ?? "UNKNOWN";
console.log("sync status:", status);
if (status !== "SUCCEEDED" && status !== "FAILED") await new Promise((r) => setTimeout(r, 15_000));
}StartDataSourceSyncJob kicks off the crawl - it does not block until completion.ListDataSourceSyncJobs and check the latest entry's status.FAILED sync usually means the service role lacks a permission - check the job's error details.syncMode.ChatSync sends a question and gets one complete answer back, with source attributions.
# --- Python (boto3) ---
resp = qbiz.chat_sync(
applicationId=application_id,
userMessage="What is our remote-work policy?",
)
print(resp["systemMessage"])
for a in resp.get("sourceAttributions", []):
print("source:", a.get("title"), a.get("url"))// --- TypeScript (AWS SDK v3) ---
import { ChatSyncCommand } from "@aws-sdk/client-qbusiness";
const resp = await qbiz.send(new ChatSyncCommand({
applicationId,
userMessage: "What is our remote-work policy?",
}));
console.log(resp.systemMessage);
for (const a of resp.sourceAttributions ?? []) console.log("source:", a.title, a.url);ChatSync needs only applicationId and userMessage for a first question - no index or data source id in the call itself.sourceAttributions cites the documents the answer drew from - surface these to end users for trust.conversationId in the response lets you continue the same thread on the next turn.Related: Q Business Chat & Plugin Integrations - multi-turn chat, streaming, and plugins.
Before troubleshooting further, confirm what actually exists and its current state.
# --- Python (boto3) ---
apps = qbiz.list_applications()["applications"]
for a in apps:
print(a["applicationId"], "-", a["displayName"], "-", a["status"])// --- TypeScript (AWS SDK v3) ---
import { ListApplicationsCommand } from "@aws-sdk/client-qbusiness";
const apps = (await qbiz.send(new ListApplicationsCommand({}))).applications ?? [];
for (const a of apps) console.log(a.applicationId, "-", a.displayName, "-", a.status);ListApplications is the authoritative way to see what you have created and its current status, rather than assuming a create call finished.ACTIVE means the application is ready; CREATING or FAILED need waiting or investigation.ListIndices) and data sources (ListDataSources).DeleteApplication when done - it cascades to its indexes and data sources.Stack versions: This page was written for boto3 1.43.x (Python 3.10+) and the AWS SDK for JavaScript v3 (Node.js 18+).
Revisado por Chris St. John·Última actualización: 25 jul 2026