fix(package): review pass on the PyPI package

- docsgpt api binds 127.0.0.1 by default, like gunicorn and uvicorn do;
  --host 0.0.0.0 exposes it. The docs say so.
- The embedded Milvus and LanceDB defaults derive from the data home, so
  they follow DOCSGPT_HOME like the faiss indexes and uploads do. A checkout
  run from its root and the Docker image resolve to the same paths as before.
- The docs and the pyproject comment describe the CPU torch install as two
  steps (torch and torchvision from the PyTorch CPU index first, then the
  docling extra): pip picks the highest version across indexes, so
  --extra-index-url only yields the CPU build while that index keeps pace
  with PyPI.
- AGENTS.md separates DOCSGPT_HOME (moves the data home) from
  DOCSGPT_ENV_FILE (selects the .env file); the docs example uses a password
  placeholder.
This commit is contained in:
Alex committed 2026-09-07 15:25:30 +01:00
1 parent bea26336f8
commit ae9348bb2a
7 files changed
+43 -12

No files matched your search

+3 -2
View File
@@ -41,8 +41,9 @@ The backend is also an installable package (`pyproject.toml`, hatchling).
`uv sync` installs it editable and puts a `docsgpt` command on PATH:
`docsgpt api --reload`, `docsgpt worker`, `docsgpt migrate`,
`docsgpt prefetch-models`, `docsgpt verify-offline`. Runtime data (`.env`,
`inputs/`, `indexes/`) lives in the checkout by default; `DOCSGPT_HOME` and
`DOCSGPT_ENV_FILE` move it (see `docsgpt/core/paths.py`).
`inputs/`, `indexes/`) lives in the checkout by default; `DOCSGPT_HOME` moves
that data home, and `DOCSGPT_ENV_FILE` selects only the `.env` file (see
`docsgpt/core/paths.py`).
Dependencies are declared in `pyproject.toml` and locked in `uv.lock`; the
`docsgpt/requirements*.txt` files are exported from the lock. To add or
+12 -3
View File
@@ -34,7 +34,14 @@ pip install "docsgpt[docling]" # DOC_PARSER_ENGINE=docling: OCR backend, struc
pip install "docsgpt[milvus]" # VECTOR_STORE=milvus
```
The `docling` extra pulls in PyTorch. On Linux, PyPI's torch wheels bring the CUDA stack with them; on a CPU-only machine add `--extra-index-url https://download.pytorch.org/whl/cpu` to the install command to get the CPU build instead. `uv pip install` and `pipx install` work the same way.
The `docling` extra pulls in PyTorch, and on Linux the PyPI torch wheels bring the CUDA stack with them. On a CPU-only machine install the CPU build first, then the extra; pip keeps the torch it already has:
```bash
pip install --index-url https://download.pytorch.org/whl/cpu torch torchvision
pip install "docsgpt[docling]"
```
`uv pip install` accepts the same two commands. With `pipx`, install `docsgpt[docling]` and then run `pipx inject --index-url https://download.pytorch.org/whl/cpu docsgpt torch torchvision` to swap the CUDA build for the CPU one.
## Configure
@@ -49,7 +56,7 @@ LLM_NAME=<model name>
API_KEY=<provider API key>
# User data
POSTGRES_URI=postgresql://docsgpt:docsgpt@localhost:5432/docsgpt
POSTGRES_URI=postgresql://docsgpt:<password>@localhost:5432/docsgpt
# Worker-to-API authentication (required for uploads)
INTERNAL_KEY=<a long random string>
@@ -61,10 +68,12 @@ Redis defaults to `localhost:6379` (`CELERY_BROKER_URL`, `CELERY_RESULT_BACKEND`
```bash
docsgpt migrate # create the database if it is missing and apply the migrations
docsgpt api # the API on http://localhost:7091
docsgpt api # the API on http://127.0.0.1:7091
docsgpt worker # in a second terminal: the Celery worker, with the scheduler
```
`docsgpt api` listens on localhost only. Pass `--host 0.0.0.0` to accept connections from other machines or containers, and put a reverse proxy with TLS in front of it for anything public.
The API applies pending migrations when it starts (`AUTO_MIGRATE`), so `docsgpt migrate` is the explicit step for deployments that want the schema in place before the first request or that run the API with a restricted database role.
The worker is not optional: query embedding runs on it, so search fails without one. `docsgpt worker --help` lists the queue, concurrency and pool options; `--no-beat` starts a worker without the scheduler when another worker already runs it.
+2 -2
View File
@@ -14,7 +14,7 @@ from typing import Optional, Sequence
from docsgpt.version import __version__
DEFAULT_HOST = "0.0.0.0"
DEFAULT_HOST = "127.0.0.1"
DEFAULT_PORT = 7091
DEFAULT_QUEUES = "docsgpt,parsing,embeddings"
@@ -105,7 +105,7 @@ def build_parser() -> argparse.ArgumentParser:
commands = parser.add_subparsers(dest="command", metavar="<command>")
api = commands.add_parser("api", help="serve the HTTP API")
api.add_argument("--host", default=DEFAULT_HOST)
api.add_argument("--host", default=DEFAULT_HOST, help="interface to listen on (default: localhost; 0.0.0.0 for all)")
api.add_argument("--port", type=int, default=DEFAULT_PORT)
api.add_argument("--workers", type=int, default=1, help="gunicorn worker processes (default: 1)")
api.add_argument("--reload", action="store_true", help="development mode: uvicorn with auto-reload")
+3 -2
View File
@@ -326,11 +326,12 @@ class Settings(BaseSettings):
PGVECTOR_IVFFLAT_PROBES: Optional[int] = None
# Milvus vectorstore config
MILVUS_COLLECTION_NAME: Optional[str] = "docsgpt"
MILVUS_URI: Optional[str] = "./milvus_local.db" # milvus lite version as default
# milvus-lite (embedded) database file, under the data home like the other local stores
MILVUS_URI: Optional[str] = Field(default_factory=lambda: str(home_dir() / "milvus_local.db"))
MILVUS_TOKEN: Optional[str] = ""
# LanceDB vectorstore config
LANCEDB_PATH: str = "./data/lancedb" # Path where LanceDB stores its local data
LANCEDB_PATH: str = Field(default_factory=lambda: str(home_dir() / "data" / "lancedb")) # LanceDB local data
LANCEDB_TABLE_NAME: Optional[str] = "docsgpts" # Name of the table to use for storing vectors
FLASK_DEBUG_MODE: bool = False
+3 -2
View File
@@ -122,8 +122,9 @@ dependencies = [
# attachment parsing, and read_document's `structured` output. Pulls torch and
# transformers; with uv on Linux torch resolves from the CPU-only PyTorch index
# (see [tool.uv.sources]) so the extra does not drag the CUDA stack in. pip
# users on Linux get the same by adding
# --extra-index-url https://download.pytorch.org/whl/cpu.
# users on Linux install torch and torchvision from that index first
# (--index-url https://download.pytorch.org/whl/cpu), then the extra; pip keeps
# the torch it already has.
docling = [
"docling>=2.119.0,<3",
"rapidocr>=3.9.2,<4",
+19
View File
@@ -36,6 +36,25 @@ class TestEnvFile:
assert paths.env_file() == tmp_path / "custom.env"
class TestSettingsFollowTheHome:
def test_embedded_vector_stores_default_under_the_home(self, monkeypatch, tmp_path):
from docsgpt.core.settings import Settings
monkeypatch.setenv(paths.HOME_ENV, str(tmp_path))
monkeypatch.delenv("MILVUS_URI", raising=False)
monkeypatch.delenv("LANCEDB_PATH", raising=False)
fresh = Settings(_env_file=None)
assert fresh.MILVUS_URI == str(tmp_path.resolve() / "milvus_local.db")
assert fresh.LANCEDB_PATH == str(tmp_path.resolve() / "data" / "lancedb")
def test_env_overrides_still_win(self, monkeypatch, tmp_path):
from docsgpt.core.settings import Settings
monkeypatch.setenv(paths.HOME_ENV, str(tmp_path))
monkeypatch.setenv("LANCEDB_PATH", "/srv/lancedb")
assert Settings(_env_file=None).LANCEDB_PATH == "/srv/lancedb"
class TestPackageDir:
def test_holds_the_shipped_data(self):
assert paths.package_dir().name == "docsgpt"
+1 -1
View File
@@ -43,7 +43,7 @@ class TestApi:
run.assert_called_once_with()
argv = sys.argv
assert argv[0] == "gunicorn" and argv[-1] == "docsgpt.asgi:asgi_app"
assert argv[argv.index("--bind") + 1] == "0.0.0.0:8000"
assert argv[argv.index("--bind") + 1] == "127.0.0.1:8000"
assert argv[argv.index("-w") + 1] == "2"
assert argv[argv.index("-k") + 1] == "docsgpt.gunicorn_worker.BoundedDrainUvicornWorker"
assert argv[argv.index("--config") + 1] == "python:docsgpt.gunicorn_conf"