Zubaish commited on
Commit
2d4b429
·
1 Parent(s): b713a11

Fix Docker build: create kb_docs at runtime

Browse files
Files changed (4) hide show
  1. Dockerfile +7 -6
  2. app.py +1 -5
  3. ingest.py +7 -1
  4. rag.py +19 -17
Dockerfile CHANGED
@@ -1,22 +1,23 @@
1
  FROM python:3.10-slim
2
 
3
- # Set working directory
4
  WORKDIR /app
5
 
6
- # Install system dependencies
7
  RUN apt-get update && apt-get install -y \
8
  git \
9
  && rm -rf /var/lib/apt/lists/*
10
 
11
- # Install Python dependencies
12
  COPY requirements.txt .
13
  RUN pip install --no-cache-dir -r requirements.txt
14
 
15
- # Copy application code
16
  COPY app.py rag.py ingest.py guardrails.py config.py ./
17
- COPY kb_docs ./kb_docs
18
 
19
- # Hugging Face Spaces expects port 7860
 
 
 
20
  EXPOSE 7860
21
 
22
  # Start FastAPI
 
1
  FROM python:3.10-slim
2
 
 
3
  WORKDIR /app
4
 
5
+ # System dependencies
6
  RUN apt-get update && apt-get install -y \
7
  git \
8
  && rm -rf /var/lib/apt/lists/*
9
 
10
+ # Python dependencies
11
  COPY requirements.txt .
12
  RUN pip install --no-cache-dir -r requirements.txt
13
 
14
+ # Application code
15
  COPY app.py rag.py ingest.py guardrails.py config.py ./
 
16
 
17
+ # Create empty kb_docs directory (PDFs added later via HF UI)
18
+ RUN mkdir -p kb_docs
19
+
20
+ # Hugging Face Spaces port
21
  EXPOSE 7860
22
 
23
  # Start FastAPI
app.py CHANGED
@@ -1,6 +1,5 @@
1
  from fastapi import FastAPI
2
  from pydantic import BaseModel
3
-
4
  from rag import ask_rag_with_status
5
 
6
  app = FastAPI(title="HubRAG API")
@@ -10,10 +9,7 @@ class Question(BaseModel):
10
 
11
  @app.get("/")
12
  def root():
13
- return {
14
- "status": "ok",
15
- "message": "RAG API is running"
16
- }
17
 
18
  @app.post("/chat")
19
  def chat(req: Question):
 
1
  from fastapi import FastAPI
2
  from pydantic import BaseModel
 
3
  from rag import ask_rag_with_status
4
 
5
  app = FastAPI(title="HubRAG API")
 
9
 
10
  @app.get("/")
11
  def root():
12
+ return {"status": "ok", "message": "RAG API running"}
 
 
 
13
 
14
  @app.post("/chat")
15
  def chat(req: Question):
ingest.py CHANGED
@@ -1,7 +1,11 @@
1
  from langchain_community.document_loaders import DirectoryLoader, PyPDFLoader
2
  from langchain_text_splitters import RecursiveCharacterTextSplitter
 
3
 
4
  def load_and_split_docs(path="kb_docs"):
 
 
 
5
  loader = DirectoryLoader(
6
  path,
7
  glob="**/*.pdf",
@@ -9,9 +13,11 @@ def load_and_split_docs(path="kb_docs"):
9
  )
10
  docs = loader.load()
11
 
 
 
 
12
  splitter = RecursiveCharacterTextSplitter(
13
  chunk_size=800,
14
  chunk_overlap=100
15
  )
16
-
17
  return splitter.split_documents(docs)
 
1
  from langchain_community.document_loaders import DirectoryLoader, PyPDFLoader
2
  from langchain_text_splitters import RecursiveCharacterTextSplitter
3
+ import os
4
 
5
  def load_and_split_docs(path="kb_docs"):
6
+ if not os.path.exists(path):
7
+ return []
8
+
9
  loader = DirectoryLoader(
10
  path,
11
  glob="**/*.pdf",
 
13
  )
14
  docs = loader.load()
15
 
16
+ if not docs:
17
+ return []
18
+
19
  splitter = RecursiveCharacterTextSplitter(
20
  chunk_size=800,
21
  chunk_overlap=100
22
  )
 
23
  return splitter.split_documents(docs)
rag.py CHANGED
@@ -4,46 +4,48 @@ from langchain.schema import SystemMessage, HumanMessage
4
 
5
  from ingest import load_and_split_docs
6
 
7
- print("⏳ Indexing documents...")
8
-
9
- embeddings = HuggingFaceEmbeddings(
10
- model_name="sentence-transformers/all-MiniLM-L6-v2"
11
- )
12
 
13
  documents = load_and_split_docs()
14
 
15
- vectorstore = Chroma.from_documents(
16
- documents,
17
- embedding=embeddings
18
  )
19
 
20
- retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
 
 
 
 
 
 
 
21
 
22
  llm = ChatHuggingFace(
23
  repo_id="microsoft/Phi-4-mini-instruct",
24
  temperature=0.2
25
  )
26
 
27
- print("✅ Indexing complete.")
28
 
29
  def ask_rag_with_status(question: str):
30
- status = [
31
- "🔍 Retrieving relevant documents...",
32
- "🧠 Building context...",
33
- "💭 Thinking..."
34
- ]
35
 
36
  docs = retriever.get_relevant_documents(question)
37
  context = "\n\n".join(d.page_content for d in docs)
38
 
39
  messages = [
40
- SystemMessage(content="You are a helpful assistant. Answer using the context."),
41
  HumanMessage(content=f"Context:\n{context}\n\nQuestion: {question}")
42
  ]
43
 
44
  response = llm.invoke(messages)
45
 
46
  return {
47
- "status": status,
48
  "answer": response.content
49
  }
 
4
 
5
  from ingest import load_and_split_docs
6
 
7
+ print("⏳ Loading documents...")
 
 
 
 
8
 
9
  documents = load_and_split_docs()
10
 
11
+ embeddings = HuggingFaceEmbeddings(
12
+ model_name="sentence-transformers/all-MiniLM-L6-v2"
 
13
  )
14
 
15
+ if documents:
16
+ vectorstore = Chroma.from_documents(
17
+ documents,
18
+ embedding=embeddings
19
+ )
20
+ retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
21
+ else:
22
+ retriever = None
23
 
24
  llm = ChatHuggingFace(
25
  repo_id="microsoft/Phi-4-mini-instruct",
26
  temperature=0.2
27
  )
28
 
29
+ print("✅ RAG initialized.")
30
 
31
  def ask_rag_with_status(question: str):
32
+ if not retriever:
33
+ return {
34
+ "status": ["⚠️ No documents uploaded yet"],
35
+ "answer": "Please upload PDF files to the kb_docs folder."
36
+ }
37
 
38
  docs = retriever.get_relevant_documents(question)
39
  context = "\n\n".join(d.page_content for d in docs)
40
 
41
  messages = [
42
+ SystemMessage(content="Answer using the provided context."),
43
  HumanMessage(content=f"Context:\n{context}\n\nQuestion: {question}")
44
  ]
45
 
46
  response = llm.invoke(messages)
47
 
48
  return {
49
+ "status": ["🔍 Retrieved documents", "🧠 Generating answer"],
50
  "answer": response.content
51
  }