Agent Data (Python)
See the Agent Data Overview for concepts, constraints, and environment details.
Install
Section titled “Install”uv add llama-cloud-services
Client overview
Section titled “Client overview”The Python llama-cloud-services
SDK provides AsyncAgentDataClient
for working with the Agent Data API.
import httpximport osfrom pydantic import BaseModelfrom llama_cloud_services.beta.agent_data import AsyncAgentDataClientfrom llama_cloud.client import AsyncLlamaCloud
class ExtractedPerson(BaseModel): name: str age: int email: str
project_id = os.getenv("LLAMA_DEPLOY_PROJECT_ID")
# Base URL and API key (if running outside LlamaCloud)base_url = os.getenv("LLAMA_CLOUD_BASE_URL")api_key = os.getenv("LLAMA_CLOUD_API_KEY")
# Reusable async HTTP client with optional project scopinghttp_client = httpx.AsyncClient(headers={"Project-Id": project_id} if project_id else None)
# Optional: base client for other SDK operationsbase_client = AsyncLlamaCloud( base_url=base_url, token=api_key, httpx_client=http_client,)
# Only set when deployed in LlamaCloud (falls back inside the Agent Data client)deployment_name = os.getenv("LLAMA_DEPLOY_DEPLOYMENT_NAME")
client = AsyncAgentDataClient( type=ExtractedPerson, collection="extracted_people", # If omitted, uses LLAMA_DEPLOY_DEPLOYMENT_NAME or "_public" deployment_name=deployment_name, client=base_client,)
Create, Get, Update, Delete
Section titled “Create, Get, Update, Delete”person = ExtractedPerson(name="John Doe", age=30, email="john@example.com")created = await client.create_item(person)fetched = await client.get_item(created.id)updated = await client.update_item(created.id, ExtractedPerson(name="Jane", age=31, email="jane@example.com"))await client.delete_item(updated.id)
Retry behavior: Network errors (timeouts, connection errors, retriable HTTP statuses) are retried up to 3 times with exponential backoff.
Notes:
- Updates overwrite the entire
data
object. get_item
raises anhttpx.HTTPStatusError
with status code 404 if not found.
Search
Section titled “Search”You can filter by data
fields and by created_at
/updated_at
(top-level fields). Sort using a comma-delimited list of fields; the data.
prefix is required when sorting by data fields. The default page size is 50 (max 1000).
results = await client.search( filter={ # Data fields "age": {"gte": 21, "lt": 65}, "status": {"eq": "active"}, "tags": {"includes": ["python", "ml"]}, # Top-level timestamps (ISO strings accepted) "created_at": {"gte": "2024-01-01T00:00:00Z"}, }, order_by="data.name desc, created_at", page_size=50, offset=0, include_total=True, # request only on the first page if needed)
for item in results.items: print(item.data)
print(results.has_more, results.total)
Sorting:
- Example:
"data.name desc, created_at"
. - If no sort is provided, results default to
created_at desc
.
Pagination:
- Use
offset
andpage_size
. The server may returnhas_more
and anext_page_token
(SDK exposeshas_more
).
Aggregate
Section titled “Aggregate”Group data by one or more data
fields, optionally count items per group, and/or fetch the first item per group.
agg = await client.aggregate( filter={"status": {"eq": "active"}}, group_by=["department", "role"], count=True, first=True, # return the earliest item per group (by created_at) order_by="data.department asc, data.role asc", page_size=100,)
for group in agg.items: # items are groups print(group.group_key) # {"department": "Sales", "role": "AE"} print(group.count) # optional print(group.first_item) # optional dict
Details:
group_by
: dot-style data paths (e.g.,"department"
,"contact.email"
).count
: adds acount
per group.first
: returns the firstdata
item per group (earliestcreated_at
).order_by
: uses the same semantics as search (applies to group key expressions).- Pagination uses
offset
andpage_size
similarly to search.