
    	]j\                     0   d Z ddlZddlZddlZddlZddlZddlZddlZddlZddl	m
Z
mZmZmZmZ ddlmZ ddl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 m!Z!m"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/m0Z0m1Z1m2Z2 ddl3m4Z4m5Z5m6Z6m7Z7 ddl8m9Z9 ddl:m;Z;m<Z<m=Z=m>Z> ddl?m@Z@mAZA ddlBmCZC ddlDmEZE ddlFmGZG ddlHmIZJ ddlKmLZL ddlMmNZN ddlOmPZP ddlQmRZR ddlSmTZT  ej                  eV      ZW e e.j                        ZY G d deYeL      ZZ e@       Z[ e@       Z\ G d  d!e1j                        Z^ G d" d#eNe^      Z_ G d$ d%e1j                        Za e e.j                        Zc G d& d'eceL      Zd G d( d)e1j                        Ze G d* d+eNee      Zf G d, d-e1j                        Zg G d. d/eL      Zh G d0 d1e1j                        Zi G d2 d3eNei      Zj G d4 d5e1j                        Zk G d6 d7eL      Zl G d8 d9e1j                        Zn G d: d;e1j                        Zo G d< d=e1j                        Zp eAe;eZ>      d?        Zq eAe=eZ>      d@        ZrdA Zs eAe>eZ>      dB        Zt eAe<eZ>      dC        Zu eAe>ed>      dD        Zv eAe<ed>      dE        Zw eAe=en>      dF        Zx eAe<en>      dG        Zy eAe<ed>      dH        Zz eAe<ed>      dI        Z{dRdJZ|dSdKZ}dSdLZ~ e7dMN       e7dMO      z  Z e7dMP       e7dMQ      z  Zy)TzThis 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)AnyMappingOptionalUnioncast)urljoin)bulk_update)CurrentContextget_current_request)flag_set)SINGLE_VALUED_TAGS)start_job_async_or_sync)-find_first_one_to_one_related_field_by_prefix	load_funcstring_is_url temporary_disconnect_list_signal)batch_delete
fast_first)get_env)
FileUpload)PreparedTaskManagerTaskManager)settings)OperationalErrormodelstransaction)CheckConstraintF	JSONFieldQ)GreaterThanOrEqual)post_delete	post_save
pre_deletepre_save)Signalreceiver)reverse)	timesince)now)gettext_lazy)FsmHistoryStateModel)FSMStateQuerySetMixin)PredictionValue)ValidationError)
ActionTypec            	           e Zd ZdZ ej
                  ddddd      Z eddd      Z ed	de	d
      Z
 ej                  ddej                  dd      Z ej                   ed      dd      Z ej                   ed      dd      Z ej                  ej&                  dej(                  d ed      d      Z ej,                   ed      dd      Z ej,                   ed      ddd      Z ej2                   ed       d!dd"#      Z ej                  d$ej(                  dddd%&      Z ej8                   ed'      d(dd)      ZdgZ ej2                   ed*      d(dd+#      Z ej2                   ed,      d(dd-#      Z  ej2                   ed.      d(dd/#      Z! ejD                   ed0      dd1      Z# ej2                   ed2      d(dd3#      Z$ ej2                   ed4      d(dd5#      Z% ejL                  ej&                  dd6d7d89      Z' ej                   ed:      d6ddd;<      Z( e)       Z* e+       Z, G d= d>      Z-e.d?        Z/e0d@        Z1e0d_dA       Z2dB Z3dC Z4d`dDZ5e.dE        Z6dF Z7dG Z8dH Z9dIdJdKe:f fdLZ;dM Z<dN Z=d`dOZ>dP Z?e@dQ        ZAe@dR        ZBdKeCeDeEeFf      fdSZGdT ZHe.dU        ZIe.dV        ZJdW ZKdX ZLdY ZMd6dZ fd[
ZNe@d\        ZOe@d]        ZP fd^ZQ xZRS )aTaskzBusiness tasks from projectTFID)auto_createdprimary_key	serializeverbose_namedb_indexdatazUser imported or uploaded data for a task. Data is formatted according to the project label config. You can find examples of data for your project on the Import page in the Label Studio Data Manager UI.)null	help_textmetazMeta is user imported (uploaded) data and can be useful as input for an ML Backend for embeddings, advanced vectors, and other info. It is passed to ML during training/predicting steps.r:   defaultr;   projects.ProjecttaskszProject ID for this taskrelated_name	on_deleter:   r;   
created atzTime a task was createdauto_now_addr;   
updated atzLast time a task was updatedauto_nowr;   updated_tasks
updated byz0Last annotator or reviewer who updated this taskrB   rC   r:   r7   r;   
is_labeledz}True if the number of annotations for this task is greater than or equal to the number of maximum_completions for the projectr>   r;   
allow_skipzHWhether this task can be skipped. Set to False to make task unskippable.)r>   r:   r;   overlap   z=Number of distinct annotators that processed the current task)r>   r8   r;   zdata_import.FileUploadz/Uploaded file used as data source for this taskrC   r:   blankrB   r;   zinner idr   z.Internal task ID in the project, starts with 1total_annotationszMNumber of total annotations for the current task except cancelled annotationscancelled_annotationsz:Number of total cancelled annotations for the current tasktotal_predictionsz0Number of total predictions for the current taskprecomputed_agreementz$Average agreement score for the taskzcomment countz8Number of comments in the task including all annotationszunresolved comment countzCNumber of unresolved comments in the task including all annotationsNtasks_with_commentszUsers who wrote comments)rS   r>   rB   r;   zlast comment updated atz!When the last comment was updated)r>   r:   r8   r;   c            	          e Zd ZdZ ej
                  ddg       ej
                  ddg       ej
                  ddg       ej
                  ddg       ej
                  dg       ej
                  ddg      gZy)		Task.MetataskprojectrM   fieldsinner_ididrP   N__name__
__module____qualname__db_tabler   Indexindexes     C/root/env/lib/python3.12/site-packages/label_studio/tasks/models.pyMetarZ      s}    FLLL 9:FLLJ 78FLLy 12FLLy 12FLL,FLLD 12
ri   rk   c                 |    t         j                  j                  | j                  j                  j
                        S N)ospathbasenamefile_uploadfilenameselfs    rj   file_upload_namezTask.file_upload_name   s)    ww 0 0 5 5 : :;;ri   c                     | j                   j                  |      j                  dd      }t        |      dk(  ryt	        j
                  |      }| j                   j                  |      S )z^Get random task from a project, this should not be used lightly as its expensive method to runr\   r`   Tflatr   Nr`   )objectsfiltervalues_listlenrandomchoiceget)clsr\   ids	random_ids       rj   
