b5e18f5b47
Add to packages/storage/: - README.md and README_zh.md - comprehensive documentation - store/persistence/async_provider.py - async persistence provider Update repositories: - contracts/thread_meta.py - add new contract method - db/thread_meta.py - implement new method - factory.py - update factory logic Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
77 lines
2.2 KiB
Python
77 lines
2.2 KiB
Python
from __future__ import annotations
|
|
|
|
import asyncio
|
|
from contextlib import asynccontextmanager
|
|
from typing import AsyncIterator
|
|
|
|
from sqlalchemy import URL
|
|
|
|
from store.config.app_config import get_app_config
|
|
|
|
|
|
@asynccontextmanager
|
|
async def make_checkpointer() -> AsyncIterator[object]:
|
|
"""Create a LangGraph checkpointer from the unified storage config."""
|
|
storage = get_app_config().storage
|
|
|
|
if storage.driver == "sqlite":
|
|
from langgraph.checkpoint.sqlite.aio import AsyncSqliteSaver
|
|
|
|
conn_str = storage.sqlite_storage_path
|
|
await asyncio.to_thread(_ensure_sqlite_parent_dir, conn_str)
|
|
async with AsyncSqliteSaver.from_conn_string(conn_str) as saver:
|
|
await saver.setup()
|
|
yield saver
|
|
return
|
|
|
|
if storage.driver == "postgres":
|
|
from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
|
|
|
|
async with AsyncPostgresSaver.from_conn_string(_create_postgres_url(storage)) as saver:
|
|
await saver.setup()
|
|
yield saver
|
|
return
|
|
|
|
if storage.driver == "mysql":
|
|
from langgraph.checkpoint.mysql.aio import AIOMySQLSaver
|
|
|
|
async with AIOMySQLSaver.from_conn_string(_create_mysql_url(storage)) as saver:
|
|
await saver.setup()
|
|
yield saver
|
|
return
|
|
|
|
raise ValueError(f"Unsupported storage driver for checkpointer: {storage.driver}")
|
|
|
|
|
|
def _ensure_sqlite_parent_dir(connection_string: str) -> None:
|
|
from pathlib import Path
|
|
|
|
if connection_string == ":memory:":
|
|
return
|
|
Path(connection_string).expanduser().parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
|
|
def _create_postgres_url(storage) -> URL:
|
|
return URL.create(
|
|
drivername="postgresql+asyncpg",
|
|
username=storage.username,
|
|
password=storage.password,
|
|
host=storage.host,
|
|
port=storage.port,
|
|
database=storage.db_name or "deerflow",
|
|
)
|
|
|
|
|
|
def _create_mysql_url(storage) -> URL:
|
|
return URL.create(
|
|
drivername="mysql+aiomysql",
|
|
username=storage.username,
|
|
password=storage.password,
|
|
host=storage.host,
|
|
port=storage.port,
|
|
database=storage.db_name or "deerflow",
|
|
)
|
|
|
|
|
|
__all__ = ["make_checkpointer"]
|