AuthorBot commited on
Commit
9eb7e65
Β·
1 Parent(s): 0cadd33

Fix: replace Celery dispatch with asyncio.create_task for ingestion - books now properly marked ready + chatbot responds correctly

Browse files
Files changed (2) hide show
  1. app/api/ingest.py +27 -13
  2. app/services/rag_pipeline.py +1 -1
app/api/ingest.py CHANGED
@@ -77,15 +77,22 @@ async def upload_book(
77
  })
78
  await db.commit()
79
 
80
- # R-082: Dispatch to Celery for crash resilience, retries, and worker isolation
81
- from app.tasks.ingestion_task import process_document
82
- process_document.delay(
83
- document_id=doc.id,
84
- author_id=current_user.id,
85
- book_id=book.id,
86
- file_path=str(tmp_path),
87
- file_extension=suffix.lstrip("."),
88
- )
 
 
 
 
 
 
 
89
 
90
  return {"book_id": book.id, "doc_id": doc.id, "status": "processing"}
91
 
@@ -149,9 +156,11 @@ async def _run_ingestion(
149
  redis,
150
  db: AsyncSession,
151
  ) -> None:
152
- """Full async ingestion: validate β†’ parse β†’ chunk β†’ embed β†’ summarize."""
153
  channel = f"ingestion:{author_id}:{book_id}"
154
  book_repo = BookRepository(db)
 
 
155
 
156
  try:
157
  await _publish(redis, channel, "validating", 5)
@@ -162,6 +171,7 @@ async def _run_ingestion(
162
  from app.services.parser import parse_document
163
  parse_result = parse_document(file_path, ext)
164
  text = parse_result.text if hasattr(parse_result, "text") else str(parse_result)
 
165
 
166
  await _publish(redis, channel, "chunking", 40)
167
  from app.services.chunker import chunk_document
@@ -175,24 +185,28 @@ async def _run_ingestion(
175
  from app.services.summarizer import summarize_book
176
  summary = await summarize_book(text[:3000])
177
 
 
178
  await book_repo.update(book_id, author_id, {
179
- "status": "active",
180
  "chroma_collection_id": collection_name,
181
  "ai_summary": summary,
182
  "chunk_count": len(chunks),
 
183
  })
184
  await db.commit()
185
  await _publish(redis, channel, "complete", 100)
186
 
187
  except Exception as e:
188
- await book_repo.update(book_id, author_id, {"status": "failed"})
 
 
189
  await db.commit()
190
  await _publish(redis, channel, "error", 0, str(e))
191
 
192
  finally:
193
- # Clean up temp file
194
  try:
195
  if os.path.exists(file_path):
196
  os.remove(file_path)
197
  except Exception:
198
  pass
 
 
77
  })
78
  await db.commit()
79
 
80
+ # No Celery worker on HF Spaces β€” run ingestion as asyncio background task
81
+ import asyncio
82
+ from app.dependencies import _get_session_factory
83
+
84
+ async def _background():
85
+ async with _get_session_factory()() as bg_db:
86
+ await _run_ingestion(
87
+ file_path=str(tmp_path),
88
+ book_id=book.id,
89
+ author_id=current_user.id,
90
+ title=title or filename.rsplit(".", 1)[0],
91
+ redis=redis,
92
+ db=bg_db,
93
+ )
94
+
95
+ asyncio.create_task(_background())
96
 
97
  return {"book_id": book.id, "doc_id": doc.id, "status": "processing"}
98
 
 
156
  redis,
157
  db: AsyncSession,
158
  ) -> None:
159
+ """Full async ingestion: validate β†’ parse β†’ chunk β†’ embed β†’ summarize β†’ mark ready."""
160
  channel = f"ingestion:{author_id}:{book_id}"
161
  book_repo = BookRepository(db)
162
+ from app.repositories.document_repo import DocumentRepository
163
+ doc_repo = DocumentRepository(db)
164
 
165
  try:
166
  await _publish(redis, channel, "validating", 5)
 
171
  from app.services.parser import parse_document
172
  parse_result = parse_document(file_path, ext)
173
  text = parse_result.text if hasattr(parse_result, "text") else str(parse_result)
174
+ page_count = getattr(parse_result, "page_count", 0)
175
 
176
  await _publish(redis, channel, "chunking", 40)
177
  from app.services.chunker import chunk_document
 
185
  from app.services.summarizer import summarize_book
186
  summary = await summarize_book(text[:3000])
187
 
188
+ # Mark book as ready β€” matches rag_pipeline.py status check
189
  await book_repo.update(book_id, author_id, {
190
+ "status": "ready",
191
  "chroma_collection_id": collection_name,
192
  "ai_summary": summary,
193
  "chunk_count": len(chunks),
194
+ "page_count": page_count,
195
  })
196
  await db.commit()
197
  await _publish(redis, channel, "complete", 100)
198
 
199
  except Exception as e:
200
+ import structlog as _log
201
+ _log.get_logger(__name__).error("Ingestion failed", book_id=book_id, error=str(e))
202
+ await book_repo.update(book_id, author_id, {"status": "error"})
203
  await db.commit()
204
  await _publish(redis, channel, "error", 0, str(e))
205
 
206
  finally:
 
207
  try:
208
  if os.path.exists(file_path):
209
  os.remove(file_path)
210
  except Exception:
211
  pass
212
+
app/services/rag_pipeline.py CHANGED
@@ -764,7 +764,7 @@ async def _no_context_response(
764
 
765
  if len(books) == 1:
766
  book = books[0]
767
- if book.status != "ready":
768
  text = (
769
  f"{book.title} is still being indexed β€” give it a minute and ask again. "
770
  "I'll be able to answer detailed questions once processing finishes."
 
764
 
765
  if len(books) == 1:
766
  book = books[0]
767
+ if book.status not in ("ready", "active"):
768
  text = (
769
  f"{book.title} is still being indexed β€” give it a minute and ask again. "
770
  "I'll be able to answer detailed questions once processing finishes."