get_randomzTask.get_random   s\     kk   1==d=Ns8q=MM#&	{{),,ri   c                     d}|4t        t        j                  j                  |t	               |            }n5|(t        |j                  |t	                           }|r|S t        d      |r|j                  S y)zdRetrieve the task locked by specified user. Returns None if the specified user didn't lock anything.N)userexpire_at__gttask__project)locks__userlocks__expire_at__gtz0Neither project or tasks passed to get_locked_by)r   TaskLockr|   r}   r*   r/   r[   )r   r   r\   r@   locklocked_tasks         rj   get_locked_byzTask.get_locked_by   s|     h..554sudk5lmD$U\\dY\Y^\%_`K""!"TUU99 ri   c                     ddl m} | j                  }| j                  }|j                  rc|j
                  W|j                  r/ || g      }t        |t              r|}|j                  |      S |S |j                  |j
                        S g S )zThis is called to return either new predictions from the
        model or grab static predictions if they were set, depending
        on the projects configuration.

        r   )evaluate_predictions)model_version)
data_manager.functionsr   r\   predictionsshow_collab_predictionsr   ml_backend_in_model_version
isinstancestrr}   )ru   r   r\   r   new_predictionsr   s         rj   get_predictions_for_prelabelingz$Task.get_predictions_for_prelabeling   s     	@,,&& **w/D/D/P22"6v"> os3$3M&--M-JJ**"))8M8M)NNIri   c                    | j                   j                  }| j                   j                  |j                  k(  rt	               }n| j                   j                  |j
                  k(  rt	        d      t	        |      z  }n`| j                   j                  |j                  k(  rt	        d      t	        |       z  }n"t        d| j                   j                         | j                         }|r||z  }|t	        d      z  S )zI
        Get query for excluding annotations from the lock check
        Twas_cancelled)completed_byzInvalid SkipQueue value: ground_truth)	r\   	SkipQueue
skip_queueIGNORE_SKIPPEDr    REQUEUE_FOR_MEREQUEUE_FOR_OTHERSr/   get_rejected_query)ru   r   r   q
rejected_qs        rj   get_lock_exclude_queryzTask.get_lock_exclude_query   s     LL**	<<""i&>&>> A||&&)*B*BB D)A4,@@((I,H,HH D)QD-A,AA%(A$,,BYBYAZ&[\\ 002JZ1$'''ri   c                 |   ddl m} | j                  j                  r+| j                  j                  d      j                         ry| j                  |      }| j                  |      }| j                  j                  |      j                         }||z   }|| j                  ||      kD  rt        j                  d| d| j                   d	| j                   d
| j                  j                    d	t#        | j$                  j'                  dd      ||             | j(                  du r1| j+                          | j(                  du r| j-                  dg       t/        || j                  ||      k\        }t        j1                   ||      d|  d| d| d| d| j                  j                    
       |S )z
        Check whether current task has been locked by some user

        Also has workaround for fixing not consistent is_labeled flag state
        r   get_next_task_logging_levelTr   Fr   z
Num takes=z > overlap=z
 for task=z, skipped mode z - it's a bugr   	expire_at)lock_ttl	num_locksnum_annotations)extrarM   update_fieldszTask z	 locked: z; num_locks: z num_annotations: z skipped mode: )projects.functions.next_taskr   r\   annotator_evaluation_enabledannotationsr}   existsr   num_locks_userexcludecount overlap_with_agreement_thresholdloggererrorrP   r`   r   dictlocksr~   rM   update_is_labeledsaveboollog)ru   r   r   r   r   r   numresults           rj   has_lockzTask.has_lock  s    	M<<44&&D&9@@B''-''T'2	**2215;;=/)66sIFFLLSET\\N*TWWI N  $ 7 78G!ZZ33FKH'$3   %'&&(??d*II\NI;cTBB3	RRS

'-D66(-	{BTUdTe f!\\4457	

 ri   c                 f    | j                   j                  t                     j                         S )Nr   )r   r}   r*   r   rt   s    rj   r   zTask.num_locksG  s%    zz  su 5;;==ri   c                    t        | j                  d      r| j                  j                  r| j                  j                  j                  u	 ddlm}  ||       }|d|| j                  j                  j                  k  rA|dk(  r:t        | j                  | j                  j                  j                  z   |dz         S |S | j                  S # t        t        f$ r Y y w xY w)Nlse_projectr   )get_task_agreementrQ   )hasattrr\   r   agreement_thresholdstats.modelsr   ModuleNotFoundErrorImportErrorminrP   $max_additional_annotators_assignable)ru   r   r   r   	agreements        rj   r   z%Task.overlap_with_agreement_thresholdK  s    
 DLL-0((((<<H; +40I$T\\5M5M5a5a)a !A~ t||'?'?'d'ddfilmfmn 
 || (5 s   C C C c                     | j                   j                  t                     j                  |      j	                         S )Nr   r   )r   r}   r*   r   r   ru   r   s     rj   r   zTask.num_locks_userb  s3    zz  su 5==4=HNNPPri   c                 v    t         j                  D ]&  }t        | |      st        | |      j                  c S  y rm   )r   IO_STORAGES_IMPORT_LINK_NAMESr   getattrkey)ru   	link_names     rj   get_storage_filenamezTask.get_storage_filenamee  s4    !?? 	4ItY'tY/333	4ri   r   Userreturnc                     t        t        t        |   |            }| j                  |_        |xr | j                  j                  |      S rm   r   r   superhas_permissionr\   ru   r   mixin_has_permission	__class__s      rj   r   zTask.has_permissionj  ?    #D%'*@*FG||#I(C(CD(IIri   c                 h    | j                   j                  t                     j                          y )N)expire_at__lt)r   r}   r*   deletert   s    rj   clear_expired_lockszTask.clear_expired_locksp  s"    

.557ri   c           	         ddl m} | j                  }|| j                  k  rt        j
                  }t        d|      r,| j                  j                  r| j                  j                  }t               t        j                  |      z   }	 t        j                  j                  | |      }||_        |j!                          t&        j)                   ||      d| d	|  d
|        n3t&        j+                  d| j,                   d| d| j                   d       | j/                          y# t        j"                  $ r% t        j                  j%                  | ||       Y w xY w)zMLock current task by specified user. Lock lifetime is set by `expire_in_secs`r   r   7fflag_feat_all_leap_1534_custom_task_lock_timeout_shortr   )seconds)r[   r   )r[   r   r   zUser=z acquires a lock for the task=z ttl: z!Current number of locks for task z is z, but overlap=z^: that's a bug because this task should not be taken in a label stream (task should be locked)N)r   r   r   rP   r   TASK_LOCK_TTLr   r\   custom_task_lock_ttlr*   datetime	timedeltar   r|   r   r   r   DoesNotExistcreater   r   r   r`   r   )ru   r   r   r   r   r   	task_locks          rj   set_lockzTask.set_locks  s?   LNN	t||#--HRY]^LL55<<<< 2 28 DDI!$,,00d0F	 '0	# JJ+D1v;D6zR
 LL3DGG9D>Z^ZfZfYg ho p 	  " (( S  ''T	'RSs   !D/ /5E'&E'c                     |+| j                   j                  |      j                          n(| j                   j                         j                          | j	                          y)zRelease lock for the task.
        If user specified, it checks whether lock is released by the user who previously has locked that task
        Nr   )r   r}   r   allr   r   s     rj   release_lockzTask.release_lock  sK    
 JJ4(//1JJNN##%  "ri   c                     t        | d      S )Nz.*io_storages_)r   rt   s    rj   get_storage_linkzTask.get_storage_link  s    <TCSTTri   c                 h    t        | t              sy| j                  t        j                  dz         S )NF/)r   r   
startswithr   
UPLOAD_DIRfilenames    rj   is_upload_filezTask.is_upload_file  s+    (C(""8#6#6#<==ri   c                 f    t        | t              r | j                  t        j                  d      S | S )N )r   r   replacer   	MEDIA_URLr   s    rj   prepare_filenamezTask.prepare_filename  s*    h$##H$6$6;;ri   c                     ddl m} | j                  j                  } |||      }|r|j	                  |      |j
                  dS y )Nr   get_storage_by_url)urlpresign_ttl)io_storages.functionsr
  r\   get_all_import_storage_objectsgenerate_http_urlr  )ru   r  r
  storage_objectsstorages        rj   resolve_storage_urizTask.resolve_storage_uri  sK    < ,,EE$S/:005&22  ri   c                 ~   ddl m} |j                  r|j                  ri }|j	                         D ]  \  }}t        |t              rst        |      rht        dd|j                  i      dz   t        j                  |j                               j                         z   }t        t        j                   |      }|||<    |S |j"                  }|D ]  }	| j%                  ||	         }
