Fix cold-start crash: probe vector store via filesystem, not a Chroma client
Browse filesensure_index() opened a Chroma client to check for documents, which created
an empty database and held it open. chromadb caches clients per path, so the
subsequent rebuild deleted the directory out from under the cached client and
Chroma.from_documents crashed with sqlite 'unable to open database file'
(code 14) on fresh deployments. Check for chroma.sqlite3 on disk instead.
Also remove the unused Dockerfile left over from the Space template (the
Space runs with sdk: streamlit from README frontmatter; the Dockerfile
referenced a nonexistent src/streamlit_app.py).
- Dockerfile +0 -20
- src/rag.py +8 -8
Dockerfile
DELETED
|
@@ -1,20 +0,0 @@
|
|
| 1 |
-
FROM python:3.13.5-slim
|
| 2 |
-
|
| 3 |
-
WORKDIR /app
|
| 4 |
-
|
| 5 |
-
RUN apt-get update && apt-get install -y \
|
| 6 |
-
build-essential \
|
| 7 |
-
curl \
|
| 8 |
-
git \
|
| 9 |
-
&& rm -rf /var/lib/apt/lists/*
|
| 10 |
-
|
| 11 |
-
COPY requirements.txt ./
|
| 12 |
-
COPY src/ ./src/
|
| 13 |
-
|
| 14 |
-
RUN pip3 install -r requirements.txt
|
| 15 |
-
|
| 16 |
-
EXPOSE 8501
|
| 17 |
-
|
| 18 |
-
HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
|
| 19 |
-
|
| 20 |
-
ENTRYPOINT ["streamlit", "run", "src/streamlit_app.py", "--server.port=8501", "--server.address=0.0.0.0"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/rag.py
CHANGED
|
@@ -52,21 +52,21 @@ def get_vectorstore() -> Chroma:
|
|
| 52 |
|
| 53 |
|
| 54 |
def ensure_index() -> None:
|
| 55 |
-
"""Build the vector store on first run if it'
|
| 56 |
|
| 57 |
Lets the app bootstrap itself on a fresh deployment (e.g. Hugging Face
|
| 58 |
Spaces). On normal runs where the store already exists, this is a fast
|
| 59 |
no-op.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
"""
|
| 61 |
-
|
| 62 |
-
has_docs = len(get_vectorstore().get(limit=1).get("ids", [])) > 0
|
| 63 |
-
except Exception:
|
| 64 |
-
has_docs = False
|
| 65 |
-
if not has_docs:
|
| 66 |
-
get_vectorstore.cache_clear() # release the empty store handle
|
| 67 |
from src.ingest import build_index
|
| 68 |
build_index()
|
| 69 |
-
get_vectorstore.cache_clear() # reopen the freshly built store
|
| 70 |
|
| 71 |
|
| 72 |
@lru_cache(maxsize=1)
|
|
|
|
| 52 |
|
| 53 |
|
| 54 |
def ensure_index() -> None:
|
| 55 |
+
"""Build the vector store on first run if it doesn't exist yet.
|
| 56 |
|
| 57 |
Lets the app bootstrap itself on a fresh deployment (e.g. Hugging Face
|
| 58 |
Spaces). On normal runs where the store already exists, this is a fast
|
| 59 |
no-op.
|
| 60 |
+
|
| 61 |
+
IMPORTANT: this checks the filesystem instead of opening a Chroma client.
|
| 62 |
+
Probing with a client would create an empty database and keep it open --
|
| 63 |
+
and because chromadb caches clients per path, the subsequent rebuild
|
| 64 |
+
(delete + recreate the directory) would leave that cached client pointing
|
| 65 |
+
at deleted files, crashing with "unable to open database file".
|
| 66 |
"""
|
| 67 |
+
if not (config.VECTORSTORE_DIR / "chroma.sqlite3").exists():
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
from src.ingest import build_index
|
| 69 |
build_index()
|
|
|
|
| 70 |
|
| 71 |
|
| 72 |
@lru_cache(maxsize=1)
|