docpipe
Capabilities
DocsQuickstart
GitHubPyPI v0.6.0

Getting Started

Documentation

SDK reference for parse, extract, ingest, RAG, observability, and deployment — aligned with the docpipe README.

Getting Started

docpipe is an open-source document-to-RAG stack: parse PDFs and Office files, extract structured fields with LLMs, ingest chunks into your pgvector Postgres, and query with six retrieval strategies. Run it as a library, CLI, or shared HTTP service — vectors always stay in the database you pass per request.

Four pipelines you can use independently or together: Parse → Extract → Ingest → RAG. Install a profile extra for production defaults, then use the Python SDK, CLI, or FastAPI server.

  • Parse — unstructured docs → markdown/text (auto router or explicit parser)
  • Extract — text → structured entities (LangExtract / LangChain)
  • Ingest — chunks → embeddings → pgvector or turbovec (per-request connection_string)
  • RAG — six strategies, presets, optional AutoGen agents via /agents/query
Minimal flow
import docpipe

doc = docpipe.parse("invoice.pdf")
config = docpipe.IngestionConfig(
    connection_string="postgresql://user:pass@localhost:5432/mydb",
    table_name="docs",
    embedding_provider="openai",
    embedding_model="text-embedding-3-small",
)
docpipe.ingest("invoice.pdf", config=config)
result = docpipe.query("What is the invoice total?", config=docpipe.RAGConfig(
    connection_string=config.connection_string,
    table_name=config.table_name,
    embedding_provider="openai",
    embedding_model="text-embedding-3-small",
    llm_provider="openai",
    llm_model="gpt-4o",
))
print(result.answer)

Install

Install from PyPI with optional extras. Use curated profile extras for production defaults, or pick à la carte parser/embedding/server packages.

pip extras
pip install docpipe-sdk                        # Core only

# Curated profiles (recommended)
pip install "docpipe-sdk[profile-slim]"      # MarkItDown, fast chunking
pip install "docpipe-sdk[profile-balanced]"  # Docling, semchunk, hybrid RAG (default)
pip install "docpipe-sdk[profile-quality]"     # GLM-OCR, BGE rerank
pip install "docpipe-sdk[profile-agents]"    # Balanced + AutoGen

# À la carte
pip install "docpipe-sdk[docling]"             # Docling parser
pip install "docpipe-sdk[markitdown]"        # Lightweight Office/PDF → Markdown
pip install "docpipe-sdk[glm-ocr]"           # GLM-OCR (scanned docs)
pip install "docpipe-sdk[langextract]"       # Google LangExtract
pip install "docpipe-sdk[openai]"            # OpenAI embeddings & LLM
pip install "docpipe-sdk[pgvector]"          # PostgreSQL vector store
pip install "docpipe-sdk[turbovec]"          # On-disk vector indices
pip install "docpipe-sdk[rag]"               # Hybrid BM25 + vector
pip install "docpipe-sdk[rerank]"            # FlashRank reranker
pip install "docpipe-sdk[server]"            # FastAPI + /admin + Alembic
pip install "docpipe-sdk[observability]"     # OpenTelemetry + Prometheus
pip install "docpipe-sdk[http]"              # Python HTTP client
pip install "docpipe-sdk[all]"               # Dev/CI only

For API server + admin panel + Alembic migrations: pip install "docpipe-sdk[server]". Add observability for OTEL + Prometheus.

Runtime presets & discovery
# Runtime presets (pass on /ingest, /rag/query, /agents/query)
# fast     — low latency, recursive chunks, no rerank
# balanced — default production (semchunk + flashrank)
# quality  — OCR parsers, semantic chunks, BGE rerank
# agents   — tool-using RAG via /agents/query

curl -u admin:pass http://localhost:8000/profiles
curl -u admin:pass http://localhost:8000/plugins

docpipe plugins list
docpipe profiles list
docpipe resolve invoice.pdf --goal ingest

Plugins & Presets

Install profiles bundle parsers, chunkers, and rerankers. Runtime presets (fast, balanced, quality, agents) select a bundle per API call without hardcoding plugin names.