t        j&                  rY| j)                  |
      rHt+        t,        j.                  j1                  ||
            }||j2                  ||	<   n||	   dz   ||	<    |||	   |      xs | j4                  }|s	 |j7                  ||	   |       }|s|||	<    |S # t8        $ r#}t:        j=                  |d	
       d }Y d }~3d }~ww xY w)Nr   r	  zprojects-file-proxypk)kwargsz?url=)r\   rr   z?not_uploaded_project_fileTexc_info)r  r
  task_data_logintask_data_passworditemsr   r   r   r(   r  base64urlsafe_b64encodeencodedecoder   r   HOSTNAMEr  r  CLOUD_FILE_STORAGE_ENABLEDr  r   r   r|   r}   r  r  resolve_uri	Exceptionr   debug)ru   	task_datar\   r
  protected_datar   valuero   r  fieldprepared_filenamerq   r  resolved_uriexcs                  rj   r!  zTask.resolve_uri  s   <""w'A'AN'oo/ ,
UeS)mE.B 5tWZZ>PQ!" 225<<>BIIKL 
 $H$5$5t<E&+s#, "!%DDO # 8$($9$9)E:J$K!664;N;NO`;a",Z-?-?-F-Fw]n-F-o"pK".+6??	%( ,5U+;>Z+Z	%( -Yu-=O_SWS_S_,'.':':9U;KT'R $+7	%(586  % ,S48'+,s   /F	F<F77F<c                 v    | j                         }|r|j                  S t        ddd      rddlm}  |       S y )NUSE_DEFAULT_S3_STORAGEFT)r>   is_boolr   )S3ImportStorage)r   r  r   io_storages.s3.modelsr.  )ru   storage_linkr.  s      rj   r  zTask.storage  sD     ,,.''' -udK >"$$ Lri   c                     | j                   j                  | j                   j                  j                  k(  r| j                  S | j                  j                  t              S )zKAnnotations that we take into account when set completed status to the task)r\   r   r   r   r   r}   Q_finished_annotationsrt   s    rj   completed_annotationszTask.completed_annotations  sJ     <<""dll&<&<&K&KK#####**+ABBri   c                     t        | j                  d      r)| j                  j                  }|j                  | g       y y Nsummary)r   r\   r6  update_data_columnsru   r6  s     rj   !increase_project_summary_countersz&Task.increase_project_summary_counters  4    4<<+ll**G''/ ,ri   c                     t        | j                  d      r)| j                  j                  }|j                  | g       y y r5  )r   r\   r6  remove_data_columnsr8  s     rj   !decrease_project_summary_countersz&Task.decrease_project_summary_counters
  r:  ri   c                 \    | j                   j                  |      j                  d       y )Nr{   Fr   )r   r   update)ru   annotation_ids     rj   ensure_unique_groundtruthzTask.ensure_unique_groundtruth  s'      M 299u9Mri   r   c                8   | j                   dk(  ryt        j                  j                  | j                        j                  d      j                         }d}|r|j                   }|d n|dz   | _         |dhj                  |      }t        | $  |d|i| y )Nr   rx   z	-inner_idrQ   r_   r   )
r_   r2   r|   r}   r\   order_byfirstunionr   r   )ru   r   argsr  r[   max_inner_idr   s         rj   r   z	Task.save  s    ==A<<&&t||&<EEkRXXZDL#}} %1$8D|a?ODM(!+ 2 2= AdB-B6Bri   c                     t         t        t        ft        t        t        fg}t        |      5  t        | d      cddd       S # 1 sw Y   yxY w)z
        Delete Tasks queryset with switched off signals in batches to minimize memory usage
        :param queryset: Tasks queryset
        i  )
batch_sizeN)r"   *update_all_task_states_after_deleting_taskr2   r$   r<  r   r   )querysetsignalss     rj   delete_tasks_without_signalsz!Task.delete_tasks_without_signals   sJ     DdK,d3
 .g6 	:S9	: 	: 	:s   AAc                 n    t         j                  j                  |       }t         j                  |       y )Nid__in)r2   r|   r}   rM  )task_idsrK  s     rj   *delete_tasks_without_signals_from_task_idsz/Task.delete_tasks_without_signals_from_task_ids-  s'    <<&&h&7))(3ri   c                 F    | j                          t        |   |i |}|S rm   )before_delete_actionsr   r   ru   rF  r  r   r   s       rj   r   zTask.delete2  s'    ""$00ri   )NNrm   )Srb   rc   rd   __doc__r   	AutoFieldr`   r   r9   r   r<   
ForeignKeyCASCADEr\   DateTimeField_
created_at
updated_atr   AUTH_USER_MODELSET_NULL
updated_byBooleanFieldrM   rO   IntegerFieldrP   rq   BigIntegerFieldr_   updatesrT   rU   rV   
FloatFieldrW   comment_countunresolved_comment_countManyToManyFieldcomment_authorslast_comment_updated_atr   r|   r   preparedrk   propertyrv   classmethodr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   staticmethodr  r  r   r   r   r   r  r!  r  r3  r9  r=  rA  r   rM  rR  r   __classcell__r   s   @rj   r2   r2   3   sW   %			
B BD /	D  f..,G &%%aoDTmnJ%%%aoPnoJ"""  $//|_DJ %$$	,?J %$$	,\	J "f!!	)Q	G $&## //CK &v%%	*B	H nG+++	
a	 0F//	
!"N	 ,++	
D	 .F--	
!"8 (F''	/L	M  3v22	
$%W	  -f,,  *,O 3f22	
#$5 mG"$H	
 	
 < < 	- 	-  <(<)V > >.Q4
J6 Jd J8#>	#U > >
  
(7383D*E .` % %" C C0
0
N )- C 
: 
: 4 4 ri   r2   c                       e Zd Zy)AnnotationQuerySetNrb   rc   rd   rh   ri   rj   rr  rr  =      ri   rr  c                       e Zd Zy)AnnotationQuerySetWithFSMNrs  rh   ri   rj   rv  rv  A  rt  ri   rv  c                   6     e Zd ZdZd Zd Zd Zd fd	Z xZS )AnnotationManagerz
    Manager for Annotation model with FSM state support.

    Provides:
    - User-scoped filtering
    - Bulk creation with signals
    - FSM state annotation support
    c                 D    t        | j                  | j                        S )z;Return AnnotationQuerySet with FSM state annotation supportusing)rv  model_dbrt   s    rj   get_querysetzAnnotationManager.get_querysetO  s     )488DDri   c                 V    | j                         j                  |j                        S )N)project__organization)r~  r}   active_organizationr   s     rj   for_userzAnnotationManager.for_userU  s%      "))@X@X)YYri   c                 >    | j                         j                         S z)Return queryset with FSM state annotated.r~  
