Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mccalluc/consistent arrays #2965

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions CHANGELOG-consistent-arrays.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Update to handle new response structure from portal-vis
23 changes: 12 additions & 11 deletions context/app/api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@
import requests

from hubmap_commons.type_client import TypeClient
from vitessce import VitessceConfig

from .client_utils import files_from_response
from portal_visualization.builder_factory import get_view_config_builder
from portal_visualization.builders.base_builders import ConfCells
from portal_visualization.builders.base_builders import ConfigsCells

Entity = namedtuple('Entity', ['uuid', 'type', 'name'], defaults=['TODO: name'])


@dataclass
class VitessceConfLiftedUUID:
vitessce_conf: dict
configs_cells: tuple
vis_lifted_uuid: str


Expand Down Expand Up @@ -151,9 +152,9 @@ def get_files(self, uuids):
body_json=query)
return files_from_response(response_json)

def get_vitessce_conf_cells_and_lifted_uuid(self, entity, marker=None, wrap_error=True):
def get_configs_cells_and_lifted_uuid(self, entity, marker=None, wrap_error=True):
'''
Returns a dataclass with vitessce_conf and is_lifted.
Returns a dataclass with configs_cells and vis_lifted_uuid.
'''
vis_lifted_uuid = None # default
image_pyramid_descendants = _get_image_pyramid_descendants(entity)
Expand All @@ -167,13 +168,13 @@ def get_vitessce_conf_cells_and_lifted_uuid(self, entity, marker=None, wrap_erro
# about "files". Bill confirms that when the new structure comes in
# there will be a period of backward compatibility to allow us to migrate.
derived_entity['files'] = derived_entity['metadata'].get('files', [])
vitessce_conf = self.get_vitessce_conf_cells_and_lifted_uuid(
configs_cells = self.get_configs_cells_and_lifted_uuid(
derived_entity, marker=marker, wrap_error=wrap_error
).vitessce_conf
).configs_cells
vis_lifted_uuid = derived_entity['uuid']

elif not entity.get('files') or not entity.get('data_types'):
vitessce_conf = ConfCells(None, None)
configs_cells = ConfigsCells([], [])

# Otherwise, just try to visualize the data for the entity itself:
else:
Expand All @@ -185,13 +186,13 @@ def get_assay(name):
return type_client.getAssayType(name)
Builder = get_view_config_builder(entity=entity, get_assay=get_assay)
builder = Builder(entity, self.groups_token, current_app.config["ASSETS_ENDPOINT"])
vitessce_conf = builder.get_conf_cells(marker=marker)
configs_cells = builder.get_configs_cells(marker=marker)
except Exception as e:
if not wrap_error:
raise e
current_app.logger.error(
f'Building vitessce conf threw error: {traceback.format_exc()}')
vitessce_conf = ConfCells({
configs_cells = ConfigsCells([VitessceConfig.from_dict({
'name': 'Error',
'version': '1.0.4',
'datasets': [],
Expand All @@ -203,10 +204,10 @@ def get_assay(name):
},
'x': 0, 'y': 0, 'w': 12, 'h': 1
}],
}, None)
})], [])

return VitessceConfLiftedUUID(
vitessce_conf=vitessce_conf,
configs_cells=configs_cells,
vis_lifted_uuid=vis_lifted_uuid)


Expand Down
4 changes: 2 additions & 2 deletions context/app/api/mock_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from datauri import DataURI

from portal_visualization.builders.base_builders import ConfCells
from portal_visualization.builders.base_builders import ConfigsCells
from .client import ApiClient


Expand All @@ -19,7 +19,7 @@ def get_entity(self, uuid=None, hbm_id=None):
}

def get_vitessce_conf_cells(self, entity):
return ConfCells(_get_mock_vitessce_conf(), None)
return ConfigsCells(_get_mock_vitessce_conf(), None)


def _get_mock_vitessce_conf():
Expand Down
14 changes: 8 additions & 6 deletions context/app/routes_browse.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,13 @@ def details(type, uuid):
marker = request.args.get('marker')

if type == 'dataset':
conf_cells_uuid = client.get_vitessce_conf_cells_and_lifted_uuid(entity, marker=marker)
configs_cells_uuid = client.get_configs_cells_and_lifted_uuid(entity, marker=marker)
flask_data.update({
'vitessce_conf': conf_cells_uuid.vitessce_conf.conf,
'has_notebook': conf_cells_uuid.vitessce_conf.cells is not None,
'vis_lifted_uuid': conf_cells_uuid.vis_lifted_uuid
'vitessce_conf_list': [
config.to_dict() for config in
configs_cells_uuid.configs_cells.configs],
'has_notebook': len(configs_cells_uuid.configs_cells.cells) > 0,
'vis_lifted_uuid': configs_cells_uuid.vis_lifted_uuid
})

template = 'base-pages/react-content.html'
Expand Down Expand Up @@ -89,9 +91,9 @@ def details_vitessce(type, uuid):
abort(404)
client = get_client()
entity = client.get_entity(uuid)
vitessce_conf = client.get_vitessce_conf_cells_and_lifted_uuid(entity).vitessce_conf
configs_cells = client.get_configs_cells_and_lifted_uuid(entity).configs_cells
# Returns a JSON null if there is no visualization.
response = jsonify(vitessce_conf.conf)
response = jsonify([config.to_dict() for config in configs_cells.configs])
response.headers.add("Access-Control-Allow-Origin", "*")
return response

