
    	]j              	       &   d Z ddlZddlmZ ddlZddlmZm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mZ ddlm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)m*Z* ddl+m,Z, ddl-m.Z. ddl/m0Z0 ddl1m2Z2 ddl3m4Z4 ddl5m6Z6m7Z7m8Z8m9Z9m:Z: ddl;m<Z< ddl=m>Z> ddl?m@Z@  ej                  eB      ZCd ZD G d de*j                        ZF ed d!d"d#d$d%d&d'       G d( d)e*j                               ZH ed d*d+d#d,d-d&d'       G d. d/e*j                               ZI G d0 d1e0      ZJ G d2 d3e*j                        ZL G d4 d5e@      ZM G d6 d7e'      ZN G d8 d9e'      ZO G d: d;e'      ZP G d< d=e'      ZQ G d> d?e*j                        ZR eej                        ZT G d@ dAeT      ZU G dB dCe0      ZV G dD dEeT      ZW G dF dGeW      ZX G dH dIe0      ZY G dJ dKe0      ZZ G dL dMe0      Z[ eej                        Z]y)NzThis file and its contents are licensed under the Apache License 2.0. Please see the included NOTICE for copyright information and LICENSE for a copy of the license.    N)MutableMapping)CurrentContextget_current_request)flag_set)-replace_task_data_undefined_with_config_field)	load_funcretry_database_locked)
fast_first)extract_message)settings)IntegrityErrortransaction)extend_schema_field)FSMStateField)get_or_infer_state)get_or_initialize_stateis_fsm_enabled)LabelInterface)Project)FlexFieldsModelSerializer)genericsserializers)ValidationError)	SkipField)ModelSerializer)api_settings)AnnotationDuplicateError)
AnnotationAnnotationDraft
PredictionPredictionMetaTask)TaskValidator)User)UserSerializerc                 N    t        | t              s| S | j                  dd       | S )z6Drop only FSM `state` from prediction import payloads.stateN)
isinstancer   pop)
predictions    H/root/env/lib/python3.12/site-packages/label_studio/tasks/serializers.py"sanitize_prediction_import_payloadr,   $   s&    j.1NN7D!    c                   \    e Zd Z ej                  dd      Z ej                  dd      Zy)PredictionQuerySerializerFzTask ID to filter predictions)required	help_textz Project ID to filter predictionsN)__name__
__module____qualname__r   IntegerFieldtaskproject r-   r+   r/   r/   ,   s,    #;##U>]^D&k&&AcdGr-   r/   arrayzPrediction result listz'List of prediction results for the taskobjectz!Prediction result items (regions)z&List of predicted regions for the task)typetitledescription)r;   r<   r=   itemsc                       e Zd Zy)PredictionResultFieldNr2   r3   r4   r8   r-   r+   r@   r@   1        	r-   r@   zAnnotation result listz'List of annotation results for the taskz!Annotation result items (regions)z&List of annotated regions for the taskc                       e Zd Zy)AnnotationResultFieldNrA   r8   r-   r+   rD   rD   A   rB   r-   rD   c                        e Zd Z e       Z ej                  ddd      Z ej                  ddd      Z fdZ	 G d	 d
      Z
 xZS )PredictionSerializerTFzModel version - tag for predictions that can be used to filter tasks in Data Manager, as well as select specific model version for showing preannotations in the labeling interface)allow_blankr0   r1    Delta time from creation timedefault	read_onlyr1   c                 x   d}d|v r|d   j                   }n	d|v r|d   }|r|j                  j                  nd}t        d|      s't        j                  d|        t        |   |      S d|vr|S |st        d	      t        |j                        }|j                  |d
      }|rt        d|       |S )zFValidate prediction using LabelInterface against project configurationNr6   r7   auto1fflag_feat_utc_210_prediction_validation_15082025userz@Skipping prediction validation in PredictionSerializer for user resultz-Project is required for prediction validationTreturn_errorszError validating prediction: )r7   organization
created_byr   loggerinfosupervalidater   r   label_configvalidate_prediction)selfdatar7   ff_userlivalidation_errors	__class__s         r+   rZ   zPredictionSerializer.validate[   s    T>6l**G$9oG5<'&&11&KRYZKKZ[bZcde7#D)) 4K!"QRR G001224t2L!$ABSAT"UVVr-   c                       e Zd ZeZdZy)PredictionSerializer.Meta__all__N)r2   r3   r4   r    modelfieldsr8   r-   r+   Metard   y   s    r-   rh   )r2   r3   r4   r@   rR   r   	CharFieldmodel_versioncreated_agorZ   rh   __classcell__rb   s   @r+   rF   rF   Q   sQ    "$F)K))]M (+''dNmnK< r-   rF   c                       e Zd Zy)ListAnnotationSerializerNrA   r8   r-   r+   ro   ro   ~   s    r-   ro   c                        e Zd Z G d d      Zy)CompletedByDMSerializerc                       e Zd ZeZg dZy)CompletedByDMSerializer.Meta)id
first_name	last_nameavataremailinitialsN)r2   r3   r4   r$   rf   rg   r8   r-   r+   rh   rs      s    Qr-   rh   Nr2   r3   r4   rh   r8   r-   r+   rq   rq      s    R Rr-   rq   c                   L    e Zd ZdZ ed      Z	  ed      Z ej                  ddd      Z
 ej                  ddd	      Z ej                  dej                  j!                         
      Z ej                  dd      Z fdZd ZdefdZ fdZ G d d      Z xZS )AnnotationSerializerz
    Annotation Serializer with FSM state support.

    Note: The 'state' field will be populated from the queryset annotation
    if present, preventing N+1 queries. Use .with_state() on your queryset.
    TrL   F)r0   rH   Username stringrJ   Time delta from creation timer0   queryset)r0   
write_onlyc           
          	 t        |   |i |S # t        $ r>}ddg}t        |D cg c]  }|t	        |      v  nc c}w c}      r
t                d }~ww xY w)Nz3UNIQUE constraint failed: task_completion.unique_idzNduplicate key value violates unique constraint "task_completion_unique_id_key")rY   creater   anystrr   )r]   argskwargseerrorserrorrb   s         r+   r   zAnnotationSerializer.create   se    		7>42622 	E`F 8ESVO889.00	s    	AA=
AAc                     |}t        |t              r	 t        j                  |      }t        |t
              st        d      |S #  t	        d      xY w)Nz3annotation "result" can't be parse from str to JSONz4annotation "result" field in annotation must be list)r(   r   jsonloads
ValueErrorlistr   )r]   valuer^   s      r+   validate_resultz$AnnotationSerializer.validate_result   sV    eS!Yzz%(
 $%!"XYYY !WXXs   A Areturnc                     |j                   }|sy|j                  }t        |j                        r|dz   |j                  z   }|d|j                   d|j
                   z  }|S NrH    , completed_byru   lenrv   rx   rt   r]   
annotationrQ   names       r+   get_created_usernamez)AnnotationSerializer.get_created_username   ^    &&t~~#:.D!DJJ<r$''++r-   c                     t         |   |      }t        j                         }t	        d|      rt	        d|      s|j                  dd       |S z0Remove state field if feature flags are disabled*fflag_feat_fit_568_finite_state_managementrP   #fflag_feat_fit_710_fsm_state_fieldsr'   NrY   to_representationr   get_userr   r)   r]   objretrQ   rb   s       r+   r   z&AnnotationSerializer.to_representation   I    g',&&(AM>TJGGGT"
r-   c                   "    e Zd ZeZddgZdefiZy)AnnotationSerializer.Metar*   result_countr   N)r2   r3   r4   r   rf   excluderq   expandable_fieldsr8   r-   r+   rh   r      s     0+.E-GHr-   rh   )r2   r3   r4   __doc__r   r'   rD   rR   r   SerializerMethodFieldcreated_usernameri   rk   PrimaryKeyRelatedFieldr$   objectsallr   	unique_idr   r   r   r   r   rh   rl   rm   s   @r+   r|   r|      s     D)E
"E2F8{88t_pq'+''dNmnK5;55ut||O_O_OabL%%%uFI

# 
	I Ir-   r|   c                      e Zd ZdZ ej
                  ddd      Z ej                  ddd      Z ej                  de
j                  j                               Z ej
                  d	      Zd
efdZd
efdZ G d d      Zy)AnnotationStubSerializera  
    Lightweight Annotation Serializer for lazy loading.

    Returns only minimal metadata needed for annotation list display.
    Used when fflag_fix_all_fit_720_lazy_load_annotations is enabled
    to improve performance for tasks with many annotations.

    Fields included:
    - id: for selection and hydration
    - created_username: for display in annotation list
    - created_ago: for display in annotation list (relative time string)
    - created_at: for TimeAgo component (actual timestamp)
    - completed_by: user id for avatar lookup
    - ground_truth: for showing star indicator
    - was_cancelled: for skip queue / cancel-skip button display
    - is_stub: signals frontend to fetch full data on selection
    rH   Tr~   rJ   r   Fr   r}   r   c                     |j                   }|sy|j                  }t        |j                        r|dz   |j                  z   }|d|j                   d|j
                   z  }|S r   r   r   s       r+   r   z-AnnotationStubSerializer.get_created_username   r   r-   c                      y)NTr8   )r]   r   s     r+   get_is_stubz$AnnotationStubSerializer.get_is_stub   s    r-   c                       e Zd ZeZg dZy)AnnotationStubSerializer.Meta)rt   r   rk   
created_atr   ground_truthwas_cancelledis_stubN)r2   r3   r4   r   rf   rg   r8   r-   r+   rh   r      s    	
r-   rh   N)r2   r3   r4   r   r   r   r   ri   rk   r   r$   r   r   r   r   r   r   boolr   rh   r8   r-   r+   r   r      s    $ 9{88t_pq'+''dNmnK5;55ut||O_O_OabL/k//$?G
# 
 
 
r-   r   c                   <     e Zd Z fdZ fdZ G d d      Z xZS )TaskSimpleSerializerc                     t        |   |i | t        dg | j                  d      | j                  d<   t        dg | j                  d      | j                  d<   y )NT)manyrK   contextrL   annotationspredictionsrY   __init__r|   r   rg   rF   r]   r   r   rb   s      r+   r   zTaskSimpleSerializer.__init__
  sW    $)&)%9tRY]YeYequ%vM"%9tRY]YeYequ%vM"r-   c                 n    |j                   }|r|j                  }t        ||       t        |   |      S N)r7   r^   r   rY   r   r]   instancer7   r^   rb   s       r+   r   z&TaskSimpleSerializer.to_representation  s4    ""==D9$Hw(22r-   c                       e Zd ZeZdZy)TaskSimpleSerializer.Metaprecomputed_agreement
allow_skipNr2   r3   r4   r"   rf   r   r8   r-   r+   rh   r         9r-   rh   )r2   r3   r4   r   r   rh   rl   rm   s   @r+   r   r   	  s    w
3: :r-   r   c                   D     e Zd ZdZddZd Z fdZ G d d      Z xZS )BaseTaskSerializerz6Task Serializer with project scheme configs validationc                 *   d| j                   v r| j                   d   }|S d| j                   v rSd| j                   d   j                  v r8| j                   d   j                  }t        j                  t        |d         }|S |r|j
                  }|S d}|S )zTake the project from contextr7   view
project_idN)r   r   r   get_object_or_404r   r7   )r]   r6   r7   r   s       r+   r7   zBaseTaskSerializer.project   s    $ll9-G  t||#V8L8S8S(S\\&)00F00&:NOG
 	 llG  Gr-   c                 j   t        | d      r| j                  nd }| j                  |      }t               }|r0|j                  dk(  r!|s	 | j
                  d   j                  d       t        |d|vr|nd       }|j                  |      S # t        $ r}t        d|j                  i      d }~ww xY w)Nr   )r6   POSTr7   r0   r^   )r   )hasattrr   r7   r   methodrg   failr   detailr#   rZ   )r]   r6   r   r7   current_requestexc	validators          r+   rZ   zBaseTaskSerializer.validate-  s    $+D*$=4==4,,H,--/55?I&++J7 "!'t!3X
	 !!$'' # %!3:: s   B 	B2B--B2c                     | j                  |      }|rU| j                  j                  dd      r!|j                  |j                  |      |_        |j                  }t        ||       t        |   |      S )Nresolve_uriF)r7   r   getr   r^   r   rY   r   r   s       r+   r   z$BaseTaskSerializer.to_representationD  se    ,,x(||u5 ( 4 4X]]G L ==D9$Hw(22r-   c                       e Zd ZeZdZy)BaseTaskSerializer.Metar   Nr   r8   r-   r+   rh   r   Q  r   r-   rh   r   )	r2   r3   r4   r   r7   rZ   r   rh   rl   rm   s   @r+   r   r     s    @(.3: :r-   r   c                   ,   e Zd ZdZ edg d      Z edg d      Zed        Z	e
d        Zd Ze
d        Ze
d        Ze
d	        Z e       d
        Zd Zd Zd Zd Zd ZddefdZe
d        Ze
d        Ze
d        Ze
d        Z G d d      Zy)BaseTaskSerializerBulkz4Serialize task with annotation from source json dataT)r   rK   rL   c                 8    | j                   j                  d      S )Nr7   )r   r   r]   s    r+   r7   zBaseTaskSerializerBulk.project\  s    ||	**r-   c                    t        |      dk(  r7|d   j                  dk7  rd|d   j                   nd}d| d|  d|d    d	| S d
j                  |      }|D cg c]  }|j                   }}d| d|  d| d	| S c c}w )N   r   invalidr   rH   Errorz	 at item : z :: r   zErrors )r   codejoin)ir   itemr   r   dcodess          r+   format_errorz#BaseTaskSerializerBulk.format_error`  s    v;!+1!9>>Y+FQvay~~&'BD4&	!BvaykdVDDYYv&F%+,QVV,E,UG9QCr&dVDD -s   A>c                    |t        d      t        |t              st        t        j                  did      | j
                  sMt        |      dk(  r?| j                  r| j                  r
t               t        t        j                  did      g g }}d\  | _
        | _        t        |      D ]  \  }}	 | j                  j                  |      }|j                  |       |j                  i        d	|v r!| xj                  t        |d	         z  c_
        d
|v sn| xj                  t        |d
         z  c_         t%        |      r,t&        j)                  dt+        |      z          t        |      |S # t         $ rR}| j!                  ||j"                  |      }|j                  |       t        |      dk\  rd|d<   Y d}~ Y d}~ d}~ww xY w)z)Body of run_validation for all data itemsNzAll tasks are empty (None)z
not a list
not_a_list)r   r   empty)r   r   r   r   d   z...c   zCan't deserialize tasks due to )r   r(   r   r   NON_FIELD_ERRORS_KEYallow_emptyr   parentpartialr   annotation_countprediction_count	enumeratechildrZ   appendr   r   r   rW   warningr   )	r]   r^   r   r   r   r   	validatedr   r   s	            r+   to_internal_valuez(BaseTaskSerializerBulk.to_internal_valuej  s   <!">??$%!<#D#Dl"SZfggCIN{{t||k!!<#D#Dg"NU\]]"V7;4t4  	FGAtF JJ//5	 

9%b! D())Sm1D-EE) D())Sm1D-EE)#	F& v;NN<s6{JK!&))
) # ))!SZZ>e$v;#%!&F2J &	s   9E<<	GAGGc                    | D ]  }|j                  d      }||j                  |d<   nt        |t              rOd|vrt	        d      |d   }||vr.t
        j                  r|j                  |d<   nRt	        d|       ||   |d<   n;t        |t              r||v r||vrt	        d|       ||d<   nt	        d| d	      |j                  dd        y)
z>Insert the correct id for completed_by by email in annotationsr   Ncompleted_by_idrx   zIIt's expected to have 'email' field in 'completed_by' data in annotationszUnknown annotator's email zUnknown annotator's ID z"Import data contains completed_by=z- which is not a valid annotator's email or ID)	r   rt   r(   dictr   r   &ALLOW_IMPORT_TASKS_WITH_UNKNOWN_EMAILSintr)   )r   members_email_to_idmembers_idsdefault_userr   r   rx   s          r+   _insert_valid_completed_byz1BaseTaskSerializerBulk._insert_valid_completed_by  s    &  	1J%>>.9L#0<
,- L$/,.)*uvv$W- 33FF8D
#45-0J5'.RSS 5H4NJ01 L#.<;3N{2),CL>*RSS0<
,- &8Fst  NN>40A 	1r-   c                    | D ]z  }|j                  di       }t        |t              r|j                  d      nd}||vr%|j                  |d<   t        j                  d       n||   |d<   |j                  dd       | y):  Insert correct user id by email from snapshot

        :param dicts: draft or review dicts from snapshot
        :param members_email_to_id: mapping from emails to current LS instance user IDs
        :param default_user: if email is not found in membr_email_to_id, this user will be used
        :return:
        rV   rx   Ncreated_by_idAEmail not found in members_email_to_id, default user used instead)r   r(   r  rt   rW   r
  r)   )dictsr  r  r   rV   rx   s         r+   _insert_valid_user_reviewsz1BaseTaskSerializerBulk._insert_valid_user_reviews  s      	(Cr2J/9*d/KJNN7+QUE //'3O$bc (;5'AO$GGL$'	(r-   c                     | D ]V  }|j                  d      }||vr%|j                  |d<   t        j                  d       n||   |d<   |j	                  dd       X y)r  rQ   user_idr  N)r   rt   rW   r
  r)   )r  r  r  r   rx   s        r+   _insert_valid_user_draftsz0BaseTaskSerializerBulk._insert_valid_user_drafts  sc      	"CGGFOE //!-Ibc "5U!;IGGFD!	"r-   c                 >   |}t        j                  dt        |              | j                  j	                  dd      }|xs | j
                  j                  }| j
                  j                  j                  }| j
                  j                  }t        |j                  j                  dd            }t        |j                               }t        j                  t        |       d|        t        j                          5  g g }
}	g g }}|D ]  }|j#                  dg       }| j%                  ||||       |	j'                  |       |j#                  dg       }|
j'                  |       t)        d	|
      sk|j#                  dg       }| j+                  |||       |j'                  |       |D ]8  }|j	                  dg       }| j-                  |||       |j'                  |       :  | j/                  |	|
|      }| j1                  |	|      }| j3                  |
      }d}t)        d|
      sd}|r|rt5        d|i      ddd       | j7                  |d       | j9                  | j
                  j:                  | j<                  D cg c]  }|j:                   c}       | j?                  | j
                  j:                  |       t)        d	|
      rt        j                          5  |D ci c]  }|j@                  |j:                   }}d|d<   | jC                  || j
                         | jE                  || j
                         ddd       | jG                  | j<                         S # 1 sw Y   6xY wc c}w c c}w # 1 sw Y   =xY w)z&Create Tasks, Annotations, etc in bulkz4Try to serialize tasks with annotations, data len = rQ   Nuser__emailuser__idz members found in organization r   r   >fflag_feat_back_lsdv_5307_import_reviews_drafts_29062023_shortrP   draftsreviewsTrO   Fimported)$loggingrX   r   r   r   r7   rV   rU   r  membersvalues_listsetvaluesrW   debugr   atomicr)   r  r	  r   r  r  	add_tasksadd_annotationsadd_predictionsr   post_process_annotationspost_process_tasksrt   db_taskspost_process_custom_callback	import_id
