Official Python SDK for Wauldo — Verified AI answers from your documents
Project description
Wauldo Python SDK
Verified AI answers from your documents — or no answer at all.
Most RAG APIs guess. Wauldo verifies.
0% hallucination | 83% accuracy | 61 eval tasks | 14 LLMs tested
Demo • Docs • Free API Key • Benchmarks
Quickstart (30 seconds)
pip install wauldo
Try it locally (no API key needed)
from wauldo import MockHttpClient
client = MockHttpClient(chat_response="Returns are accepted within 60 days.")
client.rag_upload(content="Our refund policy allows returns within 60 days.", filename="policy.txt")
result = client.rag_query("What is the refund policy?")
print(result.answer) # Returns are accepted within 60 days.
print(result.sources) # [RagSource(document_id='mock-doc-001', ...)]
Run examples/quickstart.py for the full offline walkthrough.
With a real server
from wauldo import HttpClient
client = HttpClient(base_url="https://api.wauldo.com", api_key="YOUR_API_KEY")
client.rag_upload(content="Our refund policy allows returns within 60 days...", filename="policy.txt")
result = client.rag_query("What is the refund policy?")
print(result.answer)
print(result.sources)
Output:
Answer: Returns are accepted within 60 days of purchase.
Sources: policy.txt — "Our refund policy allows returns within 60 days"
Grounded: true | Confidence: 0.92
Try the demo | Get a free API key
Why Wauldo (and not standard RAG)
Typical RAG pipeline
retrieve → generate → hope it's correct
Wauldo pipeline
retrieve → extract facts → generate → verify → return or refuse
If the answer can't be verified, it returns "insufficient evidence" instead of guessing.
See the difference
Document: "Refunds are processed within 60 days"
Typical RAG: "Refunds are processed within 30 days" ← wrong
Wauldo: "Refunds are processed within 60 days" ← verified
or "insufficient evidence" if unclear ← safe
Examples
Upload a PDF and ask questions
result = client.upload_file("contract.pdf", title="Q3 Contract")
print(f"Extracted {result.chunks_count} chunks, quality: {result.quality_label}")
# -> Extracted 12 chunks, quality: high
result = client.rag_query("What are the payment terms?")
print(f"Answer: {result.answer}")
# -> Answer: Net 30 from invoice date.
print(f"Confidence: {result.get_confidence():.0%}")
# -> Confidence: 94%
print(f"Grounded: {result.audit.grounded}")
# -> Grounded: True
Fact-check any LLM output
result = client.fact_check(
text="Returns are accepted within 60 days.",
source_context="Our policy allows returns within 14 days.",
mode="lexical",
)
print(result.verdict) # "rejected"
print(result.action) # "block"
print(result.claims[0].reason) # "numerical_mismatch"
Verify citations
result = client.verify_citation(
text="The policy covers damage [Source: Manual]. Warranty is unlimited.",
sources=[{"name": "Manual", "content": "Coverage for accidental damage only."}],
)
print(result.citation_ratio) # 0.5
print(result.uncited_sentences) # ["Warranty is unlimited."]
Chat (OpenAI-compatible)
reply = client.chat_simple("auto", "Explain Python decorators")
print(reply)
Streaming
Sync — print tokens as they arrive:
import sys
from wauldo import ChatRequest, HttpChatMessage
request = ChatRequest(
model="auto",
messages=[
HttpChatMessage.system("You are a helpful assistant."),
HttpChatMessage.user("Explain Python decorators"),
],
)
for chunk in client.chat_stream(request):
sys.stdout.write(chunk)
sys.stdout.flush()
print()
Async streaming (requires pip install wauldo[async]):
import asyncio
from wauldo import AsyncHttpClient, ChatRequest, HttpChatMessage
async def main():
async with AsyncHttpClient(base_url="https://api.wauldo.com", api_key="YOUR_API_KEY") as client:
req = ChatRequest.quick("auto", "How does HTTP/2 multiplexing work?")
async for token in client.chat_stream(req):
print(token, end="", flush=True)
print()
asyncio.run(main())
RAG query with streaming answer:
client.rag_upload(content="Our SLA guarantees 99.9% uptime...", filename="sla.txt")
req = ChatRequest(
model="auto",
messages=[HttpChatMessage.user("What uptime does the SLA guarantee?")],
)
for chunk in client.chat_stream(req):
print(chunk, end="", flush=True)
print()
Error handling during streaming:
from wauldo import WauldoError, ServerError, AgentConnectionError
try:
for chunk in client.chat_stream(request):
print(chunk, end="", flush=True)
except AgentConnectionError:
print("\n[connection lost]")
except ServerError as e:
print(f"\n[server error: {e}]")
except WauldoError as e:
print(f"\n[error: {e}]")
See examples/streaming_chat.py and examples/async_streaming.py for runnable scripts.
Real-world use cases
| Example | Description |
|---|---|
pdf_qa.py |
Upload a product manual PDF and ask technical questions |
support_chatbot.py |
Build a verified support chatbot from FAQ docs |
contract_analysis.py |
Extract clauses from a contract + fact-check claims |
multi_document.py |
Cross-reference answers across multiple documents |
Async Support
pip install wauldo[async]
import asyncio
from wauldo import AsyncHttpClient
async def main():
async with AsyncHttpClient(base_url="https://api.wauldo.com", api_key="YOUR_API_KEY") as client:
result = await client.rag_query("What are the payment terms?")
print(result.answer)
asyncio.run(main())
All sync methods have async equivalents. Contributed by @qorexdev.
Features
- Pre-generation fact extraction — numbers, dates, limits injected as constraints before the LLM call
- Post-generation grounding check — every answer verified against sources
- Citation validation — detects phantom references
- Analytics & Insights — track token savings, cache performance, cost per hour, and per-tenant traffic
- Fact-check API — verify any claim against any source (3 modes: lexical, hybrid, semantic)
- Native PDF/DOCX upload — server-side extraction with quality scoring
- Smart model routing — auto-selects cheapest model that meets quality
- OpenAI-compatible — swap your
base_url, keep your existing code - Sync + Async — full async/await support
Built For
- Production RAG systems that need reliable answers
- Teams where "confidently wrong" is unacceptable
- Legal, finance, healthcare, support automation
- Anyone replacing "hope-based" RAG
Benchmarks
| Metric | Result |
|---|---|
| Hallucination rate | 0% |
| Accuracy | 83% (17% = correct refusals) |
| Eval tasks | 61 |
| LLMs tested | 14 models, 3 runs each |
| Avg latency | ~1.2s |
Error Handling
from wauldo import WauldoError, ServerError, AgentTimeoutError
try:
response = client.chat(ChatRequest.quick("auto", "Hello"))
except ServerError as e:
print(f"Server error: {e}")
except AgentTimeoutError:
print("Request timed out")
except WauldoError as e:
print(f"SDK error: {e}")
RapidAPI
client = HttpClient(
base_url="https://api.wauldo.com",
headers={
"X-RapidAPI-Key": "YOUR_RAPIDAPI_KEY",
"X-RapidAPI-Host": "smart-rag-api.p.rapidapi.com",
},
)
Free tier (300 req/month): RapidAPI
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
ConnectionError |
Server unreachable | Check base_url, make sure the server is running |
ServerError (401) |
Bad API key | Verify your key at RapidAPI dashboard |
AgentTimeoutError |
Request took too long | Pass timeout_ms=30000 or try a smaller document |
ModuleNotFoundError: aiohttp |
Async extras not installed | Run pip install wauldo[async] |
ImportError: MockHttpClient |
Old SDK version | Run pip install --upgrade wauldo |
Still stuck? Open an issue.
Contributing
PRs welcome. Check the good first issues.
Contributors
- @qorexdev — async client, streaming, MockHttpClient, quickstart, CONTRIBUTING guide
- @dagangtj — analytics demo + MockHttpClient analytics methods
License
MIT — see LICENSE
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wauldo-0.7.0.tar.gz.
File metadata
- Download URL: wauldo-0.7.0.tar.gz
- Upload date:
- Size: 40.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9e1884337ffe48561fc8ba589b25285b3df084c70350519b4f394d3a8beb19d6
|
|
| MD5 |
4af67be0f44a5a65b70e746333b19f9c
|
|
| BLAKE2b-256 |
09a5cecfc452faf3e0c3fc2ac0ce8ef197386f2164505d97c65c7d2e36d9f748
|
File details
Details for the file wauldo-0.7.0-py3-none-any.whl.
File metadata
- Download URL: wauldo-0.7.0-py3-none-any.whl
- Upload date:
- Size: 34.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ecb3e34a450d143d8e31d7472f22fc8427eeba8a5fd3bf48d8d702e0a3b22624
|
|
| MD5 |
27afedd671271b22b83388aa9a0aa9fa
|
|
| BLAKE2b-256 |
412ef1791139136e2fcb81a11edde387a230cb86d526280d30b3866f8ea875f3
|