Skip to main content

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

PyPI  Downloads  Python  MIT

DemoDocsFree API KeyBenchmarks


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
  • Guard method — hallucination firewall: client.guard(text, source_context) → verdict, action, claims with confidence scoring
  • 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


Download files

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

Source Distribution

wauldo-0.8.0.tar.gz (39.8 kB view details)

Uploaded Source

Built Distribution

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

wauldo-0.8.0-py3-none-any.whl (32.9 kB view details)

Uploaded Python 3

File details

Details for the file wauldo-0.8.0.tar.gz.

File metadata

  • Download URL: wauldo-0.8.0.tar.gz
  • Upload date:
  • Size: 39.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for wauldo-0.8.0.tar.gz
Algorithm Hash digest
SHA256 b2f63f0880d43d60ec670495a2520ca8912f221c54f5107b9230687479b055fb
MD5 5c7566afc90d4d8587320a7d6c0ab1a0
BLAKE2b-256 c9e88ab2b461a18052a999bed1c6a03d5965a75cae3146dee649932bacfb27aa

See more details on using hashes here.

File details

Details for the file wauldo-0.8.0-py3-none-any.whl.

File metadata

  • Download URL: wauldo-0.8.0-py3-none-any.whl
  • Upload date:
  • Size: 32.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for wauldo-0.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 94ae807a990cfc95ed3ea271f0fc72e5d801675c4b5baafe97ff43bf458fae5a
MD5 714a20ccc0c37e60b004611f439f4395
BLAKE2b-256 2991dab09241037e3cb7509d4c53ca867474b46f93e4853636650451c28ed6dd

See more details on using hashes here.

Supported by

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