Files
Ai/weather/views.py
T
2026-05-05 21:02:12 +03:30

152 lines
5.5 KiB
Python

from django.apps import apps
from drf_spectacular.utils import OpenApiExample, extend_schema
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from config.openapi import build_envelope_serializer, build_response
from rag.failure_contract import RAGServiceError
from .serializers import (
FarmWeatherRequestSerializer,
FarmWeatherResponseSerializer,
WaterNeedPredictionRequestSerializer,
WaterNeedPredictionResponseSerializer,
)
FarmWeatherEnvelopeSerializer = build_envelope_serializer(
"FarmWeatherEnvelopeSerializer",
FarmWeatherResponseSerializer,
)
WeatherErrorSerializer = build_envelope_serializer(
"WeatherErrorSerializer",
data_required=False,
allow_null=True,
)
WaterNeedPredictionEnvelopeSerializer = build_envelope_serializer(
"WaterNeedPredictionEnvelopeSerializer",
WaterNeedPredictionResponseSerializer,
)
class FarmWeatherCardView(APIView):
@extend_schema(
tags=["Weather"],
summary="دریافت کارت آب و هوای مزرعه",
description="با دریافت farm_uuid، داده مستقل کارت آب و هوای مزرعه را از اپ weather برمی گرداند.",
request=FarmWeatherRequestSerializer,
responses={
200: build_response(
FarmWeatherEnvelopeSerializer,
"داده کارت آب و هوای مزرعه با موفقیت بازگردانده شد.",
),
400: build_response(
WeatherErrorSerializer,
"داده ورودی نامعتبر است.",
),
404: build_response(
WeatherErrorSerializer,
"مزرعه یافت نشد.",
),
},
examples=[
OpenApiExample(
"نمونه درخواست weather",
value={"farm_uuid": "11111111-1111-1111-1111-111111111111"},
request_only=True,
)
],
)
def post(self, request):
serializer = FarmWeatherRequestSerializer(data=request.data)
if not serializer.is_valid():
return Response(
{"code": 400, "msg": "داده نامعتبر.", "data": serializer.errors},
status=status.HTTP_400_BAD_REQUEST,
)
service = apps.get_app_config("weather").get_farm_weather_service()
try:
data = service.get_farm_weather_card(
farm_uuid=str(serializer.validated_data["farm_uuid"])
)
except ValueError as exc:
return Response(
{"code": 404, "msg": str(exc), "data": None},
status=status.HTTP_404_NOT_FOUND,
)
return Response(
{"code": 200, "msg": "success", "data": data},
status=status.HTTP_200_OK,
)
class WaterNeedPredictionView(APIView):
@extend_schema(
tags=["Weather"],
summary="دریافت پیش بینی نیاز آبی کوتاه مدت مزرعه",
description="با دریافت farm_uuid، محاسبات نیاز آبی 7 روز آینده را از اپ weather برمی گرداند و با RAG تفسیر عملیاتی اضافه می کند.",
request=WaterNeedPredictionRequestSerializer,
responses={
200: build_response(
WaterNeedPredictionEnvelopeSerializer,
"داده پیش بینی نیاز آبی مزرعه با موفقیت بازگردانده شد.",
),
400: build_response(
WeatherErrorSerializer,
"داده ورودی نامعتبر است.",
),
404: build_response(
WeatherErrorSerializer,
"مزرعه یافت نشد.",
),
500: build_response(
WeatherErrorSerializer,
"خطا در تحلیل نیاز آبی مزرعه.",
),
},
examples=[
OpenApiExample(
"نمونه درخواست water need",
value={"farm_uuid": "11111111-1111-1111-1111-111111111111"},
request_only=True,
)
],
)
def post(self, request):
serializer = WaterNeedPredictionRequestSerializer(data=request.data)
if not serializer.is_valid():
return Response(
{"code": 400, "msg": "داده نامعتبر.", "data": serializer.errors},
status=status.HTTP_400_BAD_REQUEST,
)
service = apps.get_app_config("weather").get_water_need_service()
try:
data = service.get_water_need_prediction(
farm_uuid=str(serializer.validated_data["farm_uuid"])
)
except ValueError as exc:
return Response(
{"code": 404, "msg": str(exc), "data": None},
status=status.HTTP_404_NOT_FOUND,
)
except RAGServiceError as exc:
return Response(
{"code": exc.http_status, "msg": exc.contract.message, "data": exc.to_dict()},
status=exc.http_status,
)
except Exception as exc:
return Response(
{"code": 500, "msg": f"خطا در تحلیل نیاز آبی مزرعه: {exc}", "data": None},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
)
return Response(
{"code": 200, "msg": "success", "data": data},
status=status.HTTP_200_OK,
)