Skip to content

Repository files navigation

Knowhere Python SDK

PyPI version

Official Python SDK for the Knowhere document parsing API.

Installation

pip install knowhere-python-sdk

Or with uv:

uv add knowhere-python-sdk

Usage

importknowhereclient=knowhere.Knowhere(api_key="sk_...")
result=client.parse(
url="https://example.com/report.pdf",
)
print(result.statistics.total_chunks)
print(result.full_markdown[:200])
forchunkinresult.text_chunks:
print(chunk.content[:80])
forpageinresult.page_chunks:
print(page.content_source) # "summary"print(page.content[:120]) # page-level summaryprint(page.metadata.page_nums) # [4, 5, 6]

Retrieval and document lifecycle

New documents are published into a retrieval namespace. The server returns a stable document_id after the job is published. client.jobs.create(...) does not return a usable document_id; persist job_result.document_id if you need to update or archive the same document later.

job=client.jobs.create(
source_type="url",
source_url="https://example.com/manual.pdf",
namespace="support-center",
)
job_result=client.jobs.wait(job.job_id)
document_id=job_result.document_idifdocument_idisNone:
raiseRuntimeError("Expected document_id after successful publication.")

After the job is done and published, query the canonical document content:

response=client.retrieval.query(
namespace="support-center",
query="How do I reset Bluetooth pairing?",
chunk_types=["page"],
top_k=5,
channels=["path", "term"],
filter_mode="keep",
signal_paths=["Bluetooth", "Pairing"],
)
print(response.router_used)
print(response.answer_text)
print(response.evidence_text)
print(response.stop_reason)
print(response.failure_reason)
forreferenceinresponse.referenced_chunks:
print(reference.chunk_id, reference.chunk_type, reference.content_source)
print(reference.metadata, reference.asset_url)
forresultinresponse.results:
print(result.chunk_id, result.chunk_type, result.content_source)
print(result.content)
print(result.score)
print(result.source.source_file_name, result.source.section_path)

Use document_id to update or archive a document:

update_job=client.jobs.create(
source_type="url",
source_url="https://example.com/manual-v2.pdf",
document_id=document_id,
)
document=client.documents.get(document_id)
print(document.status)
chunks=client.documents.list_chunks(
document_id,
page=1,
page_size=50,
chunk_type="page",
include_asset_urls=True,
)
print(chunks.pagination.total)
ifchunks.chunks:
chunk=client.documents.get_chunk(
document_id,
chunks.chunks[0].id,
include_asset_urls=True,
)
print(chunk.chunk.content)
print(chunk.chunk.metadata.get("page_nums")) # Page citations.print(chunk.chunk.asset_url) # Requested 7-day URL when available.client.documents.archive(document_id)

You can also list documents in a namespace:

documents=client.documents.list(
namespace="support-center",
page=1,
page_size=50,
)
fordocumentindocuments.documents:
print(document.document_id, document.status)
print(documents.pagination.total_pages)

Retrieval supports exclusions when clients want follow-up results that avoid previously used documents or sections:

response=client.retrieval.query(
namespace="support-center",
query="battery charging",
exclude_document_ids=["doc_old"],
exclude_sections=[
{"document_id": "doc_123", "section_path": "Appendix / Legal"}
],
)

While you can provide an api_key keyword argument, we recommend using python-dotenv to add KNOWHERE_API_KEY="sk_..." to your .env file so that your API key is not stored in source control.

Parse a local file

frompathlibimportPathresult=client.parse(
file=Path("report.pdf"),
parsing_params={"model": "advanced", "ocr_enabled": True},
)
print(result.manifest.source_file_name) # "report.pdf"print(len(result.chunks)) # 152print(result.namespace) # "default" or your explicit namespaceprint(result.document_id) # Published canonical document id

Bring your own LLM keys (BYOK)

Pass OpenAI-compatible credentials for parsing or agentic retrieval.

Flat root applies to both channels (one multimodal model). Use models for different model ids on the same endpoint, or text / vision for different provider endpoints:

# Multimodal shorthand — one model for text + visionllm_config= {
"api_key": "sk-...",
"model": "gpt-4o",
"base_url": "https://api.openai.com/v1",
}
# Same endpoint, different models per channelllm_config= {
"api_key": "sk-...",
"base_url": "https://api.openai.com/v1",
"models": {"text": "gpt-4o-mini", "vision": "gpt-4o"},
}
# Or two different endpointsllm_config= {
"text": {
"api_key": "sk-...",
"model": "gpt-4o-mini",
"base_url": "https://api.openai.com/v1",
},
"vision": {
"api_key": "sk-ali-...",
"model": "qwen-vl-max",
"base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
},
}
result=client.parse(file=Path("report.pdf"), llm_config=llm_config)
response=client.retrieval.query(
namespace="support-center",
query="refund policy",
use_agentic=True,
llm_config=llm_config,
)

Access different chunk types

result=client.parse(url="https://example.com/report.pdf")
# Text chunksforchunkinresult.text_chunks:
print(chunk.metadata.keywords)
print(chunk.metadata.summary)
# Page chunks (v2 page-memory results)forchunkinresult.page_chunks:
print(chunk.content_source) # "summary"print(chunk.content[:120])
print(chunk.metadata.page_nums) # citation pagesprint(chunk.metadata.entities)
# Image chunks (raw bytes loaded from ZIP)forchunkinresult.image_chunks:
print(chunk.file_path)
print(len(chunk.data)) # byteschunk.save("./output/") # writes image to disk# Table chunks (HTML loaded from ZIP)forchunkinresult.table_chunks:
print(chunk.file_path)
print(chunk.html[:100])

Save all results to disk

result=client.parse(file=Path("report.pdf"))
result.save("./output/report/")

Async usage

importasyncioimportknowhereasyncdefmain():
asyncwithknowhere.AsyncKnowhere(api_key="sk_...") asclient:
result=awaitclient.parse(url="https://example.com/report.pdf")
print(result.statistics.total_chunks)
forchunkinresult.text_chunks:
print(chunk.summary)
asyncio.run(main())

Step-by-step control

For granular control over the parsing workflow, use the jobs resource directly:

frompathlibimportPath# Step 1: Create a parsing jobjob=client.jobs.create(
source_type="file",
file_name="report.pdf",
namespace="support-center",
parsing_params={"model": "advanced", "ocr_enabled": True},
)
# Step 2: Upload file to presigned URLclient.jobs.upload(job, file=Path("report.pdf"))
# Step 3: Poll until done (adaptive backoff)job_result=client.jobs.wait(job.job_id, poll_interval=10.0, poll_timeout=1800.0)
print(job_result.document_id) # Persist this to update/archive the document later.# Step 4: Download and parse resultsresult=client.jobs.load(job_result)
print(result.statistics)

Handling errors

All errors inherit from knowhere.KnowhereError.

importknowheretry:
result=client.parse(url="https://example.com/report.pdf")
exceptknowhere.AuthenticationError:
print("Invalid API key")
exceptknowhere.APIStatusErrorase:
print(f"{e.status_code}: {e.message}")

Configuration

The SDK reads configuration from constructor arguments, environment variables, or defaults (in that priority order):

VariableDescriptionDefault
KNOWHERE_API_KEYAPI key (required)
KNOWHERE_BASE_URLAPI base URLhttps://api.knowhereto.ai
KNOWHERE_LOG_LEVELLog levelWARNING
# Uses environment variables automaticallyclient=knowhere.Knowhere()
# Or configure explicitlyclient=knowhere.Knowhere(
api_key="sk_...",
base_url="https://api.knowhereto.ai",
timeout=30.0, # HTTP request timeout (default: 60s)upload_timeout=300.0, # File upload timeout (default: 600s)max_retries=3, # Max retry attempts (default: 5)
)

Retries

Connection errors, 429 Rate Limit, and >=500 Internal errors are automatically retried with exponential backoff.

client=knowhere.Knowhere(
api_key="sk_...",
max_retries=3, # default is 5
)

Determining the installed version

importknowhereprint(knowhere.__version__)

Versioning

This package follows Semantic Versioning.

We publish stable releases to PyPI. To install the latest unreleased changes directly from the repository: https://github.com/Ontos-AI/knowhere-python-sdk

Requirements

Community

License

MIT

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages