
    	]j                     ,   d Z ddlZddlZddlZddlmZ ddlmZ ddlm	Z	 ddl
mZ ddlmZmZ ddlmZ dd	lmZmZmZ dd
lmZmZ ddlmZ ddlmZmZmZ ddlmZ ddl m!Z!m"Z" ddl#m$Z$ ddl%m&Z& ddl'm(Z( ddl)m*Z* ddl+m,Z, ddl-m.Z.m/Z/ ddl0m1Z1 ddl2m3Z3 ddl4m5Z5m6Z6m7Z7m8Z8 ddl9m:Z: ddl;m<Z< ddl=m>Z> ddl?m@Z@ ddlAmBZB ddlCmDZDmEZEmFZFmGZGmHZH ddlImJZJmKZKmLZLmMZMmNZNmOZOmPZPmQZQmRZR ddlSmTZTmUZUmVZV dd lWmXZX dd!lWmYZZ dd"l[m\Z\ dd#l]m^Z^m_Z_m`Z` dd$lambZb dd%lcmdZd dd&lemfZf dd'lgmhZh dd(limjZjmkZk dd)llmmZmmnZnmoZompZp dd*lqmrZr dd+lsmtZt dd,lumvZv dd-lwmxZxmyZymzZz dd.l{m|Z|  ej                  e~      Z e|e$j                         Zd/d0d1d2d3d4d2d3d4d1d5d4d6d7d8d9d:gid6d;Zd<d<d1d=d>d?d@Z G dA dBe\      Z G dC dDe/      Z e,dE e8dFgdGdHj                  e$j                  xs dI      g  eeJ       ee      dJdKdLgdMdNdOdPQ      R       e,dS e8dFgdTdUj                  e$j                  xs dI      eQdJdVdLgdWX      R       G dY dZeUj                                      Z e,dE e8dFgd[g  eeJ       ee      d\dJd]dLgdW^      R       G d_ d`eUj                               Z e,dE e8dFgdadbdc e7ddeQ e5dei dfd=dgdhdidjdkdldmdndodpdqdpdrdpdsdpdtd=dudvdwd=dxdpdydzd{d|d}d=d~dddddi ddddpddpdddddddddddddddddd|ddpdddddddi dd|dpddpddddd	d      g      idJdEdLgdW      R       e,d e8dFgdddJddLgdW      R       e,d e8dFgddeQdJddLgdWX      R       G d deUj                                             Z e8dp       G d deUj                               Z e8dp       G d deUj                               Z e,dS e8dFgdd e7d       e7d      deMddgi      R       G d deUj"                               Z e,dS e8dFgddd e6dfe3j&                  dd      geMdJddLgdWë      R       G dĄ deUj                               Z G dƄ deUj                        Z G dȄ deeUj"                        Z e,dE e8dFgdd e6dfe3j&                  dd̬      gdddLgdWQ      R       G dτ deUj                               Z e,dE e8dFgdd e6dfe3j&                  ddӬ      gddgiQ      R       G dԄ deUj                               Z e,d e8dFgdd e6dfe3j&                  dd      gdddLgdWQ      R       e,dE e8dFgddڐj                  e$j                  xs dI       e6dfe3j&                  dd      g eddF      d   z   ddgiQ      R       G d܄ deeUj                  eUj2                                      Zdބ Z e8dp       G d߄ deUj                               Z e8dp       G d deUj                               Z e8dp       G d deUj                               Z e,dE e8dFgddd e7d etdp            idJddLgdW      R       G d deUj                               Zy)zThis 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)flag_set)
ListFilter)!config_essential_data_has_changed)GetParentObjectMixin)ViewClassPermissionall_permissions)start_job_async_or_sync)	paginatorpaginator_help temporary_disconnect_all_signals)LabelStudioDatabaseExceptionProjectExistException)filterset_to_openapi_params)find_dir	find_file	read_yaml)serializer_to_openapi_params)%filters_ordering_selected_items_existget_prepared_queryset)settings)IntegrityError)F)Http404)method_decorator)
CharFilter	FilterSet)DjangoFilterBackend)OpenApiTypes)OpenApiExampleOpenApiParameterOpenApiResponseextend_schema)LabelInterface)MLBackendSerializer)get_next_task)get_label_stream_history)7recalculate_created_annotations_and_labels_from_scratch)ProjectProjectImportProjectManagerProjectReimportProjectSummary)	GetFieldsSerializerProjectCountsSerializerProjectImportSerializerProjectLabelConfigSerializer%ProjectModelVersionExtendedSerializer#ProjectModelVersionParamsSerializerProjectReimportSerializerProjectSerializerProjectSummarySerializer)filtersgenericsstatus)NotFound)ValidationError)PageNumberPagination)
FormParser
JSONParserMultiPartParser)AllowAny)Response)api_settings)exception_handler)
AnnotationTask)NextTaskSerializerTaskSerializerTaskSimpleSerializer4TaskWithAnnotationsAndPredictionsAndDraftsSerializer)User)UserSimpleSerializer)WebhookAction)api_webhookapi_webhook_for_deleteemit_webhooks_for_instance)	load_funczLabeling resultz7Labeling result (choices, labels, bounding boxes, etc.)objectstringz4The name of the labeling tag from the project config)typedescriptionz:Labeling result value. Format depends on chosen ML backend)	from_nameto_namevalueimage_classimagelabelsCat)titlerS   rR   
propertiesexamplez	Task data   z/static/samples/kittens.jpg)idmy_image_url)r[   rS   rR   r]   c                       e Zd ZdZdZdZy)ProjectListPagination   	page_sized   N)__name__
__module____qualname__rd   page_size_query_parammax_page_size     C/root/env/lib/python3.12/site-packages/label_studio/projects/api.pyrb   rb   e   s    I'Mrl   rb   c                   4    e Zd Z edd      Z edd      Zy)ProjectFilterSetr_   in)
field_namelookup_exprr[   	icontainsN)rf   rg   rh   r   idsr   r[   rk   rl   rm   ro   ro   k   s    
$
7C'{CErl   ro   getProjectszList your projectsa  
    Return a list of the projects that you've created.

    To perform most tasks with the Label Studio API, you must specify the project ID, sometimes referred to as the `pk`.
    To retrieve a list of your Label Studio projects, update the following command to match your own environment.
    Replace the domain name, port, and authorization token, then run the following from the command line:
    ```bash
    curl -X GET {}/api/projects/ -H 'Authorization: Token abc123'
    ```
    zhttps://localhost:8080projectscountspublicz$request.pagez$response.results)offsetresults)x-fern-sdk-group-namex-fern-sdk-method-namex-fern-audienceszx-fern-pagination)tagssummaryrS   
parameters
extensions)name	decoratorpostzCreate new projecta  
    Create a project and set up the labeling interface in Label Studio using the API.

    ```bash
    curl -H Content-Type:application/json -H 'Authorization: Token abc123' -X POST '{}/api/projects'     --data '{{"title": "My project", "label_config": "<View></View>"}}'
    ```
    create)r|   r}   r~   )r   r   rS   requestr   c                        e Zd ZeeefZeZe	j                  egZeZ eej"                  ej$                        ZeZd Z fdZd Z fdZ eej8                         fd       Z xZS )ProjectListAPI)GETPOSTc                    t        | j                  j                        }|j                  d       |j                  j                  d      }|j                  j                  d      }t        j                  j                  | j                  j                  j                        j                  t        d      j                  d      d	      }|d
