MAC / mac /models /notebook.py
Aaryan17's picture
chore: upload MAC codebase to HF Space
0e76632 verified
"""Notebook, cell, and execution models — durable notebook architecture."""
import uuid
from datetime import datetime, timezone
from sqlalchemy import String, Integer, Float, DateTime, Text, ForeignKey, JSON, Boolean
from sqlalchemy.orm import Mapped, mapped_column, relationship
from mac.database import Base
def _utcnow():
return datetime.now(timezone.utc)
def _gen_uuid():
return str(uuid.uuid4())
class Notebook(Base):
"""A user-owned notebook containing ordered cells."""
__tablename__ = "notebooks"
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=_gen_uuid)
owner_id: Mapped[str] = mapped_column(String(36), ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True)
title: Mapped[str] = mapped_column(String(200), nullable=False, default="Untitled Notebook")
description: Mapped[str] = mapped_column(Text, nullable=True)
language: Mapped[str] = mapped_column(String(30), nullable=False, default="python")
# python | javascript | bash | markdown
visibility: Mapped[str] = mapped_column(String(20), nullable=False, default="private")
# private | shared | public
is_archived: Mapped[bool] = mapped_column(Boolean, default=False)
cell_count: Mapped[int] = mapped_column(Integer, default=0)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_utcnow, index=True)
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_utcnow, onupdate=_utcnow)
cells: Mapped[list["NotebookCell"]] = relationship(
back_populates="notebook", cascade="all, delete-orphan", order_by="NotebookCell.position"
)
class NotebookCell(Base):
"""A single cell in a notebook — code or markdown."""
__tablename__ = "notebook_cells"
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=_gen_uuid)
notebook_id: Mapped[str] = mapped_column(String(36), ForeignKey("notebooks.id", ondelete="CASCADE"), nullable=False, index=True)
cell_type: Mapped[str] = mapped_column(String(20), nullable=False, default="code")
# code | markdown | raw
language: Mapped[str] = mapped_column(String(30), nullable=True) # override notebook default
source: Mapped[str] = mapped_column(Text, nullable=False, default="")
position: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_utcnow)
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_utcnow, onupdate=_utcnow)
notebook: Mapped["Notebook"] = relationship(back_populates="cells")
executions: Mapped[list["CellExecution"]] = relationship(
back_populates="cell", cascade="all, delete-orphan", order_by="CellExecution.created_at.desc()"
)
class CellExecution(Base):
"""Execution record for a notebook cell — immutable history."""
__tablename__ = "cell_executions"
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=_gen_uuid)
cell_id: Mapped[str] = mapped_column(String(36), ForeignKey("notebook_cells.id", ondelete="CASCADE"), nullable=False, index=True)
user_id: Mapped[str] = mapped_column(String(36), ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
status: Mapped[str] = mapped_column(String(20), nullable=False, default="queued")
# queued | running | completed | failed | cancelled | timeout
source_snapshot: Mapped[str] = mapped_column(Text, nullable=False) # code at time of execution
stdout: Mapped[str | None] = mapped_column(Text, nullable=True)
stderr: Mapped[str | None] = mapped_column(Text, nullable=True)
result: Mapped[dict | None] = mapped_column(JSON, nullable=True) # structured output / display data
exit_code: Mapped[int | None] = mapped_column(Integer, nullable=True)
duration_ms: Mapped[int] = mapped_column(Integer, default=0)
worker_node_id: Mapped[str | None] = mapped_column(String(36), nullable=True) # which node ran it
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_utcnow)
cell: Mapped["NotebookCell"] = relationship(back_populates="executions")