with_statert   s    rj   r  zAnnotationManager.with_stateX        "--//ri   c                     t         j                  | j                  ||       t        t        |   ||      }t        j                  | j                  ||       |S )N)senderobjsrI  )pre_bulk_createsendr|  r   rx  bulk_createpost_bulk_create)ru   r  rI  resr   s       rj   r  zAnnotationManager.bulk_create\  sN    DJJTjQ%t8zJTZZdzR
ri   rm   )	rb   rc   rd   rV  r~  r  r  r  ro  rp  s   @rj   rx  rx  E  s#    EZ0 ri   rx  c            	       l    e Zd ZdZ e       Z edddd      Z ej                  dej                  ddd	
      Z ej                  ddej                  dd      Z ej                  ej                  dej                  dd      Z ej                  ej                  dej                  d ed      d      Z ej&                   ed      dd      Z ej&                   ed      dd      Z ej,                   ed      dd      Z ej,                   ed      dd      Z ej,                   ed      ddd       Z ej4                   ed!      ddd"      Z e ed#      ded$      Z ej<                   ed%      d&d'      Z ej                  d(ej                  d)dd*
      Z  ej                  d+ej                  d)dd,
      Z! ejD                  e#jH                  dddd-      Z% ejL                  ddddd./      Z' ejP                   ed0      d1e)jT                  d2dd3      Z+ ej                  ej                  ej                   ed4      d5dd6      Z, ej&                   ed7      dddd89      Z- G d: d;      Z.d< Z/d= Z0d>d?d@e1f fdAZ2dB Z3dC Z4dD Z5ddE fdF
Z6 fdGZ7dH Z8dI Z9 xZ:S )J
AnnotationzAnnotations & Labeling resultsr   TNzAThe main value of annotator work - labeling result in JSON formatr=   
tasks.Taskr   z&Corresponding task for this annotationrC   rB   r:   r;   r?   zProject ID for this annotationrA   z1User ID of the person who created this annotationupdated_annotationsrK   z%Last user who updated this annotationrL   zwas cancelledFzUser skipped the taskrN   r   z0This annotation is a Ground Truth (ground_truth)rD   Creation timerE   rG   zLast updated timerH   zdraft created atzDraft creation time	lead time*How much time it took to annotate the task
predictionz+Prediction viewed at the time of annotationzresult countr   z$Results inside of annotation counterztasks.Predictionchild_annotationsz?Points to the prediction from which this annotation was createdtasks.AnnotationzFPoints to the parent annotation from which this annotation was createdr>   r:   rS   uniqueeditablez]Original annotation ID that was at the import step or NULL if this annotation wasn't importedr>   r:   rS   r8   r;   zlast action   z>Action which was performed in the last annotation history item)
max_lengthchoicesr;   r>   r:   zlast created byz1User who created the last annotation history item)rC   r7   r;   r>   r:   zbulk createdz#Annotation was created in bulk mode)r>   
db_defaultr:   r;   c                      e Zd ZdZ ej
                  dg       ej
                  dg       ej
                  ddg       ej
                  dg       ej
                  ddg       ej
                  ddg       ej
                  dd	g       ej
                  dd
g       ej
                  ddg       ej
                  dd	g       ej
                  d	g      gZy)Annotation.Metatask_completionr\  r]   r   r`   r[   last_actionr\   r   r   Nra   rh   ri   rj   rk   r    s    $FLL/FLL 01FLLv/FLL0FLLN ;<FLLD 12FLLO <=FLL 89FLL 89FLL 9:FLL 12
ri   rk   c                 ,    t        | j                        S zHumanize dater)   r\  rt   s    rj   created_agozAnnotation.created_ago      ))ri   c                     | j                   }t        |t              rt        j                  |      }|g }t        |      S rm   )r   r   r   jsonloadsr   )ru   r  s     rj   entities_numzAnnotation.entities_num  s5    kkc3**S/C;C3xri   r   r   r   c                     t        t        t        |   |            }| j                  |_        |xr | j                  j                  |      S rm   r   r   s      rj   r   zAnnotation.has_permission  r   ri   c                     t        | j                  d      rAt        j                  d|         | j                  j                  }|j                  | g       y y )Nr6  z'Increase project.summary counters from )r   r\   r   r#  r6  %update_created_annotations_and_labelsr8  s     rj   r9  z,Annotation.increase_project_summary_counters  H    4<<+LLB4&IJll**G994&A ,ri   c                     t        | j                  d      rAt        j                  d|         | j                  j                  }|j                  | g       y y )Nr6  z'Decrease project.summary counters from )r   r\   r   r#  r6  %remove_created_annotations_and_labelsr8  s     rj   r=  z,Annotation.decrease_project_summary_counters   r  ri   c                     dg}t               }|r,|j                  | j                  _        |j	                  d       | j                  j                  |d       y Nr]  r`  Tr   skip_fsmr   r   r[   r`  appendr   ru   r   requests      rj   update_taskzAnnotation.update_task  H    % &'#*<<DII   .		]TBri   r   c                V   t               }|r%|j                  | _        |dhj                  |      }| j                  xs g D ch c]  }|j                  d       }}t        |      | _        |dhj                  |      }t        | $  |d|i|}| j                          |S c c}w )Nr`  r`   result_countr   )r   r   r`  rE  r   r   r   r  r   r   r  )ru   r   rF  r  r  r   unique_listr   s          rj   r   zAnnotation.save  s    %'%llDO(!- 4 4] C7;{{7HbJFvzz$'JJ,$+,22=AMtK=KFK Ks   B&c                 f    t        |   |i |}| j                          | j                          |S rm   )r   r   r  on_delete_update_countersrU  s       rj   r   zAnnotation.delete"  s5     00&&(ri   c                 "    ddl m}  |||       y)z0Update task FSM state after annotation deletion.r   )+update_task_state_after_annotation_deletionN)fsm.functionsr  )ru   r[   r\   r  s       rj   !_update_task_state_after_deletionz,Annotation._update_task_state_after_deletion+  s    M3D'Bri   c                 *   | j                   }| j                  }t        j                  d|j                   d       | j
                  r|j                  j                         j                  d      j                         }t        j                  j                  |j                        j                  |       t        j                  d|j                          n|j                  j                         j                  d      j                         }t        j                  j                  |j                        j                  |	       t        j                  d
