Add periodic exchange task management API
Some checks failed
CI/CD Pipeline / Code Quality Checks (push) Successful in 3m16s
CI/CD Pipeline / Run Tests (push) Successful in 3m26s
CI/CD Pipeline / Telegram Notify Success (push) Failing after 1m29s
CI/CD Pipeline / Run Tests (pull_request) Successful in 1m44s
CI/CD Pipeline / Code Quality Checks (pull_request) Successful in 20m19s
CI/CD Pipeline / Telegram Notify Success (pull_request) Failing after 1m34s

This commit is contained in:
2026-03-19 17:03:47 +01:00
parent 941c268d32
commit 3de66cc25c
8 changed files with 867 additions and 24 deletions

View File

@@ -10,10 +10,17 @@ from apps.exchange.serializers import (
ExchangeConnectionCreateSerializer,
ExchangeConnectionSerializer,
ExchangeCopyRequestSerializer,
ExchangePeriodicTaskSerializer,
ExchangePeriodicTaskUpsertSerializer,
)
from apps.exchange.services import (
ExchangeConnectionService,
ExchangePeriodicTaskService,
ExchangeServiceError,
)
from apps.exchange.services import ExchangeConnectionService, ExchangeServiceError
from apps.exchange.tasks import copy_parsers_data_async
from django.db import IntegrityError
from django.shortcuts import get_object_or_404
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework import status
@@ -203,3 +210,124 @@ class ExchangeCopyDataView(APIView):
},
status_code=status.HTTP_202_ACCEPTED,
)
class ExchangePeriodicTaskListCreateView(APIView):
"""API списка и создания периодических задач обмена."""
permission_classes = [IsAdminUser]
@swagger_auto_schema(
tags=[EXCHANGE_TAG],
operation_summary="Список периодических задач обмена",
operation_description=(
"Возвращает периодические задачи exchange, созданные через "
"django_celery_beat."
),
responses={
200: ExchangePeriodicTaskSerializer(many=True),
**ErrorResponses.ADMIN,
},
)
def get(self, request):
queryset = ExchangePeriodicTaskService.get_queryset()
serializer = ExchangePeriodicTaskSerializer(queryset, many=True)
return api_response(serializer.data, status_code=status.HTTP_200_OK)
@swagger_auto_schema(
tags=[EXCHANGE_TAG],
operation_summary="Создать периодическую задачу обмена",
operation_description=(
"Создаёт периодическую задачу exchange с interval или crontab "
"расписанием. При выполнении задача использует текущее активное "
"подключение exchange."
),
request_body=ExchangePeriodicTaskUpsertSerializer,
responses={
201: ExchangePeriodicTaskSerializer,
400: CommonResponses.BAD_REQUEST,
**ErrorResponses.ADMIN,
},
)
def post(self, request):
serializer = ExchangePeriodicTaskUpsertSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
try:
task = ExchangePeriodicTaskService.create_periodic_task(
name=serializer.validated_data["name"],
description=serializer.validated_data.get("description", ""),
enabled=serializer.validated_data.get("enabled", True),
payload=serializer.validated_data["payload"],
schedule=serializer.validated_data["schedule"],
)
except ExchangeServiceError as exc:
raise ValidationError({"periodic_task": str(exc)}) from exc
output = ExchangePeriodicTaskSerializer(task)
return api_created_response(output.data)
class ExchangePeriodicTaskDetailView(APIView):
"""API чтения и изменения периодической задачи обмена."""
permission_classes = [IsAdminUser]
@swagger_auto_schema(
tags=[EXCHANGE_TAG],
operation_summary="Детали периодической задачи обмена",
responses={
200: ExchangePeriodicTaskSerializer,
404: CommonResponses.NOT_FOUND,
**ErrorResponses.ADMIN,
},
)
def get(self, request, task_id: int):
task = get_object_or_404(
ExchangePeriodicTaskService.get_queryset(),
id=task_id,
)
output = ExchangePeriodicTaskSerializer(task)
return api_response(output.data, status_code=status.HTTP_200_OK)
@swagger_auto_schema(
tags=[EXCHANGE_TAG],
operation_summary="Изменить периодическую задачу обмена",
operation_description=(
"Обновляет расписание, payload и состояние exchange-задачи. "
"PATCH допускает частичное обновление."
),
request_body=ExchangePeriodicTaskUpsertSerializer,
responses={
200: ExchangePeriodicTaskSerializer,
400: CommonResponses.BAD_REQUEST,
404: CommonResponses.NOT_FOUND,
**ErrorResponses.ADMIN,
},
)
def patch(self, request, task_id: int):
task = get_object_or_404(
ExchangePeriodicTaskService.get_queryset(),
id=task_id,
)
serializer = ExchangePeriodicTaskUpsertSerializer(
task,
data=request.data,
partial=True,
)
serializer.is_valid(raise_exception=True)
try:
task = ExchangePeriodicTaskService.update_periodic_task(
task=task,
name=serializer.validated_data.get("name"),
description=serializer.validated_data.get("description"),
enabled=serializer.validated_data.get("enabled"),
payload=serializer.validated_data["payload"],
schedule=serializer.validated_data["schedule"],
)
except ExchangeServiceError as exc:
raise ValidationError({"periodic_task": str(exc)}) from exc
output = ExchangePeriodicTaskSerializer(task)
return api_response(output.data, status_code=status.HTTP_200_OK)