muhammadghiffari commited on
Commit
7a16f4e
·
1 Parent(s): 7ffa183

fix: use MemorySaver to avoid async checkpoint NotImplementedError

Browse files
Files changed (2) hide show
  1. src/ai/graph.py +3 -4
  2. src/tasks/ocr_tasks.py +3 -3
src/ai/graph.py CHANGED
@@ -14,7 +14,7 @@ from __future__ import annotations
14
 
15
  import redis
16
  import structlog
17
- from langgraph.checkpoint.redis import RedisSaver
18
  from langgraph.graph import END, StateGraph
19
 
20
  from ..config import settings
@@ -117,9 +117,8 @@ def get_compiled_graph():
117
  """
118
  workflow = build_extraction_graph()
119
 
120
- # Redis checkpointer stores full graph state per thread_id (batch_id)
121
- redis_conn = redis.Redis.from_url(settings.REDIS_URL)
122
- checkpointer = RedisSaver(redis_client=redis_conn)
123
 
124
  graph = workflow.compile(checkpointer=checkpointer, interrupt_before=["human_review"])
125
 
 
14
 
15
  import redis
16
  import structlog
17
+ from langgraph.checkpoint.memory import MemorySaver
18
  from langgraph.graph import END, StateGraph
19
 
20
  from ..config import settings
 
117
  """
118
  workflow = build_extraction_graph()
119
 
120
+ # Using MemorySaver to support async ainvoke correctly
121
+ checkpointer = MemorySaver()
 
122
 
123
  graph = workflow.compile(checkpointer=checkpointer, interrupt_before=["human_review"])
124
 
src/tasks/ocr_tasks.py CHANGED
@@ -121,7 +121,7 @@ def preprocess_document(self, batch_id: str) -> None:
121
  log.info("Starting extraction pipeline", batch_id=batch_id)
122
  try:
123
  config = {"configurable": {"thread_id": batch_id}}
124
- context = asyncio.get_event_loop().run_until_complete(_load_batch_context(batch_id))
125
  initial_state = {
126
  "batch_id": batch_id,
127
  "company_id": context["batch"].get("company_id") or "",
@@ -135,10 +135,10 @@ def preprocess_document(self, batch_id: str) -> None:
135
  "steps": [],
136
  }
137
  # Run sync wrapper around async graph
138
- result = asyncio.get_event_loop().run_until_complete(
139
  extraction_graph.ainvoke(initial_state, config=config)
140
  )
141
- asyncio.get_event_loop().run_until_complete(_persist_graph_result(batch_id, result))
142
  log.info("Extraction pipeline complete", batch_id=batch_id)
143
  except Exception as exc:
144
  log.error("Pipeline failed", batch_id=batch_id, error=str(exc))
 
121
  log.info("Starting extraction pipeline", batch_id=batch_id)
122
  try:
123
  config = {"configurable": {"thread_id": batch_id}}
124
+ context = asyncio.run(_load_batch_context(batch_id))
125
  initial_state = {
126
  "batch_id": batch_id,
127
  "company_id": context["batch"].get("company_id") or "",
 
135
  "steps": [],
136
  }
137
  # Run sync wrapper around async graph
138
+ result = asyncio.run(
139
  extraction_graph.ainvoke(initial_state, config=config)
140
  )
141
+ asyncio.run(_persist_graph_result(batch_id, result))
142
  log.info("Extraction pipeline complete", batch_id=batch_id)
143
  except Exception as exc:
144
  log.error("Pipeline failed", batch_id=batch_id, error=str(exc))