pip extraDocker tagUse
profile-slim:slimMarkItDown, fast chunking, flashrank
profile-balanced:balancedDefault — Docling, semchunk, hybrid RAG
profile-quality:qualityGLM-OCR, semantic chunks, BGE rerank
profile-agents:agentsBalanced + AutoGen agentic RAG
profile-gpu:gpuMinerU / PaddleOCR on quality base
  • GET /profiles — install profile, runtime presets, server defaults
  • GET /plugins — installed plugins with available, allowed, tier, license
  • POST /plugins/resolve — recommend parser/chunker for a file + goal
  • preset=fast|balanced|quality|agents on POST /ingest, /rag/query, /agents/query
  • Operator guardrails: DOCPIPE_ENABLED_PARSERS, DOCPIPE_DISABLED_PLUGINS, DOCPIPE_DEFAULT_RUNTIME_PRESET
CLI discovery
docpipe plugins list
docpipe profiles list
docpipe resolve invoice.pdf --goal ingest

Parse

Convert PDFs, Office files, HTML, and images to markdown or plain text. Default is parser=auto (tier balanced); use markitdown for lightweight conversion or glm-ocr for scanned docs.

Python
import docpipe

# Default: auto router (tier balanced) or explicit parser
doc = docpipe.parse("invoice.pdf")
print(doc.markdown)

# Lightweight Office/PDF → Markdown
doc = docpipe.parse("report.docx", parser="markitdown")

# GLM-OCR (scanned / image-heavy documents)
doc = docpipe.parse("scanned_report.pdf", parser="glm-ocr")
print(doc.markdown)
  • CLI: docpipe parse invoice.pdf --format markdown
  • API: POST /parse with source URL or path
  • Parsers: markitdown, docling, glm-ocr, pymupdf, mineru, paddleocr, unstructured

Extract

Pull structured entities from text using LangExtract or LangChain with_structured_output. Define a schema describing fields to extract.

Python
import docpipe

schema = docpipe.ExtractionSchema(
    description="Extract invoice line items with amounts",
    model_id="gemini-2.5-flash",
)
results = docpipe.extract(doc.text, schema)
for r in results:
    print(r.entity_class, r.text, r.attributes)

# Full parse + extract
result = docpipe.run("invoice.pdf", schema)
print(result.parsed.markdown)
print(result.extractions)
  • CLI: docpipe extract "text" --schema schema.yaml --model gemini-2.5-flash
  • API: POST /extract, POST /run (parse + extract)

Ingest

Chunk documents, embed with your chosen provider, and store in PostgreSQL pgvector (default) or optional turbovec on-disk indices. Each app passes its own connection_string — docpipe does not centralize RAG storage.

Python
import docpipe

config = docpipe.IngestionConfig(
    connection_string="postgresql://user:pass@localhost:5432/mydb",
    table_name="invoices",
    embedding_provider="openai",
    embedding_model="text-embedding-3-small",
    incremental=True,  # skip unchanged files by SHA-256 hash
)
docpipe.ingest("invoice.pdf", config=config)

# API: pass preset=balanced|fast|quality on ingest for parser/chunker/rerank bundle
Streaming ingest (SSE)
curl -u admin:secret -N -X POST http://localhost:8000/ingest/stream \
  -H "Content-Type: application/json" \
  -d '{
    "source": "file:///data/doc.pdf",
    "connection_string": "postgresql://user:pass@db:5432/mydb",
    "table_name": "docs",
    "embedding_provider": "openai",
    "embedding_model": "text-embedding-3-small",
    "preset": "balanced"
  }'
# SSE events: resolve → parse → chunk → complete

Set incremental=True to skip files already ingested with the same SHA-256 hash. DELETE /ingest removes chunks by exact source or path fragment (match_mode: contains). For long jobs prefer POST /ingest/stream for progress events.

  • CLI: docpipe ingest report.pdf --db ... --table docs --incremental
  • API: POST /ingest, POST /ingest/stream (SSE), DELETE /ingest
  • POST /collection/sources — list ingested sources in a collection
  • Embeddings: OpenAI, Google Gemini, Ollama, HuggingFace

RAG

Ask questions against ingested documents. Six retrieval strategies, optional reranking, conversation history, metadata filters, structured output, SSE streaming, and AutoGen agents.

Python query
import docpipe