v r|j                  |dk(        }t        j                  ||      }t!        d| j                  j                        r1t!        d| j                  j                        r|j#                         }|j%                  dd      S )NdataTraise_exceptionincludefilterorganization	pinned_at)
nulls_lastz-created_at)pinned_onlyexclude_pinnedr   )pinned_at__isnullfields*fflag_feat_fit_568_finite_state_managementuser#fflag_feat_fit_710_fsm_state_fieldsmembers
created_by)r-   r   query_paramsis_validvalidated_dataru   r(   objectsr   r   active_organizationorder_byr   descr*   with_counts_annotater   
with_stateprefetch_related)self
serializerr   r   rw   s        rm   get_querysetzProjectListAPI.get_queryset   s!   (dll.G.GH
D1**..y9**..x8??))t||7H7H7\7\)]ffkN40-
 66CS9STH!66xO @t||GXGXY^f18I8I_
  **,H((LAArl   c                 ^    t         t        |          }| j                  j                  |d<   |S )Nr   )superr   get_serializer_contextr   r   r   context	__class__s     rm   r   z%ProjectListAPI.get_serializer_context   s+    DF $ 1 1rl   c           	      "   	 |j                  | j                  j                  j                         y # t        $ rR}t        |      dk(  r4t        dj                  |j                  j                  dd                  t        d      d }~ww xY w)Nr   z>UNIQUE constraint failed: project.title, project.created_by_idz-Project with the same name already exists: {}r[    z2Database error during project creation. Try again.)saver   r   r   r   strr   formatr   ru   r   )r   seres      rm   perform_createzProjectListAPI.perform_create   s    	eHH$,,"3"3"G"GHH 	e1vYY+CJJ3K]K]KaKabikmKno  //cdd	es   03 	BAB		Bc                 2    t        t        | 
  |g|i |S N)r   r   ru   r   r   argskwargsr   s       rm   ru   zProjectListAPI.get   s    ^T.wHHHHrl   c                 2    t        t        | 
  |g|i |S r   )r   r   r   r   s       rm   r   zProjectListAPI.post   s    ^T/I$I&IIrl   )rf   rg   rh   r=   r<   r>   parser_classesr4   serializer_classr6   OrderingFilterr   filter_backendsro   filterset_classr   r   projects_viewprojects_createpermission_requiredrb   pagination_classr   r   r   ru   rL   rK   PROJECT_CREATEDr   __classcell__r   s   @rm   r   r   p   s    p !*o>N(--/BCO&O-)),, -B(
eI ../J 0Jrl   r   zList projects' countszpReturns a list of projects with their counts. For example, task_number which is the total task number in projectlist_counts)r   r   r   rS   r   c                   D    e Zd ZeZeZ eej                        Z
eZd Zy)ProjectCountsListAPI)r   c                    t        | j                  j                        }|j                  d       |j                  j                  d      }t        j                  j                  |      j                  | j                  j                  j                        }t        d| j                  j                        r1t        d	| j                  j                        r|j                         }|S 
Nr   Tr   r   r   r   r   r   r   r-   r   r   r   r   ru   r(   r   with_countsr   r   r   r   r   r   r   r   rw   s       rm   r   z!ProjectCountsListAPI.get_queryset       (dll.G.GH
D1**..y9??..f.=DD**>> E 

 @t||GXGXY^f18I8I_
  **,Hrl   N)rf   rg   rh   r.   r   ro   r   r   r   r   r   rb   r   r   rk   rl   rm   r   r      s0    $ /&O-)) -rl   r   zGet project by IDz3Retrieve information about a project by project ID.200zProject informationresponser_   r[   z
My projectrS   zMy first projectlabel_configz<View>[...]</View>expert_instructionzLabel all catsshow_instructionTshow_skip_buttonenable_empty_annotationshow_annotation_historyr   colorz#FF0000maximum_annotationsis_publishedmodel_versionz1.0.0is_draftFr   JoDoezmanager@humansignal.com)r_   
first_name	last_nameemail
created_atz2023-08-24T14:15:22Z!min_annotations_to_start_training#start_training_on_annotation_updateshow_collab_predictionsnum_tasks_with_annotations
   task_numberre   useful_annotation_numberground_truth_number   skipped_annotations_numbertotal_annotations_numbertotal_predictions_numbersamplingzSequential samplingannotator_evaluation_enabledshow_overlap_firstoverlap_cohort_percentagetask_data_loginr   task_data_passwordsecretcontrol_weightsz{"tag": {...}}REQUEUE_FOR_ME)	parsed_label_config"evaluate_predictions_automaticallyconfig_has_control_tags
