Skip to main content

GraphSearch: a GraphQL API server for Retrieval-Augmented Generation (RAG) over your documents

Project description

GraphSearch

CI License: MIT Python 3.10+

A GraphQL API server for Retrieval-Augmented Generation (RAG) over your documents.

Upload documents through a GraphQL mutation, then ask questions through a GraphQL query. GraphSearch chunks and embeds your documents, retrieves the most relevant passages with vector similarity search, and feeds them to an LLM to generate a grounded answer — all behind a single, typed, introspectable GraphQL endpoint.

query {
  answer(question: "How do I reset my password?") {
    text                                # cites sources as [1], [2], ...
    sources { documentTitle text score }
  }
}

GraphSearch demo: asking "How do I get my money back?" in GraphiQL and getting the returns policy with ranked sources

Semantic retrieval with the offline local backend: "How do I get my money back?" finds the returns policy — no shared keywords needed.

Why GraphQL for RAG?

  • One endpoint, typed schema — clients ask for exactly the fields they need (answer text, source chunks, scores) instead of juggling REST routes.
  • Introspection & tooling for free — GraphiQL, codegen'd TypeScript clients, and schema docs come with the ecosystem.
  • Composableanswer, search, and document management live in one schema and can be combined in a single request.

Quickstart

Install

pip install graphsearch-rag        # from PyPI (imports as `graphsearch`)
# or run the prebuilt image:
docker run -p 8000:8000 ghcr.io/mohithgowdak/graphsearch:latest
# or from source:
git clone https://github.com/mohithgowdak/graphsearch && cd graphsearch
pip install -e ".[dev]"

Run locally (no API keys needed)

The default configuration is fully offline: a hashing-trick embedder plus an extractive answer mode. It exercises the entire pipeline and is perfect for kicking the tires, tests, and CI.

# Ingest some documents (bundled examples shown; .pdf/.md/.txt all work)
graphsearch-ingest data/example_docs

# Start the server
graphsearch