rag_config = docpipe.RAGConfig(
    connection_string="postgresql://user:pass@localhost:5432/mydb",
    table_name="invoices",
    embedding_provider="openai",
    embedding_model="text-embedding-3-small",
    llm_provider="openai",
    llm_model="gpt-4o",
    strategy="hyde",
    reranker="flashrank",
)
result = docpipe.query("What is the total amount on the invoice?", config=rag_config)
print(result.answer)
print(result.sources)
print(result.usage)  # token counts when available
StrategyDescription
naiveSimple cosine similarity search. Fast and reliable for well-formed queries.
hydeLLM generates a hypothetical answer, embeds it for retrieval. Highest accuracy on complex questions.
multi_queryExpands query into N variants, merges and deduplicates results. Best for vague or short queries.
parent_documentRetrieves seed chunks then expands context window per source. Best for long documents.
hybridCombines dense vector search with BM25 keyword matching. Best for exact terms, IDs, and proper nouns.
autoLLM classifies the question and dispatches to the optimal strategy automatically.
  • CLI: docpipe rag query "..." --strategy hyde --reranker flashrank
  • API: POST /rag/query (JSON), POST /rag/stream (SSE)
  • POST /agents/query — tool-using RAG (preset=agents, requires profile-agents image)
  • Multi-turn: pass history: [{role, content}, ...] on query/stream
  • Filters: filters: {"source": "report.pdf"} on search/RAG

App Integration

Open source: you handle TLS, ingress, and secrets. docpipe handles in-process guardrails on a shared internal instance — plugin allowlists, rate limits, URL fetch policy, optional audit. Each app passes its own connection_string; vectors stay in that app's Postgres.

Python client
from docpipe.client.integration import DocpipeClient

with DocpipeClient(
    "http://docpipe.docpipe.svc.cluster.local:8000",
    username="admin",
    password="...",
) as client:
    print(client.available_preset_names())  # fast, balanced, quality, agents
    rec = client.resolve(source="invoice.pdf", preset="balanced")
    client.ingest(
        source="s3://bucket/invoice.pdf",
        connection_string="postgresql://delegate:pass@delegate-db:5432/delegate",
        table_name="assistant_docs",
        embedding_provider="openai",
        embedding_model="text-embedding-3-small",
        preset="balanced",
    )
UI label (Delegate)API
Fastpreset=fast
Balancedpreset=balanced
Qualitypreset=quality
Agentspreset=agents on /agents/query
  • Docker example: github.com/thesunnysinha/docpipe/tree/main/examples/internal-shared
  • GET /mcp/tools + POST /mcp/call — agent tool descriptors (parse, rag_query)
  • POST /cost/estimate — heuristic parse seconds and embedding USD by preset (planning only)
  • Internal MinIO: DOCPIPE_ALLOW_PRIVATE_URLS=true on trusted networks only
  • X-Docpipe-Tenant-Id: set from your backend only — docpipe does not issue tenant tokens
  • Security model: github.com/thesunnysinha/docpipe/blob/main/docs/INTERNAL_SECURITY.md

Observability

OpenTelemetry traces, JSON logs, health checks with dependency probes, and Prometheus metrics on GET /metrics (no auth). Optional Phoenix tracing via DOCPIPE_PHOENIX_ENABLED.

Environment
# pip install "docpipe-sdk[server,observability]"
DOCPIPE_OTEL_ENABLED=true
DOCPIPE_OTEL_SERVICE_NAME=docpipe
DOCPIPE_OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318/v1/traces
DOCPIPE_OTEL_TRACES_SAMPLER_ARG=1.0
DOCPIPE_LOG_FORMAT=json
DOCPIPE_HEALTH_CHECK_DB=true

$ docpipe serve

# curl http://localhost:8000/health   # plugins + dependency status
# curl http://localhost:8000/metrics # Prometheus (no auth on /metrics)
VariableDefaultPurpose
DOCPIPE_OTEL_ENABLEDfalseExport traces via OTLP/HTTP
DOCPIPE_OTEL_SERVICE_NAMEdocpipeservice.name resource
DOCPIPE_OTEL_EXPORTER_OTLP_ENDPOINTe.g. http://localhost:4318/v1/traces
DOCPIPE_LOG_FORMATtextjson for structured logs
DOCPIPE_HEALTH_CHECK_DBtrueSELECT 1 when DB URL set
DOCPIPE_PHOENIX_ENABLEDfalseArize Phoenix trace UI

Turbovec

Optional compressed on-disk vector indices when you do not want pgvector in Postgres. Good for local prototypes and air-gapped RAG; production Postgres deployments should use pgvector.

Setup
# pip install "docpipe-sdk[turbovec,openai]"   # + your embedding provider
export DOCPIPE_VECTOR_BACKEND=turbovec
export DOCPIPE_TURBVEC_INDEX_DIR=./.docpipe/indices   # default on-disk index root

# Per-request override on ingest / search / RAG API bodies:
# { "vector_backend": "turbovec", "table_name": "my_library", ... }

import docpipe