|j                          t        j                  d|        |j                          t        j                  j                  |j                        j                  |j                         | j                  ||       t        j                  d       | j!                          y )Nz!Start updating counters for task .Tr   r{   )rU   z1On delete updated cancelled_annotations for task F)rT   z-On delete updated total_annotations for task Update task stats for task=rM   zPRemove annotation counters in project summary followed by deleting an annotation)r[   r\   r   r#  r`   r   r   r   r}   r   r2   r|   r?  r   rM   r  r=  )ru   r[   r\   	cancelledtotals        rj   r  z$Annotation.on_delete_update_counters1  s   yy,,8	CD((,,.55D5IOOQILL477+222SLLLTWWIVW$$((*111FLLNELL477+22U2KLLH	RS24&9: tww'..$//.J 	..tW= 	gh..0ri   );rb   rc   rd   rV  rx  r|   r   r   r   rX  rY  r[   r\   r   r^  r_  r   r[  r`  ra  r   r   rZ  r\  r]  draft_created_atre  	lead_timer   r  rb  r  parent_predictionparent_annotation	UUIDFielduuiduuid4	unique_idrc  	import_id	CharFieldr0   r  r  last_created_bybulk_createdrk   r  r  r   r   r9  r=  r  r   r   r  r  ro  rp  s   @rj   r  r  f  s@   (!GX	F 6..":D  f"..2G %6$$  "//EL #""  *//|_9J (F''/(:EUlmM&6&&	.DL
 &%%aoDTcdJ%%%aoPcdJ+v++	
D$BW "!!	+>	I 	,?	J '6&&q'8!OuvL)))//(S *))//(Z !  $dSWbghI&&&qI #&""	-""RK (f''  //()EO '6&&	.7L
 
 *J6 Jd JBB	C )- "C1ri   r  c                       e Zd ZdZy)TaskLockQuerySetz"Custom QuerySet for TaskLock modelNrb   rc   rd   rV  rh   ri   rj   r  r  K  s    ,ri   r  c                       e Zd Zy)TaskLockQuerySetWithFSMNrs  rh   ri   rj   r  r  Q  rt  ri   r  c                       e Zd ZdZd Zd Zy)TaskLockManagerz+Manager for TaskLock with FSM state supportc                 D    t        | j                  | j                        S z1Return QuerySet with FSM state annotation supportrz  )r  r|  r}  rt   s    rj   r~  zTaskLockManager.get_querysetX  s    &tzzBBri   c                 >    | j                         j                         S r  r  rt   s    rj   r  zTaskLockManager.with_state\  r  ri   Nrb   rc   rd   rV  r~  r  rh   ri   rj   r  r  U  s    5C0ri   r  c                   ^   e Zd Z e       Z ej                  dej                  dd      Z ej                   e
d            Z ej                  ej                  dddd      Z ej                  ej"                  d	ej                  d
      Z ej                   e
d      ddd      Zd Zy)r   r  r   zLocked task)rC   rB   r;   r   TFr  
task_lockszUser who locked this taskrB   rC   r;   rD   r  )rF   r;   r:   c                 8    | j                   j                  |      S rm   )r[   r   r   s     rj   r   zTaskLock.has_permissions  s    yy''--ri   N)rb   rc   rd   r  r|   r   rX  rY  r[   rZ  r[  r   r  r  r  r  r   r^  r   r\  r   rh   ri   rj   r   r   a  s    G6..	D %$$Q{^4I   $dSWbghI6  !..-	D &%%aoDTcjnoJ.ri   r   c                       e Zd ZdZy)AnnotationDraftQuerySetz)Custom QuerySet for AnnotationDraft modelNr  rh   ri   rj   r  r  w  s    3ri   r  c                       e Zd Zy)AnnotationDraftQuerySetWithFSMNrs  rh   ri   rj   r  r  }  rt  ri   r  c                       e Zd ZdZd Zd Zy)AnnotationDraftManagerz2Manager for AnnotationDraft with FSM state supportc                 D    t        | j                  | j                        S r  )r  r|  r}  rt   s    rj   r~  z#AnnotationDraftManager.get_queryset  s    -djjIIri   c                 >    | j                         j                         S r  r  rt   s    rj   r  z!AnnotationDraftManager.with_state  r  ri   Nr  rh   ri   rj   r  r    s    <J0ri   r  c                   H    e Zd Z e       Z e ed      d      Z ej                   ed      ddd      Z
 ej                  dej                  d	ddd
      Z ej                  dej                  d	ddd      Z ej                  ej                   d	ej                  d      Z ej$                   ed      ddd      Z ej(                  ddddd      Z ej,                   ed      dd      Z ej,                   ed      dd      Zd Zd Z fdZ fd Z xZS )!AnnotationDraftr   zDraft result in JSON format)r;   r  Tr  )rS   r:   r;   r  draftsz!Corresponding task for this draft)rC   rB   rS   r:   r;   r  z'Corresponding annotation for this draftzUser who created this draftr  zwas postponedFzHUser postponed this draft (clicked a forward button) in the label stream)r>   r;   r8   NzSOriginal draft ID that was at the import step or NULL if this draft wasn't importedr  rD   r  rE   rG   zLast update timerH   c                 ,    t        | j                        S r  r  rt   s    rj   r  zAnnotationDraft.created_ago  r  ri   c                     | j                   j                  |_        | j                   j                  j                  |      S rm   )r[   r\   r   r   s     rj   r   zAnnotationDraft.has_permission  s.    yy((yy  //55ri   c                    t        j                         5  | j                  j                  }t	        |d      rRddlm} |j                  j                         j                  |j                  j                        j                          t        | 8  |i | t	        |d      r|j                  j                  | g       d d d        y # 1 sw Y   y xY wNr6  r   )ProjectSummaryr  )r   atomicr[   r\   r   projects.modelsr  r|   select_for_updater}   r6  r  rD  r   r   update_created_labels_draftsru   rF  r  r\   r  r   s        rj   r   zAnnotationDraft.save  s    ! 
	Eii''G w	*:&&88:AAW__EWEWAX^^`GL$)&)w	*<<dVD
	E 
	E 
	Es   B,CCc                 :   t        j                         5  | j                  j                  }t	        |d      rRddlm} |j                  j                         j                  |j                  j                        j                          t        j                  j                         j                  | j                        j                          t	        |d      r|j                  j                  | g       t        | @  |i | d d d        y # 1 sw Y   y xY wr  )r   r  r[   r\   r   r  r  r|   r  r}   r6  r  rD  r   remove_created_drafts_and_labelsr   r   r  s        rj   r   zAnnotationDraft.delete  s    ! 	,ii''G w	*:&&88:AAW__EWEWAX^^`##557>>$''>JPPRw	*@@$HGND+F+	, 	, 	,s   C2DD)rb   rc   rd   r  r|   r   r[  r   r   re  r  rX  rY  r[   
annotationr   r^  r   ra  was_postponedrc  r  rZ  r\  r]  r  r   r   r   ro  rp  s   @rj   r  r    sV   $&Gq{.KLF!!!	+>	I 6..5D #""..;J 6  ../	D (F''	/\	M '&&gI &%%aoDTcdJ%%%aoPbcJ*6E, ,ri   r  c                       e Zd ZdZ edded      Z ej                   e	d      ddd	      Z
 ej                   e	d
      dddd      Z ej                  dej                  ddd      Z ej                  dej                  ddd      Z ej"                   e	d      ddd	      Z edddd      Z ej                   e	d      dd      Z ej                  dej                  d      Z ej                  dej                  dd       Z ej.                   e	d!      d"      Z ej.                   e	d#      d$      Zd% Zd& Zed'        Zd( Zdd) fd*
Z fd+Z ed,e!d    fd-       Z" G d. d/      Z# xZ$S )0
Predictionz ML backend / Prompts predictionsr   TzPrediction resultr=   scoreNzPrediction score)r>   r;   r:   model versionr  zA string value that for model version that produced the prediction. Used in both live models and when uploading offline predictions.r>   rS   r:   r;   ml.MLBackendr   z3An ML Backend instance that created the prediction.r  ml_models.ModelRunz4A run of a ModelVersion that created the prediction.clusterz"Cluster for the current prediction	neighborsz*Array of task IDs of the closest neighborsr:   rS   r;   mislabelingg        zRelated task mislabeling scorerN   r  rC   rB   r?   rC   rB   r:   rD   rF   rG   )rI   c                 ,    t        | j                        S r  r  rt   s    rj   r  zPrediction.created_ago  r  ri   c                 Z    | j                   |_         | j                   j                  |      S rm   )r\   r   r   s     rj   r   zPrediction.has_permission  s"    ||||**400ri   c                    t        |t              r$|D ]  }t        |t              rt        d       |S t        |t              rZ|j	                         j                         D ]8  \  }}|d   j                         }||v s|dj                  |d         ||dgc S  yt        |t        t        j                  f      ru|j	                         j                         D ]S  \  }}|d   j                         }|t        v s"t        |t        |         s6|dj                  |d         |||gidgc S  yt        dt        |       d|       )	a  
        This function does the following logic of transforming "result" object:
        result is list -> use raw result as is
        result is dict -> put result under single "value" section
        result is string -> find first occurrence of single-valued tag (Choices, TextArea, etc.) and put string under corresponding single field (e.g. "choices": ["my_label"])  # noqa
        z-Each item in prediction result should be dicttype,to_name)	from_namer  r  r&  zIncorrect format z for prediction result N)r   listr   r/   get_parsed_configr  lowerjoinr   numbersIntegralr   r  )r   r   r\   itemtagtag_infotag_types          rj   prepare_prediction_resultz$Prediction.prepare_prediction_result  so    fd# [!$-)*YZZ[ M% ")!:!:!<!B!B!D 
