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

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.0.tar.gz (26.9 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.0-py3-none-any.whl (24.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: graphsearch_rag-0.4.0.tar.gz
  • Upload date:
  • Size: 26.9 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.0.tar.gz
Algorithm Hash digest
SHA256 d4b603332754b70dd80c42163cfe0741871705d6de944331929ac19b6d6af177
MD5 2d2811d65a11c8dbaf07303f54491103
BLAKE2b-256 ee439a0e9ebd87ed90fee798654c2b7da662e114f8307ad008339720739f1b50

See more details on using hashes here.

Provenance

The following attestation bundles were made for graphsearch_rag-0.4.0.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.0-py3-none-any.whl.

File metadata

File hashes

Hashes for graphsearch_rag-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 273e728cc025fddc090592a57fbf4f5f724deae1e3ea4bcb7ff013ddc85c3443
MD5 accf4731fbc6d106350959af880954cf
BLAKE2b-256 0b4a79d7308a11a78be00b0452065806e45b3a741e26e18ca1b60a565d66167c

See more details on using hashes here.

Provenance

The following attestation bundles were made for graphsearch_rag-0.4.0-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