Ë
    LµCjÜ  ã                   óž  — d Z ddlZddlmZ ddlmZ ddlmZmZ ddl	m
Z
 ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ  e«       Z ee«      Z ej4                  ddd¬«      	 	 	 	 d!dedededededz  dedz  dedz  dedz  defd„«       Z	 	 d"dededededededededz  dedz  dedz  dedz  ddfd„Zdedededededdfd „Z y)#u‰  
Celery task definitions.

run_crop_analysis is the single task type this system queues. It is
intentionally synchronous (no async/await inside) because Celery's
worker model is process+thread based, not asyncio based â€” mixing the
two reliably is more complexity than this system needs.

Failure handling: if any unexpected exception escapes everything inside
(which should be rare, since aggregator.py and model_runners.py already
catch and degrade per-model), the task is marked FAILURE in the Celery
result backend, and the failure is also written to failed_request_logs
so the project coordinator can see it in the database, not just in logs.
é    N)Úget_task_logger)Úget_settings)ÚAnalysisRecordÚFailedRequestLog)Úsync_db_session)Úmodel_registry)Úrun_full_analysis)Úfeature_builder)Úllm_service)Ú#notify_feasibility_change_if_needed)Ú
celery_appÚrun_crop_analysisTé   )ÚnameÚbindÚmax_retriesÚ
request_idÚdistrictÚcropÚmonthÚapi_key_prefixÚ	client_ipÚuser_idÚcrop_plan_idÚreturnc	                 ó>  — t        j                  «       }		 t        t        t        |||«      }
t        j                  ||||
«      }t        t        j                  «       |	z
  dz  «      }||||dœ|
d   |
d   |
d   |
d   |
d   |
d   |
d	   d
œ|t        j                  |ddœ}t        |||||
||||||«       |rt        ||
d   j                  d«      «       |S # t        $ r;}t        j                  d|› d|› �d¬«       t!        ||||t#        |«      «       ‚ d }~ww xY w)Niè  ©r   Úlocationr   ÚclimateÚfeasibilityÚyield_predictionÚtrendÚrecommendationÚmarketÚ	conflicts)r   r    r!   r"   r#   r$   r%   F)r   ÚinputÚmodelsÚexplanationÚmodel_versionÚprocessing_msÚcachedÚlabelz(run_crop_analysis failed for request_id=ú: T©Úexc_info)ÚtimeÚperf_counterr	   r   r
   r   Úget_explanationÚintÚsettingsÚMODEL_VERSIONÚ_persist_successr   ÚgetÚ	ExceptionÚloggerÚerrorÚ_persist_failureÚstr)Úselfr   r   r   r   r   r   r   r   ÚstartÚmodel_outputsr(   Útotal_msÚresultÚexcs                  ú>C:\Crop_Prediction\Backend\crop-ai-system\app\workers\tasks.pyr   r   "   sX  € ô ×ÑÓ€Eð(Ü)¬.¼/È8ÐUYÐ[`Óaˆä!×1Ñ1°(¸DÀ%ÈÓWˆäœ×)Ñ)Ó+¨eÑ3°tÑ;Ó<ˆð %Ø"°À5ÑIà(¨Ñ3Ø,¨]Ñ;Ø$1Ð2DÑ$EØ& wÑ/Ø"/Ð0@Ñ"AØ'¨Ñ1Ø*¨;Ñ7ñð 'Ü%×3Ñ3Ø%Øñ
ˆô$ 	Ø˜ $¨¨}¸fÀhØ˜I w°ô	
ñ
 Ü/Ø˜m¨MÑ:×>Ñ>¸wÓGôð ˆøäò Ü�‰Ð?À
