From 7eee169448928962eb70b11147dbfdf782ef104b Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Mon, 8 Apr 2024 15:48:20 +0200 Subject: [PATCH 1/4] Never fail on display_peek wrapper --- lib/galaxy/model/__init__.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/galaxy/model/__init__.py b/lib/galaxy/model/__init__.py index 53bd1e5faedb..96cd9157dfb3 100644 --- a/lib/galaxy/model/__init__.py +++ b/lib/galaxy/model/__init__.py @@ -4666,7 +4666,11 @@ def as_display_type(self, type, **kwd): return self.datatype.as_display_type(self, type, **kwd) def display_peek(self): - return self.datatype.display_peek(self) + try: + return self.datatype.display_peek(self) + except Exception: + log.exception("Error occurred while generating dataset pee") + return None def display_name(self): return self.datatype.display_name(self) From 031d59ff2b2898f6aa7e337089090217ff7062cf Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Mon, 8 Apr 2024 16:12:34 +0200 Subject: [PATCH 2/4] Don't set peek in display_peek method --- lib/galaxy/datatypes/data.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/datatypes/data.py b/lib/galaxy/datatypes/data.py index be434cbcc3cd..cad936f06b16 100644 --- a/lib/galaxy/datatypes/data.py +++ b/lib/galaxy/datatypes/data.py @@ -337,10 +337,10 @@ def set_peek(self, dataset: DatasetProtocol, **kwd) -> None: def display_peek(self, dataset: DatasetProtocol) -> str: """Create HTML table, used for displaying peek""" + if not dataset.peek: + return "Peek not available" out = [''] try: - if not dataset.peek: - dataset.set_peek() data = dataset.peek lines = data.splitlines() for line in lines: From b971e332634b9b2ccaa6e3a31c019278789c078b Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Mon, 8 Apr 2024 16:19:26 +0200 Subject: [PATCH 3/4] Fix Qiime2 display_peek method Fixes: ``` ExceptionGroup: unhandled errors in a TaskGroup File "starlette/_utils.py", line 87, in collapse_excgroups yield File "starlette/middleware/base.py", line 190, in __call__ async with anyio.create_task_group() as task_group: File "anyio/_backends/_asyncio.py", line 678, in __aexit__ raise BaseExceptionGroup( AttributeError: 'NoneType' object has no attribute 'replace' File "starlette/applications.py", line 123, in __call__ await self.middleware_stack(scope, receive, send) File "starlette/middleware/errors.py", line 186, in __call__ raise exc File "starlette/middleware/errors.py", line 164, in __call__ await self.app(scope, receive, _send) File "starlette_context/middleware/raw_middleware.py", line 92, in __call__ await self.app(scope, receive, send_wrapper) File "starlette/middleware/base.py", line 189, in __call__ with collapse_excgroups(): File "contextlib.py", line 155, in __exit__ self.gen.throw(typ, value, traceback) File "starlette/_utils.py", line 93, in collapse_excgroups raise exc File "starlette/middleware/base.py", line 191, in __call__ response = await self.dispatch_func(request, call_next) File "galaxy/webapps/galaxy/fast_app.py", line 108, in add_x_frame_options response = await call_next(request) File "starlette/middleware/base.py", line 165, in call_next raise app_exc File "starlette/middleware/base.py", line 151, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "starlette/middleware/exceptions.py", line 62, in __call__ await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) File "starlette/_exception_handler.py", line 64, in wrapped_app raise exc File "starlette/_exception_handler.py", line 53, in wrapped_app await app(scope, receive, sender) File "starlette/routing.py", line 758, in __call__ await self.middleware_stack(scope, receive, send) File "starlette/routing.py", line 778, in app await route.handle(scope, receive, send) File "starlette/routing.py", line 299, in handle await self.app(scope, receive, send) File "starlette/routing.py", line 79, in app await wrap_app_handling_exceptions(app, request)(scope, receive, send) File "starlette/_exception_handler.py", line 64, in wrapped_app raise exc File "starlette/_exception_handler.py", line 53, in wrapped_app await app(scope, receive, sender) File "starlette/routing.py", line 74, in app response = await func(request) File "fastapi/routing.py", line 278, in app raw_response = await run_endpoint_function( File "fastapi/routing.py", line 193, in run_endpoint_function return await run_in_threadpool(dependant.call, **values) File "starlette/concurrency.py", line 42, in run_in_threadpool return await anyio.to_thread.run_sync(func, *args) File "anyio/to_thread.py", line 56, in run_sync return await get_async_backend().run_sync_in_worker_thread( File "anyio/_backends/_asyncio.py", line 2144, in run_sync_in_worker_thread return await future File "anyio/_backends/_asyncio.py", line 851, in run result = context.run(func, *args) File "galaxy/webapps/galaxy/api/history_contents.py", line 465, in index items = self.service.index( File "galaxy/webapps/galaxy/services/history_contents.py", line 312, in index return self.__index_v2(trans, history_id, params, serialization_params, filter_query_params, accept) File "galaxy/webapps/galaxy/services/history_contents.py", line 992, in __index_v2 items = [ File "galaxy/webapps/galaxy/services/history_contents.py", line 993, in self._serialize_content_item( File "galaxy/webapps/galaxy/services/history_contents.py", line 1064, in _serialize_content_item rval = serializer.serialize_to_view( File "galaxy/managers/base.py", line 785, in serialize_to_view return self.serialize(item, all_keys, **context) File "galaxy/managers/hdas.py", line 614, in serialize return super().serialize(hda, keys, user=user, **context) File "galaxy/managers/datasets.py", line 770, in serialize serialized = super().serialize(dataset_assoc, keys, **context) File "galaxy/managers/base.py", line 698, in serialize returned[key] = self.serializers[key](item, key, **context) File "galaxy/managers/datasets.py", line 633, in "peek": lambda item, key, **context: item.display_peek() if item.peek and item.peek != "no peek" else None, File "galaxy/model/__init__.py", line 4669, in display_peek return self.datatype.display_peek(self) File "galaxy/datatypes/qiime2.py", line 57, in display_peek table += [make_row(pair) for pair in self._peek(dataset, simple=True)] File "galaxy/datatypes/qiime2.py", line 57, in table += [make_row(pair) for pair in self._peek(dataset, simple=True)] File "galaxy/datatypes/qiime2.py", line 54, in make_row return f"" File "__init__.py", line 19, in escape s = s.replace("&", "&") # Must be done first! ``` --- lib/galaxy/datatypes/qiime2.py | 4 ++++ test/unit/data/datatypes/test_qiime2.py | 3 +++ 2 files changed, 7 insertions(+) diff --git a/lib/galaxy/datatypes/qiime2.py b/lib/galaxy/datatypes/qiime2.py index cff199def66c..0b998bf69c5e 100644 --- a/lib/galaxy/datatypes/qiime2.py +++ b/lib/galaxy/datatypes/qiime2.py @@ -50,6 +50,10 @@ def set_peek(self, dataset: DatasetProtocol, **kwd) -> None: dataset.peek = "\n".join(map(": ".join, self._peek(dataset))) def display_peek(self, dataset: DatasetProtocol) -> str: + if dataset.metadata.semantic_type is None: + # Proxy for metadata elements not (yet) set + return "Peek unavailable" + def make_row(pair): return f"" diff --git a/test/unit/data/datatypes/test_qiime2.py b/test/unit/data/datatypes/test_qiime2.py index 7dab355b0b75..8b57cf4431bc 100644 --- a/test/unit/data/datatypes/test_qiime2.py +++ b/test/unit/data/datatypes/test_qiime2.py @@ -38,6 +38,9 @@ def test_qza_set_peek(): with get_input_files("qiime2.qza") as input_files: dataset = MockDataset(1) dataset.set_file_name(input_files[0]) + dataset.metadata.semantic_type = None + dataset.metadata.uuid = None + assert qza.display_peek(dataset) == "Peek unavailable" qza.set_meta(dataset) qza.set_peek(dataset) From 456f33fbd7a234e2b5b6a7a1a6a65546ac0cf867 Mon Sep 17 00:00:00 2001 From: Marius van den Beek Date: Mon, 8 Apr 2024 16:34:15 +0200 Subject: [PATCH 4/4] Fix peek typo Co-authored-by: Nicola Soranzo --- lib/galaxy/model/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/galaxy/model/__init__.py b/lib/galaxy/model/__init__.py index 96cd9157dfb3..34ce0c47937e 100644 --- a/lib/galaxy/model/__init__.py +++ b/lib/galaxy/model/__init__.py @@ -4669,7 +4669,7 @@ def display_peek(self): try: return self.datatype.display_peek(self) except Exception: - log.exception("Error occurred while generating dataset pee") + log.exception("Error occurred while generating dataset peek") return None def display_name(self):
{pair[0]}{html.escape(pair[1])}
{pair[0]}{html.escape(pair[1])}