skip_queue#reveal_preannotations_interactivelyr   finished_task_numberqueue_total
queue_donezapplication/json)r   rV   
media_type)rS   r   examples)r   r   rS   	responsesr   deletezDelete projectz)Delete a project by specified project ID.)r   r   rS   r   patchzUpdate projectz3Update the project settings for a specific project.updatec                       e Zd ZeeefZej                  j                         Z
 eej                  ej                  ej                  ej                  ej                         ZeZdZdZd Z fdZ eej4                         fd       Z eej:                         fd       Zd Z e d	
       eej:                         fd              Z! xZ"S )
ProjectAPI)r   DELETEPATCHPUTr   zprojects:project-detailpkc                    t        | j                  j                        }|j                  d       |j                  j                  d      }t        j                  j                  |      j                  | j                  j                  j                        }t        d| j                  j                        r1t        d	| j                  j                        r|j                         }|S r   r   r   s       rm   r   zProjectAPI.get_queryset|  r   rl   c                 2    t        t        | 
  |g|i |S r   )r   r  ru   r   s       rm   ru   zProjectAPI.get  s    Z*7DTDVDDrl   c                 2    t        t        | 
  |g|i |S r   )r   r  r  r   s       rm   r  zProjectAPI.delete  s    Z-gGGGGrl   c                     | j                         }| j                  j                  j                  d      }|r	 t	        ||j
                        }t        t        | &  |g|i |S # t        $ r Y "w xY w)Nr   )

