anysearch (Python)
One interface for every web search API. anysearch is an adapter layer — think
LiteLLM, but for search providers — that lets you call Octen, Exa, Parallel, Brave, Tavily,
SerpAPI, Perplexity, Linkup, Firecrawl, Keenable, OpenAI, and more through a single function with a
common set of parameters and a common response shape. It also ships a dependency-free
stdio MCP server and optional FastAPI proxy server that adapt to whatever API
keys you have configured.
import anysearch
# Auto-selects a provider based on which API keys are set in your environment.
resp = anysearch.search("best vector databases 2026", max_results=5)
for r in resp:
print(r.title, r.url)
# Pin a provider and ask for richer content — same parameters everywhere.
resp = anysearch.search(
"how do transformers work",
provider="exa",
include_content=True,
highlights=True,
include_summary=True,
)
Install
Install the released package from PyPI, or the latest main from GitHub:
pip install anysearch-sdk
# or from main
pip install "git+https://github.com/dhruv-anand-aintech/anysearch.git@main#subdirectory=python"
# or
uv add anysearch-sdk
The base install works for all providers (every adapter is REST-based on httpx).
Use extras to also install a provider's official SDK (for anysearch.native(...)):
pip install "anysearch-sdk[exa,parallel]"
pip install "anysearch-sdk[all]"
uv add "anysearch-sdk[exa,tavily,brave]"
REST-only providers (brave, serper, you, jina, kagi, searchapi,
google-pse, searxng, keenable, tinyfish, deepseek, brightdata,
dataforseo, openai, anthropic, xai) need no extra dependency — the extra name
still resolves so the selection syntax is uniform.
Providers
| Provider | Name / aliases | Env var(s) | Extra (native SDK) |
|---|---|---|---|
| Octen | octen, octen_ai |
OCTEN_API_KEY |
octen |
| Exa | exa |
EXA_API_KEY |
exa-py |
| Parallel | parallel |
PARALLEL_API_KEY |
parallel-web |
| Tavily | tavily |
TAVILY_API_KEY |
tavily-python |
| Brave | brave |
BRAVE_API_KEY |
— |
| Keiro | keiro |
KEIRO_API_KEY |
— |
| Linkup | linkup |
LINKUP_API_KEY |
linkup-sdk |
| Perplexity | perplexity, pplx |
PERPLEXITY_API_KEY |
perplexityai |
| Gemini | gemini, google_gemini |
GEMINI_API_KEY |
google-genai |
| OpenAI | openai |
OPENAI_API_KEY |
— |
| Anthropic | anthropic, claude |
ANTHROPIC_API_KEY |
— |
| xAI | xai, grok |
XAI_API_KEY |
— |
| Keenable | keenable |
KEENABLE_API_KEY |
— |
| TinyFish | tinyfish |
TINYFISH_API_KEY |
— |
| DeepSeek | deepseek |
DEEPSEEK_API_KEY |
— |
| Bright Data | brightdata, bright_data |
BRIGHTDATA_API_KEY + BRIGHTDATA_ZONE |
— |
| DataForSEO | dataforseo, data_for_seo |
DATAFORSEO_LOGIN + DATAFORSEO_PASSWORD |
— |
| Serper | serper |
SERPER_API_KEY |
— |
| SerpApi | serpapi, serp |
SERPAPI_API_KEY |
google-search-results (engine: bing, baidu, yandex, …) |
| SearchApi | searchapi |
SEARCHAPI_API_KEY |
— |
| You.com | you, ydc |
YDC_API_KEY |
— |
| Jina | jina |
JINA_API_KEY |
— |
| Kagi | kagi |
KAGI_API_KEY |
— |
| Firecrawl | firecrawl |
FIRECRAWL_API_KEY |
firecrawl-py |
| Google PSE | google_pse, google |
GOOGLE_PSE_API_KEY + GOOGLE_PSE_CX |
— |
| SearXNG | searxng, searx |
SEARXNG_BASE_URL (no key) |
— |
| DuckDuckGo | duckduckgo, ddg |
none (keyless fallback) | ddgs |
Unified parameters
| Param | Type | Notes |
|---|---|---|
query |
str |
required |
max_results |
int |
honored everywhere (sliced client-side when needed) |
search_type |
"web" | "news" |
|
country |
str |
ISO 3166-1 alpha-2 |
language |
str |
ISO 639-1 |
include_domains / exclude_domains |
list[str] |
|
start_published_date / end_published_date |
str |
ISO 8601 / YYYY-MM-DD |
safe_search |
"off" | "moderate" | "strict" |
|
mode |
"fast" | "balanced" | "deep" |
depth/quality knob, mapped per provider |
answer |
bool |
synthesized, cited answer where supported |
include_content |
bool |
full page text where supported |
include_summary |
bool |
per-result AI summary where supported |
highlights |
bool |
query-relevant excerpts where supported |
extra |
dict |
raw provider-specific passthrough |
Unsupported parameters are handled by on_unsupported ("warn" default, or "ignore"
/ "error"). Unknown keyword arguments are forwarded to the provider as extra.
Common response shape
search() returns a SearchResponse:
resp.provider # "exa"
resp.query # "..."
resp.answer # synthesized answer, if any
resp.results # list[SearchResult]
resp.urls # [r.url for r in results]
resp.to_dict() # JSON-serializable
r = resp.results[0]
r.title, r.url, r.snippet, r.text, r.summary, r.highlights, r.score, r.published_date, r.author, r.source
r.raw # the provider's raw result
Fallbacks, async, and the native escape hatch
from anysearch import AnySearch
client = AnySearch(provider="exa", fallbacks=["tavily", "brave"])
resp = client.search("...", mode="deep")
# Async
resp = await client.asearch("...")
# Drop down to a provider's official SDK (requires the extra installed)
exa = anysearch.native("exa") # -> exa_py.Exa instance
MCP server
anysearch-mcp # stdio MCP server
anysearch-mcp --probe # also verify each provider with a tiny live query at startup
Tools exposed: search, list_providers, check_providers, and migrate_codebase
(scans a repo for direct search-API usage and suggests unified replacements). See the
repo root README for client configuration examples.
FastAPI proxy
The proxy is a small search gateway inspired by LiteLLM Proxy: bearer-key auth,
provider routing/fallbacks, OpenAI-style /v1/models and /v1/search, native
/search, health checks, and simple in-process request limits.
pip install "anysearch-sdk[proxy] @ git+https://github.com/dhruv-anand-aintech/anysearch.git@main#subdirectory=python"
export ANYSEARCH_PROXY_KEYS="dev-key"
export EXA_API_KEY="..."
anysearch-proxy
curl -H "Authorization: Bearer dev-key" http://localhost:4000/v1/models
curl -X POST http://localhost:4000/v1/search \
-H "Authorization: Bearer dev-key" \
-H "Content-Type: application/json" \
-d '{"model":"exa","query":"best vector databases","max_results":3}'
Useful env vars: ANYSEARCH_PROXY_KEYS, ANYSEARCH_PROXY_ADMIN_KEYS,
ANYSEARCH_PROXY_REQUIRE_AUTH=0, ANYSEARCH_PROXY_REQUEST_LIMIT,
ANYSEARCH_PROXY_HOST, and ANYSEARCH_PROXY_PORT.
Metadata
Release files for anysearch-sdk 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| anysearch_sdk-0.2.0.tar.gz | 45.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| anysearch_sdk-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 113.0 kB
Release files / anysearch_sdk-0.2.0.tar.gz
| Download URL | anysearch_sdk-0.2.0.tar.gz |
|---|---|
| Size | 45.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3a975b62ebaa35a5a34fc441e3596a62ddca8e7113e01e4d9f163bfc48571db2
|
|
BLAKE2b-256 checksum How to use checksums |
ca7170fe989af1e37fb606e2cd0c57ac93992998135ca886a9a60ae07f529d70
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / anysearch_sdk-0.2.0-py3-none-any.whl
| Download URL | anysearch_sdk-0.2.0-py3-none-any.whl |
|---|---|
| Size | 67.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2e9ba9b4283301762465663037a64a2249f7dab299e3bec3733dad2a60b2639c
|
|
BLAKE2b-256 checksum How to use checksums |
95344049569c5a39525ed1b99905c313ba3802bacf1fd06d3f97fdd0ec33122b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for anysearch-sdk 0.2.0
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.