from __future__ import annotations
import datetime
import uuid
import enum
from typing import Any
from sqlalchemy import Column, String, DateTime, Integer, JSON, Enum
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, async_sessionmaker
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
[docs]
class Base(DeclarativeBase):
pass
[docs]
class JobStatus(str, enum.Enum):
PENDING = "PENDING"
RUNNING = "RUNNING"
COMPLETED = "COMPLETED"
FAILED = "FAILED"
[docs]
class RefineryJob(Base):
__tablename__ = "refinery_jobs"
id: Mapped[str] = mapped_column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
target_url: Mapped[str] = mapped_column(String, nullable=False)
plan_json: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
status: Mapped[JobStatus] = mapped_column(Enum(JobStatus), default=JobStatus.PENDING)
created_at: Mapped[datetime.datetime] = mapped_column(DateTime, default=datetime.datetime.utcnow)
updated_at: Mapped[datetime.datetime] = mapped_column(DateTime, default=datetime.datetime.utcnow, onupdate=datetime.datetime.utcnow)
retry_count: Mapped[int] = mapped_column(Integer, default=0)
# Database Setup
DATABASE_URL = "postgresql+asyncpg://unsprawl:unsprawl_secret@localhost:5433/unsprawl_memory"
engine = create_async_engine(DATABASE_URL, echo=False)
AsyncSessionLocal = async_sessionmaker(engine, expire_on_commit=False)
[docs]
async def init_db():
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)