get_objectr   r   ru   r   r   KeyErrorr   r  r  )r   r   r   r   projectr   _has_changesr   s          rm   r  zProjectAPI.patch  sw    //#||((,,^< @wOcOcd Z,WFtFvFF  s   A' '	A32A3c                 b    t               5  |j                          d d d        y # 1 sw Y   y xY wr   )r   r  )r   instances     rm   perform_destroyzProjectAPI.perform_destroy  s'    -/ 	OO	 	 	s   %.Texcludec                 2    t        t        | 
  |g|i |S r   )r   r  putr   s       rm   r"  zProjectAPI.put  s!     Z*7DTDVDDrl   )#rf   rg   rh   r=   r<   r>   r   r(   r   r   querysetr   r   r   projects_deleteprojects_changer   r   r4   r   redirect_routeredirect_kwargr   ru   rM   rK   PROJECT_DELETEDr  rL   PROJECT_UPDATEDr  r  r"   r"  r   r   s   @rm   r  r    s    N !*o>N**,H-))..--++,, ).NN E M99:H ;H ../G 0G
 4 ../E 0 !Erl   r  r  c                   b    e Zd Zej                  ZeZej                  j                         Zd Zy)ProjectNextTaskAPIc                 .   | j                         }t        |j                        }t        ||      }t	        |j
                  |||      \  }}|t        d|j
                         ||ddd}	t        ||	      }
|
j                  }||d<   t        |      S )NzThere are no tasks for TF)r   r  resolve_uriannotations)r   queue)	r  r   r   r   r%   r   r9   rE   r@   )r   r   r   r   r  dm_queueprepared_tasks	next_task
queue_infor   r   r   s               rm   ru   zProjectNextTaskAPI.get  s    //#8F.w@ -gllNGU] ^	:4W\\NCDD &'$_de'	7C
??&!!rl   N)rf   rg   rh   r   
tasks_viewr   rH   r   r(   r   allr#  ru   rk   rl   rm   r+  r+    s+    )44K""$H"rl   r+  c                   ^    e Zd Zej                  Zej                  j                         Z	d Z
y)LabelStreamHistoryAPIc                 d    | j                         }t        |j                  |      }t        |      S r   )r  r&   r   r@   )r   r   r   r   r  historys         rm   ru   zLabelStreamHistoryAPI.get  s)    //#*7<<A  rl   N)rf   rg   rh   r   r4  r   r(   r   r5  r#  ru   rk   rl   rm   r7  r7    s%    )44""$H!rl   r7  Validate label configz-Validate an arbitrary labeling configuration.zValidation success)rS   zValidation failed)   i  r~   internal)r   r   rS   r
  r   r   c                   8     e Zd ZeeefZefZe	Z
 fdZd Z xZS )LabelConfigValidateAPIc                 2    t        t        | 
  |g|i |S r   )r   r>  r   r   s       rm   r   zLabelConfigValidateAPI.post  s     +T7Q$Q&QQrl   c                     | j                  |j                        }	 |j                  d       t        t        j                        S # t        $ r:}| j	                         }t        ||      }| j                  ||      }|cY d }~S d }~ww xY w)Nr   Tr   r8   )
