Skip to content

Commit efd6f94

Browse files
authored
Merge pull request #103 from octue/allow-execute-wrap
Allow wrapping of execute() by subclasses
2 parents caa4976 + c0b8457 commit efd6f94

File tree

5 files changed

+41
-23
lines changed

5 files changed

+41
-23
lines changed

django_gcp/tasks/tasks.py

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -111,19 +111,15 @@ def enqueue_later(self, when, **kwargs):
111111
api_kwargs=dict(delay_in_seconds=delay_in_seconds),
112112
)
113113

114-
def execute(self, request_body):
115-
"""Deserialises the received request and calls the run() method"""
116-
try:
117-
task_kwargs = self._body_to_kwargs(request_body=request_body)
118-
except Exception as e:
119-
logger.warning(e, exc_info=True)
120-
return f"Unable to parse request arguments. Error was: {e}", 400
121-
122-
try:
123-
return self.run(**task_kwargs), 200
124-
except Exception as e:
125-
logger.error(e, exc_info=True)
126-
return "Error running task", 500
114+
def execute(self, **task_kwargs):
115+
"""Executes the run() method
116+
117+
This simple wrapper allows subsubclasses to retain a simple run()
118+
method api, whilst a subclass overloads execute() to add common
119+
functionality.
120+
"""
121+
122+
return self.run(**task_kwargs)
127123

128124
@property
129125
def manager(self):
@@ -176,10 +172,10 @@ def _send(self, task_kwargs, api_kwargs=None):
176172
if self.manager.disable_execute:
177173
return None
178174

179-
payload = serialize(task_kwargs)
180175
if self.manager.eager_execute:
181-
return self.execute(payload)
176+
return self.execute(**task_kwargs)
182177

178+
payload = serialize(task_kwargs)
183179
api_kwargs = api_kwargs or {}
184180
api_kwargs.update(
185181
dict(

django_gcp/tasks/views.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
import logging
23
from typing import Any, Dict
34

45
from django.apps import apps
@@ -7,6 +8,8 @@
78
from django.views.decorators.csrf import csrf_exempt
89
from django.views.generic import View
910

11+
logger = logging.getLogger(__name__)
12+
1013

1114
@method_decorator(csrf_exempt, name="dispatch")
1215
class GoogleCloudTaskView(View):
@@ -31,13 +34,22 @@ def post(self, request, task_name, *args, **kwargs):
3134
result = {"error": f"Task {task_name} not found", "available_tasks": list(self.tasks)}
3235
return self._prepare_response(status=status, payload=result)
3336

34-
output, status = task_class().execute(request_body=request.body)
35-
if status == 200:
36-
result = {"result": output}
37-
else:
38-
result = {"error": output}
37+
task = task_class()
38+
try:
39+
task_kwargs = task._body_to_kwargs(request_body=request.body)
40+
except Exception as e:
41+
logger.warning(e, exc_info=True)
42+
return self._prepare_response(
43+
status=400, payload={"error": f"Unable to parse request arguments. Error was: {e}"}
44+
)
45+
46+
try:
47+
result = task.execute(**task_kwargs)
48+
except Exception as e:
49+
logger.error(e, exc_info=True)
50+
return self._prepare_response(status=500, payload={"error": f"Error running task. Error was: {e}"})
3951

40-
return self._prepare_response(status=status, payload=result)
52+
return self._prepare_response(status=200, payload={"result": result})
4153

4254
def _prepare_response(self, status: int, payload: Dict[str, Any]):
4355
return HttpResponse(status=status, content=json.dumps(payload), content_type="application/json")

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "django-gcp"
3-
version = "0.23.0"
3+
version = "0.24.0"
44
description = "Utilities to run Django on Google Cloud Platform"
55
authors = [{name="Tom Clark"}]
66
license = "MIT"

tests/test_tasks_enqueuing.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,13 @@ def test_disable_enqueueing_with_a_setting(self):
104104
with override_settings(GCP_TASKS_DISABLE_EXECUTE=True, GCP_TASKS_EAGER_EXECUTE=True):
105105
with self.assertRaises(IncompatibleSettingsError):
106106
MyOnDemandTask().enqueue(a="1")
107+
108+
def test_enqueueing_with_eager_execute(self):
109+
"""Assert that tasks are successfully executed if GCP_TASKS_EAGER_EXECUTE is true"""
110+
111+
with patch("tests.server.example.tasks.MyOnDemandTask.run", return_value=None) as patched_run:
112+
with override_settings(GCP_TASKS_DISABLE_EXECUTE=False, GCP_TASKS_EAGER_EXECUTE=True):
113+
result = MyOnDemandTask().enqueue(a="1")
114+
115+
self.assertIsNone(result)
116+
patched_run.assert_called_once()

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)