add_draftsadd_reviews_backfill_fsm_states)r]   validated_datavalidated_tasksrQ   r  r_   rU   r  r  task_annotationstask_predictionstask_draftstask_reviewsr6   r   r   r#  r   r$  r2  db_annotationsprediction_errorsraise_prediction_errorstvannotation_mappings                             r+   r   zBaseTaskSerializerBulk.create  sd    )KCP^L_K`ab||-6t||66,,++66 ||00"<#7#7#C#CMS]#^_-4467/011PQ]P^_` ! &	J 24R.(*BK' 5"hh}b9//=PR]_kl ''4 #hh}b9 ''4\cjk!XXh3F226;NP\]&&v. '2 5
",..B"?77ATVbc$++G45#5, ~~&68H/ZH!112BDIN $ 4 45E F&*#OV]^*/' !%<%}6G&HIIM&	JP 	%%dNJG1N1!$$1NO))$,,//4@T[bc##% Q BP%PAakk144&7%P"%P+/"4(X7I4<<X  /A4<<PQ 	!!$--0w&	J &	JR 2O &QQ Qs9   A5M<;CM<N	
2N7NAN<NNNc                 X   g }g }| j                   j                  xr+ t        d| j                   j                  j                        }d}t        |      D ]  \  }}t        |      D ]|  \  }}	t        |	t              s|j                  d| d| d       0| j                   j                  j                  }
t        d|
      rt        d|
      r|	j                  d	d       |rg	 t        |	      }	|rt        | j                   j                        nd}|j                  |	d
      }|r"|D ]  }|j                  d| d| d|         	 	 t!        j"                  |	d   | j                         }|	j%                  d      }|	 t'        |      }|	j%                  dd      }|j                  t!        | j.                  |   | j.                  |   j                   |||               |r|S t         j0                  j3                  |t4        j6                        | _        t;        j<                  dt?        | j8                                | j                   j@                  s-|+|| j                   _         | j                   jC                          y# t        $ r.}|j                  d| d| dt        |              Y d}~\d}~ww xY w# t(        $ r t*        j-                  d       d}Y _w xY w# t        $ r.}|j                  d| d| dt        |              Y d}~d}~ww xY w)zFSave predictions to DB and set the latest model version in the projectrO   rP   NzTask z, prediction z!: Prediction must be a dictionaryr   r   r'   TrS   r   z : Error validating prediction - rR   scorezOCan't upload prediction score: should be in float format.Fallback to score=Nonerj   	undefined)r6   r7   rR   rE  rj   z : Failed to create prediction - 
batch_sizez)Predictions serialization success, len = )"r7   label_config_is_not_defaultr   rU   rV   r  r(   r  r	  r)   r,   r   r[   r\   	Exceptionr   r    prepare_prediction_resultr   floatr   rW   r   r2  r   bulk_creater   
BATCH_SIZEdb_predictionsr&  rX   r   rj   save)r]   r;  rO  ra   should_validatelast_model_versionr   r   jr*   r_   r`   validation_errors_listr   r   rR   prediction_scores                    r+   r/  z&BaseTaskSerializerBulk.add_predictions3  s8   ,,BB 
x?dllF_F_FjFjH

 "'(89 <	NA{!*;!7 ;:!*d3%,,uQC}QCGh-ij ,,33>>HwW\d9] NN7D1 #!%G
%S
JY^DLL,E,EF_c131G1G
bf1G1g.1)? _ 1 8 85=QRPSSUV[U\9] ^_$	 2'AA*XBVX\XdXdeF'1~~g'>$'34/45E/F, *4)U&"))"!%q!1$(MM!$4$<$<#)"2*<];<	~ $$ )00<<^X`XkXk<l@TEXEXAY@Z[\ ||)).@.L);DLL&LLa % !)00#A3mA36VWfghWiVjk !	!  * 4"LL q 04,	4  ! %,,s-s2RSbcdSeRfg 	sV   &A$J6K2KAK2	K#KK K/+K2.K//K22	L);#L$$L)c                     g S )zSave task reviews to DBr8   )r]   r=  rC  r7   s       r+   r6  z"BaseTaskSerializerBulk.add_reviews  s    	r-   c           
         g }t        |      D ]  \  }}|D ]  }t        |t              s|j                  ||   j                  ||j                  d         | j                  |j                  d      d       dD 	cg c]  }	|j                  |	d       c}	 |j                  t        di |         t        j                  j                  |t        j                        | _        t        j                   dt#        | j                                | j%                  | j                         | j                  S c c}	w )	zSave task drafts to DBr   rt   )task_idannotation_idr7   r4  )rt   r6   r   r7   r   rk   NrG  z$drafts serialization success, len = r8   )r  r(   r  updatert   r   r7   r)   r	  r   r   rM  r   rN  	db_draftsr&  rX   r   r7  )
