Skip to content

Commit d14d7b3

Browse files
raymond1242Raymond Negronmgonnav
authored
BITMAKER-2542 Allow setting DataPersistence field on Project/Spider models (#150)
--------- Co-authored-by: Raymond Negron <[email protected]> Co-authored-by: emegona <[email protected]>
1 parent c6bcf35 commit d14d7b3

File tree

31 files changed

+1064
-394
lines changed

31 files changed

+1064
-394
lines changed

estela-api/api/serializers/cronjob.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
from croniter import croniter
22
from rest_framework import serializers
3-
from api import errors
4-
5-
from core.models import SpiderJobArg, SpiderJobEnvVar, SpiderCronJob, SpiderJobTag
63

4+
from api import errors
75
from api.serializers.job_specific import (
86
SpiderJobArgSerializer,
97
SpiderJobEnvVarSerializer,
108
SpiderJobTagSerializer,
119
)
12-
from core.cronjob import enable_cronjob, disable_cronjob, update_schedule
10+
from core.cronjob import disable_cronjob, enable_cronjob, update_schedule
11+
from core.models import (
12+
DataStatus,
13+
SpiderCronJob,
14+
SpiderJobArg,
15+
SpiderJobEnvVar,
16+
SpiderJobTag,
17+
)
1318

1419

1520
class SpiderCronJobSerializer(serializers.ModelSerializer):
@@ -144,10 +149,10 @@ def update(self, instance, validated_data):
144149
if "unique_collection" in validated_data:
145150
instance.unique_collection = unique_collection
146151
if "data_status" in validated_data:
147-
if data_status == SpiderCronJob.PERSISTENT_STATUS:
148-
instance.data_status = SpiderCronJob.PERSISTENT_STATUS
149-
elif data_status == SpiderCronJob.PENDING_STATUS:
150-
instance.data_status = SpiderCronJob.PENDING_STATUS
152+
if data_status == DataStatus.PERSISTENT_STATUS:
153+
instance.data_status = DataStatus.PERSISTENT_STATUS
154+
elif data_status == DataStatus.PENDING_STATUS:
155+
instance.data_status = DataStatus.PENDING_STATUS
151156
if data_expiry_days < 1:
152157
raise serializers.ValidationError(
153158
{"error": errors.POSITIVE_SMALL_INTEGER_FIELD}

estela-api/api/serializers/deploy.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,12 @@ def update(self, instance, validated_data):
5959
)
6060
project.spiders.exclude(name__in=spiders_names).update(deleted=True)
6161
new_spiders = [
62-
Spider(name=spider_name, project=project)
62+
Spider(
63+
name=spider_name,
64+
project=project,
65+
data_status=project.data_status,
66+
data_expiry_days=project.data_expiry_days,
67+
)
6368
for spider_name in spiders_names
6469
if not project.spiders.filter(name=spider_name).exists()
6570
]

estela-api/api/serializers/job.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@
77
SpiderJobTagSerializer,
88
)
99
from config.job_manager import job_manager
10-
from core.models import SpiderJob, SpiderJobArg, SpiderJobEnvVar, SpiderJobTag
10+
from core.models import (
11+
DataStatus,
12+
SpiderJob,
13+
SpiderJobArg,
14+
SpiderJobEnvVar,
15+
SpiderJobTag,
16+
)
1117

1218

1319
class SpiderJobSerializer(serializers.ModelSerializer):
@@ -149,12 +155,12 @@ def update(self, instance, validated_data):
149155

