SDK de Python
typesearch, el cliente oficial para Python, sincrónico y asíncrono.
pip install typesearchPython 3.9+. Hecho sobre httpx y pydantic: cada respuesta es un modelo tipado, y los campos nuevos de
una API más reciente se conservan en vez de romper tu código.
Crea un cliente
from typesearch import Typesearch
ts = Typesearch() # lee TYPESEARCH_API_KEY| Argumento | Por defecto | |
|---|---|---|
api_key | TYPESEARCH_API_KEY | Tu key. |
base_url | https://api.typesearch.ai | O TYPESEARCH_BASE_URL. |
timeout | 70.0 | Segundos antes de cortar un pedido. Una búsqueda deep puede tardar cerca de un minuto. |
max_retries | 2 | Reintentos ante errores de conexión, 429 rate_limited y 5xx. |
default_headers | — | Encabezados que van en cada pedido. |
http_client | — | Tu propio httpx.Client (o httpx.AsyncClient en asíncrono), para proxies o pruebas. |
Úsalo como context manager para cerrar las conexiones al terminar: with Typesearch() as ts: ….
Buscar
res = ts.search(
"el dólar",
mode="normal",
max_results=10,
include_domains=["infobae.com", "lanacion.com.ar"],
published_after="2026-09-20",
highlights=True,
)
for r in res.results:
print(f"{r.score:.2f}", r.title, r.highlights[:1])Los argumentos se llaman igual que en la API HTTP. Las fechas aceptan texto
o datetime.date / datetime.datetime. days=None busca en todo el índice; si no pasas days, queda el
valor por defecto de 7.
Varias consultas a la vez:
res = ts.search(["el dólar", "el FMI"], mode="fast")
for group in res.groups or []:
print(group.query, group.total)Streaming
with ts.search_stream("el dólar", mode="deep") as stream:
for event in stream:
if event.type == "step":
print("·", event.step.text)
elif event.type == "partial":
mostrar(event.response.results)
elif event.type == "result":
mostrar(event.response.results)
# O sólo el resultado final
final = ts.search_stream("el dólar").final_response()Un evento error se lanza como APIError.
Similares y contenidos
similares = ts.similar("https://www.lanacion.com.ar/economia/…", exclude_domains=["lanacion.com.ar"])
paginas = ts.contents(["https://www.infobae.com/economia/…"], query="el dólar")Búsqueda en un sitio en vivo
# Crea el trabajo y espera el resultado
res = ts.site_search_and_wait("lanacion.com.ar", "el dólar", mode="normal")
# O maneja el trabajo tú
job = ts.site_search("lanacion.com.ar", "el dólar")
listo = ts.jobs.wait(job.id, poll_interval=2, timeout=120)jobs.wait() lanza JobFailedError si el trabajo falla.
Asíncrono
AsyncTypesearch tiene los mismos métodos, con await:
import asyncio
from typesearch import AsyncTypesearch
async def main():
async with AsyncTypesearch() as ts:
res = await ts.search("el dólar", mode="fast")
async for event in ts.search_stream("el FMI"):
...
asyncio.run(main())Errores
Todos los errores heredan de TypesearchError. Los de la API son subclases de APIError con status,
code, request_id y, en pedidos inválidos, errors por campo.
| Clase | Cuándo |
|---|---|
BadRequestError | 400 |
AuthenticationError | 401 |
BudgetError | 402: max_tokens demasiado bajo |
PermissionDeniedError | 403 |
NotFoundError | 404 |
RateLimitError | 429, con retry_after |
InternalServerError | 5xx |
APIConnectionError · APITimeoutError | Sin respuesta, o demasiado lenta |
JobFailedError | Falló un trabajo de búsqueda en sitio |
from typesearch import APIError, BadRequestError, RateLimitError
try:
ts.search("x")
except BadRequestError as e:
print(e.code, e.errors)
except RateLimitError as e:
print(e.code, e.retry_after)
except APIError as e:
print(e.status, e.code, e.request_id)Reintentos
Los errores de conexión, 429 rate_limited y 5xx se reintentan con espera exponencial y aleatoria,
respetando Retry-After; quota_exceeded nunca. Usa max_retries=0 para manejarlos tú.