Skip to content

Commit

Permalink
Add endpoint to get project workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
petebachant committed Aug 22, 2024
1 parent 5248030 commit ab3e082
Show file tree
Hide file tree
Showing 6 changed files with 1,472 additions and 9 deletions.
26 changes: 26 additions & 0 deletions backend/app/api/routes/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import yaml
from app import users
from app.api.deps import CurrentUser, SessionDep
from app.dvc import make_mermaid_diagram
from app.models import (
Dataset,
Figure,
Expand All @@ -21,6 +22,7 @@
ProjectCreate,
ProjectsPublic,
Question,
Workflow,
)
from fastapi import APIRouter, HTTPException, Request
from fastapi.responses import StreamingResponse
Expand Down Expand Up @@ -357,3 +359,27 @@ def post_project_sync(
# Publications
# TODO: Update files in Git repo with IDs?
return Message(message="success")


@router.get("/projects/{owner_name}/{project_name}/workflow")
def get_project_workflow(
owner_name: str,
project_name: str,
current_user: CurrentUser,
session: SessionDep,
) -> Workflow:
content = get_project_git_contents(
owner_name=owner_name,
project_name=project_name,
session=session,
current_user=current_user,
path="/dvc.yaml",
)
content = base64.b64decode(content["content"]).decode()
dvc_pipeline = yaml.safe_load(content)
# Generate Mermaid diagram
mermaid = make_mermaid_diagram(dvc_pipeline)
return Workflow(
stages=dvc_pipeline["stages"],
mermaid=mermaid,
)
32 changes: 32 additions & 0 deletions backend/app/dvc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""Functionality for working with DVC."""

import os
import tempfile
from dvc.commands import dag
from dvc.repo import Repo
import yaml


def make_mermaid_diagram(pipeline: dict) -> str:
"""Create a Mermaid diagram from a pipeline file (typically ``dvc.yaml``).
This is a little hacky since we need to create a Git and DVC repo in order
to run the commands in DVC.
"""
wd_orig = os.getcwd()
try:
with tempfile.TemporaryDirectory() as tmpdirname:
os.chdir(tmpdirname)
with open("dvc.yaml", "w") as f:
yaml.safe_dump(pipeline, f)
with Repo.init(
".",
no_scm=True,
force=False,
subdir=False,
) as repo:
d = dag._build(repo)
mm = dag._show_mermaid(d, markdown=False)
finally:
os.chdir(wd_orig)
return mm
15 changes: 15 additions & 0 deletions backend/app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,20 @@ class ProjectCreate(ProjectBase):
pass


class WorkflowStage(SQLModel):
cmd: str
deps: list[str] | None = None
outs: list[str]
desc: str | None = None
meta: dict | None = None
wdir: str | None = None


class Workflow(SQLModel):
mermaid: str
stages: dict[str, WorkflowStage]


class Question(SQLModel, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
project_id: uuid.UUID = Field(foreign_key="project.id")
Expand Down Expand Up @@ -219,5 +233,6 @@ class Dataset(SQLModel, table=True):

class ImportedDataset(SQLModel, table=True):
"""A dataset imported into a project in a read-only fashion."""

project_id: uuid.UUID = Field(foreign_key="project.id", primary_key=True)
dataset_id: uuid.UUID = Field(foreign_key="dataset.id", primary_key=True)
22 changes: 22 additions & 0 deletions backend/app/tests/test_dvc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""Tests for the ``dvc`` module."""

from app.dvc import make_mermaid_diagram


def test_make_mermaid_diagram():
pipeline = {
"stages": {
"do-something": {
"cmd": "echo sup",
"deps": ["somefile.py"],
"outs": ["something.png"],
},
"do-something-else": {
"cmd": "echo sup2",
"deps": ["something.png"],
"outs": ["else.pdf"],
},
}
}
mm = make_mermaid_diagram(pipeline)
return mm
Loading

0 comments on commit ab3e082

Please sign in to comment.