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

Search

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
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

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

keenable-0.1.1.tar.gz (16.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

keenable-0.1.1-py3-none-any.whl (16.5 kB view details)

Uploaded Python 3

File details

Details for the file keenable-0.1.1.tar.gz.

File metadata

  • Download URL: keenable-0.1.1.tar.gz
  • Upload date:
  • Size: 16.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for keenable-0.1.1.tar.gz
Algorithm Hash digest
SHA256 8ef95333abaeb77e335f60d089b8659ed2a1e4d9ce733c9d6c8fe21de552481a
MD5 1b3eaf3c7697a7514545426e3c07897e
BLAKE2b-256 6afb16b351fed374132f594e7d8536cb6bccb576279030b89645bc1e3f59d9f7

See more details on using hashes here.

Provenance

The following attestation bundles were made for keenable-0.1.1.tar.gz:

Publisher: publish-python.yml on keenableai/keenable-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file keenable-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: keenable-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 16.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for keenable-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 c4a91e4408bf2e269fccb04ea348f2504173d08d0e4e73e905f923123e8a5b8c
MD5 a9ed4290d47560c111942504e6c67892
BLAKE2b-256 fd887a5e8408699247e9b21c80fe6fd0cd8a3772f71991d0eb6f62defea8c099

See more details on using hashes here.

Provenance

The following attestation bundles were made for keenable-0.1.1-py3-none-any.whl:

Publisher: publish-python.yml on keenableai/keenable-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page