Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .build-files/docker-compose-local.template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,4 @@ services:

volumes:
duckdb-data:
migrations_volume:
migrations_volume:
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,30 @@ In the root of the repository, run the following following command:
python3 build.py --prepare-dev
```

### Prepare Development Environment and Run Separately with Experiment Visibility Control

Experiment visibility control allows users to control which experiments are visible to them. You specify which experiments are visible to users in the `aa_index.json` file.

```bash
python3 build.py --prepare-dev --experiment-visibility-control
```

Experiment visibility control example:

```json
{
"experiments": [
{
"filename": "Data Discovery - Automated Cell Lineage Tracking.json",
"visible-by-default": true
},
"Quality Control - Cancer Triggering Microenvironments.json",
"Communication - Tumorigenic Cell States.json"
]
}
```


This will generate the necessary environment file in the client directory while still running the rest of the container. Then, the development server can be started separately by the following:

```bash
Expand Down Expand Up @@ -109,6 +133,7 @@ The build script will do its best to validate the config before starting the doc
| -o, --overwrite | When set, any settings in your configuration file which are present as environment variables in the current session will be overwritten. | -o |
| -s, --disable-spinner | When set, disables inline spinner | -s |
| --prepare-dev | When set, will create the `.env` file based on the current configuration that is required to run a separate client development server. | --prepare-dev |
| --experiment-visibility-control | When set, will create the `.env` file based on the current configuration that is required to run a separate client development server. | --experiment-visibility-control|

In the repository, you will see two docker directories: `docker` and `docker-local`. The main deployment will use the `docker` directory. The `docker-local` directory is a separate local version of Loon which we will discuss shortly. Below are some examples.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ref, computed, watch } from 'vue';
import { defineStore } from 'pinia';
import { asyncComputed } from '@vueuse/core';
import { useRoute } from 'vue-router';
import * as vg from '@uwdata/vgplot';

import { computedAsync } from '@vueuse/core';
Expand Down Expand Up @@ -44,7 +45,7 @@ export interface LocationMetadata {
imageDataFilename?: string;
segmentationsFolder?: string;
tags?: Tags;
// name?: string; // user friendly name
name?: string; // user friendly name
// condition?: string; // experimental condition // TODO: - does this need to be an array
// plate?: string;
// well?: string;
Expand Down Expand Up @@ -95,8 +96,9 @@ export const useDatasetSelectionStore = defineStore(
})

// Generate Experiment List
const route = useRoute();
const experimentFilenameList = asyncComputed<string[]>(async () => {
if (configStore.serverUrl == null) return null;
if (configStore.serverUrl == null) return [];
const fullURL = configStore.getFileUrl(
configStore.entryPointFilename
);
Expand All @@ -115,12 +117,12 @@ export const useDatasetSelectionStore = defineStore(
`Could not access ${fullURL}. "${error.message}"`
);
});
if (response == null) return;
if (response == null) return [];
if (!response.ok) {
handleFetchEntryError(
`Server Error. "${response.status}: ${response.statusText}"`
);
return;
return [];
}
fetchingEntryFile.value = false;
serverUrlValid.value = true;
Expand All @@ -136,7 +138,33 @@ export const useDatasetSelectionStore = defineStore(
vg.coordinator().databaseConnector(connector);

const data = await response.json();
return data.experiments;
const rawExperiments: (string | { filename: string; 'visible-by-default'?: boolean })[] = data.experiments;

// Normalize entries: extract filename from objects, pass strings through
const allFilenames = rawExperiments.map((entry) =>
typeof entry === 'string' ? entry : entry.filename
);

// If experiment visibility control is not enabled, show all experiments
const visibilityControlEnabled =
import.meta.env.VITE_EXPERIMENT_VISIBILITY_CONTROL === 'true';
if (!visibilityControlEnabled) {
return allFilenames;
}

// If show-all-experiments URL param is present, show all
if ('show-all-experiments' in route.query) {
return allFilenames;
}

// Filter to only visible-by-default experiments
return rawExperiments
.filter((entry) =>
typeof entry === 'object' && entry['visible-by-default'] === true
)
.map((entry) =>
typeof entry === 'string' ? entry : entry.filename
);
}, [refreshTime.value]);