get_serializerr   r   RestValidationErrorget_exception_handler_contextrB   finalize_responser@   r8   HTTP_204_NO_CONTENT)r   r   r   r   r   excr   r   s           rm   r   zLabelConfigValidateAPI.create  s    ((gll(;
	5 v99:: # 	88:G(g6H--gx@HO		s   A
 
	B/BBB)rf   rg   rh   r=   r<   r>   r   r?   permission_classesr0   r   r   r   r   r   s   @rm   r>  r>    s*    " !*o>N"3R
;rl   r>  "api_projects_validate_label_configzValidate project label configzJDetermine whether the label configuration for a specific project is valid.pathz0A unique integer value identifying this project.)r   rR   locationrS   validate_label_config)r   operation_idr   rS   r   r   r   c                        e Zd ZdZeeefZeZ	e
j                  Zej                  j                         Zd Z ed       fd       Z xZS )ProjectLabelConfigValidateAPIr:  c                    | j                         }| j                  j                  j                  d      }|st	        d      t        ||j                        }|j                  |d       t        d|it        j                        S )Nr   #Label config is not set or is emptyT)strictr   rA  )r  r   r   ru   rC  r   r   validate_configr@   r8   HTTP_200_OK)r   r   r   r   r  r   has_changeds          rm   r   z"ProjectLabelConfigValidateAPI.post%  sx    //#||((,,^<%&KLL 8gFZFZ[T:<kJSYSeSeffrl   Tr  c                 2    t        t        | 
  |g|i |S r   )r   rO  ru   r   s       rm   ru   z!ProjectLabelConfigValidateAPI.get0  s!    2D=gWWPVWWrl   )rf   rg   rh   __doc__r=   r<   r>   r   r0   r   r   r%  r   r(   r   r5  r#  r   r"   ru   r   r   s   @rm   rO  rO    sY    0   *o>N3)99""$H	g 4 X !Xrl   rO  c                        e Zd ZefZeZej                  Z	e
j                  j                         Z ed       fd       Z xZS )ProjectSummaryAPITr  c                 *    t        t        | 
  |i |S r   )r   rY  ru   r   r   r   r   s      rm   ru   zProjectSummaryAPI.get;  s    &14B6BBrl   )rf   rg   rh   r=   r   r5   r   r   r   r   r,   r   r5  r#  r"   ru   r   r   s   @rm   rY  rY  5  sI     ]N/)77%%))+H4 C !Crl   rY  c                       e Zd ZdZefZej                  j                         Z	 e
ej                        Z ed      d        Zy)ProjectSummaryResetAPIa  This API is useful when we need to reset project.summary.created_labels and created_labels_drafts
    and recalculate them from scratch. It's hard to correctly follow all changes in annotation region
    labels and these fields aren't calculated properly after some time. Label config changes are not allowed
    when these changes touch any labels from these created_labels* dictionaries.
    )r   Tr  c                     | j                   }|j                  }t        t        ||| j                  j
                  j                  j                         t        t        j                        S )N)organization_idrA  )parent_objectr   r	   r'   r   r   r   r_   r@   r8   rT  )r   r   r   r  r   s        rm   r   zProjectSummaryResetAPI.postM  sS    $$//C LL--AADD		
 v1122rl   N)rf   rg   rh   rW  r=   r   r(   r   r5  parent_querysetr   r   projects_reset_cacher   r"   r   rk   rl   rm   r]  r]  @  sO     !]Noo))+O-11 4 	3 !	3rl   r]  zGet project import status a  
            Poll the status of an asynchronous project import operation.
            
            **Usage:**
            1. When you POST to `/api/projects/{project_id}/import`, you'll receive a response like `{"import": <import_id>}`
            2. Use that `import_id` with this GET endpoint to check the import status
            3. Poll this endpoint to see if the import has completed, is still processing, or has failed
            4. **Import errors and failures will only be visible in this GET response**, not in the original POST request
            
            This endpoint returns detailed information about the import including task counts, status, and any error messages.
        z7A unique integer value identifying this project import.taskscreate_many_statusc                       e Zd Zej                  Zej                  egz   Z	e
fZeZej                  j!                         ZdZy)ProjectImportAPI	import_pkN)rf   rg   rh   r   r%  r   rA   DEFAULT_PERMISSION_CLASSESProjectImportPermissionrH  r=   r   r/   r   r)   r   r5  r#  lookup_url_kwargrk   rl   rm   rf  rf  Z  sM    @ *99%@@D[C\\ ]N.$$((*H"rl   rf  zGet project reimport statusa  
            Poll the status of an asynchronous project reimport operation.
            
            **Usage:**
            1. When you POST to reimport tasks, you'll receive a response with a reimport ID
            2. Use that `reimport_id` with this GET endpoint to check the reimport status
            3. Poll this endpoint to see if the reimport has completed, is still processing, or has failed
            4. **Reimport errors and failures will only be visible in this GET response**, not in the original POST request
            
            This endpoint returns detailed information about the reimport including task counts, status, and any error messages.
        z9A unique integer value identifying this project reimport.c                       e Zd Zej                  Zej                  egz   Z	e