150156
if (
151157
"data_status" in validated_data
152-
and instance.data_status != SpiderJob.DELETED_STATUS
158+
and instance.data_status != DataStatus.DELETED_STATUS
153159
):
154-
if data_status == SpiderJob.PERSISTENT_STATUS:
155-
instance.data_status = SpiderJob.PERSISTENT_STATUS
156-
elif data_status == SpiderJob.PENDING_STATUS:
157-
instance.data_status = SpiderJob.PENDING_STATUS
160+
if data_status == DataStatus.PERSISTENT_STATUS:
161+
instance.data_status = DataStatus.PERSISTENT_STATUS
162+
elif data_status == DataStatus.PENDING_STATUS:
163+
instance.data_status = DataStatus.PENDING_STATUS
158164
if data_expiry_days < 1:
159165
raise serializers.ValidationError(
160166
{"error": errors.POSITIVE_SMALL_INTEGER_FIELD}

estela-api/api/serializers/project.py

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
from django.contrib.auth.models import User
2-
from django.db.models import Sum
32
from rest_framework import serializers
4-
from rest_framework.exceptions import APIException
53

6-
from config.job_manager import spiderdata_db_client
7-
from core.models import Permission, Project, SpiderJob, UsageRecord
4+
from core.models import DataStatus, Permission, Project, UsageRecord
85

96

107
class UserDetailSerializer(serializers.ModelSerializer):
@@ -39,7 +36,15 @@ class ProjectSerializer(serializers.ModelSerializer):
3936

4037
class Meta:
4138
model = Project
42-
fields = ("pid", "name", "category", "container_image", "users")
39+
fields = (
40+
"pid",
41+
"name",
42+
"category",
43+
"container_image",
44+
"users",
45+
"data_status",
46+
"data_expiry_days",
47+
)
4348

4449

4550
class UsageRecordSerializer(serializers.ModelSerializer):
@@ -97,7 +102,6 @@ class ProjectUpdateSerializer(serializers.ModelSerializer):
97102
("DEVELOPER", "Developer"),
98103
("VIEWER", "Viewer"),
99104
]
100-
101105
pid = serializers.UUIDField(
102106
read_only=True, help_text="A UUID identifying this project."
103107
)
@@ -117,7 +121,27 @@ class ProjectUpdateSerializer(serializers.ModelSerializer):
117121
required=False,
118122
help_text="New permission.",
119123
)
124+
data_status = serializers.ChoiceField(
125+
write_only=True,
126+
choices=DataStatus.HIGH_LEVEL_OPTIONS,
127+
required=False,
128+
help_text="New data status.",
129+
)
130+
data_expiry_days = serializers.IntegerField(
131+
write_only=True,
132+
required=False,
133+
help_text="New data expiry days.",
134+
)
120135

121136
class Meta:
122137
model = Project
123-
fields = ("pid", "name", "users", "email", "action", "permission")
138+
fields = (
139+
"pid",
140+
"name",
141+
"users",
142+
"email",
143+
"action",
144+
"permission",
145+
"data_status",
146+
"data_expiry_days",
147+
)
Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,36 @@
11
from rest_framework import serializers
22

3-
from core.models import Spider
3+
from core.models import DataStatus, Spider
44

55

66
class SpiderSerializer(serializers.ModelSerializer):
77
class Meta:
88
model = Spider
9-
fields = ("sid", "name", "project")
9+
fields = ("sid", "name", "project", "data_status", "data_expiry_days")
10+
11+
12+
class SpiderUpdateSerializer(serializers.ModelSerializer):
13+
sid = serializers.UUIDField(
14+
read_only=True, help_text="A UUID identifying this spider."
15+
)
16+
data_status = serializers.ChoiceField(
17+
choices=DataStatus.HIGH_LEVEL_OPTIONS,
18+
required=False,
19+
help_text="New data status.",
20+
)
21+
data_expiry_days = serializers.IntegerField(
22+
required=False,
23+
help_text="New data expiry days.",
24+
)
25+
26+
class Meta:
27+
model = Spider
28+
fields = ("sid", "name", "data_status", "data_expiry_days")
29+
30+
def update(self, instance, validated_data):
31+
instance.data_status = validated_data.get("data_status", instance.data_status)
32+
instance.data_expiry_days = validated_data.get(
33+
"data_expiry_days", instance.data_expiry_days
34+
)
35+
instance.save()
36+
return instance

estela-api/api/views/cronjob.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
SpiderCronJobUpdateSerializer,
1616
)
1717
from core.cronjob import create_cronjob, disable_cronjob, run_cronjob_once
18-
from core.models import Spider, SpiderCronJob
18+
from core.models import DataStatus, Spider, SpiderCronJob
1919

2020

2121
class SpiderCronJobViewSet(
@@ -68,9 +68,9 @@ def create(self, request, *args, **kwargs):
6868
spider = get_object_or_404(Spider, sid=self.kwargs["sid"], deleted=False)
6969
serializer = SpiderCronJobCreateSerializer(data=request.data)
7070
serializer.is_valid(raise_exception=True)
71-
data_status = request.data.pop("data_status", SpiderCronJob.PERSISTENT_STATUS)
71+
data_status = request.data.pop("data_status", DataStatus.PERSISTENT_STATUS)
7272

73-
if data_status == SpiderCronJob.PENDING_STATUS:
73+
if data_status == DataStatus.PENDING_STATUS:
7474
date_str = request.data.pop("data_expiry_days", "0/1")
7575
data_expiry_days = self.get_days(date_str)
7676
if data_expiry_days < 1:
@@ -138,7 +138,7 @@ def run_once(self, request, *args, **kwargs):
138138
partial = kwargs.pop("partial", False)
139139
instance = self.get_object()
140140

141-
cronjob = SpiderCronJobSerializer(instance)
141+
cronjob = SpiderCronJobSerializer(instance, partial=partial)
142142

143143
run_cronjob_once(cronjob.data)
144144
return Response(cronjob.data, status=status.HTTP_200_OK)

estela-api/api/views/job.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
SpiderJobUpdateSerializer,
1616
)
1717
from config.job_manager import job_manager
18-
from core.models import Spider, SpiderJob
18+
from core.models import DataStatus, Spider, SpiderJob
1919