config = docpipe.IngestionConfig(
    connection_string="postgresql://unused",  # accepted; vectors use local files
    table_name="my_library",                  # index folder name under TURBVEC_INDEX_DIR
    embedding_provider="openai",
    embedding_model="text-embedding-3-small",
    vector_backend="turbovec",
)
docpipe.ingest("invoice.pdf", config=config)
# → ./.docpipe/indices/my_library/index.tvim + docstore.json

# Default pgvector in PostgreSQL is recommended for production deployments.

API Reference

FastAPI server: docpipe serve --host 0.0.0.0 --port 8000. HTTP Basic Auth on all routes except GET /health, GET /metrics, and static license pages.

MethodPathDescription
GET/Jinja homepage (HTML)
GET/healthHealth check, plugins, dependency status
GET/metricsPrometheus metrics (no auth)
GET/profilesInstall profile + runtime presets
GET/pluginsList registered plugins (tier, license)
POST/plugins/resolveRecommend plugins for file + goal
POST/parseParse a document
POST/extractExtract structured data
POST/runParse + extract
POST/ingestIngest into vector DB
POST/ingest/streamIngest with SSE progress
DELETE/ingestRemove chunks for a source
POST/collection/sourcesList sources in a collection
POST/searchVector similarity search (filters)
POST/rag/queryRAG Q&A (history, filters, usage)
POST/rag/streamStreaming RAG (SSE)
POST/agents/queryAutoGen agentic RAG
POST/generatePlain LLM completion (no retrieval)
POST/transcribeSpeech-to-text (Whisper / VibeVoice)
POST/evaluate/runEvaluate RAG quality
POST/cost/estimateHeuristic cost/time by preset
GET/mcp/toolsMCP tool descriptors
POST/mcp/callInvoke MCP tool
GET/adminOperator panel (control DB enabled)
Python HTTP client
from docpipe.http import DocpipeClient

with DocpipeClient("http://localhost:8000", username="admin", password="docpipe") as client:
    print(client.health())
    print(client.get("/profiles").json())
    result = client.rag_query({...})
    print(result.get("usage"))

Control Plane

Optional SQLite or Postgres metadata store — separate from vector/RAG data. Stores admin login and opt-in audit/job rows; never document content unless you enable persistence flags.

Environment
# Optional operator metadata (NOT your vector/RAG data)
DOCPIPE_CONTROL_DB_ENABLED=true
DOCPIPE_CONTROL_DB_PATH=/data/docpipe.db
DOCPIPE_ADMIN_PANEL_ENABLED=true
DOCPIPE_PERSIST_AUDIT_EVENTS=true
DOCPIPE_PERSIST_INGEST_JOBS=false
DOCPIPE_PERSIST_PLUGIN_RESOLUTIONS=false

# Admin login (seeded on first boot)
DOCPIPE_USERNAME=admin
DOCPIPE_PASSWORD=change-me
VariablePurpose
DOCPIPE_CONTROL_DB_ENABLEDEnable control-plane DB (SQLite path or Postgres URL)
DOCPIPE_CONTROL_DB_PATHSQLite file path (default /data/docpipe.db in Docker)
DOCPIPE_PERSIST_AUDIT_EVENTSStore plugin policy / resolve audit rows
DOCPIPE_PERSIST_INGEST_JOBSStore ingest job metadata (no document content)
DOCPIPE_ADMIN_PANEL_ENABLEDServe GET /admin Jinja UI
  • Admin UI: GET /admin, /admin/audit, /admin/jobs (Basic Auth)
  • Alembic migrations run on server startup when control DB enabled
  • Full reference: github.com/thesunnysinha/docpipe/blob/main/docs/CONTROL_DB.md

Docker / Production

Official GHCR profile-tagged images, example Compose stacks, shared internal API pattern, and production sidecar notes.

Built from docpipe/Dockerfile on python:3.12-slim; default entrypoint runs docpipe serve on port 8000. Tags: :slim, :balanced (default), :quality, :agents, :gpu.

Pull & run API
# Profile-tagged images (GHCR)
docker pull ghcr.io/thesunnysinha/docpipe:balanced
docker pull ghcr.io/thesunnysinha/docpipe:slim
docker pull ghcr.io/thesunnysinha/docpipe:quality
docker pull ghcr.io/thesunnysinha/docpipe:agents

# API server — .env: OPENAI_API_KEY, DOCPIPE_PASSWORD, etc.
docker run -p 8000:8000 --env-file .env -v ./data:/data \
  ghcr.io/thesunnysinha/docpipe:balanced

# curl -u admin:password http://localhost:8000/health
# curl -u admin:password http://localhost:8000/admin
# curl http://localhost:8000/metrics