X#F+113v% *-'*xx0C'D$,%+	 
 g&6&6 78!(!:!:!<!B!B!D 
X#F+11311jI[\dIe6f *-'*xx0C'D$,&.%9	 
 "$5d6l^CZ[aZb"cddri   c                     dg}t               }|r,|j                  | j                  _        |j	                  d       | j                  j                  |d       y r  r  r  s      rj   r  zPrediction.update_taskH  r  ri   r   c                   | j                   }| j                  rqt        j                  d       t        j
                  j                  d      j                  | j                        j                   | _         |dhj                  |      }| j                  | j                  | j                        | _
        |dhj                  |      }| j                          t        t        | >  |d|i|S )NzIproject_id is not set for prediction, project_id being set in save method
project_idr  r   r   )r&  task_idr   warningr2   r|   onlyr   rE  r#  r   r\   r  r   r  r   )ru   r   rF  r  r   s       rj   r   zPrediction.saveS  s    ??"t||NNfg"ll//=AAT\\AR]]DO(!- 4 4] C 44T[[$,,O$%J,,];MZ+TYYRXYYri   c                 F    t        |   |i |}| j                          |S rm   )r   r   r  rU  s       rj   r   zPrediction.deletec  s'    00ri   r   c                 &   	 t        |j                  |            j                         }t        |t	        |      ||d|d         }|S # t
        $ r=}	t        j                  d| d| d|	 dt        j                                 Y d	}	~	y	d	}	~	ww xY w)
a  
        Creates a Prediction object from the given result data, without committing it to the database.
        or returns None if it fails.

        Args:
            project: The Project object to associate with the Prediction object.
            label_interface: The LabelInterface object to use to create regions from the result data.
            data: The data to create the Prediction object with.
                    Must contain keys that match control tags in labeling configuration
                    Example:
                        ```
                        {
                            'my_choices': 'positive',
                            'my_textarea': 'generated document summary'
                        }
                        ```
            task_id: The ID of the Task object to associate with the Prediction object.
            model_version: The model version that produced the prediction.
            model_run: The model run that created the prediction.
        )r   g      ?r   )r\   r'  r   	model_runr  r   z#Error creating prediction for task z with : . Traceback: N)
r.   create_regions
model_dumpr  intr"  r   r   	traceback
format_exc)
r   r\   label_interfacer'  r9   r   r,  predr  r*  s
             rj   create_no_commitzPrediction.create_no_commiti  s    0	 #/*H*H*NOZZ\D#G+#H~J  	LL5gYfTF"SE R'22457 	s   AA
 
	B3BBc                       e Zd ZdZy)Prediction.Metar  N)rb   rc   rd   re   rh   ri   rj   rk   r8    s    ri   rk   )%rb   rc   rd   rV  r   r   r   r   re  r[  r  	TextFieldr   rX  rY  r|  r,  rb  r  r  r  r[   r\   rZ  r\  r]  r  r   rm  r#  r  r   r   r   r6  rk   ro  rp  s   @rj   r  r    s   *xdDDWXFFaj$BT[_`E$F$$	/ YM F.."GE "!!.."HI "f!!	)6	G >	I $&##Am$4cMmnK6\V^^R_`Df 2fnn[hostG%%%aoDIJ%%%aoEJ*1 ,e ,e\	C )- Z  +	,	+ +Z   ri   r  c                      e Zd ZdZ ej
                   ed      dddd      Z ej                   ed      dddd	
      Z	 ej                  dej                  ddd      Z ej
                   ed      dddd      Z ej                  dej                  ddd      Z ej                  dej                  dd      Z ej                  dej                  d      Z ej$                   ed      d      Zy)FailedPredictionz;
    Class for storing failed prediction(s) for a task
    messageNTz<The message explaining why generating this prediction failedr  