r]   r<  r2  rC  r7   r[  r   r#  draftfields
             r+   r5  z!BaseTaskSerializerBulk.add_drafts  s   	 #;/ 	;IAv ;!%.#+A;>>);EIIl<S)T#'<<%*YYt_	 "l IIeT*   !95!9:#;	;( )00<<YS[SfSf<g;C<O;PQR 	!!$..1~~s   <D<c                    g }t        |      D ]  \  }}|D ]  }t        |t              s|j                  dd      }|j                  dd      }|j                  dd      }	| j                  |   | j
                  |||d   |d   |	|j                  d	      d
}
|j                  t        di |
         t        j                  t        j                  k(  r~g | _        	 t        j                  j                  d	      }|j                  dz   }|D ]  }||_        |dz  } t        j                  j#                  |t        j$                        | _        n4t        j                  j#                  |t        j$                        | _        t'        j(                  dt+        | j                                | j-                  | j                         | j                  S # t        j                   $ r d}Y w xY w)zSave task annotations to DBr   Tr   F	lead_timeNr  rR   rt   )r6   r7   r   r   r  rR   r_  r4  r   rG  z)Annotations serialization success, len = r8   )r  r(   r  r)   r2  r7   r   r	  r   r   	DJANGO_DBDJANGO_DB_SQLITEr>  r   latestrt   DoesNotExistrM  rN  r&  rX   r   r7  )r]   r:  rQ   r>  r   r   r   r   r   r_  bodylast_annotation
current_ids                r+   r.  z&BaseTaskSerializerBulk.add_annotations  s    ((89 	:NA{) :
!*d3)~~ndC * F&NN;=	 !MM!,#||$0%2'12C'D(2!*!+!5	 %%j&84&89%:	:, !:!::"$D","4"4";";D"A,//!3
 -  
 *
a
  #-"4"4"@"@\d\o\o"@"pD","4"4"@"@\d\o\o"@"pD@TEXEXAY@Z[\ 	!!$"5"56""" ** 
s   .G G21G2c                    g }| j                   j                  }t        j                  j	                         j                  | j                   j                        }t        t        j                  j                  |      j                  d            }|r|j                  nd}|r|dz   nd}	t        |      D ]  \  }
}t        ||
   D cg c]  }|j                  dd      s| c}      }t        ||
         |z
  }t        t        ||
   D cg c]  }|j                  d       c}            }t        | j                   |d	   |j                  d
i       |||k\  |j                  d      |dn|	|
z   t        ||
         |||j                  dd            }|j                  |        t         j"                  t         j$                  k(  r~g | _        	 t        j                  j)                  d      }|j                  dz   }|D ]  }||_        |dz  } t        j                  j-                  |t         j.                        | _        n4t        j                  j-                  |t         j.                        | _        t1        j2                  dt        | j&                                |S c c}w c c}w # t        j*                  $ r d}Y w xY w)z7Extract tasks from validated_tasks and store them in DB)rt   )r7   z	-inner_idr   r   r   Fr  r^   metafile_upload_idNr   T)r7   r^   rh  overlap
is_labeledri  inner_idtotal_predictionstotal_annotationscancelled_annotationsr   rt   rG  z#Tasks serialization success, len = )r7   maximum_annotationsr   r   select_for_updater   rt   r
   r"   filterorder_byrl  r  r   r)  r	  r   r`  ra  r2  rb  rc  rM  rN  r&  rX   )r]   r:  r;  r9  r2  max_overlapr7   	last_taskprev_inner_idmax_inner_idr   r6   annro  rn  current_overlaprA  rf  s                     r+   r-  z BaseTaskSerializerBulk.add_tasks  sx   ll66 //33599T\\__9Mt||2272CLL[YZ	.7	**Q.;) 1 	GAt$'8H8K(oswwWfhmOn(o$p! #$4Q$7 8;P P!#M]^_M`&acsww/@'A&a"bcO&\XXfb)#*k9#xx(89!.!6L1<L"%&6q&9":"3&;88L$7A OOA#	( !:!::DM LL//5	&\\A-
 !  $a
  !LL44X(J]J]4^DM LL44X(J]J]4^DM:3t}};M:NOPI )p&a, $$ 