fZeZej                  j!                         ZdZy)ProjectReimportAPIreimport_pkN)rf   rg   rh   r   r%  r   rA   rh  ri  rH  r=   r   r3   r   r+   r   r5  r#  rj  rk   rl   rm   rl  rl    sL    < *99%@@D[C\\ ]N0&&**,H$rl   rl  zDelete all tasksz)Delete all tasks from a specific project.delete_all_taskszList project tasksa  
            Retrieve a paginated list of tasks for a specific project. For example, use the following cURL command:
            ```bash
            curl -X GET {}/api/projects/{{id}}/tasks/?page=1&page_size=10 -H 'Authorization: Token abc123'
            ```
        r   c                   0    e Zd ZeefZej                  j                         Z	e
j                  j                         Z eej                  ej                  ej                         ZeZdZdZd Zd Zd Z fdZ ed	       fd
       Z fdZd Z xZS )ProjectTaskListAPI)r   r   r  zprojects:project-settingsr  c                 L    | j                   j                  dk(  rt        S t        S )Nr   )r   methodrG   rF   r   s    rm   get_serializer_classz'ProjectTaskListAPI.get_serializer_class  s     <<%'''!!rl   c                 d   t        j                  t        j                  j	                  | j
                  j                        | j                  j                  dd            }t        j                  j                  |      j                  d      }t        || j
                        }|r|S t        )Nr  r   r  r  z-updated_at)r7   get_object_or_404r(   r   for_userr   r   r   ru   rD   r   r   r
   r   )r   r#  r  rc  pages        rm   filter_querysetz"ProjectTaskListAPI.filter_queryset  s    ,,W__-E-EdllFWFW-X]a]h]h]l]lmqst]uv##G#4==mL-KMrl   c                 t   t        j                  t        j                  j	                  | j
                  j                        | j                  d         }t        t        j                  j                  |      j                  d            }t        j                  t        j                  j                  |             t        j                  d|j                   d       |j                   j#                          t%        |j                  j&                  d t(        j*                  |       t-        d      S )	Nr  rv  rw  r_   zcalling reset project_id=z ProjectTaskListAPI.delete()r;  rA  )r7   rx  r(   r   ry  r   r   r   listrD   r   valuesdelete_tasks_without_signalsloggerinfor_   r   resetrN   r   rK   TASKS_DELETEDr@   )r   r   r   r   r  task_idss         rm   r  zProjectTaskListAPI.delete  s    ,,W__-E-EdllFWFW-X]a]h]him]no++G+<CCDIJ))$,,*=*=g*=*NO/

|;WXY"7<<#C#CT=KfKfhpqs##rl   c                 *    t        t        | 
  |i |S r   )r   rp  ru   r[  s      rm   ru   zProjectTaskListAPI.get  s    '2DCFCCrl   Tr  c                 *    t        t        | 
  |i |S r   )r   rp  r   r[  s      rm   r   zProjectTaskListAPI.post  s    '3TDVDDrl   c                 J    t         t        |          }| j                  |d<   |S )Nr  )r   rp  r   r`  r   s     rm   r   z)ProjectTaskListAPI.get_serializer_context  s(    *DHJ!//	rl   c                     | j                   }|j                  |      }t        | j                  j                  j
                  |t        j                  |g       |S )Nrw  )r`  r   rN   r   r   r   rK   TASKS_CREATED)r   r   r  r  s       rm   r   z!ProjectTaskListAPI.perform_create
  sO    $$??7?3"LL117M<W<WZbYc	
 rl   )rf   rg   rh   r=   r<   r   rD   r   r5  r#  r(   ra  r   r   r4  tasks_changetasks_deleter   rF   r   r&  r'  rt  r{  r  ru   r"   r   r   r   r   r   s   @rm   rp  rp    s    b !*-N||!Hoo))+O-&&))++
 &0NN"$D 4 E !E
rl   rp  c                  <   t        d      } g }t        j                  |       j                  d      D ]  }t	        |      }t
        j                  dk7  r$|j                  dd      j                         dk(  rE|j                  dd      j                  d      r)t
        j                  rt
        j                  |d   z   |d<   |j                  |        t        t        j                  j                  dd	            }t!        |d
      5 }|j#                         j%                         }d d d        t
        j                  dk7  r#D cg c]  }|j                         dk7  s| }}t&        j)                  t+        |       d       |dS # 1 sw Y   exY wc c}w )Nannotation_templatesz**/*.yml	Communitygroupr   zcommunity contributionsrX   z/staticz
groups.txtzutf-8)encodingz templates found.)	templatesgroups)r   pathlibPathglobr   r   VERSION_EDITIONru   lower
startswithHOSTNAMEappendr   osrJ  joinopenread
splitlinesr  debuglen)annotation_templates_dirconfigsconfig_fileconfigtemplate_groups_filefr  r  s           rm   read_templates_and_groupsr    s`   '(>?G||$<=BB:N 
;'##{2zz'2&,,.2KK::gr"--i8X=N=N&//&/AF7Ov
 %RWW\\2H,%WX	"W	5 '$$&' ;.%+ZEu{{}@Y/Y%ZZ
