Skip to main content

keenable

Official Python SDK for Keenable, a web search API built for AI agents: ranked results that come back with the page text already extracted, plus a fetch endpoint that returns any URL as clean markdown.

Keyless by default. Every call works with no account and no key. An optional KEENABLE_API_KEY only lifts the hourly rate limit.

pip install keenable
from keenable import Keenable

keenable = Keenable()  # or Keenable("keen_...") / set KEENABLE_API_KEY

results = keenable.search("how wafer scale chips avoid the memory bottleneck")

for result in results:
    print(result.title, result.url)
    print(result.snippet)

Results carry the page text in snippet. (description is the page's meta description and is empty for most pages, so build prompts from snippet.)

Filters are optional and combine freely:

results = keenable.search(
    "post-training quantization results",
    site="arxiv.org",
    published_after="2026-01-01",
    snippet_max_length=500,
)
Argument What it does
site Restrict to one domain, e.g. "arxiv.org"
published_after / published_before Filter by publication date (YYYY-MM-DD)
acquired_after / acquired_before Filter by when Keenable indexed the page
snippet_max_length Cap the page text returned per result
max_results How many results to return, 1 to 50 (default 10)
query_time Search the index as it stood at that moment (YYYY-MM-DD, ISO 8601, or "7d"); not a recency filter
mode Search mode; "pro" (default) does deeper retrieval

Ground a model in one line

to_context() renders the result set as a numbered, citable block you can drop straight into a prompt:

context = keenable.search("cerebras inference benchmarks").to_context()

prompt = f"Answer using only these sources, citing them by number.\n\n{context}\n\nQuestion: ..."

It emits [1] Title (url) headers followed by the page text, adds results whole until the character budget is reached (max_chars=12000 by default), and never truncates a source mid-sentence.

To print a source list that matches the citations in the answer, ask which results were actually rendered rather than listing them all:

results = keenable.search("cerebras inference benchmarks")

for index, result in enumerate(results.cited(), start=1):
    print(f"[{index}] {result.title} - {result.url}")

Read a full page

page = keenable.fetch("https://cerebras.ai/chip")
print(page.title)
print(page.content)  # markdown, boilerplate stripped
print(page.to_context())  # same citable block shape as search results

Tool calling

The SDK ships OpenAI-compatible tool definitions, so any inference API that speaks that schema can call Keenable directly:

from keenable import Keenable, TOOLS, run_tool_call

keenable = Keenable()
response = client.chat.completions.create(model=..., messages=messages, tools=TOOLS)

for call in response.choices[0].message.tool_calls or []:
    messages.append(
        {
            "role": "tool",
            "tool_call_id": call.id,
            "content": run_tool_call(
                keenable, call.function.name, call.function.arguments
            ),
        }
    )

TOOLS exposes keenable_search and keenable_fetch; run_tool_call executes whichever the model picked and returns text ready for the tool message. Both tools render the same numbered, citable block, so the model can cite a fetched page the way it cites a search result. arun_tool_call is the async counterpart, for use with AsyncKeenable.

Async

AsyncKeenable mirrors the sync client:

import asyncio
from keenable import AsyncKeenable


async def main():
    async with AsyncKeenable() as keenable:
        results = await keenable.search("wafer scale engine")
        print(results.to_context())


asyncio.run(main())

Errors

All errors subclass KeenableError:

Exception When
KeenableRateLimitError HTTP 429. Set KEENABLE_API_KEY to lift the keyless cap
KeenableAuthError HTTP 401/403, the key was rejected
KeenableAPIError Any other non-2xx response; carries status_code
KeenableConnectionError The API could not be reached
KeenableInvalidRequestError Bad arguments; no request was sent

Configuration

Variable Default Purpose
KEENABLE_API_KEY unset Lifts the hourly rate limit. Create one at keenable.ai/console
KEENABLE_API_URL https://api.keenable.ai Override the API base URL

Both can also be passed to the constructor as api_key and base_url, alongside timeout and client_source. Building an integration on top of this SDK? Set client_source="Your Integration" so your traffic is attributed to you rather than to the bare SDK.

License

MIT

Metadata

Release files for keenable 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for keenable 0.1.3
File Size Uploaded Provenance Actions
keenable-0.1.3.tar.gz 16.8 kB With provenance Details for keenable-0.1.3.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for keenable 0.1.3
File Interpreter ABI Platform Actions
keenable-0.1.3-py3-none-any.whl Python 3 none any Details for keenable-0.1.3-py3-none-any.whl

Total release size: 33.8 kB

Release files / keenable-0.1.3.tar.gz

Download URL keenable-0.1.3.tar.gz
Size 16.8 kB
Tags Source
SHA-256 checksum
How to use checksums
94b39372bbb6829ed19899db573022442e20a0560c4732cc6a1cc8c27d52f05c
BLAKE2b-256 checksum
How to use checksums
896217cb1db49118c7bcad98b9a2e0fa7dc0e8643a51e5a32eac061d0f0316e5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.

Transparency log

Release files / keenable-0.1.3-py3-none-any.whl

Download URL keenable-0.1.3-py3-none-any.whl
Size 17.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ab78457b0c8be568b8d81cea42ecc7b3f2b74403385fa90250426e565df9e699
BLAKE2b-256 checksum
How to use checksums
f8aa2acc59a9339805b53d3da7348417c020cc0084920856536cafa7448f734b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.

Transparency log

Security for keenable 0.1.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for keenable-0.1.3.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page