¸|È2ÈcÈUÐSÐ^bˆÔcÜ˜ X¨t°U¼CÀ»HÔEØûðús   –CC Ã	DÃ!6DÄDr?   Úfull_resultr*   c                 óø  — 	 t        «       5 }t        di d| “d|	“d|
“d|“d|“d|“d|d   j                  d	«      “d
|d   j                  d
«      “dt        |d   «      “ddj	                  |j                  dg «      «      “d|“dt
        j                  “dd“d|“d|“d|“Ž}|j                  |«       d d d «       y # 1 sw Y   y xY w# t        $ r'}t        j                  d| › d|› �d¬«       Y d }~y d }~ww xY w)Nr   r   r   r   r   r   Úfeasibility_labelr    r,   Úexpected_yield_ton_har!   Úhad_conflictsr%   Údegraded_modelsú,rD   r)   Úserved_from_cacheFr*   r   r   z1Failed to persist analysis record for request_id=r-   Tr.   © )r   r   r7   ÚboolÚjoinr4   r5   Úaddr8   r9   r:   )r   r   r   r   r?   rD   r*   r   r   r   r   ÚsessionÚrecordrB   s                 rC   r6   r6   [   s\  € ðmÜÓð 	  'Ü#ò Ù%ðáðñ *ðñ ð	ñ
 "ðñ ðð #0°Ñ">×"BÑ"BÀ7Ô"Kðð '4Ð4FÑ&G×&KÑ&KÐLcÔ&dðô # =°Ñ#=Ô>ðð !$§¡¨×):Ñ):Ð;LÈbÓ)QÔ Rðñ (ðô '×4Ò4ðñ #(ðñ ,ðñ  .ðñ  $ð!ˆFð$ �K‰K˜Ô÷'	 ÷ 	 ñ 	 ûô( ò mô 	�‰ÐHÈÈÐTVÐWZÐV[Ð\Ðgkˆ×lÑlûðmús5   ‚
C	 ŒB(B=Â4C	 Â=CÃC	 ÃC	 Ã		C9ÃC4Ã4C9Úerror_messagec           
      óò   — 	 t        «       5 }t        | d||||dœ¬«      }|j                  |«       d d d «       y # 1 sw Y   y xY w# t        $ r'}t        j                  d| › d|› �d¬«       Y d }~y d }~ww xY w)NÚTASK_EXECUTION_FAILEDr   )r   Ú
error_coderR   Úinput_payloadz-Failed to persist failure log for request_id=r-   Tr.   )r   r   rO   r8   r9   r:   )r   r   r   r   rR   rP   rQ   rB   s           rC   r;   r;   ƒ   sˆ   € ð
iÜÓð 	  'Ü%Ø%Ø2Ø+Ø'+¸ÈEÑRô	ˆFð �K‰K˜Ô÷	 ÷ 	 ñ 	 ûô ò iÜ�‰ÐDÀZÀLÐPRÐSVÐRWÐXÐcgˆ×hÑhûðiús0   ‚
A Œ%:±A ºA¿A ÁA Á	A6ÁA1Á1A6)NNNN)NN)!Ú__doc__r0   Úcelery.utils.logr   Úapp.core.configr   Úapp.db.modelsr   r   Úapp.db.sync_sessionr   Úapp.models_loader.registryr   Úapp.services.aggregatorr	   Úapp.services.feature_builderr
   Úapp.services.llm_servicer   Ú!app.services.notification_servicer   Úapp.workers.celery_appr   r4   Ú__name__r9   Útaskr<   r3   Údictr   r6   r;   rL   ó    rC   ú<module>rf      s±  ðñó å ,å (ß :Ý /Ý 5Ý 5Ý 8Ý 0Ý QÝ -á‹>€Ù	˜Ó	"€ð €‡�Ð)°À!ÔDð "&Ø ØØ#ñ5àð5ð ð5ð ð	5ð
 ð5ð ˜$‘Jð5ð �T‰zð5ð �4‰Zð5ð ˜‘*ð5ð 
ò5ó Eð5ðD Ø#ñ%mØð%màð%mð ð%mð ð	%mð
 ð%mð ð%mð ð%mð ˜$‘Jð%mð �T‰zð%mð �4‰Zð%mð ˜‘*ð%mð 
ó%mðPi ð i°ð i¸3ð iÀsð iÐ[^ð iÐcgô ire   