Packaging and distribution

AutoRAG is distributed from GitHub, not PyPI. Consumers pin to a git tag:

pip install "autorag[all] @ git+https://github.com/AutoLogger/AutoRAG@v0.10.0"

Build backend: uv_build. The package layout is the standard src/ shape:

src/autorag/             # importable package
src/autorag/static/viz/  # committed React bundle (shipped in the wheel)
frontend/                # React source — not shipped

Releasing a new version

  1. Bump __version__ in src/autorag/__init__.py and version in pyproject.toml.

  2. Run uv lock to refresh the lock file. Commit.

  3. git tag v0.x.0 && git push --tags.

Consumers then pin to the tag.

CI

.github/workflows/ci.yml runs on every push and PR to main. Three parallel jobs:

  • Lint & Type Checkruff check, ruff format --check, mypy (installs --all-extras so mypy can see torch / chromadb / etc.).

  • Tests (all extras)pytest -v against the full dep stack.

  • SDK base install (no extras)uv sync --frozen --no-dev, then asserts from autorag import AutoRAG boots and the SDK methods are callable. This is the regression guard for the lazy-import contract — if anyone re-introduces a chromadb / torch / whisper / pyannote / yt_dlp import at module top in core.py / embed.py / __init__.py / store.py / audio_source.py, this job fails.

The workflow uses uv sync --frozen (fails if uv.lock is out of sync with pyproject.toml). If you change dependencies, run uv lock locally before pushing.

Docs build

Local build:

uv sync --group docs
uv run make -C docs strict        # treats warnings as errors

The [docs] extra (sphinx, furo, sphinx-autodoc-typehints, myst-parser) lives in [dependency-groups] rather than [project.optional-dependencies] so it doesn’t appear in published wheels — docs aren’t a runtime extra.

docs/conf.py mirrors the runtime extras in autodoc_mock_imports so the strict docs build works from a base+docs install too (no extras). When you add a new extras-gated import, add it to that list as well — same rule as the mypy overrides and the [tool.pyright] config.

CI also builds and publishes the docs to GitHub Pages via .github/workflows/docs.yml. On push to main (path-filtered to docs/**, src/autorag/**, pyproject.toml, uv.lock, and the workflow itself) plus workflow_dispatch, it runs uv sync --frozen --group docs, make -C docs strict, drops a .nojekyll, and publishes docs/_build/html to GitHub Pages with the official upload-pages-artifact / deploy-pages actions (build + deploy jobs, concurrency: pages, cancel-in-progress: false). It installs base + docs only, so it doubles as a second guard that the autodoc_mock_imports list stays complete. Requires Settings → Pages → Source = “GitHub Actions” (one-time, UI-only); served at https://autologger.github.io/AutoRAG/.

Pydantic schemas + TYPE_CHECKING

Pydantic API-schema models (src/autorag/schemas.py) resolve field annotations at runtime, so imports used only in their annotations (e.g. pathlib.Path) must stay as runtime imports — never moved into a TYPE_CHECKING block. [tool.ruff.lint.flake8-type-checking] runtime-evaluated-base-classes = ["pydantic.BaseModel"] stops TC003 from auto-suggesting that move; doing it anyway leaves the model “not fully defined” and breaks model_rebuild() / FastAPI schema gen / the autodoc build.

Third-party stubs

These packages have no stubs — covered by mypy ignore_missing_imports overrides in pyproject.toml:

  • whisperx, faster_whisper, umap, pydantic_sqlite, imageio_ffmpeg, chromadb, pyannote, yt_dlp.

langchain-ollama and langchain-core ship inline types — no overrides needed. sklearn has no stubs and is suppressed with # type: ignore[import-untyped] at each import site.

Pylance / Pyright

.vscode/settings.json enables Pylance with typeCheckingMode: "strict". Pylance doesn’t read mypy overrides, so [tool.pyright] in pyproject.toml mirrors them: reportMissingTypeStubs = "none" for the unstubbed third-party set, and reportPrivateUsage = "none" for the pydantic_sqlite._db access. It also disables reportUnknownArgumentType / VariableType / MemberType, since mypy strict already catches the cases the codebase cares about and Pylance’s strict mode flags Any propagation more aggressively than wanted.

If you add a new untyped third-party dep: add it to both the mypy overrides and the pyright config — reportMissingTypeStubs = "none" covers all unstubbed deps in one shot.