LLCL>!234 F33' ' [s   
FF!FFc                   B    e Zd ZeeefZej                  Z	 e
       Zd Zy)TemplateListAPIc                 ,    t        | j                        S r   )r@   templates_and_groups)r   r   r   r   s       rm   r}  zTemplateListAPI.list3  s    1122rl   N)rf   rg   rh   r=   r<   r>   r   r   r   r   r  r  r}  rk   rl   rm   r  r  ,  s(     *o>N)77463rl   r  c                   h    e Zd ZefZej                  j                         Ze	j                  ZeZd Zy)ProjectSampleTaskc                 f   | j                   j                  j                  d      }| j                   j                  j                  dd      }|st        d      | j	                         }|rR	 t        |      }|j                  d      }|j                  j                  }	|d   D ]  }
|	|
d<   	 t        d	|id
      S t        d	|j                  |      id
      S # t        $ rL}t        j                  dt        |       d|        t        d	|j                  |      id
      cY d }~S d }~ww xY w)Nr   !include_annotation_and_predictionFrQ  T)raise_on_failurer.  completed_bysample_task   rA  zHError generating enhanced sample task, falling back to original method: z. Label config: )r   r   ru   rC  r  r#   generate_complete_sample_taskr   r_   r@   	Exceptionr  errorr   get_sample_task)r   r   r   r   r   r  r  label_interfacecomplete_taskuser_id
