Skip to content

Commit 81bb6a3

Browse files
committed
delete old cron approach
1 parent 58c3e9b commit 81bb6a3

File tree

12 files changed

+74
-132
lines changed

12 files changed

+74
-132
lines changed

codeforlife/mixins/__init__.py

Lines changed: 0 additions & 6 deletions
This file was deleted.

codeforlife/mixins/cron.py

Lines changed: 0 additions & 24 deletions
This file was deleted.

codeforlife/permissions/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,4 @@
99
from .allow_none import AllowNone
1010
from .base import BasePermission
1111
from .is_authenticated import IsAuthenticated
12-
from .is_cron_request_from_google import IsCronRequestFromGoogle
1312
from .operators import AND, NOT, OR, Permission

codeforlife/permissions/is_cron_request_from_google.py

Lines changed: 0 additions & 22 deletions
This file was deleted.

codeforlife/settings/third_party.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,4 @@
3737

3838
CELERY_BROKER_URL = REDIS_URL
3939
CELERY_TASK_TIME_LIMIT = 60 * 30
40-
CELERY_BEAT_SCHEDULE: t.Dict[str, t.Dict[str, CeleryBeat]] = {}
40+
CELERY_BEAT_SCHEDULE: t.Dict[str, CeleryBeat] = {}

codeforlife/tasks.py

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,30 @@
77

88
import typing as t
99

10-
from celery import schedules
1110
from celery import shared_task as _shared_task
11+
from celery.schedules import crontab, solar
1212
from django.conf import settings
1313

1414
from .types import Args, KwArgs
1515

16+
Schedule = t.Union[int, crontab, solar]
1617

17-
class CeleryBeat(t.Dict[str, t.Any]):
18+
19+
class CeleryBeat(t.TypedDict):
1820
"""A Celery beat schedule.
1921
2022
https://docs.celeryq.dev/en/v5.4.0/userguide/periodic-tasks.html
2123
"""
2224

23-
# Shorthand for convenience.
24-
crontab = schedules.crontab
25-
solar = schedules.solar
26-
27-
def __init__(
28-
self,
29-
task: str,
30-
schedule: t.Union[int, schedules.crontab, schedules.solar],
31-
args: t.Optional[Args] = None,
32-
kwargs: t.Optional[KwArgs] = None,
33-
):
34-
super().__init__()
35-
self["task"] = f"{settings.SERVICE_NAME}.{task}"
36-
self["schedule"] = schedule
37-
if args:
38-
self["args"] = args
39-
if kwargs:
40-
self["kwargs"] = kwargs
25+
task: str
26+
schedule: Schedule
27+
args: t.NotRequired[Args]
28+
kwargs: t.NotRequired[KwArgs]
29+
30+
def __init__(self, **kwargs): # type: ignore[misc]
31+
kwargs["task"] = f"{settings.SERVICE_NAME}.{kwargs['task']}"
32+
33+
super().__init__(**kwargs)
4134

4235

4336
def shared_task(*args, **kwargs):

codeforlife/tests/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from .api import APITestCase, BaseAPITestCase
99
from .api_client import APIClient, BaseAPIClient
1010
from .api_request_factory import APIRequestFactory, BaseAPIRequestFactory
11-
from .cron import CronTestCase
11+
from .celery import CeleryTestCase
1212
from .model import ModelTestCase
1313
from .model_list_serializer import (
1414
BaseModelListSerializerTestCase,

codeforlife/tests/celery.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
"""
2+
© Ocado Group
3+
Created on 01/04/2025 at 16:57:19(+01:00).
4+
"""
5+
6+
from importlib import import_module
7+
from unittest import TestCase
8+
9+
from celery import Celery, Task
10+
from django.conf import settings
11+
12+
from ..tasks import CeleryBeat
13+
from ..types import Args, KwArgs
14+
15+
16+
class CeleryTestCase(TestCase):
17+
"""A test case for celery tasks."""
18+
19+
# The dot-path of the module containing the Celery app.
20+
app_module: str = "application"
21+
# The name of the Celery app.
22+
app_name: str = "celery_app"
23+
# The Celery app instance. Auto-imported if not set.
24+
app: Celery
25+
26+
@classmethod
27+
def setUpClass(cls):
28+
if not hasattr(cls, "app"):
29+
cls.app = getattr(import_module(cls.app_module), cls.app_name)
30+
31+
def apply_periodic_task(self, beat_name: str):
32+
"""Apply a periodic task.
33+
34+
Args:
35+
beat_name: The name of the beat in the schedule.
36+
"""
37+
beat: CeleryBeat = self.app.conf.beat_schedule[beat_name]
38+
39+
task_dot_path = (
40+
beat["task"].removeprefix(f"{settings.SERVICE_NAME}.").split(".")
41+
)
42+
task_module = ".".join(task_dot_path[:-1])
43+
task_name = task_dot_path[-1]
44+
task: Task = getattr(import_module(task_module), task_name)
45+
46+
args, kwargs = beat.get("args", tuple()), beat.get("kwargs", {})
47+
task.apply(*args, **kwargs)
48+
49+
def apply_task(self, name: str, args: Args, kwargs: KwArgs):
50+
"""Apply a task.
51+
52+
Args:
53+
name: The name of the task.
54+
args: The args to pass to the task.
55+
kwargs: The keyword args to pass to the task.
56+
"""
57+
task: Task = self.app.tasks[f"{settings.SERVICE_NAME}.{name}"]
58+
task.apply(*args, **kwargs)

codeforlife/tests/cron.py

Lines changed: 0 additions & 20 deletions
This file was deleted.

codeforlife/tests/model_view_set_client.py

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -599,26 +599,6 @@ def bulk_destroy(
599599

600600
return response
601601

602-
# --------------------------------------------------------------------------
603-
# OTHER
604-
# --------------------------------------------------------------------------
605-
606-
def cron_job(self, action: str):
607-
"""Call a CRON job.
608-
609-
Args:
610-
action: The name of the action.
611-
612-
Returns:
613-
The HTTP response.
614-
"""
615-
response: Response = self.get(
616-
self._test_case.reverse_action(action),
617-
HTTP_X_APPENGINE_CRON="true",
618-
)
619-
620-
return response
621-
622602

623603
# pylint: enable=no-member
624604

codeforlife/views/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from .api_root import APIRootView
88
from .base_login import BaseLoginView
99
from .csrf import CsrfCookieView
10-
from .decorators import action, cron_job
10+
from .decorators import action
1111
from .health_check import HealthCheckView
1212
from .model import BaseModelViewSet, ModelViewSet
1313
from .session import LogoutView, session_expired_view

codeforlife/views/decorators.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -52,19 +52,3 @@ def wrapper(handler: t.Callable):
5252
return _action(**kwargs)(handler)
5353

5454
return wrapper
55-
56-
57-
def cron_job(handler: t.Callable):
58-
# pylint: disable=line-too-long
59-
"""
60-
Create an action that is meant to be called by Google as a CRON job.
61-
62-
See https://github.com/ocadotechnology/codeforlife-workspace/blob/main/cron.yaml.
63-
"""
64-
# pylint: enable=line-too-long
65-
66-
return action(
67-
detail=False,
68-
methods=["get"],
69-
url_path=f"cron/{_handler_name_to_url_path(handler)}",
70-
)(handler)

0 commit comments

Comments
 (0)