2020

2121
class SpiderJobViewSet(
@@ -101,8 +101,8 @@ def create(self, request, *args, **kwargs):
101101
async_param = request.query_params.get("async", False)
102102
serializer = SpiderJobCreateSerializer(data=request.data)
103103
serializer.is_valid(raise_exception=True)
104-
data_status = request.data.pop("data_status", SpiderJob.PERSISTENT_STATUS)
105-
if data_status == SpiderJob.PENDING_STATUS:
104+
data_status = request.data.pop("data_status", DataStatus.PERSISTENT_STATUS)
105+
if data_status == DataStatus.PENDING_STATUS:
106106
data_expiry_days = request.data.pop("data_expiry_days", 1)
107107
if data_expiry_days < 1:
108108
raise ParseError({"error": "Invalid data expiry days value."})

estela-api/api/views/project.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
UsageRecordSerializer,
2020
)
2121
from core.models import (
22+
DataStatus,
2223
Permission,
2324
Project,
2425
Spider,
@@ -86,8 +87,12 @@ def update(self, request, *args, **kwargs):
8687
user_email = serializer.validated_data.pop("email", "")
8788
action = serializer.validated_data.pop("action", "")
8889
permission = serializer.validated_data.pop("permission", "")
90+
data_status = serializer.validated_data.pop("data_status", "")
91+
data_expiry_days = serializer.validated_data.pop("data_expiry_days", 0)
92+
8993
if name:
9094
instance.name = name
95+
9196
if user_email and user_email != request.user.email:
9297
if not (
9398
request.user.permission_set.get(project=instance).permission
@@ -120,8 +125,13 @@ def update(self, request, *args, **kwargs):
120125
instance.users.add(user, through_defaults={"permission": permission})
121126
else:
122127
raise ParseError({"error": "Action not supported."})
123-
serializer.save()
124128

129+
if data_status:
130+
instance.data_status = data_status
131+
if data_status == DataStatus.PENDING_STATUS and data_expiry_days > 0:
132+
instance.data_expiry_days = data_expiry_days
133+
134+
serializer.save()
125135
headers = self.get_success_headers(serializer.data)
126136
return Response(serializer.data, status=status.HTTP_200_OK, headers=headers)
127137

estela-api/api/views/spider.py

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
1-
from rest_framework import viewsets
1+
from drf_yasg.utils import swagger_auto_schema
2+
from rest_framework import mixins, status
3+
from rest_framework.response import Response
24

35
from api.mixins import BaseViewSet
4-
from api.serializers.spider import SpiderSerializer
6+
from api.serializers.spider import SpiderSerializer, SpiderUpdateSerializer
57
from core.models import Spider
68

79

8-
class SpiderViewSet(BaseViewSet, viewsets.ReadOnlyModelViewSet):
10+
class SpiderViewSet(
11+
mixins.ListModelMixin,
12+
mixins.RetrieveModelMixin,
13+
mixins.UpdateModelMixin,
14+
BaseViewSet,
15+
):
916
model_class = Spider
1017
serializer_class = SpiderSerializer
1118
lookup_field = "sid"
@@ -15,3 +22,21 @@ def get_queryset(self):
1522
return self.model_class.objects.filter(
1623
project__pid=self.kwargs["pid"], deleted=False
1724
)
25+
26+
@swagger_auto_schema(
27+
request_body=SpiderUpdateSerializer,
28+
responses={status.HTTP_200_OK: SpiderUpdateSerializer()},
29+
)
30+
def update(self, request, *args, **kwargs):
31+
partial = kwargs.pop("partial", False)
32+
instance = self.get_object()
33+
serializer = SpiderUpdateSerializer(
34+
instance, data=request.data, partial=partial
35+
)
36+
serializer.is_valid(raise_exception=True)
37+
self.perform_update(serializer)
38+
39+
if getattr(instance, "_prefetched_objects_cache", None):
40+
instance._prefetched_objects_cache = {}
41+
42+
return Response(serializer.data, status=status.HTTP_200_OK)

0 commit comments

Comments
 (0)