Skip to content

Commit

Permalink
Merge pull request #68 from ssciwr/fix_58_add_platform_to_sample
Browse files Browse the repository at this point in the history
Add platform to Sample
  • Loading branch information
lkeegan authored Jan 2, 2025
2 parents d166efb + 9b11eb3 commit 9d0901e
Show file tree
Hide file tree
Showing 12 changed files with 41 additions and 13 deletions.
7 changes: 5 additions & 2 deletions README_DEPLOYMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ To deploy the latest version on a virtual machine with docker compose installed,
download [docker-compose.yml](https://raw.githubusercontent.com/ssciwr/predicTCR/main/docker-compose.yml), then do

```
sudo docker compose pull
sudo docker compose up -d
sudo docker compose pull && sudo docker compose up -d && sudo docker system prune -af
```

The same command can be used to update the running website to use the latest available docker images.

The location of data directory, SSL keys and secret key should be set
either in env vars or in a file `.env` in the same location as the docker compose.yml.

Expand Down Expand Up @@ -60,9 +61,11 @@ sudo sqlite3 docker_volume/predicTCR.db
sqlite> UPDATE user SET is_admin=true WHERE email='user@embl.de';
sqlite> .quit
```

### Visitor count

To get a count of the unique visitor IPs from the nginx logs:

```
sudo docker compose logs frontend --no-log-prefix | grep "GET" | awk '{print $1}' | sort | uniq | wc -l
```
4 changes: 3 additions & 1 deletion backend/src/predicTCR_server/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,12 @@ def add_sample():
name = form_as_dict.get("name", "")
tumor_type = form_as_dict.get("tumor_type", "")
source = form_as_dict.get("source", "")
platform = form_as_dict.get("platform", "")
h5_file = request.files.get("h5_file")
csv_file = request.files.get("csv_file")
logger.info(f"Adding sample {name} from {email}")
new_sample, error_message = add_new_sample(
email, name, tumor_type, source, h5_file, csv_file
email, name, tumor_type, source, platform, h5_file, csv_file
)
if new_sample is not None:
logger.info(" - > success")
Expand Down Expand Up @@ -443,6 +444,7 @@ def runner_result():
global_quota=1000,
tumor_types="Lung;Breast;Other",
sources="TIL;PMBC;Other",
platforms="Illumina;Other",
csv_required_columns="barcode;cdr3;chain",
runner_job_timeout_mins=60,
max_filesize_h5_mb=50,
Expand Down
4 changes: 4 additions & 0 deletions backend/src/predicTCR_server/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class Settings(db.Model):
global_quota: Mapped[int] = mapped_column(Integer, nullable=False)
tumor_types: Mapped[str] = mapped_column(String, nullable=False)
sources: Mapped[str] = mapped_column(String, nullable=False)
platforms: Mapped[str] = mapped_column(String, nullable=False)
csv_required_columns: Mapped[str] = mapped_column(String, nullable=False)
runner_job_timeout_mins: Mapped[int] = mapped_column(Integer, nullable=False)
max_filesize_h5_mb: Mapped[int] = mapped_column(Integer, nullable=False)
Expand Down Expand Up @@ -83,6 +84,7 @@ class Sample(db.Model):
name: Mapped[str] = mapped_column(String(128), nullable=False)
tumor_type: Mapped[str] = mapped_column(String(128), nullable=False)
source: Mapped[str] = mapped_column(String(128), nullable=False)
platform: Mapped[str] = mapped_column(String(128), nullable=False)
timestamp: Mapped[int] = mapped_column(Integer, nullable=False)
timestamp_job_start: Mapped[int] = mapped_column(Integer, nullable=False)
timestamp_job_end: Mapped[int] = mapped_column(Integer, nullable=False)
Expand Down Expand Up @@ -488,6 +490,7 @@ def add_new_sample(
name: str,
tumor_type: str,
source: str,
platform: str,
h5_file: FileStorage,
csv_file: FileStorage,
) -> tuple[Sample | None, str]:
Expand All @@ -504,6 +507,7 @@ def add_new_sample(
name=name,
tumor_type=tumor_type,
source=source,
platform=platform,
timestamp=timestamp_now(),
timestamp_job_start=0,
timestamp_job_end=0,
Expand Down
1 change: 1 addition & 0 deletions backend/tests/helpers/flask_test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def add_test_samples(app, data_path: pathlib.Path):
name=name,
tumor_type=f"tumor_type{sample_id}",
source=f"source{sample_id}",
platform=f"platform{sample_id}",
timestamp=sample_id,
timestamp_job_start=0,
timestamp_job_end=0,
Expand Down
2 changes: 2 additions & 0 deletions backend/tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ def test_get_settings_valid(client):
"id": 1,
"sources": "TIL;PMBC;Other",
"tumor_types": "Lung;Breast;Other",
"platforms": "Illumina;Other",
"runner_job_timeout_mins": 60,
"max_filesize_h5_mb": 50,
"max_filesize_csv_mb": 10,
Expand All @@ -158,6 +159,7 @@ def test_update_settings_valid(client):
"id": 1,
"sources": "a;b;g",
"tumor_types": "1;2;6",
"platforms": "Alpha;Beta;Other",
"runner_job_timeout_mins": 12,
"max_filesize_h5_mb": 77,
"max_filesize_csv_mb": 12,
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/components/SamplesTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,10 @@ function job_runtime(sample: Sample): string {
}
function download_samples_as_csv() {
let csv = "Id,Date,Email,SampleName,TumorType,Source,Status,Runtime\n";
let csv =
"Id,Date,Email,SampleName,TumorType,Source,Platform,Status,Runtime\n";
for (const sample of props.samples) {
csv += `${sample.id},${timestamp_to_date(sample.timestamp)},${sample.email},${sample.name},${sample.tumor_type},${sample.source},${sample.status},${job_runtime(sample)}\n`;
csv += `${sample.id},${timestamp_to_date(sample.timestamp)},${sample.email},${sample.name},${sample.tumor_type},${sample.source},${sample.platform},${sample.status},${job_runtime(sample)}\n`;
}
download_string_as_file("samples.csv", csv);
}
Expand All @@ -101,6 +102,7 @@ function download_samples_as_csv() {
<fwb-table-head-cell>Sample Name</fwb-table-head-cell>
<fwb-table-head-cell>Tumor type</fwb-table-head-cell>
<fwb-table-head-cell>Source</fwb-table-head-cell>
<fwb-table-head-cell>Platform</fwb-table-head-cell>
<fwb-table-head-cell>Status</fwb-table-head-cell>
<fwb-table-head-cell v-if="admin">Runtime</fwb-table-head-cell>
<fwb-table-head-cell>Inputs</fwb-table-head-cell>
Expand All @@ -122,6 +124,7 @@ function download_samples_as_csv() {
<fwb-table-cell>{{ sample.name }}</fwb-table-cell>
<fwb-table-cell>{{ sample.tumor_type }}</fwb-table-cell>
<fwb-table-cell>{{ sample.source }}</fwb-table-cell>
<fwb-table-cell>{{ sample.platform }}</fwb-table-cell>
<fwb-table-cell>{{ sample.status }}</fwb-table-cell>
<fwb-table-cell v-if="admin">{{ job_runtime(sample) }}</fwb-table-cell>
<fwb-table-cell>
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/components/SettingsTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ function update_settings() {
class="mb-2"
label="Sources (separated by ;)"
></fwb-input>
<fwb-input
v-model="settingsStore.settings.platforms"
class="mb-2"
label="Platforms (separated by ;)"
></fwb-input>
<fwb-input
v-model="settingsStore.settings.csv_required_columns"
class="mb-2"
Expand Down
1 change: 1 addition & 0 deletions frontend/src/stores/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const useSettingsStore = defineStore("settings", () => {
global_quota: 1,
tumor_types: "",
sources: "",
platforms: "",
csv_required_columns: "",
runner_job_timeout_mins: 1,
about_md: "",
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ export type Sample = {
email: string;
name: string;
tumor_type: string;
source: number;
source: string;
platform: string;
timestamp: number;
timestamp_job_start: number;
timestamp_job_end: number;
Expand Down Expand Up @@ -32,6 +33,7 @@ export type Settings = {
global_quota: number;
tumor_types: string;
sources: string;
platforms: string;
csv_required_columns: string;
runner_job_timeout_mins: number;
about_md: string;
Expand Down
1 change: 0 additions & 1 deletion frontend/src/views/ActivateView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const icon = ref("bi-person-exclamation");
apiClient
.get(`activate/${props.activation_token}`)
.then((response) => {
console.log(response);
message.value = response.data.message;
icon.value = "bi-person-check";
title.value =
Expand Down
1 change: 0 additions & 1 deletion frontend/src/views/ResetPasswordView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ function reset_password() {
new_password: new_password.value,
})
.then((response) => {
console.log(response);
message.value = response.data.message;
icon.value = "bi-person-check";
title.value = "Password reset successful";
Expand Down
17 changes: 12 additions & 5 deletions frontend/src/views/SamplesView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import SamplesTable from "@/components/SamplesTable.vue";
import ListComponent from "@/components/ListComponent.vue";
import ListItem from "@/components/ListItem.vue";
import { apiClient, logout } from "@/utils/api-client";
import type { Sample, Settings } from "@/utils/types";
import type { Sample } from "@/utils/types";
import {
FwbButton,
FwbSelect,
Expand All @@ -24,6 +24,7 @@ type OptionsType = {
const tumor_types = ref([] as Array<OptionsType>);
const sources = ref([] as Array<OptionsType>);
const platforms = ref([] as Array<OptionsType>);
const required_columns = ref([] as Array<string>);
function closeModalSubmit() {
Expand All @@ -39,6 +40,7 @@ const agree_to_conditions = ref(false);
const sample_name = ref("");
const tumor_type = ref("");
const source = ref("");
const platform = ref("");
const selected_h5_file = ref(null as null | File);
const h5_file_input_key = ref(0);
const selected_csv_file = ref(null as null | File);
Expand Down Expand Up @@ -68,10 +70,8 @@ async function validate_csv_file(file: File) {
const lines = text.split(/\n/);
if (lines.length >= 1) {
const columns = lines[0].split(/,/);
console.log(columns);
for (const required_column of required_columns.value) {
if (!columns.includes(required_column)) {
console.log(`Missing header: ${required_column}`);
return false;
}
}
Expand Down Expand Up @@ -110,6 +110,7 @@ function string_to_options(str: string): Array<OptionsType> {
tumor_types.value = string_to_options(settingsStore.settings.tumor_types);
sources.value = string_to_options(settingsStore.settings.sources);
platforms.value = string_to_options(settingsStore.settings.platforms);
required_columns.value = settingsStore.settings.csv_required_columns.split(";");
const samples = ref([] as Sample[]);
Expand All @@ -119,7 +120,6 @@ function update_samples() {
.get("samples")
.then((response) => {
samples.value = response.data;
console.log(samples.value);
})
.catch((error) => {
if (error.response.status > 400) {
Expand All @@ -144,7 +144,6 @@ onUnmounted(() => {
});
function update_submit_message() {
console.log("update_submit_message");
apiClient
.get("user_submit_message")
.then((response) => {
Expand All @@ -165,6 +164,7 @@ function add_sample() {
formData.append("name", sample_name.value);
formData.append("tumor_type", tumor_type.value);
formData.append("source", source.value);
formData.append("platform", platform.value);
formData.append("h5_file", selected_h5_file.value as File);
formData.append("csv_file", selected_csv_file.value as File);
apiClient
Expand Down Expand Up @@ -225,6 +225,13 @@ function add_sample() {
label="Source"
class="mb-2"
/>
<fwb-select
v-model="platform"
:options="platforms"
id="platform"
label="Platform"
class="mb-2"
/>
<fwb-file-input
type="file"
id="input_h5_file"
Expand Down

0 comments on commit 9d0901e

Please sign in to comment.