Tako Python SDK
The Tako Python SDK provides convenient access to the Tako API from any Python 3.9+ application. It ships fully typed request and response models and offers both synchronous and asynchronous clients.
Documentation
API reference and guides are available at docs.tako.com.
Installation
pip install tako-sdk
The import package is tako:
from tako.lib import Tako
Authentication
Create an API key from your Tako account and provide it when building the client. We recommend keeping it out of source control — for example, reading it from an environment variable:
import os
from tako import Configuration
from tako.lib import Tako
config = Configuration()
config.api_key["apiKey"] = os.environ["TAKO_API_KEY"]
client = Tako(config)
Usage
import os
from tako import Configuration, SearchRequest
from tako.lib import Tako
config = Configuration()
config.api_key["apiKey"] = os.environ["TAKO_API_KEY"]
client = Tako(config)
results = client.search(SearchRequest(query="S&P 500 performance this year"))
print(results.request_id)
for card in results.cards or []:
print(card.title, card.webpage_url)
Operations
| Method | Description |
|---|---|
client.search(SearchRequest(...)) |
Search the Tako knowledge base; returns matching cards and web results. |
client.answer(SearchRequest(...)) |
Get a written answer with supporting cards. |
client.create_card(CreateCardRequest(...)) |
Build a visualization card from component configurations. |
client.contents(ContentsRequest(...)) |
Fetch downloadable content (e.g. a CSV) for a card or web URL. |
For example, fetch the underlying data for a card returned by a search. Not every
card is exportable (some come from protected sources), so guard for the case where
no card has downloadable content:
from tako import ContentsRequest, SearchRequest
results = client.search(SearchRequest(query="US Oil Prices"))
card = next(
(c for c in (results.cards or []) if c.webpage_url and c.content and c.content.formats),
None,
)
if card is None:
print("No exportable card found")
else:
contents = client.contents(ContentsRequest(url=card.webpage_url))
for item in contents.contents or []:
print(item.content_format, item.url)
Async usage
Use AsyncTako with the tako.aio package and await each call:
import asyncio
import os
from tako.aio import Configuration, SearchRequest
from tako.lib import AsyncTako
async def main() -> None:
config = Configuration()
config.api_key["apiKey"] = os.environ["TAKO_API_KEY"]
client = AsyncTako(config)
results = await client.search(SearchRequest(query="S&P 500 performance this year"))
print(results.request_id)
asyncio.run(main())
The async client exposes the same operations as the synchronous one.
Agents
Two agent products hang off client.agent:
| Namespace | Endpoint | Product |
|---|---|---|
client.agent.search.* |
/v1/agent/search/runs |
Search Agent — agentic data retrieval (multi-hop lookup, cohort resolution, structured outputs) |
client.agent.answer.* |
/v1/agent/answer/runs |
Answer Agent — opinionated agentic research returning cited prose |
Each exposes run(req) (202 dispatch → run object), get(run_id) (poll for
status), and stream(req) (live SSE). (client.agent.answer.*, the Answer
Agent, is distinct from client.answer(), the one-shot /v1/answer call.)
Streaming
Stream a run live over Server-Sent Events. The stream yields typed per-product
envelopes (SearchAgentStreamEnvelope / AnswerAgentStreamEnvelope) and
auto-reconnects (resuming via the last seq) on transient network drops. Use it
as a context manager so the connection is always closed.
from tako import Configuration
from tako.lib import Tako
from tako.models.search_agent_run_request import SearchAgentRunRequest
config = Configuration()
config.api_key["apiKey"] = "YOUR_API_KEY"
client = Tako(config)
req = SearchAgentRunRequest(query="Which S&P 500 semis grew revenue fastest in 2024?")
with client.agent.search.stream(req) as stream:
for event in stream:
block = event.block.actual_instance
print(event.seq, block.kind)
# The stream ends at `stream_done`. If it ended without a terminal result
# (and produced at least one event, so `run_id` is known), poll for status:
if stream.result is None and stream.run_id is not None:
run = client.agent.search.get(stream.run_id)
print(run.status)
Async usage mirrors this — stream = await client.agent.search.stream(req) then async with stream: async for event in stream: .... The Answer Agent is identical with client.agent.answer.* and AnswerAgentRunRequest.
Structured output (Search Agent)
Pass an output_schema (JSON Schema) to shape the response. Mark a property with
"x-tako-dataset": true to request a dataset slot — filled with exact
retrieved rows as a TakoDataset. Two helpers make this ergonomic:
derive_response_schema(schema)— the schemastructured_outputactually validates against (each slot becomesTakoDataset | null). Pair withjsonschema.TakoDatasetView— a records / DataFrame view over a filled slot..recordsneeds no extra dependency;.to_dataframe()needs thepandasextra (pip install tako-sdk[pandas]).
import jsonschema
from tako.lib import Tako, TakoDatasetView, derive_response_schema
from tako.models.search_agent_run_request import SearchAgentRunRequest
schema = {
"type": "object",
"properties": {
"headline": {"type": "string"},
"cohort": {"x-tako-dataset": True, "columns": ["company", "revenue"]},
},
"required": ["headline", "cohort"],
}
run = client.agent.search.run(SearchAgentRunRequest(query="...", output_schema=schema))
run = client.agent.search.get(run.run_id) # poll to a terminal status
if run.result and run.result.structured_output:
jsonschema.validate(run.result.structured_output, derive_response_schema(schema))
view = TakoDatasetView(run.result.structured_output["cohort"])
print(view.records) # list[dict], one per row
print(view.to_dataframe()) # typed pandas DataFrame (needs tako-sdk[pandas])
See examples/ for runnable scripts — sync (search_agent_streaming.py,
answer_agent_streaming.py, search_agent_structured_output.py) and async
(search_agent_streaming_async.py, answer_agent_streaming_async.py).
Requests and responses
Request and response models are Pydantic models. Access fields as
attributes (results.request_id), and use the usual helpers to serialize:
results.model_dump() # -> dict
results.model_dump_json() # -> JSON string
Configuration
By default the client targets the Tako production API. To point at a different host, pass it to
Configuration:
from tako import Configuration
config = Configuration(host="https://staging.tako.com/api")
Handling errors
API errors raise a subclass of tako.ApiException. The exception carries the HTTP status,
reason, and response body:
from tako import Configuration, SearchRequest
from tako.exceptions import ApiException, UnauthorizedException
from tako.lib import Tako
config = Configuration()
config.api_key["apiKey"] = "invalid-key"
client = Tako(config)
try:
client.search(SearchRequest(query="US GDP growth rate"))
except UnauthorizedException:
print("Invalid or missing API key")
except ApiException as exc:
print(f"Request failed: {exc.status} {exc.reason}")
print(exc.body)
The async client (AsyncTako) raises the same exception classes, so you can
catch tako.exceptions.ApiException around await calls exactly as above — no
async-specific imports are needed.
Status codes map to the following exception types (all subclasses of ApiException):
| Status Code | Exception |
|---|---|
| 400 | BadRequestException |
| 401 | UnauthorizedException |
| 403 | ForbiddenException |
| 404 | NotFoundException |
| 409 | ConflictException |
| 422 | UnprocessableEntityException |
| >=500 | ServiceException |
Versioning
This package follows SemVer. You can check the installed version at runtime:
import tako
print(tako.__version__)
Requirements
Python 3.9 or higher.
Support
Questions, bugs, or feedback? See the documentation at docs.tako.com.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tako_sdk-2.2.1.tar.gz.
File metadata
- Download URL: tako_sdk-2.2.1.tar.gz
- Upload date:
- Size: 134.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
298a7d21b3e712af7a2a8cdd0950430b0be2391a37442381d90cc48a1c4f9318
|
|
| MD5 |
f94cb803a7e8507d8cca495c90b4d321
|
|
| BLAKE2b-256 |
917fcfe0f35eee6e303f4b3de0844e1e8e35d04f5a3bbace81e8df73c4319d69
|
File details
Details for the file tako_sdk-2.2.1-py3-none-any.whl.
File metadata
- Download URL: tako_sdk-2.2.1-py3-none-any.whl
- Upload date:
- Size: 330.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2ac9e435279910ab2b0a44aed4fc912b7d0936aa93674c5ac0994daafeeeaecb
|
|
| MD5 |
0cd293f228fe18782b46c7b5db4995bd
|
|
| BLAKE2b-256 |
48b1d280e8354b7eb78b6483d4df95a3b4ded7a786f3968f54af91c7b5a39421
|