atrium-rag 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. atrium_rag-0.1.0/.env.docker +68 -0
  2. atrium_rag-0.1.0/.env.example +169 -0
  3. atrium_rag-0.1.0/Dockerfile +67 -0
  4. atrium_rag-0.1.0/LICENSE +21 -0
  5. atrium_rag-0.1.0/MANIFEST.in +42 -0
  6. atrium_rag-0.1.0/Makefile +59 -0
  7. atrium_rag-0.1.0/PKG-INFO +522 -0
  8. atrium_rag-0.1.0/README.md +453 -0
  9. atrium_rag-0.1.0/atrium/__init__.py +43 -0
  10. atrium_rag-0.1.0/atrium/adapters.py +798 -0
  11. atrium_rag-0.1.0/atrium/bm25.py +178 -0
  12. atrium_rag-0.1.0/atrium/cli.py +1478 -0
  13. atrium_rag-0.1.0/atrium/config.py +570 -0
  14. atrium_rag-0.1.0/atrium/embedder_config.py +121 -0
  15. atrium_rag-0.1.0/atrium/errors.py +39 -0
  16. atrium_rag-0.1.0/atrium/healthcheck.py +51 -0
  17. atrium_rag-0.1.0/atrium/job_store.py +371 -0
  18. atrium_rag-0.1.0/atrium/layout_adapter.py +265 -0
  19. atrium_rag-0.1.0/atrium/local_embedder.py +149 -0
  20. atrium_rag-0.1.0/atrium/local_store.py +394 -0
  21. atrium_rag-0.1.0/atrium/main.py +1828 -0
  22. atrium_rag-0.1.0/atrium/mime.py +212 -0
  23. atrium_rag-0.1.0/atrium/models.py +75 -0
  24. atrium_rag-0.1.0/atrium/ocr_adapter.py +305 -0
  25. atrium_rag-0.1.0/atrium/pdf_backend.py +687 -0
  26. atrium_rag-0.1.0/atrium/pipeline.py +269 -0
  27. atrium_rag-0.1.0/atrium/py.typed +3 -0
  28. atrium_rag-0.1.0/atrium/rerank_adapter.py +552 -0
  29. atrium_rag-0.1.0/atrium/retrieval.py +629 -0
  30. atrium_rag-0.1.0/atrium/security.py +246 -0
  31. atrium_rag-0.1.0/atrium/setup.py +1306 -0
  32. atrium_rag-0.1.0/atrium/smart_chunker.py +1271 -0
  33. atrium_rag-0.1.0/atrium/tsr_adapter.py +102 -0
  34. atrium_rag-0.1.0/atrium/ui.py +601 -0
  35. atrium_rag-0.1.0/atrium/universal_parser.py +2314 -0
  36. atrium_rag-0.1.0/atrium/vision_adapters.py +112 -0
  37. atrium_rag-0.1.0/atrium/worker.py +311 -0
  38. atrium_rag-0.1.0/atrium_rag.egg-info/PKG-INFO +522 -0
  39. atrium_rag-0.1.0/atrium_rag.egg-info/SOURCES.txt +46 -0
  40. atrium_rag-0.1.0/atrium_rag.egg-info/dependency_links.txt +1 -0
  41. atrium_rag-0.1.0/atrium_rag.egg-info/entry_points.txt +2 -0
  42. atrium_rag-0.1.0/atrium_rag.egg-info/requires.txt +55 -0
  43. atrium_rag-0.1.0/atrium_rag.egg-info/top_level.txt +1 -0
  44. atrium_rag-0.1.0/docker-compose.yml +86 -0
  45. atrium_rag-0.1.0/docs/images/benchmark.png +0 -0
  46. atrium_rag-0.1.0/docs/images/visualize.gif +0 -0
  47. atrium_rag-0.1.0/pyproject.toml +240 -0
  48. atrium_rag-0.1.0/setup.cfg +4 -0