error_typei   z0The type of error that caused prediction to fail)r  r>   r:   r;   r	  failed_predictionsz:An ML Backend instance that created the failed prediction.r  r  zA string value that for model version that produced the failed prediction. Used in both live models and when uploading offline predictions.r
  z;A run of a ModelVersion that created the failed prediction.r?   r  r  r  rD   r  )rb   rc   rd   rV  r   r9  r[  r<  r  r=  rX  r_  ml_backend_modelr   rY  r,  r\   r[   rZ  r\  rh   ri   rj   r;  r;    s'    f	)PG "!!	,DJ )v((//)N %F$$	/ `M "!!..)OI  ffnnCW^bG 6\V^^RfgD%%%aoDIJri   r;  c            
       
   e Zd Z ej                  dej
                  ddd ed            Z ej                  dej
                  ddd ed            Z ej                   ed      dd ed	      
      Z
 ej                   ed      dd ed      
      Z ej                   ed      dd ed      
      Z ej                   ed      dd ed      
      Z ej                   ed      dd ed      
      Z ej                   ed      dd ed      
      Z ej                   ed      dd ed      
      Z ej$                   ed      dd ed      
      Zedeeef   ded    fd       Z G d d      Zy)PredictionMetar  Tr<   z&Reference to the associated predictionrR   r;  z-Reference to the associated failed predictionzinference timez#Time taken for inference in secondsr  zprompt tokens countzNumber of tokens in the promptzcompletion tokens countz"Number of tokens in the completionztotal tokens countzTotal number of tokenszprompt costzCost of the promptzcompletion costzCost of the completionz
total costz
Total costr   z"Additional metadata in JSON formatr  r   c                 F   	 t        |j                  d      |j                  d      |j                  d      |j                  d      |j                  d      |j                  dd      |j                  dd      z   |j                  d      d|j                  di       i	      }t        |t              r||_        n||_        t        j                  d
|        |S # t        $ r:}t        j                  d| d| dt        j                                 Y d}~yd}~ww xY w)a.  
        Creates a PredictionMeta object from the given result data, without committing it to the database.
        or returns None if it fails.

        Args:
            data: The data to create the PredictionMeta object with.
                  Example:
                    {
                        'total_cost_usd': 0.1,
                        'prompt_cost_usd': 0.05,
                        'completion_cost_usd': 0.05,
                        'prompt_tokens': 10,
                        'completion_tokens': 10,
                        'inference_time': 0.1
                    }
            prediction: The Prediction or FailedPrediction object to associate with the PredictionMeta object.

        Returns:
            The PredictionMeta object created from the given data, or None if it fails.
        total_cost_usdprompt_cost_usdcompletion_cost_usdprompt_tokenscompletion_tokensr   inference_timemessage_counts)
total_costprompt_costcompletion_costprompt_tokens_countcompletion_tokens_counttotal_tokens_countrH  r   zCreated prediction meta: z$Error creating prediction meta with r-  r.  N)rA  r   r   r  r  failed_predictionr   r#  r"  r   r2  r3  )r   r9   r  prediction_metar*  s        rj   r6  zPredictionMeta.create_no_commit  s   ,	t,88$45 HH%67 $)> ?$(HH_$=(,1D(E#'88OQ#?$((K^`aBb#b#xx(89$dhh/?&DO *j1-7*4>1LL4_4EFG"" 	tLL?vRuMZcZnZnZpYqrss	ts   CC 	D &0DD c                       e Zd ZdZ ed      Z ed      Z e ed       ed      z   ed       ed      z  z  d	      gZ	y
)PredictionMeta.MetarQ  zPrediction MetazPrediction MetasF)prediction__isnullT)failed_prediction__isnull(prediction_or_failed_prediction_not_null)checkrs   N)
rb   rc   rd   re   r[  r7   verbose_name_pluralr   r    constraintsrh   ri   rj   rk   rS    s`    $*+ 23 %01t3TTD1APU4VVX @	
ri   rk   N)rb   rc   rd   r   OneToOneFieldrY  r[  r  rP  re  rH  rb  rM  rN  rO  rK  rL  rJ  r   r   rm  r   r  r;  r   r6  rk   rh   ri   rj   rA  rA    s   %%%..<=J -,,..CD 'V&&	
$da@e>fN .&--	
 t41EeCf 2f11	
#$4tqImGn -,,	
d$!D\B] $&##Am$44tWXYmWnoK'f''	
4tqAY?ZO #""1\?TUVWcUdeJFQwZd$!LpJqrE)tjBR6R0S )tX`aqXr )t )tV
 
ri   rA  )r  c                     	 |j                   j                  ddd       y# t        $ r+}t        j	                  dt        |      z          Y d}~yd}~ww xY w)zsafter deleting_task
    use update_tasks_states for all project
    but call only tasks_number_changed section
    FT)maximum_annotations_changed!overlap_cohort_percentage_changedtasks_number_changedz5Error in update_all_task_states_after_deleting_task: N)r\   update_tasks_statesr"  r   r   r   )r  instancer  r*  s       rj   rJ  rJ  *  sX    Y,,(-.3!% 	- 	

  YLsSVxWXXYs   ! 	A!AAc                 $    |j                          y)z/Reduce data column counters after removing taskN)r=  r  r`  r  s      rj   r<  r<  =  s     ..0ri   c                 *    | rt        |       dgk(  ryy y )NrM   T)r  r   s    rj   _task_data_is_not_updatedrd  C  s    m,> ?}ri   c                     t        |      ry	 | j                  j                  |j                        }|j                          y# t        j
                  $ r Y yw xY w)zOBefore updating task fields - ensure previous info removed from project.summaryNr{   )rd  r|   r   r`   r2   r   r=  )r  r`  r   r  old_tasks        rj   8delete_project_summary_data_columns_before_updating_taskrg  H  sW     !/>>%%%5 ..0  s   &A AAc                 <    t        |      ry|j                          y)zNUpdate task counters in project summary in case when new task has been createdN)rd  r9  )r  r`  createdr   r  s        rj   #update_project_summary_data_columnsrj  V  s     !/..0ri   c                    	 | j                   j                  |j                        }|j                          |j                  }|j                  |j                  k7  r|j                  r)|j                  dz   |_        |j                  dz
  |_	        n(|j                  dz
  |_        |j                  dz   |_	        |j                          t        j                   j                  |j                  j                        j                  |j                  |j                  |j                         yy# t        j                  $ r Y yw xY w)zUBefore updating annotation fields - ensure previous info removed from project.summaryr{   NrQ   rM   rT   rU   )r|   r   r`   r  r   r=  r[   r   rU   rT   r   r2   r}   r?  rM   )r  r`  r  old_annotationr[   s        rj   =delete_project_summary_annotations_before_updating_annotationrn  _  s   ++x{{+; 446 ==D##x'='==!!)-)C)Ca)GD&%)%;%;a%?D")-)C)Ca)GD&%)%;%;a%?D" x}}//077"44"&"<"< 	8 	
 > "" s   &D0 0EEc                    |j                          t        j                  d|j                          |j                  rR|j                  j
                  j                         j                  d      j                         |j                  _	        nQ|j                  j
                  j                         j                  d      j                         |j                  _
        |j                  j                          |j                  j                  g dd       t        j                  d|j                  j                   d       y	)
