Async Operations
- Python
- TypeScript
The Python SDK provides an AsyncCredoAI client for applications that use async/await, alongside the synchronous CredoAI client.
The TypeScript SDK is async by default — all methods return promises. There is no separate sync client.
When to Use Async
- Python
- TypeScript
Use the async client when:
- Building async web applications (FastAPI, Starlette)
- Making concurrent API calls
- Working in an async context (e.g., async task queues)
- You need non-blocking I/O
The TypeScript client is always async. Use it everywhere:
- Node.js scripts and CLI tools
- Express / Fastify / Next.js servers
- Concurrent API calls with
Promise.all() - Any TypeScript/JavaScript application
Basic Usage
- Python
- TypeScript
import asyncio
from credoai import AsyncCredoAI
async def main():
async with AsyncCredoAI() as client:
# All operations use await
response = await client.use_cases.list()
for uc in response.items:
print(f" - {uc.name}")
asyncio.run(main())
import { createCredoAIClient } from '@credo-ai/sdk';
const client = createCredoAIClient('your-tenant');
// All operations are async
const { data, error } = await client.useCases.list();
if (!error) {
for (const uc of data.items) {
console.log(` - ${uc.name}`);
}
}
Client Lifecycle
- Python
- TypeScript
Always use the async client as a context manager to ensure proper cleanup:
async with AsyncCredoAI() as client:
# Client is ready
await client.use_cases.list()
# Client is automatically closed
Manual Lifecycle
If you can't use a context manager:
client = AsyncCredoAI()
try:
await client.use_cases.list()
finally:
await client.close()
The TypeScript client requires no special lifecycle management — just create it and use it:
const client = createCredoAIClient('your-tenant');
// Use the client directly
const { data, error } = await client.useCases.list();
Async Iteration
- Python
- TypeScript
async with AsyncCredoAI() as client:
async for use_case in client.use_cases.list_all(page_size=50):
print(f" - {use_case.name}")
# Or collect all via async list comprehension
all_use_cases = [uc async for uc in client.use_cases.list_all()]
print(f"Total: {len(all_use_cases)}")
const client = createCredoAIClient('your-tenant');
// Manual pagination (no built-in async iterator)
let cursor: string | undefined;
while (true) {
const { data, error } = await client.useCases.list({
pageLimit: 50,
pageAfter: cursor,
});
if (error || !data) break;
for (const uc of data.items) {
console.log(` - ${uc.name}`);
}
if (!data.pagination.hasMore) break;
cursor = data.pagination.nextCursor ?? undefined;
}
Concurrent Operations
Make multiple API calls concurrently:
- Python
- TypeScript
import asyncio
from credoai import AsyncCredoAI
async def main():
async with AsyncCredoAI() as client:
# Fetch use cases, models, and vendors concurrently
use_cases, models, vendors = await asyncio.gather(
client.use_cases.list(page_limit=10),
client.models.list(page_limit=10),
client.vendors.list(page_limit=10)
)
print(f"Use cases: {len(use_cases.items)}")
print(f"Models: {len(models.items)}")
print(f"Vendors: {len(vendors.items)}")
asyncio.run(main())
import { createCredoAIClient } from '@credo-ai/sdk';
const client = createCredoAIClient('your-tenant');
// Fetch use cases, models, and vendors concurrently
const [useCases, models, vendors] = await Promise.all([
client.useCases.list({ pageLimit: 10 }),
client.models.list({ pageLimit: 10 }),
client.vendors.list({ pageLimit: 10 }),
]);
if (!useCases.error) console.log('Use cases:', useCases.data.items.length);
if (!models.error) console.log('Models:', models.data.items.length);
if (!vendors.error) console.log('Vendors:', vendors.data.items.length);
Concurrent Processing
Process multiple items concurrently:
- Python
- TypeScript
import asyncio
from credoai import AsyncCredoAI
async def process_use_case(client, use_case_id):
"""Process a single use case."""
use_case = await client.use_cases.get(use_case_id=use_case_id)
models = await client.use_case_models.list(use_case_id=use_case_id)
return {
"name": use_case.name,
"model_count": len(models.items)
}
async def main():
use_case_ids = ["uc_1", "uc_2", "uc_3"]
async with AsyncCredoAI() as client:
# Process all use cases concurrently
results = await asyncio.gather(
*[process_use_case(client, uc_id) for uc_id in use_case_ids]
)
for result in results:
print(f"{result['name']}: {result['model_count']} models")
asyncio.run(main())
import { createCredoAIClient } from '@credo-ai/sdk';
async function processUseCase(client: ReturnType<typeof createCredoAIClient>, useCaseId: string) {
const useCase = await client.useCases.get(useCaseId);
const models = await client.useCases.models.list(useCaseId);
return {
name: useCase.data?.name,
modelCount: models.data?.items.length ?? 0,
};
}
const client = createCredoAIClient('your-tenant');
const useCaseIds = ['uc_1', 'uc_2', 'uc_3'];
// Process all use cases concurrently
const results = await Promise.all(
useCaseIds.map((id) => processUseCase(client, id))
);
for (const result of results) {
console.log(`${result.name}: ${result.modelCount} models`);
}
Rate Limiting with Concurrency Control
Limit concurrent requests to avoid rate limiting:
- Python
- TypeScript
import asyncio
from credoai import AsyncCredoAI
async def fetch_with_semaphore(client, semaphore, use_case_id):
async with semaphore:
return await client.use_cases.get(use_case_id=use_case_id)
async def main():
use_case_ids = ["uc_1", "uc_2", "uc_3", "uc_4", "uc_5"]
# Limit to 3 concurrent requests
semaphore = asyncio.Semaphore(3)
async with AsyncCredoAI() as client:
tasks = [
fetch_with_semaphore(client, semaphore, uc_id)
for uc_id in use_case_ids
]
results = await asyncio.gather(*tasks)
asyncio.run(main())
import { createCredoAIClient } from '@credo-ai/sdk';
async function withConcurrencyLimit<T>(
tasks: (() => Promise<T>)[],
limit: number,
): Promise<T[]> {
const results: T[] = [];
const executing = new Set<Promise<void>>();
for (const task of tasks) {
const p = task().then((r) => { results.push(r); });
executing.add(p);
p.finally(() => executing.delete(p));
if (executing.size >= limit) await Promise.race(executing);
}
await Promise.all(executing);
return results;
}
const client = createCredoAIClient('your-tenant');
const useCaseIds = ['uc_1', 'uc_2', 'uc_3', 'uc_4', 'uc_5'];
// Limit to 3 concurrent requests
const results = await withConcurrencyLimit(
useCaseIds.map((id) => () => client.useCases.get(id)),
3,
);
Web Server Integration
- Python
- TypeScript
from fastapi import FastAPI, HTTPException
from credoai import AsyncCredoAI
app = FastAPI()
@app.get("/use-cases")
async def list_use_cases():
async with AsyncCredoAI() as client:
response = await client.use_cases.list(page_limit=50)
return {"items": [uc.model_dump() for uc in response.items]}
@app.get("/use-cases/{use_case_id}")
async def get_use_case(use_case_id: str):
async with AsyncCredoAI() as client:
try:
use_case = await client.use_cases.get(use_case_id=use_case_id)
return use_case.model_dump()
except Exception as e:
raise HTTPException(status_code=404, detail="Use case not found")
import express from 'express';
import { createCredoAIClient } from '@credo-ai/sdk';
const app = express();
const client = createCredoAIClient('your-tenant');
app.get('/use-cases', async (req, res) => {
const { data, error } = await client.useCases.list({ pageLimit: 50 });
if (error) return res.status(error.status).json(error.body);
res.json({ items: data.items });
});
app.get('/use-cases/:id', async (req, res) => {
const { data, error } = await client.useCases.get(req.params.id);
if (error) return res.status(error.status).json(error.body);
res.json(data);
});
app.listen(3000);
Shared Client Instance
- Python
- TypeScript
For better performance, share a client instance:
from contextlib import asynccontextmanager
from fastapi import FastAPI
from credoai import AsyncCredoAI
@asynccontextmanager
async def lifespan(app: FastAPI):
# Startup: create client
app.state.credoai = AsyncCredoAI()
yield
# Shutdown: close client
await app.state.credoai.close()
app = FastAPI(lifespan=lifespan)
@app.get("/use-cases")
async def list_use_cases():
client = app.state.credoai
response = await client.use_cases.list(page_limit=50)
return {"items": [uc.model_dump() for uc in response.items]}
The TypeScript client is lightweight and can be shared as a module-level constant:
import express from 'express';
import { createCredoAIClient } from '@credo-ai/sdk';
// Shared client instance — no cleanup needed
const client = createCredoAIClient('your-tenant');
const app = express();
app.get('/use-cases', async (req, res) => {
const { data, error } = await client.useCases.list({ pageLimit: 50 });
if (error) return res.status(error.status).json(error.body);
res.json({ items: data.items });
});
Error Handling
- Python
- TypeScript
from credoai import AsyncCredoAI
from credoai.errors import ApiError
async def main():
async with AsyncCredoAI() as client:
try:
use_case = await client.use_cases.get(use_case_id="invalid-id")
except ApiError as e:
print(f"Error {e.status_code}: {e.message}")
asyncio.run(main())
const client = createCredoAIClient('your-tenant');
const { data, error } = await client.useCases.get('invalid-id');
if (error) {
console.error(`Error ${error.status}:`, error.body);
}
Comparison: Sync vs Async
| Feature | Python Sync (CredoAI) | Python Async (AsyncCredoAI) | TypeScript |
|---|---|---|---|
| Import | from credoai import CredoAI | from credoai import AsyncCredoAI | import { createCredoAIClient } |
| Method calls | client.use_cases.list() | await client.use_cases.list() | await client.useCases.list() |
| Iteration | for uc in list_all(): | async for uc in list_all(): | Manual pagination loop |
| Context manager | Optional | Recommended | Not needed |
| Concurrent calls | Sequential | asyncio.gather() | Promise.all() |
| Error pattern | try/except | try/except | { data, error } |
Next Steps
- Review Error Handling
- See the API Reference for all available methods