annotationr   s               rm   r   zProjectSampleTask.post>  s@   ||((,,^<,0LL,=,=,A,ABegl,m)%&KLL//#,d"0"> / M M_c M d!,,//"/"> 9J18J~.9 >sKK ]G,C,CL,QR[^__  d^_bcd_e^ffv  xD  wE  F  0G0G0U V_bccds    ,AC 	D0$AD+%D0+D0N)rf   rg   rh   r=   r   r(   r   r5  r#  r   r   r   r4   r   r   rk   rl   rm   r  r  7  s3     ]N""$H)77(`rl   r  c                   <    e Zd ZefZej                  Zd Zd Z	d Z
y)ProjectModelVersionsc                 ~    t         j                  j                  | j                  j                  j
                        S )Nr   )r(   r   r   r   r   r   rs  s    rm   r   z!ProjectModelVersions.get_queryset`  s*    %%4<<3D3D3X3X%YYrl   c                    | j                         }t        | j                  j                        }|j	                  d       |j
                  j                  dd      }|j
                  j                  dd      }|j
                  j                  dd       }|j                  d||      }	|rTd }
t        |	d	      }|r|j                         }t        |d	      }
t        |j                  |
xr |
j                  d
      S t        |	      S )Nr   Tr   extendedFinclude_live_modelslimit)with_countersr  r  many)staticlive)r  r2   r   r   r   r   ru   get_model_versionsr1   get_ml_backendsr$   r@   r   )r   r   r   r   r  r   r  r  r  r   serializer_models	ml_modelss               rm   ru   zProjectModelVersions.getc  s    //#8dll>W>WX
D1,,00UC(77;;<QSXY))--gt<))xW\)] $>t$OJ"#335	$7	$M!z@Q@lVgVlVlmnn&&rl   c                     | j                         }|j                  j                  dd       }|st        d      |j	                  |      }t        |      S )Nr   zmodel_version param is required)r   r   )r  r   ru   rC  delete_predictionsr@   )r   r   r   r   r  r   counts          rm   r  zProjectModelVersions.deletex  sQ    //#(($?%&GHH***GU##rl   N)rf   rg   rh   r=   r   r   r   r   r   ru   r  rk   rl   rm   r  r  [  s%     ]N)77Z'*	$rl   r  z"List unique annotators for projectzLReturn unique users who have submitted annotations in the specified project.r  zList of annotator usersr  )rS   r   list_unique_annotatorsc                   ^    e Zd Zej                  Zej                  j                         Z	d Z
y)ProjectAnnotatorsAPIc                 z   | j                         }t        t        j                  j	                  |d      j                  dd      j                               }t        j                  j	                  |      j                  d      j                  d      }t        |dd	|i
      j                  }t        |      S )NF)r  completed_by_id__isnullcompleted_by_idT)flat)id__in
om_throughr_   r   )r  r   )r  r}  rC   r   r   values_listdistinctrI   r   r   rJ   r   r@   )r   r   r   r   r  annotator_idsusersr   s           rm   ru   zProjectAnnotatorsAPI.get  s    //#%%gu%U[*[6XZ

 ##=#9JJ<Xaabfg#Ey'>RSXX~rl   N)rf   rg   rh   r   r   r   r(   r   r5  r#  ru   rk   rl   rm   r  r    s'    ( *77""$H	rl   r  )rW  loggingr  r  core.feature_flagsr   core.filtersr   core.label_configr   core.mixinsr   core.permissionsr   r   
core.redisr	   core.utils.commonr
   r   r   core.utils.exceptionsr   r   &core.utils.filterset_to_openapi_paramsr   core.utils.ior   r   r   'core.utils.serializer_to_openapi_paramsr   data_manager.functionsr   r   django.confr   	django.dbr   django.db.modelsr   django.httpr   django.utils.decoratorsr   django_filtersr   r   django_filters.rest_frameworkr   drf_spectacular.typesr   drf_spectacular.utilsr   r    r!   r"   *label_studio_sdk.label_interface.interfacer#   ml.serializersr$   projects.functions.next_taskr%   !projects.functions.stream_historyr&   projects.functions.utilsr'   projects.modelsr(   r)   r*   r+   r,   projects.serializersr-   r.   r/   r0   r1   r2   r3   r4   r5   rest_frameworkr6   r7   r8   rest_framework.exceptionsr9   r:   rC  rest_framework.paginationr;   rest_framework.parsersr<   r=   r>   rest_framework.permissionsr?   rest_framework.responser@   rest_framework.settingsrA   rest_framework.viewsrB   tasks.modelsrC   rD   tasks.serializersrE   rF   rG   rH   users.modelsrI   users.serializersrJ   webhooks.modelsrK   webhooks.utilsrL   rM   rN   label_studio.core.utils.commonrO   	getLoggerrf   r  PROJECT_IMPORT_PERMISSIONri  _result_schema_task_data_schemarb   ro   r   r  ListCreateAPIViewr   ListAPIViewr   RetrieveUpdateDestroyAPIViewr  RetrieveAPIViewr+  r7  CreateAPIViewr>  INTrO  rY  r]  rf  rl  DestroyAPIViewrp  r  r  r  r  r  rk   rl   rm   <module>r     s	   l  	  ' # ? , A . Y Y U N 8 8 P _   $   4 0 = . b b E . 6 F \ c c
 
 
 5 4 . L : J J / , 0 2 )   2 ) Z Z 4			8	$#H$F$FG  L Q

 Q

 W
 +w(UZT[I\]%, )FG	 0 Dy D
 	\$	 	9!9	

)*=>
()9:

 &0&.!)
)."	
'@ 	\$ 	9!9	
 "%/&.!)

.3JX// 3J/An3Jl 	\'
)*=>
()9:
 G%/&3!)

"8// #"2 	\#I?1*"'1 !1#\1 *+=1 +,@	1
 12B1 /1 /1 6t1 6t1 +A1 $Y1 211 +D1 ,W1 '1  )&'.2-2)B	+!1, )*@-1. @/10 B4112 6t314 9"516 *3718 791: 21;1< 9!=1> 7?1@ 7A1B '(=C1D ;EE1F 1$G1H 8I1J .vK1L 1(M1N .rO1P 4DBG7;*:CG)?46+-*-a1d $6i57;=
~ &0&+!)

EGJV 	\ ?%/&.!)

		 	\ I!%/&.!)


<E66 <EWJL<E\ t"11 " "0 t	!H44 	! 	! 	\'C -AB -@A
 -
 ;X33 ;! ;* 	\9/`!%%N	
 -%/&=!)

.XH$<$< X/.X0C00 C3183I3I 34 	\,
 !%%U	
 &-&:!)

->#x// #?># 	\-
 !%%W	
 
-:%11 %;:% 	\"?!%%N	
 &-&8!)

* 	\$
 F9!9
 !%%N	
 *
-l
;< 
)68-x/I/I8KbKb 87+`8v42 t3h** 3 3 t `00  `  `F t%$833 %$ %$P 	\4b5-48
 &0&>!)

&833 '&rl   