# One-off parse / ingest
docker run -v ./data:/data ghcr.io/thesunnysinha/docpipe:balanced \
  parse /data/invoice.pdf
Internal shared API (no bundled Postgres)
# Shared internal API — each app passes its own connection_string
# See: github.com/thesunnysinha/docpipe/tree/main/examples/internal-shared
services:
  docpipe:
    image: ghcr.io/thesunnysinha/docpipe:balanced
    ports:
      - "8000:8000"
    env_file: .env
    environment:
      DOCPIPE_CONTROL_DB_ENABLED: "true"
      DOCPIPE_CONTROL_DB_PATH: /data/docpipe.db
      DOCPIPE_PERSIST_AUDIT_EVENTS: "true"
      DOCPIPE_ALLOW_PRIVATE_URLS: "true"
    volumes:
      - ./data:/data
    restart: unless-stopped

# cp .env.example .env && docker compose up -d
Standalone with pgvector
# docpipe + pgvector — local dev
# Full examples: github.com/thesunnysinha/docpipe/tree/main/examples
services:
  docpipe:
    image: ghcr.io/thesunnysinha/docpipe:balanced
    ports:
      - "8000:8000"
    env_file: .env
    environment:
      DOCPIPE_DB_CONNECTION_STRING: postgresql://docpipe:docpipe@db:5432/docpipe
      DOCPIPE_CONTROL_DB_ENABLED: "true"
      DOCPIPE_CONTROL_DB_PATH: /data/docpipe.db
    volumes:
      - ./data:/data
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped

  db:
    image: pgvector/pgvector:pg16
    environment:
      POSTGRES_USER: docpipe
      POSTGRES_PASSWORD: docpipe
      POSTGRES_DB: docpipe
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U docpipe"]
      interval: 5s
      timeout: 5s
      retries: 5
    restart: unless-stopped

volumes:
  pgdata:

# cp .env.example .env && docker compose up -d
VariableExample / defaultPurpose
OPENAI_API_KEYsk-...Embedding / LLM when using OpenAI
DOCPIPE_DB_CONNECTION_STRINGpostgresql://docpipe:docpipe@db:5432/docpipeDefault pgvector URL (health + examples)
DOCPIPE_DB_TABLE_NAMEdocumentsDefault collection name
DOCPIPE_EMBEDDING_PROVIDERopenaiEmbedding vendor
DOCPIPE_EMBEDDING_MODELtext-embedding-3-smallEmbedding model id
DOCPIPE_PROFILEbalancedInstall profile: slim, balanced, quality, agents, gpu
DOCPIPE_DEFAULT_RUNTIME_PRESETbalancedDefault API preset when omitted
DOCPIPE_CONTROL_DB_ENABLEDfalseSQLite/Postgres for admin + optional audit
DOCPIPE_PERSIST_AUDIT_EVENTSfalseStore plugin policy audit rows
DOCPIPE_AUTH_ENABLEDtrueHTTP Basic Auth on API + /admin
DOCPIPE_USERNAMEadminBasic Auth user
DOCPIPE_PASSWORDdocpipeBasic Auth password — change in prod
DOCPIPE_ALLOW_PRIVATE_URLSfalseAllow MinIO/internal HTTP sources (Docker internal)
DOCPIPE_OTEL_ENABLEDfalseOpenTelemetry traces
DOCPIPE_RATE_LIMIT_ENABLEDtruePer-preset POST rate limits
  • Images: ghcr.io/thesunnysinha/docpipe — tags :slim, :balanced (default), :quality, :agents, :gpu, plus semver.
  • Shared internal API: use examples/internal-shared — no bundled Postgres; each app passes connection_string per request.
  • Vector/RAG data lives in each project's Postgres. Control-plane SQLite (optional) stores admin + opt-in audit only.
  • Runtime presets on API: preset=fast|balanced|quality|agents on /ingest and /rag/query. Discover via GET /profiles.
  • Sidecar: run docpipe on app Docker network; callers use http://docpipe:8000 with Basic Auth.
  • Internal MinIO / presigned URLs: DOCPIPE_ALLOW_PRIVATE_URLS=true on trusted networks only.
  • Admin panel: GET /admin when DOCPIPE_CONTROL_DB_ENABLED=true.
  • Full Docker examples + env reference: github.com/thesunnysinha/docpipe/tree/main/examples
  • Scrape GET /metrics (no auth) for Prometheus; optional DOCPIPE_OTEL_* for traces.