UPDATE
This commit is contained in:
+75
-33
@@ -1,18 +1,14 @@
|
||||
from drf_spectacular.utils import (
|
||||
OpenApiExample,
|
||||
OpenApiResponse,
|
||||
extend_schema,
|
||||
)
|
||||
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 config.openapi import build_envelope_serializer, build_response
|
||||
|
||||
from .serializers import FertilizationRecommendRequestSerializer
|
||||
from .serializers import (
|
||||
FertilizationRecommendationResponseDataSerializer,
|
||||
FertilizationRecommendRequestSerializer,
|
||||
)
|
||||
|
||||
|
||||
FertilizationValidationErrorSerializer = build_envelope_serializer(
|
||||
@@ -22,32 +18,27 @@ FertilizationValidationErrorSerializer = build_envelope_serializer(
|
||||
)
|
||||
FertilizationResponseSerializer = build_envelope_serializer(
|
||||
"FertilizationResponseSerializer",
|
||||
data_schema=None,
|
||||
data_schema=FertilizationRecommendationResponseDataSerializer,
|
||||
)
|
||||
|
||||
|
||||
class FertilizationRecommendView(APIView):
|
||||
"""
|
||||
توصیه کودهی به صورت مستقیم.
|
||||
POST با farm_uuid، plant_name، growth_stage.
|
||||
اطلاعات گیاه از plant app دریافت میشود.
|
||||
نیازی به دریافت نوع آبیاری نیست.
|
||||
توصیه کودهی ساختاریافته با ترکیب RAG و optimizer شبیه سازی.
|
||||
"""
|
||||
|
||||
@extend_schema(
|
||||
tags=["Fertilization Recommendation"],
|
||||
summary="درخواست توصیه کودهی",
|
||||
summary="درخواست توصیه کودهی ساختاریافته",
|
||||
description=(
|
||||
"دادههای سنسور و گیاه را دریافت کرده و "
|
||||
"توصیه کودهی را مستقیم برمیگرداند. "
|
||||
"اطلاعات گیاه از جدول Plant بارگذاری میشود. "
|
||||
"محاسبات مربوط به نیاز آبی در این endpoint انجام نمیشود و مستقل از توصیه کودهی است."
|
||||
"داده های مزرعه، گیاه و مرحله رشد را دریافت می کند و "
|
||||
"خروجی نهایی بهینه شده با ترکیب RAG و optimizer مبتنی بر crop_simulation/PCSE را برمی گرداند."
|
||||
),
|
||||
request=FertilizationRecommendRequestSerializer,
|
||||
responses={
|
||||
200: build_response(
|
||||
FertilizationResponseSerializer,
|
||||
"توصیه کودهی با موفقیت تولید شد.",
|
||||
"توصیه کودهی ساختاریافته با موفقیت تولید شد.",
|
||||
),
|
||||
400: build_response(
|
||||
FertilizationValidationErrorSerializer,
|
||||
@@ -63,11 +54,63 @@ class FertilizationRecommendView(APIView):
|
||||
"نمونه درخواست",
|
||||
value={
|
||||
"farm_uuid": "11111111-1111-1111-1111-111111111111",
|
||||
"plant_name": "گوجهفرنگی",
|
||||
"growth_stage": "گلدهی",
|
||||
"crop_id": "wheat",
|
||||
"growth_stage": "flowering",
|
||||
},
|
||||
request_only=True,
|
||||
),
|
||||
OpenApiExample(
|
||||
"نمونه پاسخ",
|
||||
value={
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": {
|
||||
"primary_recommendation": {
|
||||
"fertilizer_code": "15-10-30",
|
||||
"fertilizer_name": "کود کامل 15-10-30",
|
||||
"display_title": "کود کامل 15-10-30",
|
||||
"fertilizer_type": "NPK",
|
||||
"npk_ratio": {"n": 15, "p": 10, "k": 30, "label": "15-10-30"},
|
||||
"application_method": {
|
||||
"id": "foliar_fertigation",
|
||||
"label": "کودآبیاری یا محلول پاشی سبک",
|
||||
},
|
||||
"application_interval": {"value": 14, "unit": "day", "label": "هر 14 روز"},
|
||||
"dosage": {
|
||||
"base_amount_per_hectare": 65,
|
||||
"base_amount_per_square_meter": 0.0065,
|
||||
"unit": "kg",
|
||||
"label": "65 کیلوگرم در هکتار",
|
||||
"calculation_basis": "crop_simulation_heuristic",
|
||||
},
|
||||
"reasoning": "این ترکیب برای مرحله گلدهی و توازن نیازهای تغذیه ای مناسب است.",
|
||||
"summary": "برای پشتیبانی از گلدهی و کاهش تنش تغذیه ای پیشنهاد می شود.",
|
||||
},
|
||||
"nutrient_analysis": {
|
||||
"macro": [
|
||||
{
|
||||
"key": "n",
|
||||
"name": "نیتروژن (N)",
|
||||
"value": 15,
|
||||
"unit": "percent",
|
||||
"description": "نیتروژن برای حفظ رشد رویشی مهم است.",
|
||||
}
|
||||
],
|
||||
"micro": [],
|
||||
},
|
||||
"application_guide": {
|
||||
"safety_warning": "در ساعات خنک مصرف شود و از اختلاط ناسازگار خودداری کنید.",
|
||||
"steps": [
|
||||
{"step_number": 1, "title": "آماده سازی", "description": "دوز را آماده کنید."},
|
||||
{"step_number": 2, "title": "تزریق یا پخش", "description": "طبق روش مصرف اجرا کنید."},
|
||||
{"step_number": 3, "title": "پایش", "description": "پاسخ مزرعه را بررسی کنید."},
|
||||
],
|
||||
},
|
||||
"alternative_recommendations": [],
|
||||
},
|
||||
},
|
||||
response_only=True,
|
||||
),
|
||||
],
|
||||
)
|
||||
def post(self, request):
|
||||
@@ -81,17 +124,14 @@ class FertilizationRecommendView(APIView):
|
||||
)
|
||||
|
||||
validated = serializer.validated_data
|
||||
farm_uuid = validated["farm_uuid"]
|
||||
plant_name = validated.get("plant_name")
|
||||
growth_stage = validated.get("growth_stage")
|
||||
query = validated.get("query")
|
||||
|
||||
try:
|
||||
result = get_fertilization_recommendation(
|
||||
farm_uuid=farm_uuid,
|
||||
plant_name=plant_name,
|
||||
growth_stage=growth_stage,
|
||||
query=query,
|
||||
farm_uuid=validated["farm_uuid"],
|
||||
plant_name=validated.get("plant_name"),
|
||||
crop_id=validated.get("crop_id"),
|
||||
growth_stage=validated.get("growth_stage"),
|
||||
query=validated.get("query"),
|
||||
)
|
||||
except Exception as exc:
|
||||
return Response(
|
||||
@@ -99,8 +139,10 @@ class FertilizationRecommendView(APIView):
|
||||
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
)
|
||||
|
||||
# Public API exposes only the final farmer-facing recommendation object.
|
||||
final_result = {"sections": result.get("sections", [])}
|
||||
final_result = result.get("data") if isinstance(result, dict) else None
|
||||
if not isinstance(final_result, dict):
|
||||
final_result = {"sections": result.get("sections", [])} if isinstance(result, dict) else {}
|
||||
|
||||
return Response(
|
||||
{"code": 200, "msg": "success", "data": final_result},
|
||||
status=status.HTTP_200_OK,
|
||||
|
||||
Reference in New Issue
Block a user