@sjcrh/proteinpaint-server 2.163.1 → 2.164.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjcrh/proteinpaint-server",
3
- "version": "2.163.1",
3
+ "version": "2.164.1",
4
4
  "type": "module",
5
5
  "description": "a genomics visualization tool for exploring a cohort's genotype and phenotype data",
6
6
  "main": "src/app.js",
@@ -62,11 +62,11 @@
62
62
  },
63
63
  "dependencies": {
64
64
  "@sjcrh/augen": "2.143.0",
65
- "@sjcrh/proteinpaint-python": "2.162.0",
65
+ "@sjcrh/proteinpaint-python": "2.164.1",
66
66
  "@sjcrh/proteinpaint-r": "2.152.1-0",
67
67
  "@sjcrh/proteinpaint-rust": "2.157.0",
68
68
  "@sjcrh/proteinpaint-shared": "2.163.1",
69
- "@sjcrh/proteinpaint-types": "2.163.1",
69
+ "@sjcrh/proteinpaint-types": "2.164.1",
70
70
  "@types/express": "^5.0.0",
71
71
  "@types/express-session": "^1.18.1",
72
72
  "better-sqlite3": "^12.4.1",
@@ -154,17 +154,16 @@ function deleteProject(connection, projectId) {
154
154
  runMultiStmtSQL(connection, stmts, "delete");
155
155
  }
156
156
  function addProject(connection, project) {
157
- if (!project.users || !Array.isArray(project.users) || project.users.length === 0) {
158
- throw new Error("project.users must be a non-empty array of emails");
159
- }
160
157
  const projectSql = `INSERT INTO project (name, filter)
161
158
  VALUES (?, ?)`;
162
159
  const projectParams = [project.name, JSON.stringify(project.filter)];
163
160
  const row = runSQL(connection, projectSql, projectParams, "add");
164
- const userSql = `INSERT INTO project_users (project_id, email)
165
- VALUES (?, ?)`;
166
- const userParams = project.users.map((email) => [row.lastInsertRowid, email]);
167
- runMultiStmtSQL(connection, [{ sql: userSql, params: userParams }], "add");
161
+ if (project.users) {
162
+ const userSql = `INSERT INTO project_users (project_id, email)
163
+ VALUES (?, ?)`;
164
+ const userParams = project.users.map((email) => [row.lastInsertRowid, email]);
165
+ runMultiStmtSQL(connection, [{ sql: userSql, params: userParams }], "add");
166
+ }
168
167
  const classSql = `INSERT INTO project_classes (project_id, label, color, key_shortcut)
169
168
  VALUES (?, ?, ?, ?)`;
170
169
  const classParams = project.classes.map((c) => [row.lastInsertRowid, c.label, c.color, c.key_shortcut || ""]);
@@ -22,8 +22,20 @@ function init({ genomes }) {
22
22
  const ds = g.datasets[query.dslabel];
23
23
  if (!ds) throw "invalid dataset name";
24
24
  const projectId = query.projectId;
25
- const wsimagesFilenames = query.wsimagesFilenames;
25
+ const wsimagesFilenamesArg = query.wsimagesFilenames;
26
+ let wsimagesFilenames = [];
26
27
  const wsimages = [];
28
+ if (Array.isArray(wsimagesFilenamesArg) && wsimagesFilenamesArg.length === 1 && wsimagesFilenamesArg[0] === "all") {
29
+ if (ds.queries?.WSImages?.getAllWSImages) {
30
+ try {
31
+ wsimagesFilenames = await ds.queries.WSImages.getAllWSImages(projectId);
32
+ } catch (e) {
33
+ console.error("Failed to get WSI image list via helper, falling back to provided param", e);
34
+ }
35
+ }
36
+ } else {
37
+ wsimagesFilenames = wsimagesFilenamesArg;
38
+ }
27
39
  if (ds.queries.WSImages.getWSIAnnotations) {
28
40
  for (const wsimageFilename of wsimagesFilenames) {
29
41
  const wsimage = {
@@ -84,6 +96,12 @@ function validateWSIAnnotationsQuery(ds, connection) {
84
96
  AND pa.status = 1
85
97
  ORDER BY pa.timestamp DESC, pa.id DESC
86
98
  `;
99
+ const GET_PROJECT_IMAGES_SQL = `
100
+ SELECT DISTINCT pi.image_path AS image_path
101
+ FROM project_images pi
102
+ WHERE pi.project_id = ?
103
+ ORDER BY pi.id
104
+ `;
87
105
  if (!ds.queries) ds.queries = {};
88
106
  if (!ds.queries.WSImages) ds.queries.WSImages = {};
89
107
  ds.queries.WSImages.getWSIAnnotations = async (projectId, filename) => {
@@ -103,7 +121,8 @@ function validateWSIAnnotationsQuery(ds, connection) {
103
121
  }
104
122
  return {
105
123
  zoomCoordinates: coords,
106
- class: r.label ?? ""
124
+ class: r.label ?? "",
125
+ timestamp: r.timestamp
107
126
  };
108
127
  });
109
128
  } catch (error) {
@@ -111,6 +130,16 @@ function validateWSIAnnotationsQuery(ds, connection) {
111
130
  return [];
112
131
  }
113
132
  };
133
+ ds.queries.WSImages.getAllWSImages = async (projectId) => {
134
+ try {
135
+ const stmt = connection.prepare(GET_PROJECT_IMAGES_SQL);
136
+ const rows = stmt.all(projectId);
137
+ return (rows || []).map((r) => r.image_path);
138
+ } catch (error) {
139
+ console.error("Error loading project images list:", error);
140
+ return [];
141
+ }
142
+ };
114
143
  }
115
144
  function validateWSIClassesQuery(ds, connection) {
116
145
  if (!ds.queries) ds.queries = {};
@@ -2,6 +2,7 @@ import { ChatPayload } from "#types/checkers";
2
2
  import { run_rust } from "@sjcrh/proteinpaint-rust";
3
3
  import serverconfig from "../src/serverconfig.js";
4
4
  import { mayLog } from "#src/helpers.ts";
5
+ import { run_python } from "@sjcrh/proteinpaint-python";
5
6
  const api = {
6
7
  endpoint: "termdb/chat",
7
8
  methods: {
@@ -23,7 +24,22 @@ function init({ genomes }) {
23
24
  if (!g) throw "invalid genome";
24
25
  const ds = g.datasets?.[q.dslabel];
25
26
  if (!ds) throw "invalid dslabel";
26
- console.log("serverconfig:", serverconfig);
27
+ if (serverconfig.features.pythonChatBot) {
28
+ const chatbot_input2 = {
29
+ prompt: q.prompt,
30
+ genome: q.genome,
31
+ dslabel: q.dslabel
32
+ //terms_tsv_path: df
33
+ };
34
+ try {
35
+ const ai_output_data2 = await run_python("chatBot.py", JSON.stringify(chatbot_input2));
36
+ res.send(ai_output_data2);
37
+ } catch (error) {
38
+ const errmsg = "Error running chatBot Python script:" + error;
39
+ throw new Error(errmsg);
40
+ }
41
+ return;
42
+ }
27
43
  const serverconfig_ds_entries = serverconfig.genomes.find((genome) => genome.name == q.genome).datasets.find((dslabel) => dslabel.name == ds.label);
28
44
  console.log("serverconfig_ds_entries:", serverconfig_ds_entries);
29
45
  if (!serverconfig_ds_entries.aifiles) {