@@ -0,0 +1,68 @@
1
+ # Configuration used by `docker compose`.
2
+ #
3
+ # This file is the container-side counterpart to your local `.env`:
4
+ # the hostnames differ (a container reaches services by service name,
5
+ # and the host machine by `host.docker.internal`), everything else is
6
+ # the same.
7
+ #
8
+ # `.env` on your machine is for running atrium directly (laptop, CI).
9
+ # This file is for `docker compose up`. Keep API_KEY empty here unless
10
+ # you are putting the stack behind a network you control.
11
+
12
+ # --- Vector database ------------------------------------------------------
13
+ # `qdrant` is the service name in docker-compose.yml. Use `pgvector`
14
+ # with the pgvector profile instead.
15
+ VECTOR_DB=qdrant
16
+ QDRANT_HOST=qdrant
17
+ QDRANT_PORT=6333
18
+ PG_CONN=postgresql://user:pass@pgvector:5432/db
19
+
20
+ # --- Embedding provider ---------------------------------------------------
21
+ # Ollama runs on the host, not in the compose network.
22
+ # `host.docker.internal` resolves on Docker Desktop (macOS + Windows).
23
+ # On Linux, add `extra_hosts: ["host.docker.internal:host-gateway"]`
24
+ # to the api service, or point this at a reachable Ollama host.
25
+ EMBED_BASE_URL=http://host.docker.internal:11434
26
+ EMBED_MODEL=bge-large
27
+ EMBED_DIM=1024
28
+
29
+ # --- Optional features ----------------------------------------------------
30
+ OCR_ENABLED=0
31
+ OCR_PROVIDER=tesseract
32
+ OCR_LANG=eng
33
+ TESSERACT_CMD=
34
+
35
+ RERANK_ENABLED=0
36
+ RERANK_PROVIDER=bge
37
+ RERANK_MODEL=
38
+ RERANK_BACKEND=
39
+ RERANK_DEVICE=
40
+ RERANK_MAX_LENGTH=512
41
+ FLASHRANK_CACHE_DIR=
42
+ COHERE_API_KEY=
43
+
44
+ VISION_ENABLED=0
45
+ VISION_MODEL=minicpm-v4.6:1b
46
+ VISION_TIMEOUT_SECONDS=180
47
+
48
+ # --- Retrieval / server ---------------------------------------------------
49
+ DEFAULT_TOP_K=8
50
+ DENSE_CONFIDENT_GAP=0.05
51
+ DENSE_MIN_SCORE=0.55
52
+ LOG_LEVEL=INFO
53
+ # The job queue lives on the shared `atrium-data` volume so the API
54
+ # and every worker see the same file.
55
+ JOB_DB_PATH=/data/jobs.db
56
+ JOB_STALE_SECONDS=1800
57
+ INGEST_CONCURRENCY=4
58
+ WORKER_POLL_BASE=1.0
59
+ WORKER_POLL_MAX=10.0
60
+ WORKER_JOB_TIMEOUT=0
61
+ RETRIEVAL_LAB_MAX_SESSIONS=16
62
+
63
+ # --- Limits / security ----------------------------------------------------
64
+ MAX_UPLOAD_BYTES=104857600
65
+ ALLOWED_MIME_TYPES=
66
+ ALLOW_CHUNKED_UPLOADS=0
67
+ API_KEY=
68
+ CORS_ALLOW_ORIGINS=
@@ -0,0 +1,169 @@
1
+ # atrium configuration template.
2
+ #
3
+ # cp .env.example .env # then edit
4
+ # atrium init # or let the wizard write it for you
5
+ #
6
+ # Every variable here is read by atrium/main.py, atrium/worker.py and
7
+ # the CLI. Lines starting with # are ignored; everything after a
8
+ # value's whitespace-# is a comment.
9
+ #
10
+ # Precedence: a real environment variable beats this file, and this
11
+ # file beats the built-in default. So `API_KEY=... uvicorn
12
+ # atrium.main:app` wins over whatever is written here.
13
+
14
+ # --- Vector database ------------------------------------------------------
15
+ # Choose one. Both backends implement the same retrieval protocol.
16
+ # qdrant — Qdrant
17
+ # pgvector — Postgres + pgvector
18
+ VECTOR_DB=sqlite
19
+
20
+ # Qdrant. Ignored unless VECTOR_DB=qdrant.
21
+ # Inside Docker Compose the hostname is the service name (`qdrant`);
22
+ # on a laptop it is `localhost`.
23
+ QDRANT_HOST=localhost
24
+ QDRANT_PORT=6333
25
+
26
+ # Postgres connection string. Ignored unless VECTOR_DB=pgvector.
27
+ # Format: postgresql://user:password@host:port/database
28
+ PG_CONN=postgresql://user:pass@pgvector:5432/db
29
+
30
+ # --- Embedding provider ---------------------------------------------------
31
+ # Any server that speaks the OpenAI /v1/embeddings API: Ollama, OpenAI,
32
+ # vLLM, LM Studio, TEI, Together. The base URL includes the /v1.
33
+ EMBED_BASE_URL=http://localhost:11434/v1
34
+
35
+ # The key for that endpoint. Blank for local servers; required by
36
+ # hosted providers.
37
+ EMBED_API_KEY=
38
+
39
+ # "http" for any OpenAI-compatible endpoint, "fastembed" for the
40
+ # in-process ONNX embedder from the `local` extra (no server, no key).
41
+ EMBED_PROVIDER=http
42
+
43
+ # Embedding model + dimension. Defaults match the published 19-set
44
+ # benchmark headline (bge-large / 1024). Override with care — promote
45
+ # embedder changes only after re-running the benchmark; see README.
46
+ EMBED_MODEL=bge-large
47
+ EMBED_DIM=1024
48
+
49
+ # --- Limits ---------------------------------------------------------------
50
+ # Ceilings on what one request and one document may cost. The upload
51
+ # cap bounds the bytes; these bound what those bytes turn into.
52
+ MAX_CHUNKS_PER_DOCUMENT=50000
53
+ MAX_PAGES_PER_DOCUMENT=10000
54
+ MAX_FILES_PER_REQUEST=32
55
+ # The preview endpoint returns the document's structure, not the corpus.
56
+ MAX_PREVIEW_CHUNKS=500
57
+ # The retrieval lab holds a document's chunks and embeddings in memory.
58
+ MAX_LAB_CHUNKS_PER_SESSION=5000
59
+ MAX_LAB_TOTAL_CHUNKS=50000
60
+
61
+ # --- Worker ---------------------------------------------------------------
62
+ # How many times a job may be attempted before it is given up on.
63
+ MAX_JOB_ATTEMPTS=3
64
+ # How long a finished job row is kept (its payload is dropped at once).
65
+ JOB_RETENTION_SECONDS=86400
66
+
67
+ # --- Where the local files live -------------------------------------------
68
+ # The API and the worker must agree on this, or they use different job
69
+ # stores and different corpora. Relative paths resolve against it.
70
+ ATRIUM_DATA_DIR=
71
+
72
+ # --- The address `atrium serve` binds -------------------------------------
73
+ # Loopback by default. Set 0.0.0.0 to serve beyond this machine.
74
+ ATRIUM_BIND=127.0.0.1
75
+
76
+ # --- Local vector store ----------------------------------------------------
77
+ # The SQLite file used when VECTOR_DB=sqlite. Nothing else is needed:
78
+ # no server, no Docker.
79
+ LOCAL_DB_PATH=atrium_local.db
80
+
81
+ # --- Vision (optional) ----------------------------------------------------
82
+ # VISION_ENABLED=1 captions image-only pages and diagrams with a
83
+ # vision model during parsing. Costs a lot of time on document-heavy
84
+ # corpora; off by default.
85
+ VISION_ENABLED=0
86
+ VISION_MODEL=minicpm-v4.6:1b
87
+ VISION_TIMEOUT_SECONDS=180
88
+
89
+ # --- OCR (optional) -------------------------------------------------------
90
+ # OCR_ENABLED=1 turns on OCR for scanned pages and image-only docs.
91
+ # Requires `pip install atrium[ocr]` and (for Tesseract) the
92
+ # Tesseract binary on PATH — see README.
93
+ OCR_ENABLED=0
94
+ OCR_PROVIDER=tesseract # or rapidocr
95
+ OCR_LANG=eng
96
+ # Path to the Tesseract binary. Empty = look it up on PATH.
97
+ TESSERACT_CMD=
98
+
99
+ # --- Reranking (optional) -------------------------------------------------
100
+ # RERANK_ENABLED=1 turns on cross-encoder reranking for /search.
101
+ # Requires `pip install atrium[rerank]` (or [flashrank]).
102
+ RERANK_ENABLED=0
103
+ RERANK_PROVIDER=bge # bge | flashrank | cohere
104
+ RERANK_MODEL=
105
+ RERANK_DEVICE= # bge only: cpu | cuda | mps
106
+ RERANK_BACKEND= # cohere | flashrank | bge-local
107
+ RERANK_MAX_LENGTH=512
108
+ FLASHRANK_CACHE_DIR=
109
+ COHERE_API_KEY=
110
+
111
+ # --- Retrieval ------------------------------------------------------------
112
+ # Default top-k for /search and `atrium search`. The v0.0.1 headline
113
+ # uses 8 — the top-k sweep on the 19-fixture benchmark showed k=8
114
+ # captures 5 more queries than k=5 for 1.6x the scoring cost.
115
+ DEFAULT_TOP_K=8
116
+
117
+ # Thresholds for the dense-confidence gate. The gate decides when the
118
+ # optional BM25 sparse ranker is consulted on top of the dense one.
119
+ # Raising either one makes the gate stricter (more BM25 consulted).
120
+ DENSE_CONFIDENT_GAP=0.05
121
+ DENSE_MIN_SCORE=0.55
122
+
123
+ # --- Server ---------------------------------------------------------------
124
+ # LOG_LEVEL=DEBUG|INFO|WARNING|ERROR
125
+ LOG_LEVEL=INFO
126
+
127
+ # Where the async-job queue lives. A single SQLite file, shared by the
128
+ # API and every worker. To run workers on other hosts, put this file on
129
+ # a shared volume (NFS, a mounted PVC) — there is no Postgres job store.
130
+ JOB_DB_PATH=jobs.db
131
+
132
+ # How long a job may sit in `running` before a worker hands it back to
133
+ # the queue (seconds). Set it above the slowest document you expect:
134
+ # a 500-page PDF can take minutes, and reclaiming it early means two
135
+ # workers ingest the same document.
136
+ JOB_STALE_SECONDS=1800
137
+
138
+ # How many documents may be ingested at once.
139
+ INGEST_CONCURRENCY=4
140
+
141
+ # Worker poll backoff (seconds) and per-job timeout. 0 = no timeout.
142
+ WORKER_POLL_BASE=1.0
143
+ WORKER_POLL_MAX=10.0
144
+ WORKER_JOB_TIMEOUT=0
145
+
146
+ # How many retrieval-lab sessions to keep in RAM.
147
+ RETRIEVAL_LAB_MAX_SESSIONS=16
148
+
149
+ # --- Limits ---------------------------------------------------------------
150
+ # Maximum upload size in bytes (default 100 MB). Uploads larger than
151
+ # this are rejected with 413 before being read into memory.
152
+ MAX_UPLOAD_BYTES=104857600
153
+
154
+ # Allowed MIME types for upload (comma-separated). Empty = allow any
155
+ # detected by the built-in format detector. Set explicitly in prod for
156
+ # tighter validation.
157
+ ALLOWED_MIME_TYPES=
158
+
159
+ # Accept uploads without a Content-Length header.
160
+ ALLOW_CHUNKED_UPLOADS=0
161
+
162
+ # --- API auth (optional) --------------------------------------------------
163
+ # Set API_KEY to require `Authorization: Bearer <key>` on all routes
164
+ # except /health. Empty = no auth (dev only).
165
+ API_KEY=
166
+
167
+ # --- CORS -----------------------------------------------------------------
168
+ # Comma-separated origin allowlist. Empty = same-origin only.
169
+ CORS_ALLOW_ORIGINS=
@@ -0,0 +1,67 @@
1
+ # Atrium — container image.
2
+ #
3
+ # The image installs from pyproject.toml, not requirements.txt: the
4
+ # distribution metadata is the source of truth for what "atrium" is,
5
+ # and requirements.txt is a dev convenience that had already drifted
6
+ # from it (pinned floors vs. ranges).
7
+ #
8
+ # docker build -t atrium-rag .
9
+ # docker build -t atrium-rag --build-arg EXTRAS="ocr,rerank" .
10
+ #
11
+ # The runtime image needs libmagic (python-magic's native library) and
12
+ # nothing else from the OS. Tesseract is deliberately NOT installed:
13
+ # it is a host-level binary, the `ocr` extra is opt-in, and shipping it
14
+ # would add ~30 MB to every image for a feature most deployments do
15
+ # not use. If you want OCR in the container, either use the
16
+ # `rapidocr` provider (pure pip) or build a derived image that adds
17
+ # `apt-get install tesseract-ocr`.
18
+
19
+ FROM python:3.12-slim AS base
20
+
21
+ # libmagic: python-magic's native library. Without it the MIME
22
+ # detector falls back to the extension table, which is fine but
23
+ # weaker.
24
+ RUN apt-get update \
25
+ && apt-get install -y --no-install-recommends libmagic1 \
26
+ && rm -rf /var/lib/apt/lists/*
27
+
28
+ ENV PYTHONUNBUFFERED=1 \
29
+ PYTHONDONTWRITEBYTECODE=1 \
30
+ PIP_NO_CACHE_DIR=1 \
31
+ PIP_DISABLE_PIP_VERSION_CHECK=1
32
+
33
+ WORKDIR /app
34
+
35
+ # Optional extras, e.g. --build-arg EXTRAS="ocr,rerank".
36
+ ARG EXTRAS=""
37
+
38
+ # Dependencies first: this layer is cached until pyproject.toml
39
+ # changes, so a code-only edit doesn't reinstall the world.
40
+ COPY pyproject.toml README.md LICENSE MANIFEST.in ./
41
+ COPY atrium ./atrium
42
+ RUN if [ -n "$EXTRAS" ]; then \
43
+ pip install --no-cache-dir ".[$EXTRAS]"; \
44
+ else \
45
+ pip install --no-cache-dir .; \
46
+ fi
47
+
48
+ # Non-root. The API writes one file (the SQLite job queue) and needs
49
+ # a writable HOME for model caches.
50
+ RUN useradd --create-home --uid 10001 atrium \
51
+ && mkdir -p /data \
52
+ && chown -R atrium:atrium /app /data
53
+ USER atrium
54
+
55
+ # The job queue lives here. Mount a volume to keep job history across
56
+ # container restarts, and to share the queue with a worker container.
57
+ ENV JOB_DB_PATH=/data/jobs.db \
58
+ OLLAMA_BASE_URL=http://host.docker.internal:11434 \
59
+ QDRANT_HOST=qdrant
60
+
61
+ VOLUME ["/data"]
62
+ EXPOSE 8000
63
+
64
+ HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
65
+ CMD ["python", "-m", "atrium.healthcheck"]
66
+
67
+ CMD ["uvicorn", "atrium.main:app", "--host", "0.0.0.0", "--port", "8000"]
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Atrium contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,42 @@
1
+ # Files to include in the source distribution (sdist) but not
2
+ # covered by setuptools' defaults.
3
+
4
+ # README + LICENSE.
5
+ include README.md
6
+ include LICENSE
7
+
8
+ # Operational files referenced in the docs.
9
+ include Dockerfile
10
+ include docker-compose.yml
11
+ include Makefile
12
+ include .env.example
13
+ include .env.docker
14
+
15
+ # Type marker so mypy/PEP 561 understands the package.
16
+ include atrium/py.typed
17
+
18
+ # Exclude dev/test/build artifacts from sdist.
19
+ exclude .github
20
+ prune tests
21
+ exclude scripts
22
+ exclude docs
23
+ exclude .venv
24
+ exclude venv
25
+ exclude __pycache__
26
+ exclude .pytest_cache
27
+ exclude .mypy_cache
28
+ exclude .ruff_cache
29
+ exclude .git
30
+ exclude .gitignore
31
+ exclude .dockerignore
32
+ exclude .DS_Store
33
+ exclude *.pyc
34
+ exclude *.pyo
35
+ recursive-exclude * __pycache__
36
+ recursive-exclude * *.pyc
37
+
38
+ # The README's images travel with it: the PyPI page renders the README
39
+ # from the sdist, and a relative path to a file that is not there is a
40
+ # broken image on the front page of the project.
41
+ include docs/images/*.png
42
+ include docs/images/*.gif
@@ -0,0 +1,59 @@
1
+ # Development tasks for atrium.
2
+ #
3
+ # make install install the package + dev extras
4
+ # make test run the unit suite
5
+ # make lint ruff
6
+ # make typecheck mypy (advisory — see pyproject.toml)
7
+ # make build build the wheel + sdist
8
+ # make shot regenerate the README benchmark image
9
+ # make docker build the container image
10
+
11
+ PYTHON ?= python3
12
+ VENV ?= venv
13
+ PIP := $(VENV)/bin/pip
14
+ PYTEST := $(VENV)/bin/pytest
15
+ RUFF := $(VENV)/bin/ruff
16
+ MYPY := $(VENV)/bin/mypy
17
+
18
+ .PHONY: install test lint format typecheck build shot smoke docker clean
19
+
20
+ install:
21
+ $(PIP) install -e ".[dev]"
22
+
23
+ test:
24
+ $(PYTEST) tests/ -q
25
+
26
+ lint:
27
+ $(RUFF) check atrium tests scripts
28
+
29
+ format:
30
+ $(RUFF) check atrium tests scripts --fix
31
+
32
+ typecheck:
33
+ $(MYPY) atrium
34
+
35
+ build:
36
+ $(VENV)/bin/python -m build
37
+ $(VENV)/bin/twine check dist/*
38
+
39
+ # Install the built wheel into a throwaway environment and run the
40
+ # smoke test against it — the artifact a user gets, not the source
41
+ # tree. This is what CI's "Install the built artifact" job does.
42
+ smoke:
43
+ $(VENV)/bin/python -m build --wheel
44
+ rm -rf /tmp/atrium-smoke
45
+ $(PYTHON) -m venv /tmp/atrium-smoke
46
+ /tmp/atrium-smoke/bin/pip install --quiet dist/*.whl
47
+ cd /tmp && /tmp/atrium-smoke/bin/python $(CURDIR)/scripts/smoke_test.py
48
+
49
+ # Regenerate docs/images/benchmark.png from the published run's raw
50
+ # JSON. The README image must stay in step with the data behind it.
51
+ shot:
52
+ $(VENV)/bin/python scripts/render_benchmark_shot.py
53
+
54
+ docker:
55
+ docker build -t atrium-rag .
56
+
57
+ clean:
58
+ rm -rf build dist *.egg-info
59
+ find . -name '__pycache__' -type d -prune -exec rm -rf {} +