Skip to main content

navdoc-py

Python SDK and CLI for navdoc. Upload and manage your documents via the navdoc REST API, and run RAG-powered chat with Claude.

Installation

pip install navdoc

Credentials

export NAVDOC_API_KEY=nd_...

CLI

navdoc ask

Run a one-shot query.

# Direct question
navdoc ask "What is asyncio?"
navdoc ask "What is asyncio?" --system-prompt "Be concise."

# Config-based
navdoc ask --config daily.json
navdoc ask --config daily.json --var date=2025-05-08

Config format:

{
  "name": "Daily Summary",
  "description": "Summarize a day's lifelog entries with activity count and time-of-day trends",
  "system_prompt": "You are a lifelog analyst. Respond in {{language}}.",
  "user_prompt": "Please summarize the logs for {{date}}. Include the number of activities and time-of-day trends.",
  "placeholders": [
    {
      "key": "date",
      "label": "Target date",
      "default": "today"
    },
    {
      "key": "language",
      "label": "Response language",
      "default": "English"
    }
  ]
}
  • Both system_prompt and user_prompt support {{key}} placeholders.
  • If --var key=value is not provided, missing placeholders are prompted interactively (unless a default is set).

navdoc chat

Start an interactive multi-turn chat session.

# No config — plain chat
navdoc chat

# With a system prompt
navdoc chat --system-prompt "You are a helpful assistant."

# With a config file
navdoc chat --config qa.json
navdoc chat --config qa.json --var topic=asyncio
navdoc chat --config qa.json --no-initial-message

--config is optional. If omitted, chat starts immediately with an empty (or --system-prompt-specified) prompt. If user_prompt is set in the config, it is sent as the first message automatically (--no-initial-message suppresses this). Type exit or press Ctrl+C to quit.

Python SDK

NavdocClient

from navdoc import NavdocClient

client = NavdocClient(
    api_key="nd_...",  # or NAVDOC_API_KEY env var
)

Document management

Upload, list, and delete documents via the navdoc REST API.

upload_document()

from navdoc import NavdocClient, Document

doc = await client.upload_document(
    "Full text content of the document...",
    url="https://example.com/page",   # unique identifier for the document
    scope="my-scope",                 # optional
)
print(doc.document_id)  # str
print(doc.chunk_count)  # int

upload_chunks()

Upload pre-split chunks instead of raw text (useful when you handle chunking yourself).

chunk_ids = await client.upload_chunks(
    ["First chunk...", "Second chunk..."],
    document_url="https://example.com/page",
    scope="my-scope",
)

list_documents()

docs = await client.list_documents(scope="my-scope", limit=50, offset=0)
for doc in docs:
    print(doc.document_id, doc.chunk_count)

delete_document()

await client.delete_document("doc_id_xxx")

Document type

@dataclass
class Document:
    document_id: str
    chunk_count: int

Scope management

Scopes are namespaces that group documents.

from navdoc import NavdocClient, Scope

scopes = await client.list_scopes()
scope = await client.create_scope("my-scope", visibility="private")
scope = await client.get_scope("my-scope")
scope = await client.update_scope("my-scope", visibility="public")
await client.delete_scope("my-scope")  # also removes all documents inside

Scope type

@dataclass
class Scope:
    name: str
    visibility: str  # "private" | "public"

Server-side agent

RAG chat powered by navdoc's built-in Claude agent.

stream() — streaming

Yields StreamEvent objects as the server sends them.

from navdoc import NavdocClient, StreamEvent

async for event in client.stream(
    "What is asyncio?",
    messages=[...],            # optional conversation history
    system_prompt="Answer concisely.",
    timezone="Asia/Tokyo",
):
    if event.type == "text":
        print(event.delta, end="", flush=True)

ask_server() — non-streaming

Collects the full response and returns an AgentResponse.

response = await client.ask_server(
    "What is asyncio?",
    messages=[{"role": "user", "content": "previous turn"}, ...],  # optional history
    system_prompt="Answer concisely.",
    timezone="Asia/Tokyo",
)
print(response.answer)
print(response.tool_calls)

StreamEvent type

@dataclass
class StreamEvent:
    type: str        # "text" | "tool_use" | "tool_result" | "done" | "error"
    delta: str | None = None    # type=text
    name: str | None = None     # type=tool_use, tool_result
    input: dict | None = None   # type=tool_use, tool_result
    message: str | None = None  # type=error

Development

uv sync --dev   # install dependencies
uv run pytest   # run tests

License

MIT

Download files

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

Source Distribution

navdoc-0.2.22.tar.gz (18.2 kB view details)

Uploaded Source

Built Distribution

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

navdoc-0.2.22-py3-none-any.whl (13.3 kB view details)

Uploaded Python 3

Release history Release notifications | RSS feed

This release

0.2.22 This release

2 files

0.2.21

2 files

0.2.20

2 files

0.2.19

2 files

0.2.18

2 files

0.2.17

2 files

0.2.16

2 files

0.2.15

2 files

0.2.14

2 files

0.2.13

2 files

0.2.12

2 files

0.2.11

2 files

0.2.10

2 files

0.2.9

2 files

0.2.8

2 files

0.2.7

2 files

0.2.6

2 files

0.2.5

2 files

0.2.4

2 files

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