Skip to main content

iflow-search

Python SDK for iFlow Search (心流搜索) — a search API that exposes web search, image search, and web-page fetching with AI-friendly structured output.

This is the framework-agnostic core SDK: it has zero LangChain / MCP / FastAPI dependencies. The MCP adapter (iflow-search-mcp), the LangChain adapter (iflow-search-langchain), and the FastAPI / OpenAPI adapter (iflow-search-openapi) all ship from the same repository and depend on this package.

Install

pip install iflow-search

For local development:

git clone https://github.com/zhengyanglsun/iflow-search-py.git
cd iflow-search-py/packages/iflow-search
python -m pip install -e ".[dev]"

Quick start (sync)

import os
from iflow_search import IFlowSearchClient

client = IFlowSearchClient(api_key=os.environ["IFLOW_API_KEY"])

result = client.web_search(query="flash attention", count=5)
for r in result.results:
    print(r.title, r.url)

images = client.image_search(query="iflow logo")
for i in images.images:
    print(i.image_url, i.source_url)

page = client.web_fetch(url="https://platform.iflow.cn/docs/")
print(page.title, len(page.content), "chars")

Quick start (async)

import asyncio, os
from iflow_search import AsyncIFlowSearchClient

async def main() -> None:
    async with AsyncIFlowSearchClient(api_key=os.environ["IFLOW_API_KEY"]) as client:
        result = await client.web_search(query="flash attention", count=5)
        for r in result.results:
            print(r.title, r.url)

asyncio.run(main())

Configuration

Parameter Default Notes
api_key os.environ["IFLOW_API_KEY"] Required. Falls back to env var; raises IFlowConfigError if neither is set.
source "python" Sent as IFlow-Source header. Adapter packages override this.
integration_name "iflow-search" Sent as IFlow-Integration header.
integration_version installed package version Sent as IFlow-Integration-Version header.
base_url https://platform.iflow.cn Useful for staging/proxy environments.
timeout 30.0 seconds Applied to each individual request.
http_client new httpx.Client (or AsyncClient) Inject one for connection pooling or testing (e.g. via httpx.MockTransport).

Attribution headers

Every outbound request carries:

Authorization:             Bearer <api-key>
Content-Type:              application/json
Accept:                    application/json
IFlow-Source:              python   (configurable)
IFlow-Integration:         iflow-search   (configurable)
IFlow-Integration-Version: <installed package version>
User-Agent:                iflow-search/<version>

These are built only by the SDK; constructor arguments let adapter packages set their own source / integration_name / integration_version. There is no API for users to override Authorization, Content-Type, Accept, or User-Agent directly.

Errors

The SDK raises a typed exception hierarchy — never tuples, dicts, or sentinel values:

IFlowError
├── IFlowConfigError                 # missing api_key, invalid attribution
├── IFlowValidationError             # bad client-side input
├── IFlowAuthError                   # HTTP 401/403, business code 90402
├── IFlowRateLimitError              # HTTP 429, business code 40303
├── IFlowInsufficientCreditsError    # business code 60400
├── IFlowAPIError                    # HTTP 5xx, non-JSON 2xx, other non-2xx
├── IFlowBusinessError               # success=false with any other code
├── IFlowTimeoutError                # SDK-initiated timeout
└── IFlowNetworkError                # DNS / connection / TLS errors

Every exception carries code (stable string), message, request ({method, url, endpoint}), and response_body_truncated (first 500 chars when applicable). Switch on code rather than class identity if you want a stable contract across SDK versions.

from iflow_search import IFlowSearchClient, IFlowError, IFlowRateLimitError

# Reads IFLOW_API_KEY from the environment.
client = IFlowSearchClient()

try:
    result = client.web_search(query="latest LLM benchmarks", count=3)
except IFlowRateLimitError:
    print("Rate limit exceeded")
except IFlowError as exc:
    print(f"iFlow error: {exc.code} {exc.message}")

asyncio.CancelledError is not wrapped — it propagates as itself so cooperative cancellation keeps working.

Field renames

The wire format uses a few awkward field names. The SDK renames them:

Request Wire Python
web/image keywords query
web/image num count
Response Wire Python
web link url (on WebSearchResult)
image url image_url
image refUrl source_url
web_fetch fromCache from_cache
all — took_ms (measured client-side)

The raw envelope is preserved on response.raw for callers that need fields the SDK did not model.

Security

  • Never commit API keys. Use environment variables (IFLOW_API_KEY) or your platform's secret manager.
  • The SDK does not auto-load .env files and does not read the key from any filesystem path other than the process environment.
  • Tests in this repository use fake keys (literal test-key) and httpx.MockTransport — no real API is contacted, ever.

Local development

From packages/iflow-search/:

python -m pytest -q                    # offline test suite
python -m ruff check .                 # lint
python -m mypy src/iflow_search        # strict typecheck
python -m build                        # build sdist + wheel into dist/

Real-API smoke

A separate opt-in script exercises all three endpoints against the live API:

export IFLOW_API_KEY="your-api-key"
export IFLOW_SMOKE=1
python scripts/smoke_real_api.py

The script:

  • Is opt-in — without IFLOW_SMOKE=1 it refuses to call the live API.
  • Reads IFLOW_API_KEY from the environment only — never from disk.
  • Redacts the key in all log output.
  • Does not write any file.

Adapter packages

This package is the core. Adapter packages depend on it and live in the same repository:

  • iflow-search-mcp — published on PyPI. MCP stdio server for Claude Code, Claude Desktop, Hermes, OpenCode, and other MCP-capable hosts. Install with pip install --pre iflow-search-mcp.
  • iflow-search-langchain — published on PyPI. LangChain (and LangGraph) tools; usable from CrewAI via a one-line BaseTool subclass. Install with pip install --pre iflow-search-langchain.
  • iflow-search-openapi — published on PyPI. FastAPI / OpenAPI 3.1 tool server for Open WebUI, Coze, and other OpenAPI tool catalogues. Install with pip install --pre iflow-search-openapi.

License

MIT

Metadata

Release files for iflow-search 0.1.0

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

Source distribution (sdist)

Source distribution for iflow-search 0.1.0
File Size Uploaded Provenance
iflow_search-0.1.0.tar.gz 14.2 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for iflow-search 0.1.0
File Interpreter ABI Platform
iflow_search-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 35.0 kB

Release files / iflow_search-0.1.0.tar.gz

Download URL iflow_search-0.1.0.tar.gz
Size 14.2 kB
Tags Source
SHA-256 checksum
How to use checksums
633294dd621d2e83ca2ae90a38dce3f48c17acc9681675dbe935b3fbaf2c196a
BLAKE2b-256 checksum
How to use checksums
defbab630543a2cc24da85172738ccde907ca32e468c6573d064619ce35f80b5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.15

Release files / iflow_search-0.1.0-py3-none-any.whl

Download URL iflow_search-0.1.0-py3-none-any.whl
Size 20.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
813eea2ed21eddb10f9af65cccf901e7c946a0b26bafe72a534f84949032bc9d
BLAKE2b-256 checksum
How to use checksums
f59a08d558ccac3f9aa380da4656d7e95f34568c38c7614384c0c7988fd8444c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.15

Security for iflow-search 0.1.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.

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