z-Update annotation counters in project summaryr  Tr   Frl  r  z8Updated total_annotations and cancelled_annotations for r  N)r9  r   r#  r[   r   r   r   r}   r   rU   rT   r   r   r`   )r  r`  ri  r  s       rj   1update_project_summary_annotations_and_is_labeledrp  {  s     ..0 LL.x}}o>?.6mm.G.G.K.K.M.T.Tcg.T.h.n.n.p+*2--*C*C*G*G*I*P*P_d*P*e*k*k*m'MM##%MM%alpq
LLKHMML\L\K]]^_`ri   c                     |j                   j                  j                         j                         dz
  |j                   _        |j                   j                  dg       t        j                  d|j                   j                   d       y)zRemove predictions countersrQ   rV   r   Updated total_predictions for r  N	r[   r   r   r   rV   r   r   r#  r`   rb  s      rj   remove_predictions_from_projectrt    sl     '/mm&?&?&C&C&E&K&K&MPQ&QHMM#MM&9%:;
LL1(--2B2B1C1EFri   c                    |j                   j                  j                         j                         |j                   _        |j                   j                  dg       t        j                  d|j                   j                   d       y)zAdd predictions countersrV   r   rr  r  Nrs  rb  s      rj   save_predictions_to_projectrv    sf     '/mm&?&?&C&C&E&K&K&MHMM#MM&9%:;
LL1(--2B2B1C1EFri   c                    |j                   }||d}t        j                  j                  di |}d}|D ]  }	 |j	                          |dz  } t        j                  | d| d|        y # t        j
                  $ r Y Nw xY w)N)r[   r  r   rQ   z drafts removed from task z after saving annotation rh   )r[   r  r|   r}   r   r   r   r#  )r  r`  r  r[   
query_argsr  
num_draftsdrafts           rj   delete_draftr{    s    ==Dh7J$$++9j9FJ 	LLN!OJ LLJ<9$?XYaXbcd ++ 		s   A..BBc                 J   |j                   ry |j                  }t        |d      r~|j                  rqt        j
                  j                  |      j                         }||j                  z  dk(  r0|j                  j                         D ]  }|j                           y y y y )Nml_backendsrx   r   )r   r\   r   !min_annotations_to_start_trainingr  r|   r}   r   r}  r   train)r  r`  r  r\   annotation_count
ml_backends         rj   update_ml_backendr    s    Gw&7+T+T%--44W4EKKM gGGG1L%11557 #
  "# M	 ,U&ri   c                     t         j                  d| d|         d|v r| j                  |       |r| j                          yy)zUpdate single task statistics:
        accuracy
        is_labeled
    :param task: Task to update
    :param stats: to update separate stats
    :param save: to skip saving in some cases
    :return:
    zUpdate stats z
 for task rM   r   N)r   r#  r   r   )r[   statsr   s      rj   update_task_statsr    sG     LL=z$89uD)		 ri   c           	         | sy|| d   j                   }t        j                         5  |j                         }|rt	        d      }|j
                  |j                  j                  k(  r|t	        d      z  }t        t        |t	        d                  }| j                  |      }|j                  dd      }| j                  t        |	      
       n2| D ]  }t        |d        	 t        | dgt        j                          ddd       y# t"        $ rK t$        j'                  dd       t)        t        | t        j*                  dgt        j                          Y \w xY w# 1 sw Y   yxY w)zbulk Task update accuracy
       ex: after change settings
       apply several update queries size of batch
       on updated Task objects
       in single transaction as execute sql
    :param tasks:
    :return:
    Nr   rT   rU   rP   r`   Try   rO  r  Fr  rM   )r   rI  z-Operational error while updating tasks: {exc}r  )
in_secondsr   rI  )r\   r   r  _can_use_overlapr   r   r   r   r    r!   r}   r~   r?  r  r	   r   
BATCH_SIZEr   r   r   r   BATCH_JOB_RETRY_TIMEOUT)r@   r\   use_overlapcompleted_annotations_f_expr
finished_qfinished_tasksfinished_tasks_idsr[   s           rj   *deprecated_bulk_update_stats_project_tasksr    sY    (""				 ..0 ,--@+A(!!W%6%6%E%EE,2I0JJ,-.JAiLYZJ"\\*5N!/!;!;Dt!;!LLLA-?$@LA  4!$U34E,HL_L_`) * $ 	LW[\''??#/.'22	+ s+   CE),DAE&#E)%E&&E))E2c                 T   ddl m} t        t        j                        }t        dd      rq ||       }|sy |/t        j                  j                  |d         }|j                  }|j                  rt        j                  |j                          |||       y t        | |      S )Nr   )get_unique_ids_list7fflag_fix_back_plt_802_update_is_labeled_20062025_shortautor   r{   )projects.functions.utilsr  r   r   BULK_UPDATE_IS_LABELEDr   r2   r|   r   r\   created_by_idr
   set_user
created_byr  )r@   r\   r  bulk_update_is_labeledrQ  
first_tasks         rj   bulk_update_stats_project_tasksr    s    <&x'F'FGIPVW&u-?))Xa[)9J ((G   ##G$6$67x19%IIri   Fr   )result__isnull)annotations__was_cancelled)annotations__result__isnull)r  Trm   )rV  r  r   loggingr  rn   r   r2  r  typingr   r   r   r   r   urllib.parser   ujsonr  core.bulk_update_utilsr	   core.current_requestr
   r   core.feature_flagsr   core.label_configr   
core.redisr   core.utils.commonr   r   r   r   core.utils.dbr   r   core.utils.paramsr   data_import.modelsr   data_manager.managersr   r   django.confr   	django.dbr   r   r   django.db.modelsr   r   r   r    django.db.models.lookupsr!   django.db.models.signalsr"   r#   r$   r%   django.dispatchr&   r'   django.urlsr(   django.utils.timesincer)   django.utils.timezoner*   django.utils.translationr+   r[  
fsm.modelsr,   fsm.queryset_mixinsr-   (label_studio_sdk.label_interface.objectsr.   rest_framework.exceptionsr/   tasks.choicesr0   	getLoggerrb   r   
TASK_MIXIN	TaskMixinr2   r  r  QuerySetrr  rv  Managerrx  ANNOTATION_MIXINAnnotationMixinr  r  r  r  r   r  r  r  r  Modelr  r;  rA  rJ  r<  rd  rg  rj  rn  rp  rt  rv  r{  r  r  r  r  r2  Q_task_finished_annotationsrh   ri   rj   <module>r     s5       	    6 6    . D ' 0 .  3 % ) B   ; ; = = 7 Q Q ,  , % 6 + 5 D 5 $			8	$h))*	C9* CL (8 	 		 57I 	 < H556b1"6 b1J	v 		35E 		0fnn 	0.# .,	foo 		%:<S 		0V^^ 	0S,* S,lu  u p,Jv|| ,J^]
V\\ ]
@ 
+d#Y $Y$ 
*T"1 #1

 
(4 
1 !
1 
)D!1 "1 
(:&
 '
6 
)J'a (a 
*Z(G )G 
)J'G (G 
)J'e (e  
)J'# (# /dJ0 /!52II 5AAbgDhh ri   