Skip to content

Commit

Permalink
Merge branch 'rebase-in-time'
Browse files Browse the repository at this point in the history
  • Loading branch information
u8sand committed Jan 10, 2025
2 parents b312716 + d2b1366 commit 82838fe
Show file tree
Hide file tree
Showing 25 changed files with 328 additions and 74 deletions.
24 changes: 12 additions & 12 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:21.3.0 as base
FROM node:21.3.0 AS base
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true
RUN echo "Installing system dependencies (git+puppeteer deps)..." \
&& apt-get update \
Expand All @@ -16,32 +16,32 @@ RUN npm i -g ts-node
USER node
WORKDIR /app

FROM base as prepare_system
FROM base AS prepare_system
USER root
RUN echo "Installing system deps..." && apt-get -y update && apt-get -y install r-base python3-dev python3-pip python3-venv pkg-config libhdf5-dev && rm -rf /var/lib/apt/lists/*
ENV PYTHON_BIN="python3"
USER node

FROM prepare_system as prepare_r
FROM prepare_system AS prepare_r
USER root
COPY --chown=node:node cli/setup.R /app/setup.R
RUN echo "Running setup.R..." && R -e "source('/app/setup.R')" && rm /app/setup.R
USER node

FROM base as prepare_src
FROM base AS prepare_src
COPY --chown=node:node . /app

FROM prepare_src as prepare_package_json
FROM prepare_src AS prepare_package_json
RUN find /app -type d -name "node_modules" -exec rm -rf {} + \
&& find /app -type f -a \! \( -name "package.json" -o -name "package-lock.json" -o -name ".puppeteerrc.cjs" \) -delete \
&& find /app -type d -empty -delete

FROM prepare_src as prepare_requirements_txt
FROM prepare_src AS prepare_requirements_txt
RUN find /app -type d -name "node_modules" -exec rm -rf {} + \
&& find /app -type f -a \! \( -name "requirements.txt" -o -name "enumerate-requirements.ts" \) -delete \
&& find /app -type d -empty -delete

FROM base as prepare_npm_i
FROM base AS prepare_npm_i
COPY --from=prepare_package_json /app /app
RUN echo "Installing NodeJS dependencies..." && npm i

Expand All @@ -56,18 +56,18 @@ RUN mv /app/requirements.txt /tmp/requirements.txt \
&& chown node:node /app/requirements.txt
USER node

FROM prepare_src as prepare_build
FROM prepare_src AS prepare_build
COPY --from=prepare_npm_i /app /app
RUN echo "Building app..." && LANDING_PAGE=/graph/extend PUBLIC_URL=https://playbook-workflow-builder.cloud npm run build

FROM prepare_system as prepare_python
FROM prepare_system AS prepare_python
COPY --from=prepare_requirements_txt_complete /app /app
USER root
RUN echo "Installing python dependencies..." && python3 -m pip install --break-system-packages -r /app/requirements.txt && rm /app/requirements.txt
USER node

# TARGET: dev -- development environment with dependencies to run dev tools
FROM prepare_system as dev
FROM prepare_system AS dev
USER root
RUN echo "Installing dev deps..." \
&& apt-get -y update \
Expand Down Expand Up @@ -98,13 +98,13 @@ COPY --from=prepare_python /usr/local/lib/ /usr/local/lib/
CMD ["/bin/bash"]

# TARGET: app_minimal -- production server with dependencies to run just the webserver
FROM base as app_minimal
FROM base AS app_minimal
COPY --from=prepare_build /app /app
ENV PORT 3000
CMD ["npm", "run", "start"]

# TARGET: app -- production server with dependencies to run everything
FROM prepare_system as app
FROM prepare_system AS app
COPY --from=prepare_r /usr/local/lib/ /usr/local/lib/
COPY --from=prepare_python /usr/local/lib/ /usr/local/lib/
COPY --from=prepare_build /app /app
Expand Down
3 changes: 3 additions & 0 deletions app/api/v1/user/playbooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,9 @@ export const UpdateUserPlaybook = API.post('/api/v1/user/playbooks/[id]/update')
)
if (fpl === undefined) throw new NotFoundError()
fpl = fpl.rebasePlaybookMetadata(fpl, await fpprg.resolvePlaybookMetadata(inputs.body.playbook_metadata)).head
fpl = await fpprg.upsertFPL(fpl)
if (fpl === undefined) throw new NotFoundError()
fpl = await fpl.rebaseInTime()
if (fpl === undefined) throw new NotFoundError()
fpl = await fpprg.upsertFPL(fpl)
const session = await getServerSessionWithId(req, res)
Expand Down
3 changes: 2 additions & 1 deletion app/fragments/graph/catalog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const InputGroup = dynamic(() => import('@blueprintjs/core').then(({ InputGroup

type KVCounts = { [key: string]: { [val: string]: number } }

export default function Catalog<T extends { spec: string, meta?: { pagerank?: number, tags?: Record<string, Record<string, number>> } }>({ items, weights, serialize, children }: {
export default function Catalog<T extends { spec: string, meta?: { pagerank?: number, tags?: Record<string, Record<string, number>>, external?: boolean } }>({ items, weights, serialize, children }: {
items: Array<T>,
weights: Record<string, number>,
serialize: (item: T) => string,
Expand All @@ -27,6 +27,7 @@ export default function Catalog<T extends { spec: string, meta?: { pagerank?: nu
for (const k in items) {
const item = items[k]
const item_meta = item.meta||{}
item_meta.tags = item_meta.tags||{}
item_search_ts[k] = tsvector(serialize(item))
pagerank_max = Math.max(item_meta.pagerank||0, pagerank_max)
weight_max = Math.max(weights[item.spec]||0, weight_max)
Expand Down
9 changes: 7 additions & 2 deletions app/fragments/graph/cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ import type KRG from '@/core/KRG'
import dynamic from 'next/dynamic'
import { Metapath, useMetapathOutput } from '@/app/fragments/metapath'
import Head from 'next/head'
import { useRouter } from 'next/router'
import { useStory } from '@/app/fragments/story'
import SafeRender from '@/utils/saferender'
import { Abstract, FigureCaption, Methods, References } from './story'
import { z } from 'zod'

const Prompt = dynamic(() => import('@/app/fragments/graph/prompt'))

export default function Cell({ session_id, krg, id, head, metapath }: { session_id?: string, krg: KRG, id: string, head: Metapath, metapath: Metapath[] }) {
const router = useRouter()
const processNode = krg.getProcessNode(head.process.type)
const { data: { output, outputNode }, status, error: outputError, mutate } = useMetapathOutput({ krg, head })
const story = useStory()
Expand Down Expand Up @@ -52,11 +55,13 @@ export default function Cell({ session_id, krg, id, head, metapath }: { session_
: <SafeRender component={outputNode.view} props={output} />}
<FigureCaption id={head.id} story={{ ...story, ast: astFiltered }} />
<References story={{ ...story, ast: astFiltered }} />
{head.process.timestamp ? <div className="alert alert-info">Saved computation from {new Date(head.process.timestamp).toLocaleString()}</div> : null}
<button
className="btn btn-primary"
onClick={async (evt) => {
const req = await fetch(`${session_id ? `/api/socket/${session_id}` : ''}/api/db/process/${head.process.id}/output/delete`, { method: 'POST' })
const res = await req.text()
const req = await fetch(`${session_id ? `/api/socket/${session_id}` : ''}/api/db/fpl/${id}/recompute/${head.id}`, { method: 'POST' })
const res = z.object({ head: z.string(), rebased: z.string() }).parse(await req.json())
router.push(`${session_id ? `/session/${session_id}` : ''}/graph/${res.head}${res.head !== res.rebased ? `/node/${res.rebased}` : ''}`, undefined, { shallow: true })
mutate()
}}
>Recompute</button>
Expand Down
4 changes: 3 additions & 1 deletion app/fragments/graph/extend.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ export default function Extend({ session_id, krg, id, head, metapath }: { sessio
</Head>
<Catalog<ProcessMetaNode & ({}|{ onClick: (_: { router: NextRouter, id: string, head: Metapath }) => void })>
items={[
...krg.getNextProcess(processNode ? processNode.output.spec : '').filter(proc => proc.meta.hidden !== true),
...krg.getNextProcess(processNode ? processNode.output.spec : '')
.filter(proc => proc.meta.hidden !== true)
.map(proc => ({ ...proc, meta: { ...proc.meta, tags: { ...(proc.meta.tags??{}), External: { [proc.meta.external ? 'True': 'False']: 1 } } } })),
...SuggestionEdges(processNode ? processNode.output : undefined),
]}
serialize={item => [
Expand Down
35 changes: 35 additions & 0 deletions app/pages/api/db/fpl/[fpl_id]/recompute/[rebase_id].ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import fpprg from '@/app/fpprg'
import { z } from 'zod'
import { Process } from '@/core/FPPRG'
import handler from '@/utils/next-rest'
import { NotFoundError, UnsupportedMethodError } from '@/spec/error'

const QueryType = z.object({
fpl_id: z.string(),
rebase_id: z.string(),
})

export default handler(async (req, res) => {
if (req.method !== 'POST') throw new UnsupportedMethodError(req.method)
const { fpl_id, rebase_id } = QueryType.parse(req.query)
const rebase = await fpprg.getFPL(rebase_id)
if (rebase === undefined) throw new NotFoundError()
const old_process = rebase.process
const old_fpl = await fpprg.getFPL(fpl_id)
if (old_fpl === undefined) throw new NotFoundError()
if (old_process.timestamp !== undefined) {
const new_process = await fpprg.upsertProcess(new Process(
old_process.type,
old_process.data,
old_process.inputs,
))
const { rebased, head } = old_fpl.rebase(old_process, new_process)
const fpl = await fpprg.upsertFPL(head)
res.status(200).json({ head: fpl.id, rebased: rebased.id })
} else {
const resolved = await fpprg.getResolved(old_process.id)
if (resolved === undefined) throw new NotFoundError()
await fpprg.deleteResolved(resolved)
res.status(200).json({ head: fpl_id, rebased: rebase_id })
}
})
21 changes: 12 additions & 9 deletions app/public/playbooksDemo.ts

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions components/MW/metgene_summary/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const MetGeneSearch = MetaNode('MetGeneSearch')
description: 'Identify gene-centric information from Metabolomics.',
icon: [metgene_icon],
pagerank: 2,
external: true,
})
.inputs({ gene: GeneTerm })
.output(MetGeneSummary)
Expand Down
2 changes: 1 addition & 1 deletion components/data/limma_voom/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "limma_voom",
"version": "1.0.0",
"license": "CC-BY-4.0",
"license": "GPL-2.0-or-later",
"author": "Alex Agris <[email protected]>",
"private": true,
"dependencies": {
Expand Down
2 changes: 1 addition & 1 deletion components/data/pca_transformation/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "pca-transformation",
"version": "1.0.0",
"license": "CC-BY-4.0",
"license": "GPL-3.0-or-later",
"author": "Juncheng Pan <[email protected]>",
"private": true,
"dependencies": {
Expand Down
1 change: 1 addition & 0 deletions components/lincs/l1000-reverse-search/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export const LINCSL1000ReverseSearch = MetaNode('LINCSL1000ReverseSearch')
description: 'Identify RNA-seq-like LINCS L1000 Signatures which reverse the expression of the gene.',
icon: [lincs_icon],
pagerank: 2,
external: true,
})
.inputs({ gene: GeneTerm })
.output(LINCSL1000ReverseSearchDashboard)
Expand Down
1 change: 1 addition & 0 deletions components/service/enrichr/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,7 @@ export const EnrichrTermTSearch = [
label: `Extract Gene Sets Containing the ${T.label} in the Set Label`,
icon: [...array.ensureArray(T.icon), enrichr_icon],
description: `Find ${T.label} Terms in Enrichr Libraries`,
external: true,
})
.inputs({ term: TermT })
.output(EnrichrTermSearchResults)
Expand Down
Loading

0 comments on commit 82838fe

Please sign in to comment.