s$   	J,
!J,
J1.J6 6KKentitiesc                     t        j                         }|rt        |      sy|D ]  }t        |      }t	        ||||        y)z
        Backfill FSM states for entities created via bulk_create().

        bulk_create() bypasses the model's save() method, so FSM transitions
        don't fire automatically. This sets initial state for newly imported entities.
        N)rQ   inferred_stateoverwrite_state)r   r   r   r   r   )r]   rz  r}  rQ   entityr|  s         r+   r7  z+BaseTaskSerializerBulk._backfill_fsm_states  sI     &&(~d3 	wF/7N#Fnfuv	wr-   c                      y r   r8   )rQ   r>  actions      r+   r0  z/BaseTaskSerializerBulk.post_process_annotations$      r-   c                      y r   r8   )rQ   r2  s     r+   r1  z)BaseTaskSerializerBulk.post_process_tasks(  r  r-   c                     | S r   r8   )rd  rQ   r  s      r+   add_annotation_fieldsz,BaseTaskSerializerBulk.add_annotation_fields,  s    r-   c                      y r   r8   )r   rQ   s     r+   r3  z3BaseTaskSerializerBulk.post_process_custom_callback0  r  r-   c                       e Zd ZeZdZy)BaseTaskSerializerBulk.Metare   Nr2   r3   r4   r"   rf   rg   r8   r-   r+   rh   r  4  s    r-   rh   N)F)r2   r3   r4   r   r|   r   rF   r   propertyr7   staticmethodr   r  r  r  r  r	   r   r/  r6  r5  r.  r-  r   r7  r0  r1  r  r3  rh   r8   r-   r+   r   r   V  s,   >&D"MK&D"MK+ + E E&P "1 "1H ( (. " ", J JXVp D/#b1fwT w         r-   r   c                   6     e Zd ZdZ fdZ G d d      Z xZS )TaskWithAnnotationsSerializerr   c                 n    t        |   |i | t        dg | j                        | j                  d<   y )NTr   rK   r   r   )rY   r   r|   r   rg   r   s      r+   r   z&TaskWithAnnotationsSerializer.__init__?  s3    $)&)%9tRY]YeYe%fM"r-   c                   8    e Zd ZeZ eej                        ZdZ	y)"TaskWithAnnotationsSerializer.Metar8   N)
r2   r3   r4   r"   rf   r   r   TASK_SERIALIZER_BULKlist_serializer_classr   r8   r-   r+   rh   r  C  s     )(*G*G Hr-   rh   )r2   r3   r4   r   r   rh   rl   rm   s   @r+   r  r  <  s    g r-   r  c                        e Zd ZdZ ed      Z ej                   ej                               Z	 ej                  ddd      Z ej                  ddd      Zd	 Z fd
Z G d d      Z xZS )AnnotationDraftSerializerz
    AnnotationDraft Serializer with FSM state support.

    Note: The 'state' field will be populated from the queryset annotation
    if present, preventing N+1 queries. Use .with_state() on your queryset.
    Tr}   )rK   rH   zUser name stringrJ   rI   c                     |j                   }|sy|j                  }|j                  }t        |      r|dz   |z   }||rdnd|j                   d|j
                   z   z  }|S r   )rQ   ru   rv   r   rx   rt   )r]   r\  rQ   r   rv   s        r+   r   z.AnnotationDraftSerializer.get_created_usernameW  sc    zzNN	y>#:	)D"4::,b	(BBBr-   c                     t         |   |      }t        j                         }t	        d|      rt	        d|      s|j                  dd       |S r   r   r   s       r+   r   z+AnnotationDraftSerializer.to_representationc  r   r-   c                       e Zd ZeZdZy)AnnotationDraftSerializer.Metare   N)r2   r3   r4   r   rf   rg   r8   r-   r+   rh   r  n  s    r-   rh   )r2   r3   r4   r   r   r'   r   ri   CurrentUserDefaultrQ   r   r   rk   r   r   rh   rl   rm   s   @r+   r  r  J  su     D)E ;  )G)G)G)IJD8{88t_qr'+''dNmnK
	 r-   r  c                       e Zd Z ej                  g d      Z ej                  g d      Z ej                  g d      Z ej                  g d      Zd Z	d Z
d Zd Zd Zy)	4TaskWithAnnotationsAndPredictionsAndDraftsSerializerT)rK   rL   c                 <    |j                   rd|j                   igS g S )Nr  )updated_by_id)r]   r6   s     r+   get_updated_byzCTaskWithAnnotationsAndPredictionsAndDraftsSerializer.get_updated_byy  s#    484F4FD../0NBNr-   c                     d| j                   v r3t        | j                   d   d      r| j                   d   j                  S y y )NrequestrQ   )r   r   rQ   r   s    r+   	_get_userz>TaskWithAnnotationsAndPredictionsAndDraftsSerializer._get_user|  s>    $i1H&)Q<<	*/// *R$r-   c                    |j                   }| j                         }t        d|xs d      rX|j                  j	                         }|j                  dd      }t        j                  d|        |j                  |      }n<|j                  j                  r&|j                  |j                  j                  	      }t        |ddg | j                  
      j                  S )N5ff_front_dev_1682_model_version_dropdown_070622_shortrN   rP   rj   T)flatz=Selecting predictions from active ML backend model versions: )model_version__in)rj   r   rL   rK   r   )r   r  r   r7   get_active_ml_backendsr(  rW   r+  rr  rj   rF   r   r^   )r]   r6   r   rQ   active_ml_backendsmodel_versionss         r+   get_predictionszDTaskWithAnnotationsAndPredictionsAndDraftsSerializer.get_predictions  s    &&~~KRVR`Z`a!%!D!D!F/;;ORV;WNLLXYgXhij%,,~,NK\\''%,,4<<;U;U,VK#KddTV`d`l`lmrrrr-   c                     |j                   }| j                         }|r|j                  r|j                  |      }t	        |ddg | j
                        j                  S )z,Return annotations only for the current userr   Tr  )r   r  is_annotatorrr  r|   r   r^   )r]   r6   r   rQ   s       r+   get_annotationszDTaskWithAnnotationsAndPredictionsAndDraftsSerializer.get_annotations  sX    &&~~D%%%,,$,?K#KddTV`d`l`lmrrrr-   c                 >   t        |t              st        d      S |j                  }d| j                  v rDt        | j                  d   d      r+| j                  d   j                  }|j                  |      }t        |ddg | j                        j                  S )z'Return drafts only for the current userT)r   r  rQ   rP   r  )	r(   r"   r  r#  r   r   rQ   rr  r^   )r]   r6   r#  rQ   s       r+   