// Sets location Metadata
Expand Down Expand Up @@ -284,7 +312,7 @@ export const useDatasetSelectionStore = defineStore(
.locationMetadataList) {
if (
datasetSelectionTrrackedStore.selectedLocationIds[
location.id
location.id
]
) {
return location;
Expand Down
19 changes: 13 additions & 6 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def createComposeFile(local=False, nfs=False):
shutil.copy(docker_compose_template, '.build-files/docker-compose.yml')


def createEnvFile(configFileName, envFileName, useDid=False):
def createEnvFile(configFileName, envFileName, useDid=False, experimentVisibilityControl=False):
buildConfig = BuildConfig.BuildConfig(configFileName, envFileName)
buildConfig.reportErrors()

Expand Down Expand Up @@ -110,6 +110,7 @@ def createEnvFile(configFileName, envFileName, useDid=False):

buildConfig.set('VITE_ENVIRONMENT', environment)
buildConfig.set('VITE_SERVER_URL', f'{base_url}/data')
buildConfig.set('VITE_EXPERIMENT_VISIBILITY_CONTROL', str(experimentVisibilityControl).lower())

localPort1 = buildConfig.get("generalSettings.local_port_1")
buildConfig.set("LOCAL_PORT_1", localPort1)
Expand Down Expand Up @@ -390,14 +391,16 @@ def cleanup_and_exit(signal=None, frame=None):
sys.exit(0)


def prepare_dev(buildConfig):
def prepare_dev(buildConfig, experimentVisibilityControl=False):
vite_server_url = f"{buildConfig.get('generalSettings.baseUrl')}/data"
vite_use_http = f"{buildConfig.get('generalSettings.useHttp')}"
vite_environment = f"{buildConfig.get('generalSettings.environment')}"
vite_experiment_visibility_control = str(experimentVisibilityControl).lower()

outString = f"VITE_SERVER_URL={vite_server_url}\n" \
f"VITE_USE_HTTP={vite_use_http}\n" \
f"VITE_ENVIRONMENT={vite_environment}\n"
f"VITE_ENVIRONMENT={vite_environment}\n" \
f"VITE_EXPERIMENT_VISIBILITY_CONTROL={vite_experiment_visibility_control}\n"

fullEnvFileName = 'apps/client/.env'
with open(fullEnvFileName, 'w') as outF:
Expand Down Expand Up @@ -445,6 +448,10 @@ def spinner(msg):
help="Generates .env file for client environment.")
parser.add_argument("-i", "--use-did", action="store_true", required=False,
help="Flag to specify that this build script is running in a DiD setup.")
parser.add_argument("--experiment-visibility-control", action="store_true", required=False,
help="Enable experiment visibility control. Only experiments with "
"'visible-by-default' in aa_index.json will be shown unless "
"'show-all-experiments' URL param is used.")

args = parser.parse_args()

Expand All @@ -464,7 +471,7 @@ def spinner(msg):
print('No client .env file found.')
pass

buildConfig = createEnvFile(config_file_name, args.env_file, args.use_did)
buildConfig = createEnvFile(config_file_name, args.env_file, args.use_did, args.experiment_visibility_control)

use_http = buildConfig.get('generalSettings.useHttp')
if use_http:
Expand Down Expand Up @@ -513,7 +520,7 @@ def spinner(msg):
follow_all_logs(logs_path, services, args.verbose, args.detached)

if args.prepare_dev:
prepare_dev(buildConfig)
prepare_dev(buildConfig, args.experiment_visibility_control)

check_containers_status(services, args.detached)
else:
Expand All @@ -522,5 +529,5 @@ def spinner(msg):
if args.overwrite:
config_file_name = overwrite_config(config_file_name)

buildConfig = createEnvFile(config_file_name, args.env_file, args.use_did)
buildConfig = createEnvFile(config_file_name, args.env_file, args.use_did, args.experiment_visibility_control)
createComposeFile(local=buildConfig.local, nfs=buildConfig.nfs)
Loading