Expand Down
2 changes: 1 addition & 1 deletion context/app/routes_file_based.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def preview_details_view(name):
'created_by_user_displayname': preview_metadata['created_by_user_displayname'],
'created_by_user_email': preview_metadata['created_by_user_email'],
},
'vitessce_conf': preview_metadata.get('vitessce_conf')
'vitessce_conf_list': [preview_metadata.get('vitessce_conf')]
}
return render_template(
'base-pages/react-content.html',
Expand Down
8 changes: 3 additions & 5 deletions context/app/routes_notebooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,8 @@ def details_notebook(type, uuid, create_workspace):
client = get_client()
entity = client.get_entity(uuid)
workspace_name = f"{entity['hubmap_id']} Workspace" if create_workspace else None
vitessce_conf = client.get_vitessce_conf_cells_and_lifted_uuid(entity).vitessce_conf
if (vitessce_conf is None
or vitessce_conf.conf is None
or vitessce_conf.cells is None):
configs_cells = client.get_configs_cells_and_lifted_uuid(entity).configs_cells
if (len(configs_cells.configs) == 0 or len(configs_cells.cells) == 0):
abort(404)

hubmap_id = entity['hubmap_id']
Expand All @@ -114,7 +112,7 @@ def details_notebook(type, uuid, create_workspace):
'!pip uninstall community flask albumentations -y '
'# Preinstalled on Colab; Causes version conflicts.\n'
f'!pip install vitessce[all]=={vitessce.__version__}'),
*vitessce_conf.cells
*configs_cells.cells
]

return _nb_response_from_objs(hubmap_id, cells, workspace_name=workspace_name, uuids=[uuid])
Expand Down
12 changes: 6 additions & 6 deletions context/app/static/js/components/Routes/Routes.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const WorkspacePleaseWait = lazy(() => import('js/pages/WorkspacePleaseWait'));
function Routes({ flaskData }) {
const {
entity,
vitessce_conf,
vitessce_conf_list,
title,
publications,
markdown,
Expand Down Expand Up @@ -66,14 +66,14 @@ function Routes({ flaskData }) {
if (urlPath.startsWith('/browse/donor/')) {
return (
<Route>
<Donor assayMetadata={entity} vitData={vitessce_conf} />
<Donor assayMetadata={entity} vitData={vitessce_conf_list} />
</Route>
);
}
if (urlPath.startsWith('/browse/sample/')) {
return (
<Route>
<Sample assayMetadata={entity} vitData={vitessce_conf} />
<Sample assayMetadata={entity} vitData={vitessce_conf_list} />
</Route>
);
}
Expand All @@ -83,7 +83,7 @@ function Routes({ flaskData }) {
<Route>
<Dataset
assayMetadata={entity}
vitData={vitessce_conf}
vitData={vitessce_conf_list}
hasNotebook={has_notebook}
visLiftedUUID={vis_lifted_uuid}
/>
Expand Down Expand Up @@ -166,7 +166,7 @@ function Routes({ flaskData }) {
if (urlPath.startsWith('/preview')) {
return (
<Route>
<Preview title={title} vitData={vitessce_conf} assayMetadata={entity} markdown={markdown} />
<Preview title={title} vitData={vitessce_conf_list} assayMetadata={entity} markdown={markdown} />
</Route>
);
}
Expand Down Expand Up @@ -287,7 +287,7 @@ Routes.propTypes = {
publications: PropTypes.object,
entity: PropTypes.object,
entities: PropTypes.array,
vitessce_conf: PropTypes.oneOfType([PropTypes.object, PropTypes.arrayOf(PropTypes.object)]),
vitessce_conf_list: PropTypes.arrayOf(PropTypes.object),
markdown: PropTypes.string,
collection: PropTypes.object,
errorCode: PropTypes.number,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export function useVitessceConfig({ vitData, setVitessceState, setVitessceErrors

useEffect(() => {
function setVitessceDefaults(vData) {
setVitessceState(Array.isArray(vData) ? vData[0] : vData);
setVitessceState(vData.length === 1 ? vData[0] : vData);
setVitessceSelection(0);
setVitessceConfig(vData);
}
Expand All @@ -31,11 +31,11 @@ export function useVitessceConfig({ vitData, setVitessceState, setVitessceErrors
let initializedVitDataFromUrl = vitData;
let initialSelectionFromUrl;
// If these is a url conf and the we have a multidataset, use the url conf to find the initial selection of the multi-dataset.
if (Array.isArray(vitData)) {
if (vitData.length > 1) {
initialSelectionFromUrl = Math.max(0, vitData.map(({ name }) => name).indexOf(vitessceURLConf?.name));
initializedVitDataFromUrl[initialSelectionFromUrl] = vitessceURLConf || vitData[initialSelectionFromUrl];
} else {
initializedVitDataFromUrl = vitessceURLConf || vitData;
initializedVitDataFromUrl = vitessceURLConf || vitData[0];
}
setVitessceState(initializedVitDataFromUrl[initialSelectionFromUrl]);
setVitessceSelection(initialSelectionFromUrl);
Expand Down
6 changes: 3 additions & 3 deletions etc/qa/find-vis-bugs.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ def get_errors(override_uuids):
warn(f'{i}/{len(uuids)} ({len(errors)} errors): Checking {uuid} ...')
try:
before_conf = perf_counter()
conf_uuid = client.get_vitessce_conf_cells_and_lifted_uuid(dataset, wrap_error=False)
configs_cells_uuid = client.get_configs_cells_and_lifted_uuid(dataset, wrap_error=False)
warn(
f'\tVis: {conf_uuid.vitessce_conf.conf is not None}; '
f'Lifted: {conf_uuid.vis_lifted_uuid} ')
f'\tVis: {len(configs_cells_uuid.configs_cells.configs) > 0}; '
f'Lifted: {configs_cells_uuid.vis_lifted_uuid} ')
waiting_for_conf += perf_counter() - before_conf
except Exception as e:
warn(f'\tERROR: {e}')
Expand Down