From 26b2e90fcf7eb18c0548b43cbdaaeab2cf553fd6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Nov 2023 10:08:03 +1100 Subject: [PATCH] Bump pillow from 9.5.0 to 10.0.1 (#5657) * Bump pillow from 9.5.0 to 10.0.1 Bumps [pillow](https://github.com/python-pillow/Pillow) from 9.5.0 to 10.0.1. - [Release notes](https://github.com/python-pillow/Pillow/releases) - [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) - [Commits](https://github.com/python-pillow/Pillow/compare/9.5.0...10.0.1) --- updated-dependencies: - dependency-name: pillow dependency-type: direct:production ... Signed-off-by: dependabot[bot] * Patch requirements files * Update package requirements * Improve offload_task function: - Return True if the task runs or was offloaded - Improved warning information * Improve unit tests for task offloading - Check return value of offload_task - Check log output * Bump django-stdimage * Fix tasks.py --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Oliver --- InvenTree/InvenTree/tasks.py | 44 +++++++++++++++++++++++++++--------- InvenTree/InvenTree/tests.py | 34 ++++++++++++++++++++-------- requirements.in | 4 ++-- requirements.txt | 4 ++-- 4 files changed, 61 insertions(+), 25 deletions(-) diff --git a/InvenTree/InvenTree/tasks.py b/InvenTree/InvenTree/tasks.py index ebd68d12d5..6dbcb85bbf 100644 --- a/InvenTree/InvenTree/tasks.py +++ b/InvenTree/InvenTree/tasks.py @@ -159,11 +159,13 @@ def record_task_success(task_name: str): InvenTreeSetting.set_setting(f'_{task_name}_SUCCESS', datetime.now().isoformat(), None) -def offload_task(taskname, *args, force_async=False, force_sync=False, **kwargs): +def offload_task(taskname, *args, force_async=False, force_sync=False, **kwargs) -> bool: """Create an AsyncTask if workers are running. This is different to a 'scheduled' task, in that it only runs once! - If workers are not running or force_sync flag - is set then the task is ran synchronously. + If workers are not running or force_sync flag, is set then the task is ran synchronously. + + Returns: + bool: True if the task was offloaded (or ran), False otherwise """ try: import importlib @@ -173,19 +175,32 @@ def offload_task(taskname, *args, force_async=False, force_sync=False, **kwargs) from InvenTree.status import is_worker_running except AppRegistryNotReady: # pragma: no cover logger.warning("Could not offload task '%s' - app registry not ready", taskname) - return + + if force_async: + # Cannot async the task, so return False + return False + else: + force_sync = True except (OperationalError, ProgrammingError): # pragma: no cover raise_warning(f"Could not offload task '{taskname}' - database not ready") + if force_async: + # Cannot async the task, so return False + return False + else: + force_sync = True + if force_async or (is_worker_running() and not force_sync): # Running as asynchronous task try: task = AsyncTask(taskname, *args, **kwargs) task.run() except ImportError: - raise_warning(f"WARNING: '{taskname}' not started - Function not found") + raise_warning(f"WARNING: '{taskname}' not offloaded - Function not found") + return False except Exception as exc: - raise_warning(f"WARNING: '{taskname}' not started due to {type(exc)}") + raise_warning(f"WARNING: '{taskname}' not offloaded due to {str(exc)}") + return False else: if callable(taskname): @@ -198,14 +213,14 @@ def offload_task(taskname, *args, force_async=False, force_sync=False, **kwargs) app_mod = app + '.' + mod except ValueError: raise_warning(f"WARNING: '{taskname}' not started - Malformed function path") - return + return False # Import module from app try: _mod = importlib.import_module(app_mod) except ModuleNotFoundError: raise_warning(f"WARNING: '{taskname}' not started - No module named '{app_mod}'") - return + return False # Retrieve function try: @@ -219,10 +234,17 @@ def offload_task(taskname, *args, force_async=False, force_sync=False, **kwargs) _func = eval(func) # pragma: no cover except NameError: raise_warning(f"WARNING: '{taskname}' not started - No function named '{func}'") - return + return False # Workers are not running: run it as synchronous task - _func(*args, **kwargs) + try: + _func(*args, **kwargs) + except Exception as exc: + raise_warning(f"WARNING: '{taskname}' not started due to {str(exc)}") + return False + + # Finally, task either completed successfully or was offloaded + return True @dataclass() @@ -249,7 +271,7 @@ class ScheduledTask: class TaskRegister: - """Registry for periodicall tasks.""" + """Registry for periodic tasks.""" task_list: List[ScheduledTask] = [] def register(self, task, schedule, minutes: int = None): diff --git a/InvenTree/InvenTree/tests.py b/InvenTree/InvenTree/tests.py index b0ecab4116..b0cdab5006 100644 --- a/InvenTree/InvenTree/tests.py +++ b/InvenTree/InvenTree/tests.py @@ -1095,25 +1095,39 @@ class TestOffloadTask(InvenTreeTestCase): Ref: https://github.com/inventree/InvenTree/pull/3273 """ - offload_task( - 'dummy_tasks.parts', - part=Part.objects.get(pk=1), - cat=PartCategory.objects.get(pk=1), - force_async=True - ) - offload_task( + self.assertTrue(offload_task( 'dummy_tasks.stock', item=StockItem.objects.get(pk=1), loc=StockLocation.objects.get(pk=1), force_async=True - ) + )) - offload_task( + self.assertTrue(offload_task( 'dummy_task.numbers', 1, 2, 3, 4, 5, force_async=True - ) + )) + + # Offload a dummy task, but force sync + # This should fail, because the function does not exist + with self.assertLogs(logger='inventree', level='WARNING') as log: + self.assertFalse(offload_task( + 'dummy_task.numbers', + 1, 1, 1, + force_sync=True + )) + + self.assertIn("Malformed function path", str(log.output)) + + # Offload dummy task with a Part instance + # This should succeed, ensuring that the Part instance is correctly pickled + self.assertTrue(offload_task( + 'dummy_tasks.parts', + part=Part.objects.get(pk=1), + cat=PartCategory.objects.get(pk=1), + force_async=True + )) def test_daily_holdoff(self): """Tests for daily task holdoff helper functions""" diff --git a/requirements.in b/requirements.in index cfccc427ea..f9a5d91dc7 100644 --- a/requirements.in +++ b/requirements.in @@ -24,7 +24,7 @@ django-q-sentry # sentry.io integration for django-q django-sesame # Magic link authentication django-sql-utils # Advanced query annotation / aggregation django-sslserver # Secure HTTP development server -django-stdimage<6.0.0 # Advanced ImageField management # FIXED 2022-06-29 6.0.0 breaks serialization for django-q +django-stdimage # Advanced ImageField management django-taggit # Tagging support django-user-sessions # user sessions in DB django-weasyprint # django weasyprint integration @@ -37,7 +37,7 @@ drf-spectacular # DRF API documentation feedparser # RSS newsfeed parser gunicorn # Gunicorn web server pdf2image # PDF to image conversion -pillow==9.5.0 # Image manipulation # FIXED 2023-07-04 as we require PIL.Image.ANTIALIAS +pillow # Image manipulation pint==0.21 # Unit conversion # FIXED 2023-05-30 breaks tests https://github.com/matmair/InvenTree/actions/runs/5095665936/jobs/9160852560 python-barcode[images] # Barcode generator python-dotenv # Environment variable management diff --git a/requirements.txt b/requirements.txt index f37bc5b356..8145622024 100644 --- a/requirements.txt +++ b/requirements.txt @@ -135,7 +135,7 @@ django-sql-utils==0.7.0 # via -r requirements.in django-sslserver==0.22 # via -r requirements.in -django-stdimage==5.3.0 +django-stdimage==6.0.2 # via -r requirements.in django-taggit==4.0.0 # via -r requirements.in @@ -201,7 +201,7 @@ packaging==23.2 # via gunicorn pdf2image==1.16.3 # via -r requirements.in -pillow==9.5.0 +pillow==10.1.0 # via # -r requirements.in # django-stdimage