From c3953df26d3d1dc47ab2acee8792c81e6c0873d3 Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Mon, 15 Apr 2024 11:08:45 +0100 Subject: [PATCH 01/28] TST: Test retrieving results from real asynchronous question --- pyproject.toml | 2 +- .../cloud_run/test_cloud_run_deployment.py | 34 ++++++++++++++++--- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1d24ee7d1..23c9cf0e6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "octue" -version = "0.53.0" +version = "0.53.1" description = "A package providing template applications for data services, and a python SDK to the Octue API." readme = "README.md" authors = ["Marcus Lugg ", "Thomas Clark "] diff --git a/tests/cloud/deployment/google/cloud_run/test_cloud_run_deployment.py b/tests/cloud/deployment/google/cloud_run/test_cloud_run_deployment.py index bb6e12903..88a65f2a4 100644 --- a/tests/cloud/deployment/google/cloud_run/test_cloud_run_deployment.py +++ b/tests/cloud/deployment/google/cloud_run/test_cloud_run_deployment.py @@ -1,9 +1,15 @@ import os +import time import unittest +import uuid from unittest import TestCase import twined.exceptions -from octue.resources import Child +from octue.cloud.pub_sub.bigquery import get_events +from octue.resources import Child, Manifest + + +EXAMPLE_SERVICE_SRUID = "octue/example-service-cloud-run:0.4.0" @unittest.skipUnless( @@ -13,7 +19,7 @@ class TestCloudRunDeployment(TestCase): # This is the service ID of the example service deployed to Google Cloud Run. child = Child( - id="octue/example-service-cloud-run:0.4.0", + id=EXAMPLE_SERVICE_SRUID, backend={"name": "GCPPubSubBackend", "project_name": os.environ["TEST_PROJECT_NAME"]}, ) @@ -36,6 +42,26 @@ def test_synchronous_question(self): self.assertEqual(f.read(), "This is some example service output.") def test_asynchronous_question(self): - """Test asking an asynchronous question.""" - answer = self.child.ask(input_values={"n_iterations": 3}, asynchronous=True) + """Test asking an asynchronous question and retrieving the resulting events from the event store.""" + question_uuid = str(uuid.uuid4()) + answer = self.child.ask(input_values={"n_iterations": 3}, question_uuid=question_uuid, asynchronous=True) self.assertIsNone(answer) + + # Wait for question to complete. + time.sleep(10) + + events = get_events( + table_id="octue_sdk_python_test_dataset.service-events", + sender=EXAMPLE_SERVICE_SRUID, + question_uuid=question_uuid, + kind="result", + ) + + # Check the output values. + self.assertEqual(events[0]["event"]["output_values"], [1, 2, 3, 4, 5]) + + # Check that the output dataset and its files can be accessed. + output_manifest = Manifest.deserialise(events[0]["event"]["output_manifest"]) + + with output_manifest.datasets["example_dataset"].files.one() as (datafile, f): + self.assertEqual(f.read(), "This is some example service output.") From 610b635cbbd264d63506778b73aa3fc09c76bc66 Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Mon, 15 Apr 2024 11:35:53 +0100 Subject: [PATCH 02/28] ENH: Deserialise manifests from async events in `get_event` --- octue/cloud/pub_sub/bigquery.py | 17 +++++++++++++++++ .../cloud_run/test_cloud_run_deployment.py | 6 ++---- tests/cloud/pub_sub/test_bigquery.py | 5 +++-- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/octue/cloud/pub_sub/bigquery.py b/octue/cloud/pub_sub/bigquery.py index d02833c07..c43e8db6d 100644 --- a/octue/cloud/pub_sub/bigquery.py +++ b/octue/cloud/pub_sub/bigquery.py @@ -3,6 +3,7 @@ from google.cloud.bigquery import Client, QueryJobConfig, ScalarQueryParameter from octue.cloud.events.validation import VALID_EVENT_KINDS +from octue.resources import Manifest def get_events( @@ -86,4 +87,20 @@ def get_events( if "backend_metadata" in df: df["backend_metadata"] = df["backend_metadata"].map(json.loads) + df["event"].apply(_deserialise_manifest_if_present) return df.to_dict(orient="records") + + +def _deserialise_manifest_if_present(event): + """If the event is a "question" or "result" event and a manifest is present, deserialise the manifest and replace + the serialised manifest with it. + + :param dict event: an Octue service event + :return None: + """ + if event["kind"] == "question" and event.get("input_manifest"): + event["input_manifest"] = Manifest.deserialise(event["input_manifest"]) + return + + if event["kind"] == "result" and event.get("output_manifest"): + event["output_manifest"] = Manifest.deserialise(event["output_manifest"]) diff --git a/tests/cloud/deployment/google/cloud_run/test_cloud_run_deployment.py b/tests/cloud/deployment/google/cloud_run/test_cloud_run_deployment.py index 88a65f2a4..dc2307990 100644 --- a/tests/cloud/deployment/google/cloud_run/test_cloud_run_deployment.py +++ b/tests/cloud/deployment/google/cloud_run/test_cloud_run_deployment.py @@ -6,7 +6,7 @@ import twined.exceptions from octue.cloud.pub_sub.bigquery import get_events -from octue.resources import Child, Manifest +from octue.resources import Child EXAMPLE_SERVICE_SRUID = "octue/example-service-cloud-run:0.4.0" @@ -61,7 +61,5 @@ def test_asynchronous_question(self): self.assertEqual(events[0]["event"]["output_values"], [1, 2, 3, 4, 5]) # Check that the output dataset and its files can be accessed. - output_manifest = Manifest.deserialise(events[0]["event"]["output_manifest"]) - - with output_manifest.datasets["example_dataset"].files.one() as (datafile, f): + with events[0]["event"]["output_manifest"].datasets["example_dataset"].files.one() as (datafile, f): self.assertEqual(f.read(), "This is some example service output.") diff --git a/tests/cloud/pub_sub/test_bigquery.py b/tests/cloud/pub_sub/test_bigquery.py index 0209e339a..693b99bf2 100644 --- a/tests/cloud/pub_sub/test_bigquery.py +++ b/tests/cloud/pub_sub/test_bigquery.py @@ -49,8 +49,9 @@ def test_with_attributes(self): self.assertEqual( mock_client.mock_calls[1].args[0], - "SELECT `event`, `datetime`, `uuid`, `originator`, `sender`, `sender_type`, `sender_sdk_version`, `recipient`, `order`, `other_attributes` FROM `blah`\n" - "WHERE sender=@sender\nAND question_uuid=@question_uuid\nORDER BY `order`\nLIMIT @limit", + "SELECT `event`, `datetime`, `uuid`, `originator`, `sender`, `sender_type`, `sender_sdk_version`, " + "`recipient`, `order`, `other_attributes` FROM `blah`\nWHERE sender=@sender\n" + "AND question_uuid=@question_uuid\nORDER BY `order`\nLIMIT @limit", ) def test_with_backend_metadata(self): From bcde18ecfcb4f8563edda4145acafafb2f7230a9 Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Mon, 15 Apr 2024 11:41:48 +0100 Subject: [PATCH 03/28] ENH: Return question UUID from `Child.ask` BREAKING CHANGE: Instead of writing `answer = Child.ask(...)`, write `answer, question_uuid = Child.ask(...)` (and the same for `ChildEmulator`) --- docs/source/asking_questions.rst | 6 +++--- docs/source/manifest.rst | 4 ++-- docs/source/testing_services.rst | 8 ++++---- docs/source/troubleshooting_services.rst | 2 +- octue/cloud/emulators/child.py | 8 +++++--- octue/resources/child.py | 12 +++++++----- .../parent_service/app.py | 6 ++++-- pyproject.toml | 2 +- .../cloud_run/test_cloud_run_deployment.py | 6 ++---- tests/cloud/emulators/test_child_emulator.py | 18 +++++++++--------- tests/cloud/pub_sub/test_service.py | 4 +++- tests/resources/test_child.py | 10 +++++----- 12 files changed, 46 insertions(+), 40 deletions(-) diff --git a/docs/source/asking_questions.rst b/docs/source/asking_questions.rst index acc4b6448..e488635ef 100644 --- a/docs/source/asking_questions.rst +++ b/docs/source/asking_questions.rst @@ -35,7 +35,7 @@ Asking a question backend={"name": "GCPPubSubBackend", "project_name": "my-project"}, ) - answer = child.ask( + answer, question_uuid = child.ask( input_values={"height": 32, "width": 3}, input_manifest=manifest, ) @@ -232,7 +232,7 @@ this: .. code-block:: python - answer = analysis.children["elevation"].ask(input_values={"longitude": 0, "latitude": 1}) + answer, question_uuid = analysis.children["elevation"].ask(input_values={"longitude": 0, "latitude": 1}) if your app configuration file is: @@ -323,7 +323,7 @@ then you can override them like this: .. code-block:: python - answer = child.ask( + answer, question_uuid = child.ask( input_values={"height": 32, "width": 3}, children=[ { diff --git a/docs/source/manifest.rst b/docs/source/manifest.rst index 8d00af312..7a13fc808 100644 --- a/docs/source/manifest.rst +++ b/docs/source/manifest.rst @@ -49,7 +49,7 @@ Get an Octue service to analyse data for you as part of a larger analysis. backend={"name": "GCPPubSubBackend", "project_name": "my-project"}, ) - answer = child.ask(input_manifest=manifest) + answer, question_uuid = child.ask(input_manifest=manifest) See :doc:`here ` for more information. @@ -108,7 +108,7 @@ the cloud and then download them again for each service (as would happen with cl } ) - analysis.children["wind_speed"].ask( + answer, question_uuid = analysis.children["wind_speed"].ask( input_values=analysis.input_values, input_manifest=analysis.input_manifest, allow_local_files=True, diff --git a/docs/source/testing_services.rst b/docs/source/testing_services.rst index df2419124..cf3612922 100644 --- a/docs/source/testing_services.rst +++ b/docs/source/testing_services.rst @@ -87,7 +87,7 @@ Instantiating a child emulator in python def handle_monitor_message(message): ... - result = child_emulator.ask( + result, question_uuid = child_emulator.ask( input_values={"hello": "world"}, handle_monitor_message=handle_monitor_message, ) @@ -133,7 +133,7 @@ You can then instantiate a child emulator from this in python: def handle_monitor_message(message): ... - result = child_emulator.ask( + result, question_uuid = child_emulator.ask( input_values={"hello": "world"}, handle_monitor_message=handle_monitor_message, ) @@ -226,7 +226,7 @@ child. backend={"name": "GCPPubSubBackend", "project_name": "my-project"}, ) - result = child.ask(input_values=[1, 2, 3, 4]) + result, question_uuid = child.ask(input_values=[1, 2, 3, 4]) child.received_events >>> [ @@ -260,6 +260,6 @@ You can then feed these into a child emulator to emulate one possible response o child_emulator = ChildEmulator(events=child.received_events) child_emulator.ask(input_values=[1, 2, 3, 4]) - >>> {"some": "results"} + >>> {"some": "results"}, "9cab579f-c486-4324-ac9b-96491d26266b" You can also create test fixtures from :ref:`downloaded service crash diagnostics `. diff --git a/docs/source/troubleshooting_services.rst b/docs/source/troubleshooting_services.rst index e861a572d..f60ca5fde 100644 --- a/docs/source/troubleshooting_services.rst +++ b/docs/source/troubleshooting_services.rst @@ -121,7 +121,7 @@ For example: backend={"name": "GCPPubSubBackend", "project_name": "my-project"}, ) - answer = child.ask( + answer, question_uuid = child.ask( input_values={"height": 32, "width": 3}, save_diagnostics="SAVE_DIAGNOSTICS_OFF", ) diff --git a/octue/cloud/emulators/child.py b/octue/cloud/emulators/child.py index 7614c5fd8..7f210a1d6 100644 --- a/octue/cloud/emulators/child.py +++ b/octue/cloud/emulators/child.py @@ -125,12 +125,12 @@ def ask( :param bool asynchronous: if `True`, don't create an answer subscription :param float timeout: time in seconds to wait for an answer before raising a timeout error :raise TimeoutError: if the timeout is exceeded while waiting for an answer - :return dict: a dictionary containing the keys "output_values" and "output_manifest" + :return dict, str: a dictionary containing the keys "output_values" and "output_manifest", and the question UUID """ with ServicePatcher(): self._child.serve(allow_existing=True) - subscription, _ = self._parent.ask( + subscription, question_uuid = self._parent.ask( service_id=self._child.id, input_values=input_values, input_manifest=input_manifest, @@ -141,13 +141,15 @@ def ask( asynchronous=asynchronous, ) - return self._parent.wait_for_answer( + answer = self._parent.wait_for_answer( subscription, handle_monitor_message=handle_monitor_message, record_events=record_events, timeout=timeout, ) + return answer, question_uuid + def _emulate_analysis( self, analysis_id, diff --git a/octue/resources/child.py b/octue/resources/child.py index b0208472d..c0f30bd67 100644 --- a/octue/resources/child.py +++ b/octue/resources/child.py @@ -88,9 +88,9 @@ def ask( :param float timeout: time in seconds to wait for an answer before raising a timeout error :param float|int maximum_heartbeat_interval: the maximum amount of time (in seconds) allowed between child heartbeats before an error is raised :raise TimeoutError: if the timeout is exceeded while waiting for an answer - :return dict|octue.cloud.pub_sub.subscription.Subscription|None: for a synchronous question, a dictionary containing the keys "output_values" and "output_manifest" from the result; for a question with a push endpoint, the push subscription; for an asynchronous question, `None` + :return dict|octue.cloud.pub_sub.subscription.Subscription|None, str: for a synchronous question, a dictionary containing the keys "output_values" and "output_manifest" from the result, and the question UUID; for a question with a push endpoint, the push subscription and the question UUID; for an asynchronous question, `None` and the question UUID """ - subscription, _ = self._service.ask( + subscription, question_uuid = self._service.ask( service_id=self.id, input_values=input_values, input_manifest=input_manifest, @@ -105,9 +105,9 @@ def ask( ) if push_endpoint or asynchronous: - return subscription + return subscription, question_uuid - return self._service.wait_for_answer( + answer = self._service.wait_for_answer( subscription=subscription, handle_monitor_message=handle_monitor_message, record_events=record_events, @@ -115,6 +115,8 @@ def ask( maximum_heartbeat_interval=maximum_heartbeat_interval, ) + return answer, question_uuid + def ask_multiple(self, *questions, raise_errors=True, max_retries=0, prevent_retries_when=None, max_workers=None): """Ask the child multiple questions in parallel and wait for the answers. Each question should be provided as a dictionary of `Child.ask` keyword arguments. If `raise_errors` is `True`, an error is raised and no answers are @@ -128,7 +130,7 @@ def ask_multiple(self, *questions, raise_errors=True, max_retries=0, prevent_ret :param int|None max_workers: the maximum number of questions that can be asked at once; defaults to `min(32, os.cpu_count() + 4, len(questions))` (see `concurrent.futures.ThreadPoolExecutor`) :raise ValueError: if the maximum number of parallel questions is set too high :raise Exception: if any question raises an error if `raise_errors` is `True` - :return list: the answers or caught errors of the questions in the same order as asked + :return list(dict|Exception, str): the answers or caught errors of the questions, and the question UUIDs (in the same order as asked) """ prevent_retries_when = prevent_retries_when or [] diff --git a/octue/templates/template-child-services/parent_service/app.py b/octue/templates/template-child-services/parent_service/app.py index 426982e87..2d198c25b 100644 --- a/octue/templates/template-child-services/parent_service/app.py +++ b/octue/templates/template-child-services/parent_service/app.py @@ -16,8 +16,10 @@ def run(analysis): # Send input data to children specified in `app_configuration.json` and receive output data. The output comes as a # dictionary with an `output_values` key and an `output_manifest` key. - elevations = analysis.children["elevation"].ask(input_values=analysis.input_values, timeout=60)["output_values"] - wind_speeds = analysis.children["wind_speed"].ask(input_values=analysis.input_values, timeout=60)["output_values"] + elevations = analysis.children["elevation"].ask(input_values=analysis.input_values, timeout=60)[0]["output_values"] + wind_speeds = analysis.children["wind_speed"].ask(input_values=analysis.input_values, timeout=60)[0][ + "output_values" + ] logger.info( "The wind speeds and elevations at %s are %s and %s.", diff --git a/pyproject.toml b/pyproject.toml index 23c9cf0e6..6ff628589 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "octue" -version = "0.53.1" +version = "0.54.0" description = "A package providing template applications for data services, and a python SDK to the Octue API." readme = "README.md" authors = ["Marcus Lugg ", "Thomas Clark "] diff --git a/tests/cloud/deployment/google/cloud_run/test_cloud_run_deployment.py b/tests/cloud/deployment/google/cloud_run/test_cloud_run_deployment.py index dc2307990..6631de3f1 100644 --- a/tests/cloud/deployment/google/cloud_run/test_cloud_run_deployment.py +++ b/tests/cloud/deployment/google/cloud_run/test_cloud_run_deployment.py @@ -1,7 +1,6 @@ import os import time import unittest -import uuid from unittest import TestCase import twined.exceptions @@ -32,7 +31,7 @@ def test_synchronous_question(self): """Test that the Google Cloud Run example deployment works, providing a service that can be asked questions and send responses. """ - answer = self.child.ask(input_values={"n_iterations": 3}) + answer, _ = self.child.ask(input_values={"n_iterations": 3}) # Check the output values. self.assertEqual(answer["output_values"], [1, 2, 3, 4, 5]) @@ -43,8 +42,7 @@ def test_synchronous_question(self): def test_asynchronous_question(self): """Test asking an asynchronous question and retrieving the resulting events from the event store.""" - question_uuid = str(uuid.uuid4()) - answer = self.child.ask(input_values={"n_iterations": 3}, question_uuid=question_uuid, asynchronous=True) + answer, question_uuid = self.child.ask(input_values={"n_iterations": 3}, asynchronous=True) self.assertIsNone(answer) # Wait for question to complete. diff --git a/tests/cloud/emulators/test_child_emulator.py b/tests/cloud/emulators/test_child_emulator.py index 755058f95..22e334176 100644 --- a/tests/cloud/emulators/test_child_emulator.py +++ b/tests/cloud/emulators/test_child_emulator.py @@ -84,7 +84,7 @@ def test_ask_with_result_event(self): child_emulator = ChildEmulator(backend=self.BACKEND, events=events) - result = child_emulator.ask(input_values={"hello": "world"}) + result, _ = child_emulator.ask(input_values={"hello": "world"}) self.assertEqual(result["output_values"], [1, 2, 3, 4]) self.assertEqual(result["output_manifest"].id, output_manifest.id) @@ -102,13 +102,13 @@ def test_ask_with_input_manifest(self): child_emulator = ChildEmulator(backend=self.BACKEND, events=events) - result = child_emulator.ask(input_values={"hello": "world"}, input_manifest=input_manifest) + result, _ = child_emulator.ask(input_values={"hello": "world"}, input_manifest=input_manifest) self.assertEqual(result["output_values"], [1, 2, 3, 4]) def test_empty_output_returned_by_ask_if_no_result_present_in_events(self): """Test that an empty output is returned if no result event is present in the given events.""" child_emulator = ChildEmulator(backend=self.BACKEND, events=[]) - result = child_emulator.ask(input_values={"hello": "world"}) + result, _ = child_emulator.ask(input_values={"hello": "world"}) self.assertEqual(result, {"output_values": None, "output_manifest": None}) def test_ask_with_log_record_with_missing_log_record_key(self): @@ -288,8 +288,8 @@ def test_ask_more_than_one_question(self): ] child_emulator = ChildEmulator(backend=self.BACKEND, events=events) - result_0 = child_emulator.ask(input_values={"hello": "world"}) - result_1 = child_emulator.ask(input_values={"hello": "planet"}) + result_0, _ = child_emulator.ask(input_values={"hello": "world"}) + result_1, _ = child_emulator.ask(input_values={"hello": "planet"}) self.assertEqual(result_0, result_1) @@ -302,7 +302,7 @@ def test_with_empty_file(self): object in), asked a question, and produce a trivial result. """ child_emulator = ChildEmulator.from_file(os.path.join(self.TEST_FILES_DIRECTORY, "empty_file.json")) - result = child_emulator.ask(input_values={"hello": "world"}) + result, _ = child_emulator.ask(input_values={"hello": "world"}) self.assertEqual(result, {"output_values": None, "output_manifest": None}) def test_with_only_events(self): @@ -316,7 +316,7 @@ def test_with_only_events(self): monitor_messages = [] with self.assertLogs(level=logging.INFO) as logging_context: - result = child_emulator.ask( + result, _ = child_emulator.ask( input_values={"hello": "world"}, handle_monitor_message=lambda value: monitor_messages.append(value), ) @@ -343,7 +343,7 @@ def test_with_full_file(self): monitor_messages = [] with self.assertLogs(level=logging.INFO) as logging_context: - result = child_emulator.ask( + result, _ = child_emulator.ask( input_values={"hello": "world"}, handle_monitor_message=lambda value: monitor_messages.append(value), ) @@ -399,7 +399,7 @@ def test_with_output_manifest(self): }, ) - result = child_emulator.ask(input_values={"hello": "world"}) + result, _ = child_emulator.ask(input_values={"hello": "world"}) # Check that the output manifest has been produced correctly. self.assertEqual(result["output_manifest"].id, expected_output_manifest.id) diff --git a/tests/cloud/pub_sub/test_service.py b/tests/cloud/pub_sub/test_service.py index 8e6526acb..6900565a9 100644 --- a/tests/cloud/pub_sub/test_service.py +++ b/tests/cloud/pub_sub/test_service.py @@ -801,7 +801,9 @@ def test_providing_dynamic_children(self): def mock_child_app(analysis): analysis.children["expected_child"]._service = child - analysis.output_values = analysis.children["expected_child"].ask(input_values=[1, 2, 3, 4])["output_values"] + analysis.output_values = analysis.children["expected_child"].ask(input_values=[1, 2, 3, 4])[0][ + "output_values" + ] static_children = [ { diff --git a/tests/resources/test_child.py b/tests/resources/test_child.py index c0e866736..4acbea5ef 100644 --- a/tests/resources/test_child.py +++ b/tests/resources/test_child.py @@ -96,8 +96,8 @@ def mock_run_function(analysis_id, input_values, *args, **kwargs): # Make sure the child's underlying mock service knows how to access the mock responding service. child._service.children[responding_service.id] = responding_service - self.assertEqual(child.ask([1, 2, 3, 4])["output_values"], [1, 2, 3, 4]) - self.assertEqual(child.ask([5, 6, 7, 8])["output_values"], [5, 6, 7, 8]) + self.assertEqual(child.ask([1, 2, 3, 4])[0]["output_values"], [1, 2, 3, 4]) + self.assertEqual(child.ask([5, 6, 7, 8])[0]["output_values"], [5, 6, 7, 8]) def test_ask_multiple(self): """Test that a child can be asked multiple questions in parallel and return the answers in the correct order.""" @@ -122,7 +122,7 @@ def mock_run_function(analysis_id, input_values, *args, **kwargs): ) self.assertEqual( - answers, + [answer[0] for answer in answers], [ {"output_values": [1, 2, 3, 4], "output_manifest": None}, {"output_values": [5, 6, 7, 8], "output_manifest": None}, @@ -231,7 +231,7 @@ def test_ask_multiple_with_failed_question_retry(self): # Check that both questions succeeded. self.assertEqual( - answers, + [answer[0] for answer in answers], [ {"output_manifest": None, "output_values": [1, 2, 3, 4]}, {"output_manifest": None, "output_values": [5, 6, 7, 8]}, @@ -275,7 +275,7 @@ def test_ask_multiple_with_multiple_failed_question_retries(self): # Check that all four questions succeeded. self.assertEqual( - answers, + [answer[0] for answer in answers], [ {"output_manifest": None, "output_values": [1, 2, 3, 4]}, {"output_manifest": None, "output_values": [5, 6, 7, 8]}, From b69f18913971c3e618b0843e226f3241065213a7 Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Wed, 17 Apr 2024 09:25:59 +0100 Subject: [PATCH 04/28] DOC: Add DOI badge to readme --- README.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 13067d622..7532c5619 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ [![Documentation Status](https://readthedocs.org/projects/octue-python-sdk/badge/?version=latest)](https://octue-python-sdk.readthedocs.io/en/latest/?badge=latest) [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit) [![black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black) +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.10961975.svg)](https://doi.org/10.5281/zenodo.10961975) # Octue Python SDK Purple Fruit Snake @@ -15,7 +16,9 @@ Read the docs [here.](https://octue-python-sdk.readthedocs.io/en/latest/) Uses our [twined](https://twined.readthedocs.io/en/latest/) library for data validation. ## Installation and usage + To install, run one of: + ```shell pip install octue ``` @@ -25,6 +28,7 @@ poetry add octue ``` The command line interface (CLI) can then be accessed via: + ```shell octue --help ``` @@ -59,6 +63,7 @@ Commands: ``` ## Deprecated code + When code is deprecated, it will still work but a deprecation warning will be issued with a suggestion on how to update it. After an adjustment period, deprecations will be removed from the codebase according to the [code removal schedule](https://github.com/octue/octue-sdk-python/issues/415). This constitutes a breaking change. @@ -66,6 +71,7 @@ This constitutes a breaking change. ## Developer notes ### Installation + We use [Poetry](https://python-poetry.org/) as our package manager. For development, run the following from the repository root, which will editably install the package: @@ -76,18 +82,24 @@ poetry install --all-extras Then run the tests to check everything's working. ### Testing + These environment variables need to be set to run the tests: -* `GOOGLE_APPLICATION_CREDENTIALS=/absolute/path/to/service/account/file.json` -* `TEST_PROJECT_NAME=` + +- `GOOGLE_APPLICATION_CREDENTIALS=/absolute/path/to/service/account/file.json` +- `TEST_PROJECT_NAME=` Then, from the repository root, run + ```shell python3 -m unittest ``` + or + ```shell tox ``` ## Contributing + Take a look at our [contributing](/docs/contributing.md) page. From 6f91f08b5b118da79c03d4e37080e702d1ab8122 Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Wed, 17 Apr 2024 09:29:19 +0100 Subject: [PATCH 05/28] DEP: Upgrade `gunicorn` to avoid vulnerability --- poetry.lock | 210 +++++++++++++++++++++++++------------------------ pyproject.toml | 2 +- 2 files changed, 108 insertions(+), 104 deletions(-) diff --git a/poetry.lock b/poetry.lock index e91eec3fe..825ae8f2f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -679,26 +679,27 @@ google-crc32c = "1.3.0" [[package]] name = "google-api-core" -version = "2.17.1" +version = "2.18.0" description = "Google API client core library" optional = false python-versions = ">=3.7" files = [ - {file = "google-api-core-2.17.1.tar.gz", hash = "sha256:9df18a1f87ee0df0bc4eea2770ebc4228392d8cc4066655b320e2cfccb15db95"}, - {file = "google_api_core-2.17.1-py3-none-any.whl", hash = "sha256:610c5b90092c360736baccf17bd3efbcb30dd380e7a6dc28a71059edb8bd0d8e"}, + {file = "google-api-core-2.18.0.tar.gz", hash = "sha256:62d97417bfc674d6cef251e5c4d639a9655e00c45528c4364fbfebb478ce72a9"}, + {file = "google_api_core-2.18.0-py3-none-any.whl", hash = "sha256:5a63aa102e0049abe85b5b88cb9409234c1f70afcda21ce1e40b285b9629c1d6"}, ] [package.dependencies] google-auth = ">=2.14.1,<3.0.dev0" googleapis-common-protos = ">=1.56.2,<2.0.dev0" grpcio = [ - {version = ">=1.33.2,<2.0dev", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""}, {version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, + {version = ">=1.33.2,<2.0dev", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""}, ] grpcio-status = [ - {version = ">=1.33.2,<2.0.dev0", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""}, {version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, + {version = ">=1.33.2,<2.0.dev0", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""}, ] +proto-plus = ">=1.22.3,<2.0.0dev" protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0.dev0" requests = ">=2.18.0,<3.0.0.dev0" @@ -709,13 +710,13 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] [[package]] name = "google-auth" -version = "2.28.1" +version = "2.29.0" description = "Google Authentication Library" optional = false python-versions = ">=3.7" files = [ - {file = "google-auth-2.28.1.tar.gz", hash = "sha256:34fc3046c257cedcf1622fc4b31fc2be7923d9b4d44973d481125ecc50d83885"}, - {file = "google_auth-2.28.1-py2.py3-none-any.whl", hash = "sha256:25141e2d7a14bfcba945f5e9827f98092716e99482562f15306e5b026e21aa72"}, + {file = "google-auth-2.29.0.tar.gz", hash = "sha256:672dff332d073227550ffc7457868ac4218d6c500b155fe6cc17d2b13602c360"}, + {file = "google_auth-2.29.0-py2.py3-none-any.whl", hash = "sha256:d452ad095688cd52bae0ad6fafe027f6a6d6f560e810fec20914e17a09526415"}, ] [package.dependencies] @@ -732,17 +733,18 @@ requests = ["requests (>=2.20.0,<3.0.0.dev0)"] [[package]] name = "google-cloud-bigquery" -version = "3.18.0" +version = "3.20.1" description = "Google BigQuery API client library" optional = false python-versions = ">=3.7" files = [ - {file = "google-cloud-bigquery-3.18.0.tar.gz", hash = "sha256:74f0fc6f0ba9477f808d25924dc8a052c55f7ca91064e83e16d3ee5fb7ca77ab"}, - {file = "google_cloud_bigquery-3.18.0-py2.py3-none-any.whl", hash = "sha256:3520552075502c69710d37b1e9600c84e6974ad271914677d16bfafa502857fb"}, + {file = "google-cloud-bigquery-3.20.1.tar.gz", hash = "sha256:318aa3abab5f1900ee24f63ba8bd02b9cdafaa942d738b4dc14a4ef2cc2d925f"}, + {file = "google_cloud_bigquery-3.20.1-py2.py3-none-any.whl", hash = "sha256:d3e62fe61138c658b8853c402e2d8fb9346c84e602e21e3a26584be10fc5b0a4"}, ] [package.dependencies] -google-api-core = ">=1.31.5,<2.0.dev0 || >2.3.0,<3.0.0dev" +google-api-core = {version = ">=1.34.1,<2.0.dev0 || >=2.11.dev0,<3.0.0dev", extras = ["grpc"]} +google-auth = ">=2.14.1,<3.0.0dev" google-cloud-core = ">=1.6.0,<3.0.0dev" google-resumable-media = ">=0.6.0,<3.0dev" packaging = ">=20.0.0" @@ -781,13 +783,13 @@ grpc = ["grpcio (>=1.38.0,<2.0dev)", "grpcio-status (>=1.38.0,<2.0.dev0)"] [[package]] name = "google-cloud-pubsub" -version = "2.20.0" +version = "2.21.1" description = "Google Cloud Pub/Sub API client library" optional = false python-versions = ">=3.7" files = [ - {file = "google-cloud-pubsub-2.20.0.tar.gz", hash = "sha256:48c8e17a8168c43e3188635cbd9e07fbe3004120433712ce84b3a04bbf18c188"}, - {file = "google_cloud_pubsub-2.20.0-py2.py3-none-any.whl", hash = "sha256:8c69ed04800f4f552cdf3b9028f06d9271ac6e60443b2308c984def442e69684"}, + {file = "google-cloud-pubsub-2.21.1.tar.gz", hash = "sha256:31fcf07444b7f813a616c4b650e1fbf1dc998a088fe0059a76164855ac17f05c"}, + {file = "google_cloud_pubsub-2.21.1-py2.py3-none-any.whl", hash = "sha256:55a3602ec45bc09626604d712032288a8ee3566145cb83523cff908938f69a4b"}, ] [package.dependencies] @@ -797,8 +799,8 @@ grpc-google-iam-v1 = ">=0.12.4,<1.0.0dev" grpcio = ">=1.51.3,<2.0dev" grpcio-status = ">=1.33.2" proto-plus = [ - {version = ">=1.22.0,<2.0.0dev", markers = "python_version < \"3.11\""}, {version = ">=1.22.2,<2.0.0dev", markers = "python_version >= \"3.11\""}, + {version = ">=1.22.0,<2.0.0dev", markers = "python_version < \"3.11\""}, ] protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0dev" @@ -807,13 +809,13 @@ libcst = ["libcst (>=0.3.10)"] [[package]] name = "google-cloud-secret-manager" -version = "2.18.3" +version = "2.19.0" description = "Google Cloud Secret Manager API client library" optional = false python-versions = ">=3.7" files = [ - {file = "google-cloud-secret-manager-2.18.3.tar.gz", hash = "sha256:1db2f409324536e34f985081d389e3974ca3a3668df7845cad0be03ab8c0fa7d"}, - {file = "google_cloud_secret_manager-2.18.3-py2.py3-none-any.whl", hash = "sha256:4d4af82bddd9099ebdbe79e0c6b68f6c6cabea8323a3c1275bcead8f56310fb7"}, + {file = "google-cloud-secret-manager-2.19.0.tar.gz", hash = "sha256:bb918435835a14eb94785f4d4d9087bdcf1b6de306432d7edaa7d62e7f780c30"}, + {file = "google_cloud_secret_manager-2.19.0-py2.py3-none-any.whl", hash = "sha256:7dd9ad9ab3e70f9a7fbac432938b702ba23bce1207e9bda86463b6d6b1f5cdbb"}, ] [package.dependencies] @@ -825,13 +827,13 @@ protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4 [[package]] name = "google-cloud-storage" -version = "2.15.0" +version = "2.16.0" description = "Google Cloud Storage API client library" optional = false python-versions = ">=3.7" files = [ - {file = "google-cloud-storage-2.15.0.tar.gz", hash = "sha256:7560a3c48a03d66c553dc55215d35883c680fe0ab44c23aa4832800ccc855c74"}, - {file = "google_cloud_storage-2.15.0-py2.py3-none-any.whl", hash = "sha256:5d9237f88b648e1d724a0f20b5cde65996a37fe51d75d17660b1404097327dd2"}, + {file = "google-cloud-storage-2.16.0.tar.gz", hash = "sha256:dda485fa503710a828d01246bd16ce9db0823dc51bbca742ce96a6817d58669f"}, + {file = "google_cloud_storage-2.16.0-py2.py3-none-any.whl", hash = "sha256:91a06b96fb79cf9cdfb4e759f178ce11ea885c79938f89590344d079305f5852"}, ] [package.dependencies] @@ -920,13 +922,13 @@ requests = ["requests (>=2.18.0,<3.0.0dev)"] [[package]] name = "googleapis-common-protos" -version = "1.62.0" +version = "1.63.0" description = "Common protobufs used in Google APIs" optional = false python-versions = ">=3.7" files = [ - {file = "googleapis-common-protos-1.62.0.tar.gz", hash = "sha256:83f0ece9f94e5672cced82f592d2a5edf527a96ed1794f0bab36d5735c996277"}, - {file = "googleapis_common_protos-1.62.0-py2.py3-none-any.whl", hash = "sha256:4750113612205514f9f6aa4cb00d523a94f3e8c06c5ad2fee466387dc4875f07"}, + {file = "googleapis-common-protos-1.63.0.tar.gz", hash = "sha256:17ad01b11d5f1d0171c06d3ba5c04c54474e883b66b949722b4938ee2694ef4e"}, + {file = "googleapis_common_protos-1.63.0-py2.py3-none-any.whl", hash = "sha256:ae45f75702f7c08b541f750854a678bd8f534a1a6bace6afe975f1d0a82d6632"}, ] [package.dependencies] @@ -954,104 +956,106 @@ protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.1 || >4.21.1,<4 [[package]] name = "grpcio" -version = "1.62.0" +version = "1.62.1" description = "HTTP/2-based RPC framework" optional = false python-versions = ">=3.7" files = [ - {file = "grpcio-1.62.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:136ffd79791b1eddda8d827b607a6285474ff8a1a5735c4947b58c481e5e4271"}, - {file = "grpcio-1.62.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:d6a56ba703be6b6267bf19423d888600c3f574ac7c2cc5e6220af90662a4d6b0"}, - {file = "grpcio-1.62.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:4cd356211579043fce9f52acc861e519316fff93980a212c8109cca8f47366b6"}, - {file = "grpcio-1.62.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e803e9b58d8f9b4ff0ea991611a8d51b31c68d2e24572cd1fe85e99e8cc1b4f8"}, - {file = "grpcio-1.62.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4c04fe33039b35b97c02d2901a164bbbb2f21fb9c4e2a45a959f0b044c3512c"}, - {file = "grpcio-1.62.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:95370c71b8c9062f9ea033a0867c4c73d6f0ff35113ebd2618171ec1f1e903e0"}, - {file = "grpcio-1.62.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c912688acc05e4ff012c8891803659d6a8a8b5106f0f66e0aed3fb7e77898fa6"}, - {file = "grpcio-1.62.0-cp310-cp310-win32.whl", hash = "sha256:821a44bd63d0f04e33cf4ddf33c14cae176346486b0df08b41a6132b976de5fc"}, - {file = "grpcio-1.62.0-cp310-cp310-win_amd64.whl", hash = "sha256:81531632f93fece32b2762247c4c169021177e58e725494f9a746ca62c83acaa"}, - {file = "grpcio-1.62.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:3fa15850a6aba230eed06b236287c50d65a98f05054a0f01ccedf8e1cc89d57f"}, - {file = "grpcio-1.62.0-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:36df33080cd7897623feff57831eb83c98b84640b016ce443305977fac7566fb"}, - {file = "grpcio-1.62.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:7a195531828b46ea9c4623c47e1dc45650fc7206f8a71825898dd4c9004b0928"}, - {file = "grpcio-1.62.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab140a3542bbcea37162bdfc12ce0d47a3cda3f2d91b752a124cc9fe6776a9e2"}, - {file = "grpcio-1.62.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f9d6c3223914abb51ac564dc9c3782d23ca445d2864321b9059d62d47144021"}, - {file = "grpcio-1.62.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:fbe0c20ce9a1cff75cfb828b21f08d0a1ca527b67f2443174af6626798a754a4"}, - {file = "grpcio-1.62.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:38f69de9c28c1e7a8fd24e4af4264726637b72f27c2099eaea6e513e7142b47e"}, - {file = "grpcio-1.62.0-cp311-cp311-win32.whl", hash = "sha256:ce1aafdf8d3f58cb67664f42a617af0e34555fe955450d42c19e4a6ad41c84bd"}, - {file = "grpcio-1.62.0-cp311-cp311-win_amd64.whl", hash = "sha256:eef1d16ac26c5325e7d39f5452ea98d6988c700c427c52cbc7ce3201e6d93334"}, - {file = "grpcio-1.62.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:8aab8f90b2a41208c0a071ec39a6e5dbba16fd827455aaa070fec241624ccef8"}, - {file = "grpcio-1.62.0-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:62aa1659d8b6aad7329ede5d5b077e3d71bf488d85795db517118c390358d5f6"}, - {file = "grpcio-1.62.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:0d7ae7fc7dbbf2d78d6323641ded767d9ec6d121aaf931ec4a5c50797b886532"}, - {file = "grpcio-1.62.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f359d635ee9428f0294bea062bb60c478a8ddc44b0b6f8e1f42997e5dc12e2ee"}, - {file = "grpcio-1.62.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77d48e5b1f8f4204889f1acf30bb57c30378e17c8d20df5acbe8029e985f735c"}, - {file = "grpcio-1.62.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:662d3df5314ecde3184cf87ddd2c3a66095b3acbb2d57a8cada571747af03873"}, - {file = "grpcio-1.62.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:92cdb616be44c8ac23a57cce0243af0137a10aa82234f23cd46e69e115071388"}, - {file = "grpcio-1.62.0-cp312-cp312-win32.whl", hash = "sha256:0b9179478b09ee22f4a36b40ca87ad43376acdccc816ce7c2193a9061bf35701"}, - {file = "grpcio-1.62.0-cp312-cp312-win_amd64.whl", hash = "sha256:614c3ed234208e76991992342bab725f379cc81c7dd5035ee1de2f7e3f7a9842"}, - {file = "grpcio-1.62.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:7e1f51e2a460b7394670fdb615e26d31d3260015154ea4f1501a45047abe06c9"}, - {file = "grpcio-1.62.0-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:bcff647e7fe25495e7719f779cc219bbb90b9e79fbd1ce5bda6aae2567f469f2"}, - {file = "grpcio-1.62.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:56ca7ba0b51ed0de1646f1735154143dcbdf9ec2dbe8cc6645def299bb527ca1"}, - {file = "grpcio-1.62.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e84bfb2a734e4a234b116be208d6f0214e68dcf7804306f97962f93c22a1839"}, - {file = "grpcio-1.62.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c1488b31a521fbba50ae86423f5306668d6f3a46d124f7819c603979fc538c4"}, - {file = "grpcio-1.62.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:98d8f4eb91f1ce0735bf0b67c3b2a4fea68b52b2fd13dc4318583181f9219b4b"}, - {file = "grpcio-1.62.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:b3d3d755cfa331d6090e13aac276d4a3fb828bf935449dc16c3d554bf366136b"}, - {file = "grpcio-1.62.0-cp37-cp37m-win_amd64.whl", hash = "sha256:a33f2bfd8a58a02aab93f94f6c61279be0f48f99fcca20ebaee67576cd57307b"}, - {file = "grpcio-1.62.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:5e709f7c8028ce0443bddc290fb9c967c1e0e9159ef7a030e8c21cac1feabd35"}, - {file = "grpcio-1.62.0-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:2f3d9a4d0abb57e5f49ed5039d3ed375826c2635751ab89dcc25932ff683bbb6"}, - {file = "grpcio-1.62.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:62ccb92f594d3d9fcd00064b149a0187c246b11e46ff1b7935191f169227f04c"}, - {file = "grpcio-1.62.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:921148f57c2e4b076af59a815467d399b7447f6e0ee10ef6d2601eb1e9c7f402"}, - {file = "grpcio-1.62.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f897b16190b46bc4d4aaf0a32a4b819d559a37a756d7c6b571e9562c360eed72"}, - {file = "grpcio-1.62.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1bc8449084fe395575ed24809752e1dc4592bb70900a03ca42bf236ed5bf008f"}, - {file = "grpcio-1.62.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:81d444e5e182be4c7856cd33a610154fe9ea1726bd071d07e7ba13fafd202e38"}, - {file = "grpcio-1.62.0-cp38-cp38-win32.whl", hash = "sha256:88f41f33da3840b4a9bbec68079096d4caf629e2c6ed3a72112159d570d98ebe"}, - {file = "grpcio-1.62.0-cp38-cp38-win_amd64.whl", hash = "sha256:fc2836cb829895ee190813446dce63df67e6ed7b9bf76060262c55fcd097d270"}, - {file = "grpcio-1.62.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:fcc98cff4084467839d0a20d16abc2a76005f3d1b38062464d088c07f500d170"}, - {file = "grpcio-1.62.0-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:0d3dee701e48ee76b7d6fbbba18ba8bc142e5b231ef7d3d97065204702224e0e"}, - {file = "grpcio-1.62.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:b7a6be562dd18e5d5bec146ae9537f20ae1253beb971c0164f1e8a2f5a27e829"}, - {file = "grpcio-1.62.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:29cb592c4ce64a023712875368bcae13938c7f03e99f080407e20ffe0a9aa33b"}, - {file = "grpcio-1.62.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1eda79574aec8ec4d00768dcb07daba60ed08ef32583b62b90bbf274b3c279f7"}, - {file = "grpcio-1.62.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7eea57444a354ee217fda23f4b479a4cdfea35fb918ca0d8a0e73c271e52c09c"}, - {file = "grpcio-1.62.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0e97f37a3b7c89f9125b92d22e9c8323f4e76e7993ba7049b9f4ccbe8bae958a"}, - {file = "grpcio-1.62.0-cp39-cp39-win32.whl", hash = "sha256:39cd45bd82a2e510e591ca2ddbe22352e8413378852ae814549c162cf3992a93"}, - {file = "grpcio-1.62.0-cp39-cp39-win_amd64.whl", hash = "sha256:b71c65427bf0ec6a8b48c68c17356cb9fbfc96b1130d20a07cb462f4e4dcdcd5"}, - {file = "grpcio-1.62.0.tar.gz", hash = "sha256:748496af9238ac78dcd98cce65421f1adce28c3979393e3609683fcd7f3880d7"}, + {file = "grpcio-1.62.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:179bee6f5ed7b5f618844f760b6acf7e910988de77a4f75b95bbfaa8106f3c1e"}, + {file = "grpcio-1.62.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:48611e4fa010e823ba2de8fd3f77c1322dd60cb0d180dc6630a7e157b205f7ea"}, + {file = "grpcio-1.62.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:b2a0e71b0a2158aa4bce48be9f8f9eb45cbd17c78c7443616d00abbe2a509f6d"}, + {file = "grpcio-1.62.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fbe80577c7880911d3ad65e5ecc997416c98f354efeba2f8d0f9112a67ed65a5"}, + {file = "grpcio-1.62.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58f6c693d446964e3292425e1d16e21a97a48ba9172f2d0df9d7b640acb99243"}, + {file = "grpcio-1.62.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:77c339403db5a20ef4fed02e4d1a9a3d9866bf9c0afc77a42234677313ea22f3"}, + {file = "grpcio-1.62.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b5a4ea906db7dec694098435d84bf2854fe158eb3cd51e1107e571246d4d1d70"}, + {file = "grpcio-1.62.1-cp310-cp310-win32.whl", hash = "sha256:4187201a53f8561c015bc745b81a1b2d278967b8de35f3399b84b0695e281d5f"}, + {file = "grpcio-1.62.1-cp310-cp310-win_amd64.whl", hash = "sha256:844d1f3fb11bd1ed362d3fdc495d0770cfab75761836193af166fee113421d66"}, + {file = "grpcio-1.62.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:833379943d1728a005e44103f17ecd73d058d37d95783eb8f0b28ddc1f54d7b2"}, + {file = "grpcio-1.62.1-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:c7fcc6a32e7b7b58f5a7d27530669337a5d587d4066060bcb9dee7a8c833dfb7"}, + {file = "grpcio-1.62.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:fa7d28eb4d50b7cbe75bb8b45ed0da9a1dc5b219a0af59449676a29c2eed9698"}, + {file = "grpcio-1.62.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48f7135c3de2f298b833be8b4ae20cafe37091634e91f61f5a7eb3d61ec6f660"}, + {file = "grpcio-1.62.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71f11fd63365ade276c9d4a7b7df5c136f9030e3457107e1791b3737a9b9ed6a"}, + {file = "grpcio-1.62.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4b49fd8fe9f9ac23b78437da94c54aa7e9996fbb220bac024a67469ce5d0825f"}, + {file = "grpcio-1.62.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:482ae2ae78679ba9ed5752099b32e5fe580443b4f798e1b71df412abf43375db"}, + {file = "grpcio-1.62.1-cp311-cp311-win32.whl", hash = "sha256:1faa02530b6c7426404372515fe5ddf66e199c2ee613f88f025c6f3bd816450c"}, + {file = "grpcio-1.62.1-cp311-cp311-win_amd64.whl", hash = "sha256:5bd90b8c395f39bc82a5fb32a0173e220e3f401ff697840f4003e15b96d1befc"}, + {file = "grpcio-1.62.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:b134d5d71b4e0837fff574c00e49176051a1c532d26c052a1e43231f252d813b"}, + {file = "grpcio-1.62.1-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:d1f6c96573dc09d50dbcbd91dbf71d5cf97640c9427c32584010fbbd4c0e0037"}, + {file = "grpcio-1.62.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:359f821d4578f80f41909b9ee9b76fb249a21035a061a327f91c953493782c31"}, + {file = "grpcio-1.62.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a485f0c2010c696be269184bdb5ae72781344cb4e60db976c59d84dd6354fac9"}, + {file = "grpcio-1.62.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b50b09b4dc01767163d67e1532f948264167cd27f49e9377e3556c3cba1268e1"}, + {file = "grpcio-1.62.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3227c667dccbe38f2c4d943238b887bac588d97c104815aecc62d2fd976e014b"}, + {file = "grpcio-1.62.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3952b581eb121324853ce2b191dae08badb75cd493cb4e0243368aa9e61cfd41"}, + {file = "grpcio-1.62.1-cp312-cp312-win32.whl", hash = "sha256:83a17b303425104d6329c10eb34bba186ffa67161e63fa6cdae7776ff76df73f"}, + {file = "grpcio-1.62.1-cp312-cp312-win_amd64.whl", hash = "sha256:6696ffe440333a19d8d128e88d440f91fb92c75a80ce4b44d55800e656a3ef1d"}, + {file = "grpcio-1.62.1-cp37-cp37m-linux_armv7l.whl", hash = "sha256:e3393b0823f938253370ebef033c9fd23d27f3eae8eb9a8f6264900c7ea3fb5a"}, + {file = "grpcio-1.62.1-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:83e7ccb85a74beaeae2634f10eb858a0ed1a63081172649ff4261f929bacfd22"}, + {file = "grpcio-1.62.1-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:882020c87999d54667a284c7ddf065b359bd00251fcd70279ac486776dbf84ec"}, + {file = "grpcio-1.62.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a10383035e864f386fe096fed5c47d27a2bf7173c56a6e26cffaaa5a361addb1"}, + {file = "grpcio-1.62.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:960edebedc6b9ada1ef58e1c71156f28689978188cd8cff3b646b57288a927d9"}, + {file = "grpcio-1.62.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:23e2e04b83f347d0aadde0c9b616f4726c3d76db04b438fd3904b289a725267f"}, + {file = "grpcio-1.62.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:978121758711916d34fe57c1f75b79cdfc73952f1481bb9583399331682d36f7"}, + {file = "grpcio-1.62.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9084086190cc6d628f282e5615f987288b95457292e969b9205e45b442276407"}, + {file = "grpcio-1.62.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:22bccdd7b23c420a27fd28540fb5dcbc97dc6be105f7698cb0e7d7a420d0e362"}, + {file = "grpcio-1.62.1-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:8999bf1b57172dbc7c3e4bb3c732658e918f5c333b2942243f10d0d653953ba9"}, + {file = "grpcio-1.62.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:d9e52558b8b8c2f4ac05ac86344a7417ccdd2b460a59616de49eb6933b07a0bd"}, + {file = "grpcio-1.62.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1714e7bc935780bc3de1b3fcbc7674209adf5208ff825799d579ffd6cd0bd505"}, + {file = "grpcio-1.62.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8842ccbd8c0e253c1f189088228f9b433f7a93b7196b9e5b6f87dba393f5d5d"}, + {file = "grpcio-1.62.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1f1e7b36bdff50103af95a80923bf1853f6823dd62f2d2a2524b66ed74103e49"}, + {file = "grpcio-1.62.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bba97b8e8883a8038606480d6b6772289f4c907f6ba780fa1f7b7da7dfd76f06"}, + {file = "grpcio-1.62.1-cp38-cp38-win32.whl", hash = "sha256:a7f615270fe534548112a74e790cd9d4f5509d744dd718cd442bf016626c22e4"}, + {file = "grpcio-1.62.1-cp38-cp38-win_amd64.whl", hash = "sha256:e6c8c8693df718c5ecbc7babb12c69a4e3677fd11de8886f05ab22d4e6b1c43b"}, + {file = "grpcio-1.62.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:73db2dc1b201d20ab7083e7041946910bb991e7e9761a0394bbc3c2632326483"}, + {file = "grpcio-1.62.1-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:407b26b7f7bbd4f4751dbc9767a1f0716f9fe72d3d7e96bb3ccfc4aace07c8de"}, + {file = "grpcio-1.62.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:f8de7c8cef9261a2d0a62edf2ccea3d741a523c6b8a6477a340a1f2e417658de"}, + {file = "grpcio-1.62.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd5c8a1af40ec305d001c60236308a67e25419003e9bb3ebfab5695a8d0b369"}, + {file = "grpcio-1.62.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be0477cb31da67846a33b1a75c611f88bfbcd427fe17701b6317aefceee1b96f"}, + {file = "grpcio-1.62.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:60dcd824df166ba266ee0cfaf35a31406cd16ef602b49f5d4dfb21f014b0dedd"}, + {file = "grpcio-1.62.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:973c49086cabab773525f6077f95e5a993bfc03ba8fc32e32f2c279497780585"}, + {file = "grpcio-1.62.1-cp39-cp39-win32.whl", hash = "sha256:12859468e8918d3bd243d213cd6fd6ab07208195dc140763c00dfe901ce1e1b4"}, + {file = "grpcio-1.62.1-cp39-cp39-win_amd64.whl", hash = "sha256:b7209117bbeebdfa5d898205cc55153a51285757902dd73c47de498ad4d11332"}, + {file = "grpcio-1.62.1.tar.gz", hash = "sha256:6c455e008fa86d9e9a9d85bb76da4277c0d7d9668a3bfa70dbe86e9f3c759947"}, ] [package.extras] -protobuf = ["grpcio-tools (>=1.62.0)"] +protobuf = ["grpcio-tools (>=1.62.1)"] [[package]] name = "grpcio-status" -version = "1.62.0" +version = "1.62.1" description = "Status proto mapping for gRPC" optional = false python-versions = ">=3.6" files = [ - {file = "grpcio-status-1.62.0.tar.gz", hash = "sha256:0d693e9c09880daeaac060d0c3dba1ae470a43c99e5d20dfeafd62cf7e08a85d"}, - {file = "grpcio_status-1.62.0-py3-none-any.whl", hash = "sha256:3baac03fcd737310e67758c4082a188107f771d32855bce203331cd4c9aa687a"}, + {file = "grpcio-status-1.62.1.tar.gz", hash = "sha256:3431c8abbab0054912c41df5c72f03ddf3b7a67be8a287bb3c18a3456f96ff77"}, + {file = "grpcio_status-1.62.1-py3-none-any.whl", hash = "sha256:af0c3ab85da31669f21749e8d53d669c061ebc6ce5637be49a46edcb7aa8ab17"}, ] [package.dependencies] googleapis-common-protos = ">=1.5.5" -grpcio = ">=1.62.0" +grpcio = ">=1.62.1" protobuf = ">=4.21.6" [[package]] name = "gunicorn" -version = "20.1.0" +version = "22.0.0" description = "WSGI HTTP Server for UNIX" optional = false -python-versions = ">=3.5" +python-versions = ">=3.7" files = [ - {file = "gunicorn-20.1.0-py3-none-any.whl", hash = "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e"}, - {file = "gunicorn-20.1.0.tar.gz", hash = "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"}, + {file = "gunicorn-22.0.0-py3-none-any.whl", hash = "sha256:350679f91b24062c86e386e198a15438d53a7a8207235a78ba1b53df4c4378d9"}, + {file = "gunicorn-22.0.0.tar.gz", hash = "sha256:4a0b436239ff76fb33f11c07a16482c521a7e09c1ce3cc293c2330afe01bec63"}, ] [package.dependencies] -setuptools = ">=3.0" +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} +packaging = "*" [package.extras] -eventlet = ["eventlet (>=0.24.1)"] +eventlet = ["eventlet (>=0.24.1,!=0.36.0)"] gevent = ["gevent (>=1.4.0)"] setproctitle = ["setproctitle"] +testing = ["coverage", "eventlet", "gevent", "pytest", "pytest-cov"] tornado = ["tornado (>=0.2)"] [[package]] @@ -1128,13 +1132,13 @@ license = ["ukkonen"] [[package]] name = "idna" -version = "3.6" +version = "3.7" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.5" files = [ - {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, - {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, ] [[package]] @@ -1506,13 +1510,13 @@ files = [ [[package]] name = "packaging" -version = "23.2" +version = "24.0" description = "Core utilities for Python packages" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, - {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, + {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, + {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, ] [[package]] @@ -1551,10 +1555,10 @@ files = [ [package.dependencies] numpy = [ + {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, {version = ">=1.17.3", markers = "(platform_machine != \"aarch64\" and platform_machine != \"arm64\") and python_version < \"3.10\""}, {version = ">=1.19.2", markers = "platform_machine == \"aarch64\" and python_version < \"3.10\""}, {version = ">=1.20.0", markers = "platform_machine == \"arm64\" and python_version < \"3.10\""}, - {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, ] python-dateutil = ">=2.7.3" pytz = ">=2017.3" @@ -2637,13 +2641,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.25.1" +version = "20.25.2" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.25.1-py3-none-any.whl", hash = "sha256:961c026ac520bac5f69acb8ea063e8a4f071bcc9457b9c1f28f6b085c511583a"}, - {file = "virtualenv-20.25.1.tar.gz", hash = "sha256:e08e13ecdca7a0bd53798f356d5831434afa5b07b93f0abdf0797b7a06ffe197"}, + {file = "virtualenv-20.25.2-py3-none-any.whl", hash = "sha256:6e1281a57849c8a54da89ba82e5eb7c8937b9d057ff01aaf5bc9afaa3552e90f"}, + {file = "virtualenv-20.25.2.tar.gz", hash = "sha256:fa7edb8428620518010928242ec17aa7132ae435319c29c1651d1cf4c4173aad"}, ] [package.dependencies] @@ -2653,7 +2657,7 @@ importlib-metadata = {version = ">=6.6", markers = "python_version < \"3.8\""} platformdirs = ">=3.9.1,<5" [package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] [[package]] @@ -2705,4 +2709,4 @@ hdf5 = ["h5py"] [metadata] lock-version = "2.0" python-versions = "^3.7.1" -content-hash = "1572a843b2a77b5376349ff6cd212d39644931ab91b8e7b61c12709eda55617e" +content-hash = "61840dbaf0a8252b7e37d55461f59ccd0b1915e5e7b61f7f733cb7ef021a3d6d" diff --git a/pyproject.toml b/pyproject.toml index 6ff628589..860df93ac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ google-cloud-pubsub = "^2.5" google-cloud-secret-manager = "^2.3" google-cloud-storage = ">=1.35.1, <3" google-crc32c = "^1.1" -gunicorn = "^20.1" +gunicorn = "^22" python-dateutil = "^2.8" pyyaml = "^6" h5py = { version = "^3.6", optional = true } From 92c61a593bd3ef5050f7513df123429f188bbb00 Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Wed, 17 Apr 2024 09:35:46 +0100 Subject: [PATCH 06/28] FIX: Use correct base for `python3.11` dockerfile base image --- octue/cloud/deployment/google/cloud_run/Dockerfile-python311 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/octue/cloud/deployment/google/cloud_run/Dockerfile-python311 b/octue/cloud/deployment/google/cloud_run/Dockerfile-python311 index 2a34ef365..48203db1c 100644 --- a/octue/cloud/deployment/google/cloud_run/Dockerfile-python311 +++ b/octue/cloud/deployment/google/cloud_run/Dockerfile-python311 @@ -1,4 +1,4 @@ -FROM windpioneers/gdal-python:little-gecko-gdal-2.4.1-python-3.11-slim +FROM windpioneers/gdal-python:modest-heron-gdal-2.4.1-python-3.11-slim # Ensure print statements and log messages appear promptly in Cloud Logging. ENV PYTHONUNBUFFERED True From 40f23e944cfb07254aa469b53090a603e0d027e2 Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Wed, 17 Apr 2024 14:23:13 +0100 Subject: [PATCH 07/28] TST: Update deployment test --- .../deployment/google/cloud_run/test_cloud_run_deployment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cloud/deployment/google/cloud_run/test_cloud_run_deployment.py b/tests/cloud/deployment/google/cloud_run/test_cloud_run_deployment.py index 6631de3f1..778a2c93c 100644 --- a/tests/cloud/deployment/google/cloud_run/test_cloud_run_deployment.py +++ b/tests/cloud/deployment/google/cloud_run/test_cloud_run_deployment.py @@ -8,7 +8,7 @@ from octue.resources import Child -EXAMPLE_SERVICE_SRUID = "octue/example-service-cloud-run:0.4.0" +EXAMPLE_SERVICE_SRUID = "octue/example-service-cloud-run:0.4.1" @unittest.skipUnless( From 40e16b08a3490f54d815287d18e77c44fd4ce642 Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Wed, 17 Apr 2024 14:27:34 +0100 Subject: [PATCH 08/28] OPS: Import missing APIs into terraform config --- terraform/main.tf | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/terraform/main.tf b/terraform/main.tf index 89e7e5561..e858236dd 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -24,6 +24,7 @@ resource "google_project_service" "pub_sub" { } } + resource "google_project_service" "cloud_resource_manager" { project = var.project service = "cloudresourcemanager.googleapis.com" @@ -68,9 +69,32 @@ resource "google_project_service" "cloud_run" { } +resource "google_project_service" "cloud_functions" { + project = var.project + service = "cloudfunctions.googleapis.com" +} + + +resource "google_project_service" "eventarc" { + project = var.project + service = "eventarc.googleapis.com" +} + + +resource "google_project_service" "cloud_build" { + project = var.project + service = "cloudbuild.googleapis.com" +} + + +resource "google_project_service" "bigquery" { + project = var.project + service = "bigquery.googleapis.com" +} + + provider "google" { credentials = file(var.credentials_file) project = var.project region = var.region -# zone = var.zone } From 4a894a474001b467da3cfad93b515c719a5fb44a Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Wed, 17 Apr 2024 14:27:49 +0100 Subject: [PATCH 09/28] OPS: Deploy version `0.5.0` of event handler cloud function --- terraform/functions.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terraform/functions.tf b/terraform/functions.tf index c0be67fe8..250ca2882 100644 --- a/terraform/functions.tf +++ b/terraform/functions.tf @@ -9,7 +9,7 @@ resource "google_cloudfunctions2_function" "event_handler" { source { storage_source { bucket = "twined-gcp" - object = "event_handler/0.4.0.zip" + object = "event_handler/0.5.0.zip" } } } From b173ba6f0da00b893882d4aae1c729a65112a7a4 Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Wed, 17 Apr 2024 14:35:56 +0100 Subject: [PATCH 10/28] OPS: Update event store schema --- terraform/bigquery.tf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/terraform/bigquery.tf b/terraform/bigquery.tf index 63abffe09..4c0034b89 100644 --- a/terraform/bigquery.tf +++ b/terraform/bigquery.tf @@ -25,6 +25,11 @@ resource "google_bigquery_table" "test_table" { "type": "STRING", "mode": "REQUIRED" }, + { + "name": "kind", + "type": "STRING", + "mode": "REQUIRED" + }, { "name": "event", "type": "JSON", From 12d98827479ba04f7779b66c9311f9f4d45a37e9 Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Wed, 17 Apr 2024 14:51:46 +0100 Subject: [PATCH 11/28] FIX: Always return attributes from event store in `get_events` --- docs/source/asking_questions.rst | 1 - octue/cloud/pub_sub/bigquery.py | 54 ++++++++++++---------------- tests/cloud/pub_sub/test_bigquery.py | 28 ++++----------- 3 files changed, 29 insertions(+), 54 deletions(-) diff --git a/docs/source/asking_questions.rst b/docs/source/asking_questions.rst index e488635ef..36db95bc8 100644 --- a/docs/source/asking_questions.rst +++ b/docs/source/asking_questions.rst @@ -104,7 +104,6 @@ access the event store and run: **Options** - ``kind`` - Only retrieve this kind of event if present (e.g. "result") -- ``include_attributes`` - If ``True``, retrieve all the events' attributes as well - ``include_backend_metadata`` - If ``True``, retrieve information about the service backend that produced the event - ``limit`` - If set to a positive integer, limit the number of events returned to this diff --git a/octue/cloud/pub_sub/bigquery.py b/octue/cloud/pub_sub/bigquery.py index c43e8db6d..b894988cb 100644 --- a/octue/cloud/pub_sub/bigquery.py +++ b/octue/cloud/pub_sub/bigquery.py @@ -6,22 +6,13 @@ from octue.resources import Manifest -def get_events( - table_id, - sender, - question_uuid, - kind=None, - include_attributes=False, - include_backend_metadata=False, - limit=1000, -): +def get_events(table_id, sender, question_uuid, kind=None, include_backend_metadata=False, limit=1000): """Get Octue service events for a question from a sender from a Google BigQuery event store. :param str table_id: the full ID of the table e.g. "your-project.your-dataset.your-table" :param str sender: the SRUID of the sender of the events :param str question_uuid: the UUID of the question to get the events for :param str|None kind: the kind of event to get; if `None`, all event kinds are returned - :param bool include_attributes: if `True`, include events' attributes (excluding question UUID) :param bool include_backend_metadata: if `True`, include the service backend metadata :param int limit: the maximum number of events to return :return list(dict): the events for the question @@ -30,27 +21,25 @@ def get_events( if kind not in VALID_EVENT_KINDS: raise ValueError(f"`kind` must be one of {VALID_EVENT_KINDS!r}; received {kind!r}.") - event_kind_condition = [f'AND JSON_EXTRACT_SCALAR(event, "$.kind") = "{kind}"'] + event_kind_condition = [f"AND kind={kind!r}"] else: event_kind_condition = [] client = Client() - fields = ["`event`"] - - if include_attributes: - fields.extend( - ( - "`datetime`", - "`uuid`", - "`originator`", - "`sender`", - "`sender_type`", - "`sender_sdk_version`", - "`recipient`", - "`order`", - "`other_attributes`", - ) - ) + + fields = [ + "`event`", + "`kind`", + "`datetime`", + "`uuid`", + "`originator`", + "`sender`", + "`sender_type`", + "`sender_sdk_version`", + "`recipient`", + "`order`", + "`other_attributes`", + ] if include_backend_metadata: fields.extend(("`backend`", "`backend_metadata`")) @@ -98,9 +87,10 @@ def _deserialise_manifest_if_present(event): :param dict event: an Octue service event :return None: """ - if event["kind"] == "question" and event.get("input_manifest"): - event["input_manifest"] = Manifest.deserialise(event["input_manifest"]) - return + manifest_keys = {"input_manifest", "output_manifest"} - if event["kind"] == "result" and event.get("output_manifest"): - event["output_manifest"] = Manifest.deserialise(event["output_manifest"]) + for key in manifest_keys: + if key in event: + event[key] = Manifest.deserialise(event[key]) + # Only one of the manifest types will be in the event, so return if one is found. + return diff --git a/tests/cloud/pub_sub/test_bigquery.py b/tests/cloud/pub_sub/test_bigquery.py index 693b99bf2..fcdf9c0f9 100644 --- a/tests/cloud/pub_sub/test_bigquery.py +++ b/tests/cloud/pub_sub/test_bigquery.py @@ -22,8 +22,9 @@ def test_without_kind(self): self.assertEqual( mock_client.mock_calls[1].args[0], - "SELECT `event` FROM `blah`\nWHERE sender=@sender\nAND question_uuid=@question_uuid\n" - "ORDER BY `order`\nLIMIT @limit", + "SELECT `event`, `kind`, `datetime`, `uuid`, `originator`, `sender`, `sender_type`, `sender_sdk_version`, " + "`recipient`, `order`, `other_attributes` FROM `blah`\nWHERE sender=@sender\n" + "AND question_uuid=@question_uuid\nORDER BY `order`\nLIMIT @limit", ) def test_with_kind(self): @@ -33,25 +34,9 @@ def test_with_kind(self): self.assertEqual( mock_client.mock_calls[1].args[0], - "SELECT `event` FROM `blah`\nWHERE sender=@sender\nAND question_uuid=@question_uuid\n" - 'AND JSON_EXTRACT_SCALAR(event, "$.kind") = "result"\nORDER BY `order`\nLIMIT @limit', - ) - - def test_with_attributes(self): - """Test the query used to retrieve attributes in addition to events.""" - with patch("octue.cloud.pub_sub.bigquery.Client") as mock_client: - get_events( - table_id="blah", - sender="octue/test-service:1.0.0", - question_uuid="blah", - include_attributes=True, - ) - - self.assertEqual( - mock_client.mock_calls[1].args[0], - "SELECT `event`, `datetime`, `uuid`, `originator`, `sender`, `sender_type`, `sender_sdk_version`, " + "SELECT `event`, `kind`, `datetime`, `uuid`, `originator`, `sender`, `sender_type`, `sender_sdk_version`, " "`recipient`, `order`, `other_attributes` FROM `blah`\nWHERE sender=@sender\n" - "AND question_uuid=@question_uuid\nORDER BY `order`\nLIMIT @limit", + "AND question_uuid=@question_uuid\nAND kind='result'\nORDER BY `order`\nLIMIT @limit", ) def test_with_backend_metadata(self): @@ -66,6 +51,7 @@ def test_with_backend_metadata(self): self.assertEqual( mock_client.mock_calls[1].args[0], - "SELECT `event`, `backend`, `backend_metadata` FROM `blah`\n" + "SELECT `event`, `kind`, `datetime`, `uuid`, `originator`, `sender`, `sender_type`, `sender_sdk_version`, " + "`recipient`, `order`, `other_attributes`, `backend`, `backend_metadata` FROM `blah`\n" "WHERE sender=@sender\nAND question_uuid=@question_uuid\nORDER BY `order`\nLIMIT @limit", ) From 4b32c36511b831954fb0d193eec514e96ac00605 Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Wed, 17 Apr 2024 15:05:46 +0100 Subject: [PATCH 12/28] FIX: Return schema-compliant events and attributes from `get_events` --- octue/cloud/pub_sub/bigquery.py | 34 ++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/octue/cloud/pub_sub/bigquery.py b/octue/cloud/pub_sub/bigquery.py index b894988cb..a30c71ea1 100644 --- a/octue/cloud/pub_sub/bigquery.py +++ b/octue/cloud/pub_sub/bigquery.py @@ -69,15 +69,14 @@ def get_events(table_id, sender, question_uuid, kind=None, include_backend_metad # Convert JSON strings to python primitives. df["event"] = df["event"].map(json.loads) - - if "other_attributes" in df: - df["other_attributes"] = df["other_attributes"].map(json.loads) + df["event"].apply(_deserialise_manifest_if_present) + df["other_attributes"] = df["other_attributes"].map(json.loads) if "backend_metadata" in df: df["backend_metadata"] = df["backend_metadata"].map(json.loads) - df["event"].apply(_deserialise_manifest_if_present) - return df.to_dict(orient="records") + events = df.to_dict(orient="records") + return _denormalise_events(events) def _deserialise_manifest_if_present(event): @@ -94,3 +93,28 @@ def _deserialise_manifest_if_present(event): event[key] = Manifest.deserialise(event[key]) # Only one of the manifest types will be in the event, so return if one is found. return + + +def _denormalise_events(events): + """Convert the events from the flat (denormalised) structure of the BigQuery table into the nested (normalised) + structure required by the service communication schema. + + :param list(dict) events: normalised events + :return list(dict): denormalised events + """ + for event in events: + event["event"]["kind"] = event.pop("kind") + + event["attributes"] = { + "datetime": event.pop("datetime").isoformat(), + "uuid": event.pop("uuid"), + "originator": event.pop("originator"), + "sender": event.pop("sender"), + "sender_type": event.pop("sender_type"), + "sender_sdk_version": event.pop("sender_sdk_version"), + "recipient": event.pop("recipient"), + "order": event.pop("order"), + **event.pop("other_attributes"), + } + + return events From f496b4b365e8beeb761066926a84993125970b88 Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Tue, 23 Apr 2024 10:12:34 +0100 Subject: [PATCH 13/28] DEP: Make `db-dtypes` and `google-cloud-bigquery` optional BREAKING CHANGE: To keep using the `get_events` function, add the `bigquery` optional extra to your installation command e.g. `poetry install -E bigquery`. --- poetry.lock | 153 +++++++++++++++++++++++++------------------------ pyproject.toml | 5 +- 2 files changed, 80 insertions(+), 78 deletions(-) diff --git a/poetry.lock b/poetry.lock index 825ae8f2f..fec580d39 100644 --- a/poetry.lock +++ b/poetry.lock @@ -505,7 +505,7 @@ langdetect = ["langdetect"] name = "db-dtypes" version = "1.2.0" description = "Pandas Data Types for SQL systems (BigQuery, Spanner)" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "db-dtypes-1.2.0.tar.gz", hash = "sha256:3531bb1fb8b5fbab33121fe243ccc2ade16ab2524f4c113b05cc702a1908e6ea"}, @@ -577,13 +577,13 @@ dates = ["pytz (>=2019.1)"] [[package]] name = "exceptiongroup" -version = "1.2.0" +version = "1.2.1" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, - {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, + {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, + {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, ] [package.extras] @@ -733,13 +733,13 @@ requests = ["requests (>=2.20.0,<3.0.0.dev0)"] [[package]] name = "google-cloud-bigquery" -version = "3.20.1" +version = "3.21.0" description = "Google BigQuery API client library" -optional = false +optional = true python-versions = ">=3.7" files = [ - {file = "google-cloud-bigquery-3.20.1.tar.gz", hash = "sha256:318aa3abab5f1900ee24f63ba8bd02b9cdafaa942d738b4dc14a4ef2cc2d925f"}, - {file = "google_cloud_bigquery-3.20.1-py2.py3-none-any.whl", hash = "sha256:d3e62fe61138c658b8853c402e2d8fb9346c84e602e21e3a26584be10fc5b0a4"}, + {file = "google-cloud-bigquery-3.21.0.tar.gz", hash = "sha256:6265c39f9d5bdf50f11cb81a9c2a0605d285df34ac139de0d2333b1250add0ff"}, + {file = "google_cloud_bigquery-3.21.0-py2.py3-none-any.whl", hash = "sha256:83a090aae16b3a687ef22e7b0a1b551e18da615b1c4855c5f312f198959e7739"}, ] [package.dependencies] @@ -809,13 +809,13 @@ libcst = ["libcst (>=0.3.10)"] [[package]] name = "google-cloud-secret-manager" -version = "2.19.0" +version = "2.20.0" description = "Google Cloud Secret Manager API client library" optional = false python-versions = ">=3.7" files = [ - {file = "google-cloud-secret-manager-2.19.0.tar.gz", hash = "sha256:bb918435835a14eb94785f4d4d9087bdcf1b6de306432d7edaa7d62e7f780c30"}, - {file = "google_cloud_secret_manager-2.19.0-py2.py3-none-any.whl", hash = "sha256:7dd9ad9ab3e70f9a7fbac432938b702ba23bce1207e9bda86463b6d6b1f5cdbb"}, + {file = "google-cloud-secret-manager-2.20.0.tar.gz", hash = "sha256:a086a7413aaf4fffbd1c4fe9229ef0ce9bcf48f5a8df5b449c4a32deb5a2cfde"}, + {file = "google_cloud_secret_manager-2.20.0-py2.py3-none-any.whl", hash = "sha256:c20bf22e59d220c51aa84a1db3411b14b83aa71f788fae8d273c03a4bf3e77ed"}, ] [package.dependencies] @@ -956,84 +956,84 @@ protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.1 || >4.21.1,<4 [[package]] name = "grpcio" -version = "1.62.1" +version = "1.62.2" description = "HTTP/2-based RPC framework" optional = false python-versions = ">=3.7" files = [ - {file = "grpcio-1.62.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:179bee6f5ed7b5f618844f760b6acf7e910988de77a4f75b95bbfaa8106f3c1e"}, - {file = "grpcio-1.62.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:48611e4fa010e823ba2de8fd3f77c1322dd60cb0d180dc6630a7e157b205f7ea"}, - {file = "grpcio-1.62.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:b2a0e71b0a2158aa4bce48be9f8f9eb45cbd17c78c7443616d00abbe2a509f6d"}, - {file = "grpcio-1.62.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fbe80577c7880911d3ad65e5ecc997416c98f354efeba2f8d0f9112a67ed65a5"}, - {file = "grpcio-1.62.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58f6c693d446964e3292425e1d16e21a97a48ba9172f2d0df9d7b640acb99243"}, - {file = "grpcio-1.62.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:77c339403db5a20ef4fed02e4d1a9a3d9866bf9c0afc77a42234677313ea22f3"}, - {file = "grpcio-1.62.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b5a4ea906db7dec694098435d84bf2854fe158eb3cd51e1107e571246d4d1d70"}, - {file = "grpcio-1.62.1-cp310-cp310-win32.whl", hash = "sha256:4187201a53f8561c015bc745b81a1b2d278967b8de35f3399b84b0695e281d5f"}, - {file = "grpcio-1.62.1-cp310-cp310-win_amd64.whl", hash = "sha256:844d1f3fb11bd1ed362d3fdc495d0770cfab75761836193af166fee113421d66"}, - {file = "grpcio-1.62.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:833379943d1728a005e44103f17ecd73d058d37d95783eb8f0b28ddc1f54d7b2"}, - {file = "grpcio-1.62.1-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:c7fcc6a32e7b7b58f5a7d27530669337a5d587d4066060bcb9dee7a8c833dfb7"}, - {file = "grpcio-1.62.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:fa7d28eb4d50b7cbe75bb8b45ed0da9a1dc5b219a0af59449676a29c2eed9698"}, - {file = "grpcio-1.62.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48f7135c3de2f298b833be8b4ae20cafe37091634e91f61f5a7eb3d61ec6f660"}, - {file = "grpcio-1.62.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71f11fd63365ade276c9d4a7b7df5c136f9030e3457107e1791b3737a9b9ed6a"}, - {file = "grpcio-1.62.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4b49fd8fe9f9ac23b78437da94c54aa7e9996fbb220bac024a67469ce5d0825f"}, - {file = "grpcio-1.62.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:482ae2ae78679ba9ed5752099b32e5fe580443b4f798e1b71df412abf43375db"}, - {file = "grpcio-1.62.1-cp311-cp311-win32.whl", hash = "sha256:1faa02530b6c7426404372515fe5ddf66e199c2ee613f88f025c6f3bd816450c"}, - {file = "grpcio-1.62.1-cp311-cp311-win_amd64.whl", hash = "sha256:5bd90b8c395f39bc82a5fb32a0173e220e3f401ff697840f4003e15b96d1befc"}, - {file = "grpcio-1.62.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:b134d5d71b4e0837fff574c00e49176051a1c532d26c052a1e43231f252d813b"}, - {file = "grpcio-1.62.1-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:d1f6c96573dc09d50dbcbd91dbf71d5cf97640c9427c32584010fbbd4c0e0037"}, - {file = "grpcio-1.62.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:359f821d4578f80f41909b9ee9b76fb249a21035a061a327f91c953493782c31"}, - {file = "grpcio-1.62.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a485f0c2010c696be269184bdb5ae72781344cb4e60db976c59d84dd6354fac9"}, - {file = "grpcio-1.62.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b50b09b4dc01767163d67e1532f948264167cd27f49e9377e3556c3cba1268e1"}, - {file = "grpcio-1.62.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3227c667dccbe38f2c4d943238b887bac588d97c104815aecc62d2fd976e014b"}, - {file = "grpcio-1.62.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3952b581eb121324853ce2b191dae08badb75cd493cb4e0243368aa9e61cfd41"}, - {file = "grpcio-1.62.1-cp312-cp312-win32.whl", hash = "sha256:83a17b303425104d6329c10eb34bba186ffa67161e63fa6cdae7776ff76df73f"}, - {file = "grpcio-1.62.1-cp312-cp312-win_amd64.whl", hash = "sha256:6696ffe440333a19d8d128e88d440f91fb92c75a80ce4b44d55800e656a3ef1d"}, - {file = "grpcio-1.62.1-cp37-cp37m-linux_armv7l.whl", hash = "sha256:e3393b0823f938253370ebef033c9fd23d27f3eae8eb9a8f6264900c7ea3fb5a"}, - {file = "grpcio-1.62.1-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:83e7ccb85a74beaeae2634f10eb858a0ed1a63081172649ff4261f929bacfd22"}, - {file = "grpcio-1.62.1-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:882020c87999d54667a284c7ddf065b359bd00251fcd70279ac486776dbf84ec"}, - {file = "grpcio-1.62.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a10383035e864f386fe096fed5c47d27a2bf7173c56a6e26cffaaa5a361addb1"}, - {file = "grpcio-1.62.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:960edebedc6b9ada1ef58e1c71156f28689978188cd8cff3b646b57288a927d9"}, - {file = "grpcio-1.62.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:23e2e04b83f347d0aadde0c9b616f4726c3d76db04b438fd3904b289a725267f"}, - {file = "grpcio-1.62.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:978121758711916d34fe57c1f75b79cdfc73952f1481bb9583399331682d36f7"}, - {file = "grpcio-1.62.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9084086190cc6d628f282e5615f987288b95457292e969b9205e45b442276407"}, - {file = "grpcio-1.62.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:22bccdd7b23c420a27fd28540fb5dcbc97dc6be105f7698cb0e7d7a420d0e362"}, - {file = "grpcio-1.62.1-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:8999bf1b57172dbc7c3e4bb3c732658e918f5c333b2942243f10d0d653953ba9"}, - {file = "grpcio-1.62.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:d9e52558b8b8c2f4ac05ac86344a7417ccdd2b460a59616de49eb6933b07a0bd"}, - {file = "grpcio-1.62.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1714e7bc935780bc3de1b3fcbc7674209adf5208ff825799d579ffd6cd0bd505"}, - {file = "grpcio-1.62.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8842ccbd8c0e253c1f189088228f9b433f7a93b7196b9e5b6f87dba393f5d5d"}, - {file = "grpcio-1.62.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1f1e7b36bdff50103af95a80923bf1853f6823dd62f2d2a2524b66ed74103e49"}, - {file = "grpcio-1.62.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bba97b8e8883a8038606480d6b6772289f4c907f6ba780fa1f7b7da7dfd76f06"}, - {file = "grpcio-1.62.1-cp38-cp38-win32.whl", hash = "sha256:a7f615270fe534548112a74e790cd9d4f5509d744dd718cd442bf016626c22e4"}, - {file = "grpcio-1.62.1-cp38-cp38-win_amd64.whl", hash = "sha256:e6c8c8693df718c5ecbc7babb12c69a4e3677fd11de8886f05ab22d4e6b1c43b"}, - {file = "grpcio-1.62.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:73db2dc1b201d20ab7083e7041946910bb991e7e9761a0394bbc3c2632326483"}, - {file = "grpcio-1.62.1-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:407b26b7f7bbd4f4751dbc9767a1f0716f9fe72d3d7e96bb3ccfc4aace07c8de"}, - {file = "grpcio-1.62.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:f8de7c8cef9261a2d0a62edf2ccea3d741a523c6b8a6477a340a1f2e417658de"}, - {file = "grpcio-1.62.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd5c8a1af40ec305d001c60236308a67e25419003e9bb3ebfab5695a8d0b369"}, - {file = "grpcio-1.62.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be0477cb31da67846a33b1a75c611f88bfbcd427fe17701b6317aefceee1b96f"}, - {file = "grpcio-1.62.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:60dcd824df166ba266ee0cfaf35a31406cd16ef602b49f5d4dfb21f014b0dedd"}, - {file = "grpcio-1.62.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:973c49086cabab773525f6077f95e5a993bfc03ba8fc32e32f2c279497780585"}, - {file = "grpcio-1.62.1-cp39-cp39-win32.whl", hash = "sha256:12859468e8918d3bd243d213cd6fd6ab07208195dc140763c00dfe901ce1e1b4"}, - {file = "grpcio-1.62.1-cp39-cp39-win_amd64.whl", hash = "sha256:b7209117bbeebdfa5d898205cc55153a51285757902dd73c47de498ad4d11332"}, - {file = "grpcio-1.62.1.tar.gz", hash = "sha256:6c455e008fa86d9e9a9d85bb76da4277c0d7d9668a3bfa70dbe86e9f3c759947"}, + {file = "grpcio-1.62.2-cp310-cp310-linux_armv7l.whl", hash = "sha256:66344ea741124c38588a664237ac2fa16dfd226964cca23ddc96bd4accccbde5"}, + {file = "grpcio-1.62.2-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:5dab7ac2c1e7cb6179c6bfad6b63174851102cbe0682294e6b1d6f0981ad7138"}, + {file = "grpcio-1.62.2-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:3ad00f3f0718894749d5a8bb0fa125a7980a2f49523731a9b1fabf2b3522aa43"}, + {file = "grpcio-1.62.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e72ddfee62430ea80133d2cbe788e0d06b12f865765cb24a40009668bd8ea05"}, + {file = "grpcio-1.62.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53d3a59a10af4c2558a8e563aed9f256259d2992ae0d3037817b2155f0341de1"}, + {file = "grpcio-1.62.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a1511a303f8074f67af4119275b4f954189e8313541da7b88b1b3a71425cdb10"}, + {file = "grpcio-1.62.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b94d41b7412ef149743fbc3178e59d95228a7064c5ab4760ae82b562bdffb199"}, + {file = "grpcio-1.62.2-cp310-cp310-win32.whl", hash = "sha256:a75af2fc7cb1fe25785be7bed1ab18cef959a376cdae7c6870184307614caa3f"}, + {file = "grpcio-1.62.2-cp310-cp310-win_amd64.whl", hash = "sha256:80407bc007754f108dc2061e37480238b0dc1952c855e86a4fc283501ee6bb5d"}, + {file = "grpcio-1.62.2-cp311-cp311-linux_armv7l.whl", hash = "sha256:c1624aa686d4b36790ed1c2e2306cc3498778dffaf7b8dd47066cf819028c3ad"}, + {file = "grpcio-1.62.2-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:1c1bb80299bdef33309dff03932264636450c8fdb142ea39f47e06a7153d3063"}, + {file = "grpcio-1.62.2-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:db068bbc9b1fa16479a82e1ecf172a93874540cb84be69f0b9cb9b7ac3c82670"}, + {file = "grpcio-1.62.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2cc8a308780edbe2c4913d6a49dbdb5befacdf72d489a368566be44cadaef1a"}, + {file = "grpcio-1.62.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0695ae31a89f1a8fc8256050329a91a9995b549a88619263a594ca31b76d756"}, + {file = "grpcio-1.62.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:88b4f9ee77191dcdd8810241e89340a12cbe050be3e0d5f2f091c15571cd3930"}, + {file = "grpcio-1.62.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2a0204532aa2f1afd467024b02b4069246320405bc18abec7babab03e2644e75"}, + {file = "grpcio-1.62.2-cp311-cp311-win32.whl", hash = "sha256:6e784f60e575a0de554ef9251cbc2ceb8790914fe324f11e28450047f264ee6f"}, + {file = "grpcio-1.62.2-cp311-cp311-win_amd64.whl", hash = "sha256:112eaa7865dd9e6d7c0556c8b04ae3c3a2dc35d62ad3373ab7f6a562d8199200"}, + {file = "grpcio-1.62.2-cp312-cp312-linux_armv7l.whl", hash = "sha256:65034473fc09628a02fb85f26e73885cf1ed39ebd9cf270247b38689ff5942c5"}, + {file = "grpcio-1.62.2-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:d2c1771d0ee3cf72d69bb5e82c6a82f27fbd504c8c782575eddb7839729fbaad"}, + {file = "grpcio-1.62.2-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:3abe6838196da518863b5d549938ce3159d809218936851b395b09cad9b5d64a"}, + {file = "grpcio-1.62.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5ffeb269f10cedb4f33142b89a061acda9f672fd1357331dbfd043422c94e9e"}, + {file = "grpcio-1.62.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:404d3b4b6b142b99ba1cff0b2177d26b623101ea2ce51c25ef6e53d9d0d87bcc"}, + {file = "grpcio-1.62.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:262cda97efdabb20853d3b5a4c546a535347c14b64c017f628ca0cc7fa780cc6"}, + {file = "grpcio-1.62.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:17708db5b11b966373e21519c4c73e5a750555f02fde82276ea2a267077c68ad"}, + {file = "grpcio-1.62.2-cp312-cp312-win32.whl", hash = "sha256:b7ec9e2f8ffc8436f6b642a10019fc513722858f295f7efc28de135d336ac189"}, + {file = "grpcio-1.62.2-cp312-cp312-win_amd64.whl", hash = "sha256:aa787b83a3cd5e482e5c79be030e2b4a122ecc6c5c6c4c42a023a2b581fdf17b"}, + {file = "grpcio-1.62.2-cp37-cp37m-linux_armv7l.whl", hash = "sha256:cfd23ad29bfa13fd4188433b0e250f84ec2c8ba66b14a9877e8bce05b524cf54"}, + {file = "grpcio-1.62.2-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:af15e9efa4d776dfcecd1d083f3ccfb04f876d613e90ef8432432efbeeac689d"}, + {file = "grpcio-1.62.2-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:f4aa94361bb5141a45ca9187464ae81a92a2a135ce2800b2203134f7a1a1d479"}, + {file = "grpcio-1.62.2-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82af3613a219512a28ee5c95578eb38d44dd03bca02fd918aa05603c41018051"}, + {file = "grpcio-1.62.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55ddaf53474e8caeb29eb03e3202f9d827ad3110475a21245f3c7712022882a9"}, + {file = "grpcio-1.62.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c79b518c56dddeec79e5500a53d8a4db90da995dfe1738c3ac57fe46348be049"}, + {file = "grpcio-1.62.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a5eb4844e5e60bf2c446ef38c5b40d7752c6effdee882f716eb57ae87255d20a"}, + {file = "grpcio-1.62.2-cp37-cp37m-win_amd64.whl", hash = "sha256:aaae70364a2d1fb238afd6cc9fcb10442b66e397fd559d3f0968d28cc3ac929c"}, + {file = "grpcio-1.62.2-cp38-cp38-linux_armv7l.whl", hash = "sha256:1bcfe5070e4406f489e39325b76caeadab28c32bf9252d3ae960c79935a4cc36"}, + {file = "grpcio-1.62.2-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:da6a7b6b938c15fa0f0568e482efaae9c3af31963eec2da4ff13a6d8ec2888e4"}, + {file = "grpcio-1.62.2-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:41955b641c34db7d84db8d306937b72bc4968eef1c401bea73081a8d6c3d8033"}, + {file = "grpcio-1.62.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c772f225483905f675cb36a025969eef9712f4698364ecd3a63093760deea1bc"}, + {file = "grpcio-1.62.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07ce1f775d37ca18c7a141300e5b71539690efa1f51fe17f812ca85b5e73262f"}, + {file = "grpcio-1.62.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:26f415f40f4a93579fd648f48dca1c13dfacdfd0290f4a30f9b9aeb745026811"}, + {file = "grpcio-1.62.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:db707e3685ff16fc1eccad68527d072ac8bdd2e390f6daa97bc394ea7de4acea"}, + {file = "grpcio-1.62.2-cp38-cp38-win32.whl", hash = "sha256:589ea8e75de5fd6df387de53af6c9189c5231e212b9aa306b6b0d4f07520fbb9"}, + {file = "grpcio-1.62.2-cp38-cp38-win_amd64.whl", hash = "sha256:3c3ed41f4d7a3aabf0f01ecc70d6b5d00ce1800d4af652a549de3f7cf35c4abd"}, + {file = "grpcio-1.62.2-cp39-cp39-linux_armv7l.whl", hash = "sha256:162ccf61499c893831b8437120600290a99c0bc1ce7b51f2c8d21ec87ff6af8b"}, + {file = "grpcio-1.62.2-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:f27246d7da7d7e3bd8612f63785a7b0c39a244cf14b8dd9dd2f2fab939f2d7f1"}, + {file = "grpcio-1.62.2-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:2507006c8a478f19e99b6fe36a2464696b89d40d88f34e4b709abe57e1337467"}, + {file = "grpcio-1.62.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a90ac47a8ce934e2c8d71e317d2f9e7e6aaceb2d199de940ce2c2eb611b8c0f4"}, + {file = "grpcio-1.62.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99701979bcaaa7de8d5f60476487c5df8f27483624f1f7e300ff4669ee44d1f2"}, + {file = "grpcio-1.62.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:af7dc3f7a44f10863b1b0ecab4078f0a00f561aae1edbd01fd03ad4dcf61c9e9"}, + {file = "grpcio-1.62.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fa63245271920786f4cb44dcada4983a3516be8f470924528cf658731864c14b"}, + {file = "grpcio-1.62.2-cp39-cp39-win32.whl", hash = "sha256:c6ad9c39704256ed91a1cffc1379d63f7d0278d6a0bad06b0330f5d30291e3a3"}, + {file = "grpcio-1.62.2-cp39-cp39-win_amd64.whl", hash = "sha256:16da954692fd61aa4941fbeda405a756cd96b97b5d95ca58a92547bba2c1624f"}, + {file = "grpcio-1.62.2.tar.gz", hash = "sha256:c77618071d96b7a8be2c10701a98537823b9c65ba256c0b9067e0594cdbd954d"}, ] [package.extras] -protobuf = ["grpcio-tools (>=1.62.1)"] +protobuf = ["grpcio-tools (>=1.62.2)"] [[package]] name = "grpcio-status" -version = "1.62.1" +version = "1.62.2" description = "Status proto mapping for gRPC" optional = false python-versions = ">=3.6" files = [ - {file = "grpcio-status-1.62.1.tar.gz", hash = "sha256:3431c8abbab0054912c41df5c72f03ddf3b7a67be8a287bb3c18a3456f96ff77"}, - {file = "grpcio_status-1.62.1-py3-none-any.whl", hash = "sha256:af0c3ab85da31669f21749e8d53d669c061ebc6ce5637be49a46edcb7aa8ab17"}, + {file = "grpcio-status-1.62.2.tar.gz", hash = "sha256:62e1bfcb02025a1cd73732a2d33672d3e9d0df4d21c12c51e0bbcaf09bab742a"}, + {file = "grpcio_status-1.62.2-py3-none-any.whl", hash = "sha256:206ddf0eb36bc99b033f03b2c8e95d319f0044defae9b41ae21408e7e0cda48f"}, ] [package.dependencies] googleapis-common-protos = ">=1.5.5" -grpcio = ">=1.62.1" +grpcio = ">=1.62.2" protobuf = ">=4.21.6" [[package]] @@ -1686,7 +1686,7 @@ files = [ name = "pyarrow" version = "12.0.1" description = "Python library for Apache Arrow" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "pyarrow-12.0.1-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:6d288029a94a9bb5407ceebdd7110ba398a00412c5b0155ee9813a40d246c5df"}, @@ -2641,13 +2641,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.25.2" +version = "20.25.3" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.25.2-py3-none-any.whl", hash = "sha256:6e1281a57849c8a54da89ba82e5eb7c8937b9d057ff01aaf5bc9afaa3552e90f"}, - {file = "virtualenv-20.25.2.tar.gz", hash = "sha256:fa7edb8428620518010928242ec17aa7132ae435319c29c1651d1cf4c4173aad"}, + {file = "virtualenv-20.25.3-py3-none-any.whl", hash = "sha256:8aac4332f2ea6ef519c648d0bc48a5b1d324994753519919bddbb1aff25a104e"}, + {file = "virtualenv-20.25.3.tar.gz", hash = "sha256:7bb554bbdfeaacc3349fa614ea5bff6ac300fc7c335e9facf3a3bcfc703f45be"}, ] [package.dependencies] @@ -2704,9 +2704,10 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [extras] +bigquery = ["db-dtypes", "google-cloud-bigquery"] hdf5 = ["h5py"] [metadata] lock-version = "2.0" python-versions = "^3.7.1" -content-hash = "61840dbaf0a8252b7e37d55461f59ccd0b1915e5e7b61f7f733cb7ef021a3d6d" +content-hash = "d4a2202f4ba37898c01b69447907acaff2517a182f508ef52cdeffce676cbd4b" diff --git a/pyproject.toml b/pyproject.toml index 860df93ac..d2821fb50 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,11 +35,12 @@ pyyaml = "^6" h5py = { version = "^3.6", optional = true } twined = "^0.5.1" packaging = ">=20.4" -google-cloud-bigquery = "^3.18.0" -db-dtypes = "^1.2.0" +google-cloud-bigquery = { version = "^3.18.0", optional = true } +db-dtypes = { version = "^1.2.0", optional = true } [tool.poetry.extras] hdf5 = ["h5py"] +bigquery = ["google-cloud-bigquery", "db-dtypes"] [tool.poetry.scripts] octue = "octue.cli:octue_cli" From 0a731acedd8bc92792a01f1d1d7bf89ce62cbb72 Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Tue, 23 Apr 2024 10:37:06 +0100 Subject: [PATCH 14/28] TST: Update deployment test skipci --- .../deployment/google/cloud_run/test_cloud_run_deployment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cloud/deployment/google/cloud_run/test_cloud_run_deployment.py b/tests/cloud/deployment/google/cloud_run/test_cloud_run_deployment.py index 778a2c93c..76f60e304 100644 --- a/tests/cloud/deployment/google/cloud_run/test_cloud_run_deployment.py +++ b/tests/cloud/deployment/google/cloud_run/test_cloud_run_deployment.py @@ -8,7 +8,7 @@ from octue.resources import Child -EXAMPLE_SERVICE_SRUID = "octue/example-service-cloud-run:0.4.1" +EXAMPLE_SERVICE_SRUID = "octue/example-service-cloud-run:0.4.2" @unittest.skipUnless( From 7376f91619190a7437e5a7ef7f0a9fb3b4f2bbff Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Tue, 23 Apr 2024 10:41:49 +0100 Subject: [PATCH 15/28] REF: Rename `_denormalise_events` to `_unflatten_events` skipci --- octue/cloud/pub_sub/bigquery.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/octue/cloud/pub_sub/bigquery.py b/octue/cloud/pub_sub/bigquery.py index a30c71ea1..2aa8d5f7d 100644 --- a/octue/cloud/pub_sub/bigquery.py +++ b/octue/cloud/pub_sub/bigquery.py @@ -76,7 +76,7 @@ def get_events(table_id, sender, question_uuid, kind=None, include_backend_metad df["backend_metadata"] = df["backend_metadata"].map(json.loads) events = df.to_dict(orient="records") - return _denormalise_events(events) + return _unflatten_events(events) def _deserialise_manifest_if_present(event): @@ -95,12 +95,12 @@ def _deserialise_manifest_if_present(event): return -def _denormalise_events(events): - """Convert the events from the flat (denormalised) structure of the BigQuery table into the nested (normalised) - structure required by the service communication schema. +def _unflatten_events(events): + """Convert the events and attributes from the flat structure of the BigQuery table into the nested structure of the + service communication schema. - :param list(dict) events: normalised events - :return list(dict): denormalised events + :param list(dict) events: flattened events + :return list(dict): unflattened events """ for event in events: event["event"]["kind"] = event.pop("kind") From 76a48671f70580629985fbc2acdcc607fe599d6d Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Tue, 23 Apr 2024 10:58:37 +0100 Subject: [PATCH 16/28] ENH: Raise error if no events found when calling `get_events` skipci --- octue/cloud/pub_sub/bigquery.py | 14 ++++++++++++-- tests/cloud/pub_sub/test_bigquery.py | 26 +++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/octue/cloud/pub_sub/bigquery.py b/octue/cloud/pub_sub/bigquery.py index 2aa8d5f7d..70b278b4d 100644 --- a/octue/cloud/pub_sub/bigquery.py +++ b/octue/cloud/pub_sub/bigquery.py @@ -3,6 +3,7 @@ from google.cloud.bigquery import Client, QueryJobConfig, ScalarQueryParameter from octue.cloud.events.validation import VALID_EVENT_KINDS +from octue.exceptions import ServiceNotFound from octue.resources import Manifest @@ -15,6 +16,8 @@ def get_events(table_id, sender, question_uuid, kind=None, include_backend_metad :param str|None kind: the kind of event to get; if `None`, all event kinds are returned :param bool include_backend_metadata: if `True`, include the service backend metadata :param int limit: the maximum number of events to return + :raise ValueError: if the `kind` parameter is invalid + :raise octue.exceptions.ServiceNotFound: if the sender hasn't emitted any events related to the question UUID (or any events at all) :return list(dict): the events for the question """ if kind: @@ -64,8 +67,15 @@ def get_events(table_id, sender, question_uuid, kind=None, include_backend_metad ) query_job = client.query(query, job_config=job_config) - rows = query_job.result() - df = rows.to_dataframe() + result = query_job.result() + + if result.total_rows == 0: + raise ServiceNotFound( + f"No events found. The requested sender {sender!r} may not exist or it hasn't emitted any events for " + f"question {question_uuid!r} (or any events at all)." + ) + + df = result.to_dataframe() # Convert JSON strings to python primitives. df["event"] = df["event"].map(json.loads) diff --git a/tests/cloud/pub_sub/test_bigquery.py b/tests/cloud/pub_sub/test_bigquery.py index fcdf9c0f9..05d1dc370 100644 --- a/tests/cloud/pub_sub/test_bigquery.py +++ b/tests/cloud/pub_sub/test_bigquery.py @@ -1,7 +1,25 @@ from unittest import TestCase -from unittest.mock import patch +from unittest.mock import MagicMock, patch from octue.cloud.pub_sub.bigquery import get_events +from octue.exceptions import ServiceNotFound + + +class MockEmptyResult: + """A mock empty query result.""" + + def __init__(self, total_rows=0): + self.total_rows = total_rows + + def result(self): + return MagicMock(total_rows=self.total_rows) + + +class MockEmptyBigQueryClient: + """A mock BigQuery client that returns a mock empty query result.""" + + def query(self, *args, **kwargs): + return MockEmptyResult() class TestGetEvents(TestCase): @@ -15,6 +33,12 @@ def test_error_raised_if_event_kind_invalid(self): kind="frisbee_tournament", ) + def test_error_raised_if_no_events_found(self): + """Test that an error is raised if no events are found.""" + with patch("octue.cloud.pub_sub.bigquery.Client", MockEmptyBigQueryClient): + with self.assertRaises(ServiceNotFound): + get_events(table_id="blah", sender="octue/test-service:1.0.0", question_uuid="blah") + def test_without_kind(self): """Test the query used to retrieve events of all kinds.""" with patch("octue.cloud.pub_sub.bigquery.Client") as mock_client: From 6d04c97a8b5de6f304421c7ec9dea9afa0e74336 Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Tue, 23 Apr 2024 11:09:14 +0100 Subject: [PATCH 17/28] TST: Always make `total_rows=0` in `MockEmptyResult` --- tests/cloud/pub_sub/test_bigquery.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/cloud/pub_sub/test_bigquery.py b/tests/cloud/pub_sub/test_bigquery.py index 05d1dc370..0057dd420 100644 --- a/tests/cloud/pub_sub/test_bigquery.py +++ b/tests/cloud/pub_sub/test_bigquery.py @@ -8,11 +8,8 @@ class MockEmptyResult: """A mock empty query result.""" - def __init__(self, total_rows=0): - self.total_rows = total_rows - def result(self): - return MagicMock(total_rows=self.total_rows) + return MagicMock(total_rows=0) class MockEmptyBigQueryClient: From 8239c19fcb142e4bb4ce0e48e73f0a0c3d2c9254 Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Tue, 23 Apr 2024 11:27:59 +0100 Subject: [PATCH 18/28] OPS: Update `actions/setup-python` to version 5 --- .github/workflows/python-ci.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/version-compatibility.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index d830f7187..415b34bb8 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -34,7 +34,7 @@ jobs: uses: actions/checkout@v3 - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: 3.9 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index eb6b95e38..f20a8f0d3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,7 +26,7 @@ jobs: uses: actions/checkout@v3 - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: 3.9 diff --git a/.github/workflows/version-compatibility.yml b/.github/workflows/version-compatibility.yml index d2ce366a5..19c094116 100644 --- a/.github/workflows/version-compatibility.yml +++ b/.github/workflows/version-compatibility.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v5 - name: Install Poetry uses: snok/install-poetry@v1 - name: Check version compatibility has been tested From 6d47bb167840028fe56789ae6d16302f51ca785d Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Tue, 23 Apr 2024 11:29:38 +0100 Subject: [PATCH 19/28] OPS: Cache dependencies in some workflows --- .github/workflows/python-ci.yml | 1 + .github/workflows/release.yml | 1 + .github/workflows/version-compatibility.yml | 3 +++ 3 files changed, 5 insertions(+) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index 415b34bb8..fbaa5c1e1 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -37,6 +37,7 @@ jobs: uses: actions/setup-python@v5 with: python-version: 3.9 + cache: poetry - name: Install Poetry uses: snok/install-poetry@v1.3.2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f20a8f0d3..0859f29d1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,6 +29,7 @@ jobs: uses: actions/setup-python@v5 with: python-version: 3.9 + cache: poetry - name: Install Poetry uses: snok/install-poetry@v1.3.2 diff --git a/.github/workflows/version-compatibility.yml b/.github/workflows/version-compatibility.yml index 19c094116..d5d546cd6 100644 --- a/.github/workflows/version-compatibility.yml +++ b/.github/workflows/version-compatibility.yml @@ -11,8 +11,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + - uses: actions/setup-python@v5 + - name: Install Poetry uses: snok/install-poetry@v1 + - name: Check version compatibility has been tested run: python scripts/check_version_compatibility_tested.py From 63a6ad8c22ba39aa74769dcac46c0052df1ea819 Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Tue, 23 Apr 2024 11:34:16 +0100 Subject: [PATCH 20/28] OPS: Install poetry before caching dependencies --- .github/workflows/python-ci.yml | 6 +++--- .github/workflows/release.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index fbaa5c1e1..c6025665e 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -33,15 +33,15 @@ jobs: - name: Checkout Repository uses: actions/checkout@v3 + - name: Install Poetry + uses: snok/install-poetry@v1.3.2 + - name: Setup Python uses: actions/setup-python@v5 with: python-version: 3.9 cache: poetry - - name: Install Poetry - uses: snok/install-poetry@v1.3.2 - - name: Check pyproject.toml file run: poetry check diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0859f29d1..97557d8ed 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,15 +25,15 @@ jobs: - name: Checkout Repository uses: actions/checkout@v3 + - name: Install Poetry + uses: snok/install-poetry@v1.3.2 + - name: Setup Python uses: actions/setup-python@v5 with: python-version: 3.9 cache: poetry - - name: Install Poetry - uses: snok/install-poetry@v1.3.2 - - name: Check pyproject.toml file run: poetry check From b2590282ad751fad873cf93fc7969bb6e727317d Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Tue, 23 Apr 2024 11:34:52 +0100 Subject: [PATCH 21/28] OPS: Run tests with python3.10 --- .github/workflows/python-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index c6025665e..dea2d9d43 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -23,7 +23,7 @@ jobs: if: "!contains(github.event.head_commit.message, 'skipci')" runs-on: ${{ matrix.os }} env: - USING_COVERAGE: "3.9" + USING_COVERAGE: "3.10" strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] @@ -39,7 +39,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: "3.10" cache: poetry - name: Check pyproject.toml file From 0c45c2f10384705dc0b8ffa86219106cd1b5bd47 Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Tue, 23 Apr 2024 11:42:05 +0100 Subject: [PATCH 22/28] REV: Revert "OPS: Install poetry before caching dependencies" This reverts commit 63a6ad8c22ba39aa74769dcac46c0052df1ea819. --- .github/workflows/python-ci.yml | 6 +++--- .github/workflows/release.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index dea2d9d43..fc99755a1 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -33,15 +33,15 @@ jobs: - name: Checkout Repository uses: actions/checkout@v3 - - name: Install Poetry - uses: snok/install-poetry@v1.3.2 - - name: Setup Python uses: actions/setup-python@v5 with: python-version: "3.10" cache: poetry + - name: Install Poetry + uses: snok/install-poetry@v1.3.2 + - name: Check pyproject.toml file run: poetry check diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 97557d8ed..0859f29d1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,15 +25,15 @@ jobs: - name: Checkout Repository uses: actions/checkout@v3 - - name: Install Poetry - uses: snok/install-poetry@v1.3.2 - - name: Setup Python uses: actions/setup-python@v5 with: python-version: 3.9 cache: poetry + - name: Install Poetry + uses: snok/install-poetry@v1.3.2 + - name: Check pyproject.toml file run: poetry check From 3b1ffa71a44cd0a95887c26ae6e46c1144c8bf64 Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Tue, 23 Apr 2024 11:42:54 +0100 Subject: [PATCH 23/28] REV: Revert "OPS: Cache dependencies in some workflows" This reverts commit 6d47bb167840028fe56789ae6d16302f51ca785d. --- .github/workflows/python-ci.yml | 1 - .github/workflows/release.yml | 1 - .github/workflows/version-compatibility.yml | 3 --- 3 files changed, 5 deletions(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index fc99755a1..6596a5315 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -37,7 +37,6 @@ jobs: uses: actions/setup-python@v5 with: python-version: "3.10" - cache: poetry - name: Install Poetry uses: snok/install-poetry@v1.3.2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0859f29d1..f20a8f0d3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,7 +29,6 @@ jobs: uses: actions/setup-python@v5 with: python-version: 3.9 - cache: poetry - name: Install Poetry uses: snok/install-poetry@v1.3.2 diff --git a/.github/workflows/version-compatibility.yml b/.github/workflows/version-compatibility.yml index d5d546cd6..19c094116 100644 --- a/.github/workflows/version-compatibility.yml +++ b/.github/workflows/version-compatibility.yml @@ -11,11 +11,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: actions/setup-python@v5 - - name: Install Poetry uses: snok/install-poetry@v1 - - name: Check version compatibility has been tested run: python scripts/check_version_compatibility_tested.py From c86b441a43f4ac79c3898cd4fc06541ca855b0ee Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Tue, 23 Apr 2024 11:53:22 +0100 Subject: [PATCH 24/28] OPS: Use python3.11 for tests --- .github/workflows/python-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index 6596a5315..1d7865be2 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -23,7 +23,7 @@ jobs: if: "!contains(github.event.head_commit.message, 'skipci')" runs-on: ${{ matrix.os }} env: - USING_COVERAGE: "3.10" + USING_COVERAGE: "3.11" strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] @@ -36,7 +36,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install Poetry uses: snok/install-poetry@v1.3.2 From abfe68be021bb90845c8d45788a5174dc962d8a3 Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Tue, 23 Apr 2024 11:59:15 +0100 Subject: [PATCH 25/28] DEP: Loosen numpy dependency --- poetry.lock | 60 +++++++++++++++++++++++++------------------------- pyproject.toml | 2 +- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/poetry.lock b/poetry.lock index fec580d39..029a2fccb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1473,39 +1473,39 @@ setuptools = "*" [[package]] name = "numpy" -version = "1.21.0" +version = "1.21.1" description = "NumPy is the fundamental package for array computing with Python." optional = false python-versions = ">=3.7" files = [ - {file = "numpy-1.21.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d5caa946a9f55511e76446e170bdad1d12d6b54e17a2afe7b189112ed4412bb8"}, - {file = "numpy-1.21.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ac4fd578322842dbda8d968e3962e9f22e862b6ec6e3378e7415625915e2da4d"}, - {file = "numpy-1.21.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:598fe100b2948465cf3ed64b1a326424b5e4be2670552066e17dfaa67246011d"}, - {file = "numpy-1.21.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c55407f739f0bfcec67d0df49103f9333edc870061358ac8a8c9e37ea02fcd2"}, - {file = "numpy-1.21.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:75579acbadbf74e3afd1153da6177f846212ea2a0cc77de53523ae02c9256513"}, - {file = "numpy-1.21.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cc367c86eb87e5b7c9592935620f22d13b090c609f1b27e49600cd033b529f54"}, - {file = "numpy-1.21.0-cp37-cp37m-win32.whl", hash = "sha256:d89b0dc7f005090e32bb4f9bf796e1dcca6b52243caf1803fdd2b748d8561f63"}, - {file = "numpy-1.21.0-cp37-cp37m-win_amd64.whl", hash = "sha256:eda2829af498946c59d8585a9fd74da3f810866e05f8df03a86f70079c7531dd"}, - {file = "numpy-1.21.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:1a784e8ff7ea2a32e393cc53eb0003eca1597c7ca628227e34ce34eb11645a0e"}, - {file = "numpy-1.21.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bba474a87496d96e61461f7306fba2ebba127bed7836212c360f144d1e72ac54"}, - {file = "numpy-1.21.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fd0a359c1c17f00cb37de2969984a74320970e0ceef4808c32e00773b06649d9"}, - {file = "numpy-1.21.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e4d5a86a5257843a18fb1220c5f1c199532bc5d24e849ed4b0289fb59fbd4d8f"}, - {file = "numpy-1.21.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:620732f42259eb2c4642761bd324462a01cdd13dd111740ce3d344992dd8492f"}, - {file = "numpy-1.21.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9205711e5440954f861ceeea8f1b415d7dd15214add2e878b4d1cf2bcb1a914"}, - {file = "numpy-1.21.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ad09f55cc95ed8d80d8ab2052f78cc21cb231764de73e229140d81ff49d8145e"}, - {file = "numpy-1.21.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a1f2fb2da242568af0271455b89aee0f71e4e032086ee2b4c5098945d0e11cf6"}, - {file = "numpy-1.21.0-cp38-cp38-win32.whl", hash = "sha256:e58ddb53a7b4959932f5582ac455ff90dcb05fac3f8dcc8079498d43afbbde6c"}, - {file = "numpy-1.21.0-cp38-cp38-win_amd64.whl", hash = "sha256:d2910d0a075caed95de1a605df00ee03b599de5419d0b95d55342e9a33ad1fb3"}, - {file = "numpy-1.21.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a290989cd671cd0605e9c91a70e6df660f73ae87484218e8285c6522d29f6e38"}, - {file = "numpy-1.21.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3537b967b350ad17633b35c2f4b1a1bbd258c018910b518c30b48c8e41272717"}, - {file = "numpy-1.21.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ccc6c650f8700ce1e3a77668bb7c43e45c20ac06ae00d22bdf6760b38958c883"}, - {file = "numpy-1.21.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:709884863def34d72b183d074d8ba5cfe042bc3ff8898f1ffad0209161caaa99"}, - {file = "numpy-1.21.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:bebab3eaf0641bba26039fb0b2c5bf9b99407924b53b1ea86e03c32c64ef5aef"}, - {file = "numpy-1.21.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf680682ad0a3bef56dae200dbcbac2d57294a73e5b0f9864955e7dd7c2c2491"}, - {file = "numpy-1.21.0-cp39-cp39-win32.whl", hash = "sha256:d95d16204cd51ff1a1c8d5f9958ce90ae190be81d348b514f9be39f878b8044a"}, - {file = "numpy-1.21.0-cp39-cp39-win_amd64.whl", hash = "sha256:2ba579dde0563f47021dcd652253103d6fd66165b18011dce1a0609215b2791e"}, - {file = "numpy-1.21.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3c40e6b860220ed862e8097b8f81c9af6d7405b723f4a7af24a267b46f90e461"}, - {file = "numpy-1.21.0.zip", hash = "sha256:e80fe25cba41c124d04c662f33f6364909b985f2eb5998aaa5ae4b9587242cce"}, + {file = "numpy-1.21.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:38e8648f9449a549a7dfe8d8755a5979b45b3538520d1e735637ef28e8c2dc50"}, + {file = "numpy-1.21.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:fd7d7409fa643a91d0a05c7554dd68aa9c9bb16e186f6ccfe40d6e003156e33a"}, + {file = "numpy-1.21.1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a75b4498b1e93d8b700282dc8e655b8bd559c0904b3910b144646dbbbc03e062"}, + {file = "numpy-1.21.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1412aa0aec3e00bc23fbb8664d76552b4efde98fb71f60737c83efbac24112f1"}, + {file = "numpy-1.21.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e46ceaff65609b5399163de5893d8f2a82d3c77d5e56d976c8b5fb01faa6b671"}, + {file = "numpy-1.21.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c6a2324085dd52f96498419ba95b5777e40b6bcbc20088fddb9e8cbb58885e8e"}, + {file = "numpy-1.21.1-cp37-cp37m-win32.whl", hash = "sha256:73101b2a1fef16602696d133db402a7e7586654682244344b8329cdcbbb82172"}, + {file = "numpy-1.21.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7a708a79c9a9d26904d1cca8d383bf869edf6f8e7650d85dbc77b041e8c5a0f8"}, + {file = "numpy-1.21.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95b995d0c413f5d0428b3f880e8fe1660ff9396dcd1f9eedbc311f37b5652e16"}, + {file = "numpy-1.21.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:635e6bd31c9fb3d475c8f44a089569070d10a9ef18ed13738b03049280281267"}, + {file = "numpy-1.21.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4a3d5fb89bfe21be2ef47c0614b9c9c707b7362386c9a3ff1feae63e0267ccb6"}, + {file = "numpy-1.21.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8a326af80e86d0e9ce92bcc1e65c8ff88297de4fa14ee936cb2293d414c9ec63"}, + {file = "numpy-1.21.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:791492091744b0fe390a6ce85cc1bf5149968ac7d5f0477288f78c89b385d9af"}, + {file = "numpy-1.21.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0318c465786c1f63ac05d7c4dbcecd4d2d7e13f0959b01b534ea1e92202235c5"}, + {file = "numpy-1.21.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a513bd9c1551894ee3d31369f9b07460ef223694098cf27d399513415855b68"}, + {file = "numpy-1.21.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:91c6f5fc58df1e0a3cc0c3a717bb3308ff850abdaa6d2d802573ee2b11f674a8"}, + {file = "numpy-1.21.1-cp38-cp38-win32.whl", hash = "sha256:978010b68e17150db8765355d1ccdd450f9fc916824e8c4e35ee620590e234cd"}, + {file = "numpy-1.21.1-cp38-cp38-win_amd64.whl", hash = "sha256:9749a40a5b22333467f02fe11edc98f022133ee1bfa8ab99bda5e5437b831214"}, + {file = "numpy-1.21.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d7a4aeac3b94af92a9373d6e77b37691b86411f9745190d2c351f410ab3a791f"}, + {file = "numpy-1.21.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d9e7912a56108aba9b31df688a4c4f5cb0d9d3787386b87d504762b6754fbb1b"}, + {file = "numpy-1.21.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:25b40b98ebdd272bc3020935427a4530b7d60dfbe1ab9381a39147834e985eac"}, + {file = "numpy-1.21.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8a92c5aea763d14ba9d6475803fc7904bda7decc2a0a68153f587ad82941fec1"}, + {file = "numpy-1.21.1-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:05a0f648eb28bae4bcb204e6fd14603de2908de982e761a2fc78efe0f19e96e1"}, + {file = "numpy-1.21.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f01f28075a92eede918b965e86e8f0ba7b7797a95aa8d35e1cc8821f5fc3ad6a"}, + {file = "numpy-1.21.1-cp39-cp39-win32.whl", hash = "sha256:88c0b89ad1cc24a5efbb99ff9ab5db0f9a86e9cc50240177a571fbe9c2860ac2"}, + {file = "numpy-1.21.1-cp39-cp39-win_amd64.whl", hash = "sha256:01721eefe70544d548425a07c80be8377096a54118070b8a62476866d5208e33"}, + {file = "numpy-1.21.1-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2d4d1de6e6fb3d28781c73fbde702ac97f03d79e4ffd6598b880b2d95d62ead4"}, + {file = "numpy-1.21.1.zip", hash = "sha256:dff4af63638afcc57a3dfb9e4b26d434a7a602d225b42d746ea7fe2edf1342fd"}, ] [[package]] @@ -2710,4 +2710,4 @@ hdf5 = ["h5py"] [metadata] lock-version = "2.0" python-versions = "^3.7.1" -content-hash = "d4a2202f4ba37898c01b69447907acaff2517a182f508ef52cdeffce676cbd4b" +content-hash = "ae8933728fc5d778c4437e1869d340f8adab557187b500bb99e6d1f23099cb44" diff --git a/pyproject.toml b/pyproject.toml index d2821fb50..e122881e5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,7 +56,7 @@ black = "22.6.0" pre-commit = "^2.17" coverage = "^5" # Template app dependencies -numpy = "1.21.0" +numpy = "^1" dateparser = "1.1.1" stringcase = "1.2.0" pandas = "^1.3" From b3575804bbf272931127e925a62cb43dc4ed8fcc Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Tue, 23 Apr 2024 12:02:34 +0100 Subject: [PATCH 26/28] REV: Revert "OPS: Use python3.11 for tests" This reverts commit c86b441a43f4ac79c3898cd4fc06541ca855b0ee. --- .github/workflows/python-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index 1d7865be2..6596a5315 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -23,7 +23,7 @@ jobs: if: "!contains(github.event.head_commit.message, 'skipci')" runs-on: ${{ matrix.os }} env: - USING_COVERAGE: "3.11" + USING_COVERAGE: "3.10" strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] @@ -36,7 +36,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.10" - name: Install Poetry uses: snok/install-poetry@v1.3.2 From 330ea82852fbad8adfa7463d55e52c9979691aab Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Tue, 23 Apr 2024 12:22:44 +0100 Subject: [PATCH 27/28] TST: Update test for `python3.10` --- tests/test_cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index 153e2eff0..97c02da0c 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -231,7 +231,7 @@ def test_start_command_with_revision_tag_override_when_revision_tag_environment_ ] ): with ServicePatcher(): - with self.assertLogs(level=logging.WARNING) as logging_context: + with self.assertLogs() as logging_context: result = CliRunner().invoke(octue_cli, ["start", "--revision-tag=hello", "--timeout=0"]) self.assertEqual( From 2f4e8b77ea18c6be3c66c48f5e9b7c8bb60e9f20 Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Tue, 23 Apr 2024 12:38:06 +0100 Subject: [PATCH 28/28] OPS: Use `python3.10` for release workflow skipci --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f20a8f0d3..fec48fbdb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ jobs: if: "github.event.pull_request.merged == true" runs-on: ${{ matrix.os }} env: - USING_COVERAGE: "3.9" + USING_COVERAGE: "3.10" strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] @@ -28,7 +28,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: "3.10" - name: Install Poetry uses: snok/install-poetry@v1.3.2