graphsearch not recognized? With pip install --user (the default on Windows when site-packages isn't writable), pip puts console commands in a Scripts folder that may not be on PATH. Either add it to PATH (%APPDATA%\Python\Python3xx\Scripts on Windows), or skip PATH entirely:

python -m graphsearch                            # start the server
python -m graphsearch.ingest data/example_docs  # ingest documents

Then open:

  • http://localhost:8000/ — the Playground: drop in your own documents (PDF, Markdown, plain text) and ask questions from the browser, no GraphQL knowledge needed. Every action has a "Show the GraphQL" toggle revealing the exact query it runs, so you can copy it straight into your app.
  • http://localhost:8000/graphql — GraphiQL, for writing queries by hand:
query {
  answer(question: "What is the return policy?") {
    text
    sources { text score }
  }
}

The GraphSearch Playground: your documents on the left, grounded answers with ranked sources on the right

Run with Docker

docker compose up --build

Semantic search without any API key

The local backend runs sentence-transformers on your CPU — real semantic retrieval ("How do I get my money back?" finds the refund policy), still zero keys and zero external services:

pip install -e ".[local]"
export GRAPHSEARCH_EMBEDDINGS=local   # $env:GRAPHSEARCH_EMBEDDINGS='local' on Windows
graphsearch-ingest data/example_docs  # re-ingest: embeddings are created at ingest time
graphsearch

The default model (all-MiniLM-L6-v2, ~80 MB) downloads on first use.

Generated answers with citations

Point the LLM stage at OpenAI or Anthropic and answers become generated text that cites its sources — [1], [2], … map 1:1 to the sources list returned alongside the answer:

export GRAPHSEARCH_LLM=anthropic          # or openai
export ANTHROPIC_API_KEY=sk-ant-...
pip install -e ".[anthropic]"
graphsearch
Setting Options Default
GRAPHSEARCH_EMBEDDINGS hash (offline), local (offline, semantic), openai hash
GRAPHSEARCH_LLM extractive (offline), openai, anthropic extractive

Note: documents are embedded at ingest time, so re-ingest after switching embedding backends.

GraphQL API

Queries

answer(question: String!, topK: Int): Answer!      # RAG: retrieve + generate
search(query: String!, topK: Int): [Chunk!]!       # raw semantic search
documents(limit: Int = 20, offset: Int = 0): [Document!]!
document(id: ID!): Document

Mutations

uploadDocument(content: String!, title: String, source: String): Document!
uploadFile(file: Upload!, title: String, source: String): Document!   # PDF/Markdown/text, multipart
deleteDocument(id: ID!): Boolean!

uploadFile follows the GraphQL multipart request spec; PDF text extraction happens server-side via pypdf (scanned/image-only PDFs are rejected with a hint to OCR them first).

Example: ingest and ask in one session

mutation {
  uploadDocument(
    content: "Support hours are 9am-5pm PST, Monday through Friday."
    title: "support-hours"
  ) { id chunkCount }
}

query {
  answer(question: "When is support available?") {
    text
    sources { documentId score }
  }
}

Architecture

Client ── GraphQL (FastAPI + Strawberry) ── RagService
                                              ├─ chunking       (paragraph-aware splitter)
                                              ├─ Embedder       (hash | sentence-transformers | OpenAI)
                                              ├─ VectorStore    (SQLite-backed, in-memory cosine search)
                                              ├─ Database       (SQLite: documents, chunks, vectors)
                                              └─ LLM            (extractive | OpenAI | Anthropic)

Every pipeline stage is an abstract interface (Embedder, VectorStore, LLM), so new backends are drop-in additions — see Contributing.

Development

pip install -e ".[dev]"
ruff check .          # lint
pytest -v             # tests run fully offline

Roadmap / good first issues

  • Additional vector store backends: Qdrant, Weaviate, Redis/Valkey, pgvector, FAISS
  • Additional embedding backends: Cohere, Voyage
  • Streaming answers via GraphQL subscriptions
  • Metadata filters on search (tags, date ranges) and hybrid keyword+vector search
  • Auth (API keys / JWT) and rate limiting
  • Query/embedding caching
  • Auto-generated TypeScript client (GraphQL Code Generator)
  • Evaluation harness with known Q&A pairs; Prometheus metrics
  • Advanced RAG: query rewriting, multi-hop retrieval, citation spans

Contributing

Contributions are welcome! See CONTRIBUTING.md for setup, style, and PR guidelines, and the issue tracker for good first issue labels.

License

MIT

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

graphsearch_rag-0.4.1.tar.gz (27.5 kB view details)

Uploaded Source

Built Distribution

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

graphsearch_rag-0.4.1-py3-none-any.whl (25.1 kB view details)

Uploaded Python 3

File details

Details for the file graphsearch_rag-0.4.1.tar.gz.

File metadata

  • Download URL: graphsearch_rag-0.4.1.tar.gz
  • Upload date:
  • Size: 27.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for graphsearch_rag-0.4.1.tar.gz
Algorithm Hash digest
SHA256 38e30bd89c2275c3c97b66b6a4231ea9533f47118a1c13a7c9e9864a31de28f7
MD5 f3175e4c089326019c04b65921fbc09c
BLAKE2b-256 91bf6b1d50bc333ffa7b52841349bfe343563285b7af5c8657574af11bb75dc6

See more details on using hashes here.

Provenance

The following attestation bundles were made for graphsearch_rag-0.4.1.tar.gz:

Publisher: release.yml on mohithgowdak/graphsearch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file graphsearch_rag-0.4.1-py3-none-any.whl.

File metadata

File hashes

Hashes for graphsearch_rag-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 efce7fb609aefe733929885d8f518f636de59370078663cb55a0a8319fa9fabc
MD5 61b7f54954d75b32f7002d724d4a0188
BLAKE2b-256 b97bb08988c88fd041a65b1b4c9ecfbd3f84ef67b23345ce203f733ccfc94552

See more details on using hashes here.

Provenance

The following attestation bundles were made for graphsearch_rag-0.4.1-py3-none-any.whl:

Publisher: release.yml on mohithgowdak/graphsearch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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