get_draftsz?TaskWithAnnotationsAndPredictionsAndDraftsSerializer.get_drafts  s     $%,$77$i1H&)Q<<	*//D]]]-F(ddTV`d`l`lmrrrr-   N)r2   r3   r4   r   r   r   r   r#  
updated_byr  r  r  r  r  r8   r-   r+   r  r  s  so    3+33B$OK3+33B$OK.[..rTJF2222NJO0
sssr-   r  c                   L     e Zd Z ej                         Zd Zd Z fdZ xZ	S )NextTaskSerializerc                     | j                   d   j                  }|j                  j                  |      j	                         }|r|j
                  S y )Nr  rP   )r   rQ   locksrr  firstr   )r]   r6   rQ   locks       r+   get_unique_lock_idz%NextTaskSerializer.get_unique_lock_id  sH    ||I&++zz  d +113>>! r-   c                 j    |j                         }t        |ddg | j                        j                  S )NTr  )get_predictions_for_prelabelingrF   r   r^   )r]   r6   r   s      r+   r  z"NextTaskSerializer.get_predictions  s1    ::<#KddTV`d`l`lmrrrr-   c                    g }| j                   j                  dd      r| j                   j                  dd      }| j                   d   j                  }|r`|j                  }|j                  r|j                  |      }n|j                  |      }t        |dd| j                         j                  S t        | %  |      }|D ]2  }|j                  d      |j                  k(  s"|j                  |       4 |S )	Nr   Fannotations_stubr  r  T)r   rL   r   r   )r   r   rQ   r   r  rr  r   r^   rY   r  rt   r	  )r]   r6   rR   use_stubrQ   r   r   rb   s          r+   r  z"NextTaskSerializer.get_annotations  s    <<M51 ||''(:EBH<<	*//D"..$$"-"4"4$"4"GK"-"4"4$"4"GK/$RV`d`l`lmrrr#g5d;"- 2J!~~n5@j12 r-   )
r2   r3   r4   r   r   unique_lock_idr  r  r  rl   rm   s   @r+   r  r    s(    6[668N"s r-   r  c                   2     e Zd Z fdZ G d d      Z xZS )-TaskIDWithAnnotationsAndPredictionsSerializerc                     t        |   |i | t        dg | j                        | j                  d<   t        dg | j                        | j                  d<   y )NTr  r   r   r   r   s      r+   r   z6TaskIDWithAnnotationsAndPredictionsSerializer.__init__  sQ    $)&)%9tRY]YeYe%fM"%9tRY]YeYe%fM"r-   c                       e Zd ZeZg dZy)2TaskIDWithAnnotationsAndPredictionsSerializer.Meta)rt   r   r   Nr  r8   r-   r+   rh   r    s    5r-   rh   )r2   r3   r4   r   rh   rl   rm   s   @r+   r  r    s    g
6 6r-   r  c                        e Zd Z G d d      Zy)TaskIDOnlySerializerc                       e Zd ZeZdgZy)TaskIDOnlySerializer.Metart   Nr  r8   r-   r+   rh   r    s    r-   rh   Nrz   r8   r-   r+   r  r    s     r-   r  c                   $    e Zd ZdZ G d d      Zy)PredictionMetaSerializerz#Serializer for PredictionMeta modelc                       e Zd ZeZdZddgZy)PredictionMetaSerializer.Metare   r*   failed_predictionN)r2   r3   r4   r!   rf   rg   read_only_fieldsr8   r-   r+   rh   r    s    (*=>r-   rh   N)r2   r3   r4   r   rh   r8   r-   r+   r  r    s    -? ?r-   r  )^r   r&  collections.abcr   ujsonr   core.current_requestr   r   core.feature_flagsr   core.label_configr   core.utils.commonr   r	   core.utils.dbr
   core.utils.exceptionsr   django.confr   	django.dbr   r   drf_spectacular.utilsr   fsm.serializer_fieldsr   fsm.state_inferencer   	fsm.utilsr   r    label_studio_sdk.label_interfacer   projects.modelsr   rest_flex_fieldsr   rest_frameworkr   r   rest_framework.exceptionsr   rest_framework.fieldsr   rest_framework.serializersr   rest_framework.settingsr   tasks.exceptionsr   tasks.modelsr   r   r    r!   r"   tasks.validationr#   users.modelsr$   users.serializersr%   	getLoggerr2   rW   r,   
Serializerr/   	JSONFieldr@   rD   rF   ListSerializerro   rq   r|   r   r   r   r   TASK_SERIALIZERTaskSerializerr  r  r  r  r  r  r  r  TaskSerializerBulkr8   r-   r+   <module>r     s   l  *  D ' K > $ 1   1 5 / 2 = ; # 6 0 5 + 6 0 5 V V *  ,			8	$e 6 6 e
 )@8C
			K11 		 )@8C
			K11 		*? *Z	{99 	Rn RFI4 FIR5
8 5
p:4 :(6:2 6:r`[77 `F 8334N & &R.s> .sb"M "J6O 6? ? ? x<<= r-   