
    +jp                     	   % S SK r S SKrS SKrS SKrS SKrS SKrS SKrS SKJ	r	  S SK
Jr  S SKJr  S SKrS SKJr  S SKJrJr  S SKJr  S SKJrJr  S S	KJr  S S
KJrJr  S SKJrJ r   S SKJ!r!J"r"J#r#J$r$J%r%J&r&J'r'J(r(J)r)J*r*J+r+J,r,J-r-  S SK.J/r/  S SK0J1r1  \Rd                  " 5       r3Sq4\Rj                  S-  \6S'   Sq7S r8Sr9S\Rt                  S\;\<\	4   4S jr= SES\R|                  S\Rj                  S-  SS4S jjr?SFS jr@ SES\AS\<S\<S\;S-  S\R                  4
S jjrCS\<S\S\R                  4S  jrDS!\<S-  S\<4S" jrES#\F\<   S$\;\<\	4   S-  S\<S-  4S% jrGS&\R                  \R                  -  S\R                  4S' jrK\3R                  S(5      \8S\Rt                  S\R                  4S) j5       5       rM\3R                  S*5      \8S\Rt                  S\R                  4S+ j5       5       rO\3R                  S,\9 S-35      \8S\Rt                  S\R                  4S. j5       5       rP\3R                  S,\9 S/35      \8S\Rt                  S\R                  4S0 j5       5       rQ\3R                  S15      \8S\Rt                  S\R                  4S2 j5       5       rS\3R                  S*5      \8S\Rt                  S\R                  4S3 j5       5       rT\3R                  S,\9 S-35      \8S\Rt                  S\R                  4S4 j5       5       rV\3R                  S,\9 S-35      \8S\Rt                  S\R                  4S5 j5       5       rX\3R                  S65      \8S\Rt                  S\R                  4S7 j5       5       rY\3R                  S,\9 S835      \8S\Rt                  S\R                  4S9 j5       5       rZ\3R                  S,\9 S835      \8S\Rt                  S\R                  4S: j5       5       r[\3R                  S;5      \8S\Rt                  S\R                  4S< j5       5       r\\3R                  S=5      \8S\Rt                  S\R                  4S> j5       5       r]\3R                  S?5      \8S\Rt                  S\R                  4S@ j5       5       r^\3R                  SA5      \8S\Rt                  S\R                  4SB j5       5       r_\3R                  SC5      \8S\Rt                  S\R                  4SD j5       5       r`g)G    N)Any)web)ValidationError)user_manager)
schemas_inschemas_out)schemas)AssetValidationErrorUploadError)validate_blake3_hash)delete_temp_file_if_existsparse_multipart_upload)ScanInProgressErrorasset_seeder)DependencyMissingErrorHashMismatchError
apply_tagsasset_existscreate_from_hashdelete_asset_referenceget_asset_detaillist_assets_page	list_tagsremove_tagsresolve_asset_for_downloadupdate_asset_metadataupload_from_temp_path)InvalidCursorError)list_tag_histogramUSER_MANAGERFc                    ^  [         R                  " T 5      S[        R                  S[        R                  4U 4S jj5       nU$ )Nrequestreturnc                 `   >#    [         (       d  [        SSS5      $ T" U 5      I S h  vN $  N7f)N  SERVICE_DISABLEDzUAssets system is disabled. Start the server with --enable-assets to use this feature.)_ASSETS_ENABLED_build_error_response)r"   handlers    5/home/wildlama/comfy/ComfyUI/app/assets/api/routes.pywrapper0_require_assets_feature_enabled.<locals>.wrapper3   s4     ("g 
 W%%%%s   $.,.)	functoolswrapsr   RequestResponse)r)   r+   s   ` r*   _require_assets_feature_enabledr1   2   s;    __W&s{{ &s|| & & N    zK[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}r"   r#   c           	         U R                   R                  5        Vs0 s Hb  nU[        U R                   R                  U5      5      S:  a  U R                   R                  U5      OU R                   R	                  U5      _Md     nnU$ s  snf )zGets a dictionary of query parameters from the request.

request.query is a MultiMapping[str], needs to be converted to a dict
to be validated by Pydantic.
   )querykeyslengetallget)r"   key
query_dicts      r*   get_query_dictr<   D   s     ==%%'	 (C 	w}}##C()A- ]]!!#&]]s#	$ (	   s   A)B
appuser_manager_instancec                 <    Ub  Uq SqU R                  [        5        g )NT)r    r'   
add_routesROUTES)r=   r>   s     r*   register_assets_routesrB   X   s     
 (,NN6r2   c                      Sq g)z=Disable asset routes at runtime (e.g. after DB init failure).FN)r'    r2   r*   disable_assets_routesrE   c   s	     Or2   statuscodemessagedetailsc                 H    [         R                  " SXU=(       d    0 S.0U S9$ )Nerror)rG   rH   rI   rF   )r   json_response)rF   rG   rH   rI   s       r*   r(   r(   i   s+     	42NO r2   vec                 j    [         R                  " UR                  5       5      n[        SU SSU05      $ )N  zValidation failed.errors)jsonloadsr(   )rG   rN   rQ   s      r*    _build_validation_error_responserT   r   s-    ZZ	"F d,@8VBTUUr2   	requestedc                 D    U (       d  gU R                  5       nUS;   a  U$ g)N
created_at>   namesizerW   
updated_atlast_access_time)lower)rU   vs     r*   _validate_sort_fieldr^   w   s%    ALLr2   tagsuser_metadatac                 H   U(       d  gUR                  S5      nU(       d  gSU ;   a  SnO
SU ;   a  SnOgSnSU;   a  UR                  SS5      u  pB[        R                  R	                  USS9nS	U S
U 3nU(       a$  US[        R                  R	                  USS9 3-  nU$ )zIBuild a /api/view preview URL from asset tags and user_metadata filename.Nfilenameinputoutput /r4   )safez/api/view?type=z
&filename=z&subfolder=)r9   rspliturllibparsequote)r_   r`   rb   	view_type	subfolderencoded_filenameurls          r*   _build_preview_url_from_viewrp      s      ,H$		T		I
h&ooc15	||))()<I;j1A0B
CCV\\//	/CDEEJr2   resultc                 r   U R                   R                  (       aT  [        U R                   R                  5      nU(       a+  [        UR                  UR                   R
                  5      nO-SnO*[        U R                  U R                   R
                  5      nU R                  (       a  U R                  R                  OSn[        R                  " S0 SU R                   R                  _SU R                   R                  _SU_SU_SU R                  (       a  [        U R                  R                  5      OS_SU R                  (       a  U R                  R                  OS_SU R                  _S	U_S
U R                   R                  _SU R                   R
                  =(       d    0 _SU R                   R                  _SU R                   R                   _SU R                   R                   _SU R                   R"                  _SU R                   R$                  _SU R                   R&                  _6$ )z.Build an Asset response from a service result.NidrX   hash
asset_hashrY   	mime_typer_   preview_url
preview_idr`   metadatajob_id	prompt_idrW   rZ   r[   rD   )refrx   r   rp   r_   r`   assetrt   r   Assetrs   rX   int
size_bytesrv   system_metadatarz   rW   rZ   r[   )rq   preview_detailrw   asset_content_hashs       r*   _build_asset_responser      s   zz)&***?*?@6~7J7JNL^L^LlLlmKK26;;

@X@XY.4ll** ::==ZZ__   &	
 .4\\S(()t -3LL&,,((d [[   ::(( jj..4" ++ zz   **## ::(( ::((   44! r2   z/api/assets/hash/{hash}c                    #    U R                   R                  SS5      R                  5       R                  5       n [	        U5      n[        U5      n[        R                  " U(       a  SS9$ SS9$ ! [
         a    [        SSS5      s $ f = f7f)	Nrt   re   rP   INVALID_HASHz hash must be like 'blake3:<hex>'     rL   )

match_infor9   stripr\   r   
ValueErrorr(   r   r   r0   )r"   hash_strexistss      r*   head_asset_by_hashr      s      !!%%fb1779??AH
'1
 (#F<<fs66#66  
$!C
 	

s(   9BA1 *B1BB
BBz/api/assetsc                   #    [        U 5      n [        R                  R                  U5      n[        UR                  5      nUR                  =(       d    SR                  5       nUS;   a  UOSn [        [        R                  U 5      UR                  UR                  UR                  UR                   UR"                  UR$                  UUUR&                  S9
nUR.                   V	s/ s H  n	[1        U	5      PM     n
n	UR&                  b  UR2                  SLnO%UR$                  [5        U
5      -   UR6                  :  n[8        R:                  " U
UR6                  UUR2                  S9n[<        R>                  " URA                  S	S
S95      $ ! [         a  n[        SU5      s SnA$ SnAff = f! [(         a   n[+        SS[-        U5      5      s SnA$ SnAff = fs  sn	f 7f)z
GET request to list assets.
INVALID_QUERYNdesc>   ascr   )
owner_idinclude_tagsexclude_tagsname_containsmetadata_filterlimitoffsetsortorderafterrP   INVALID_CURSOR)assetstotalhas_morenext_cursorrR   Tmodeexclude_none)!r<   r   ListAssetsQuerymodel_validater   rT   r^   r   r   r\   r   r    get_request_user_idr   r   r   r   r   r   r   r   r(   stritemsr   r   r7   r   r   
AssetsListr   rM   
model_dump)r"   r;   qrN   r   order_candidater   rq   eitem	summariesr   payloads                r*   list_assets_router      s      (JE&&55jA  'Dww(&//1O./AOvED!!55g>//--''88''
 :@F&t,IF
 	ww%%T1HHs9~-=$$ll&&	G W//V$/OPPO  E/DDE(  D$S*:CFCCD Gsr   G&F AG&1A+F4 G&*G!?BG&
F1F,&F1'G&,F11G&4
G>GGG&GG&z/api/assets/{id:}c                   #    [        [        R                  " U R                  S   5      5      n [	        U[
        R                  U 5      S9nU(       d  [        SSSU S3SU05      $ [        U5      n[        R                  " UR                  SSS9SS9$ ! [         a#  n[        SS[        U5      SU05      s SnA$ SnAf[         a;    [        R                  " SU[
        R                  U 5      5        [        S	S
S5      s $ f = f7f)z-
GET request to get an asset's info as JSON.
rs   reference_idr   r   ASSET_NOT_FOUNDAssetReference z
 not foundNz1get_asset failed for reference_id=%s, owner_id=%s  INTERNALUnexpected server error.rR   Tr   r   rL   )r   uuidUUIDr   r   r    r   r(   r   r   	Exceptionlogging	exceptionr   rM   r   )r"   r   rq   r   r   s        r*   get_asset_router      s     tyy!3!3D!9:;LR!%!55g>
 (!!,z:|$	  (/ W//V$/OX[\\  
$"CFT<,@
 	
  R?,,W5	

 %S*6PQQRsM   -D	7B 'D	(B 3#D	
D B>8D9D	>ADD	DD	z	}/contentc                   ^#    U R                   R                  SS5      R                  5       R                  5       nUS;  a  Sn [	        [        [        R                  " U R                  S   5      5      [        R                  U 5      S9nUR                  mUR                  nUR                  n1 SknX7;   a  SnU=(       d    SR%                  SS5      R%                  SS5      n[&        R(                  R+                  U5      n	U SU	 3n
[,        R.                  R1                  T5      nUS-  n[2        R4                  " STUUUU5        U4S jn[6        R8                  " U" 5       UU
[        U5      SS.S9$ ! [         a   n[        SS[        U5      5      s S nA$ S nAf[          a   n[        SS	[        U5      5      s S nA$ S nAf["         a    [        SS
S5      s $ f = f7f)Ndisposition
attachment>   inliner   rs   r   r   r   i  BACKEND_UNSUPPORTEDFILE_NOT_FOUNDz"Underlying file not found on disk.>   text/css	text/htmltext/javascripttext/html-sandboxedapplication/xhtml+xmlzapplication/octet-streamre   
z; filename*=UTF-8''i   zJdownload_asset_content: path=%s, size=%d bytes (%.2f MB), type=%s, name=%sc                    >#    Sn [        TS5       n UR                  U 5      nU(       d  OU7v   M   S S S 5        g ! , (       d  f       g = f7f)Ni   rb)openread)
chunk_sizefchunkabs_paths      r*   stream_file_chunks2download_asset_content.<locals>.stream_file_chunksK  sC     
(D!Qz*	  "!!s   A"=	A
AAnosniff)zContent-DispositionzContent-LengthzX-Content-Type-Options)bodycontent_typeheaders)r5   r9   r\   r   r   r   r   r   r   r    r   r   r   download_namer   r(   NotImplementedErrorFileNotFoundErrorreplaceri   rj   rk   ospathgetsizer   infor   r0   )r"   r   rq   r   rb   rN   nie_DANGEROUS_MIME_TYPES	safe_nameencodedcd	file_sizesize_mbr   r   s                 @r*   download_asset_contentr     s     --##M<@FFHNNPK22"
+TYYw'9'9$'?@A!55g>
 ??**'' ,1R((r2::4DIll  +G=+G9	5B)I;'GLLT <<!!#%!)n&/
 Q  F$S*;SWEE K$S*?SJJ 
$!#G
 	

s\   AG&A+E9 0C	G&9
G#FG#G&G#+G G#G&G# G&"G##G&z/api/assets/from-hashc           
      .  #     U R                  5       I S h  vN n[        R                  R                  U5      nUR                  nUc;  SUR                  ;   a  UR                  R                  SS5      S   OUR                  n[        UR                  UUR                  UR                  [        R                  U 5      UR                   UR"                  S9nUc  [        SS	S
UR                   S35      $ [%        U5      n[&        R(                  " S0 UR+                  5       DSUR,                  0D6n[.        R0                  " UR+                  SSS9SS9$  GN@! [         a  n[        SU5      s S nA$ S nAf[         a    [        SSS5      s $ f = f7f)NINVALID_BODYrP   INVALID_JSON Request body must be valid JSON.:r4   r   rX   r_   r`   r   rv   rx   r   r   Asset content  does not existcreated_newrR   Tr      rL   rD   )rR   r   CreateFromHashBodyr   r   rT   r   r(   rX   rt   splitr   r_   r`   r    r   rv   rx   r   r   AssetCreatedr   r   r   rM   )r"   r   r   rN   rX   rq   r}   payload_outs           r*   create_asset_from_hash_router   _  sr    
&,,;;GD 99D|-0DII-=tyysA&q)499YY((11':..??F ~$"nTYYK$O
 	
 "&)E** 



&&K [33d3S\_``C ' D/CC 
$!C
 	

sP   FE E#E DFE 
F$E5/F0F5FFFFc                 R
  #     [        U [        S9I Sh  vN n[        R                  U 5      n [        R                  R                  UR                  UR                  UR                  UR                  UR                   UR"                  S.5      nUR,                  (       a  UR,                  S   S:X  a  [/        UR,                  5      S	:  d!  UR,                  S
   [0        R2                  ;  aP  ['        UR(                  5        [/        UR,                  5      S	:  a  UR,                  S
   OSn[        SSSU S35      $  UR4                  (       a  UR6                  SL a  [9        UR4                  UR:                  =(       d    UR4                  R=                  SS
5      S
   UR,                  UR>                  =(       d    0 UUR@                  URB                  S9nUc0  ['        UR(                  5        [        SSSUR4                   S35      $ ['        UR(                  5        OUR(                  (       a.  [D        RF                  RI                  UR(                  5      (       d  [        SSS5      $ [K        UR(                  UR:                  UR,                  UR>                  =(       d    0 URL                  UUR4                  UR@                  URB                  S9	n [_        U5      n[`        Rb                  " S&0 URe                  5       DS URf                  0D6n	URf                  (       a  S!OS"n
[h        Rj                  " U	Re                  S#SS$9U
S%9$  GN;! [         a5  n[        UR                  UR
                  UR                  5      s SnA$ SnAff = f! [$         a=  n['        UR(                  5        [        SSSUR+                  5        35      s SnA$ SnAff = f! [N         a?  n['        UR(                  5        [        SUR
                  [Q        U5      5      s SnA$ SnAf[R         a5  n['        UR(                  5        [        SS[Q        U5      5      s SnA$ SnAf[T         a5  n['        UR(                  5        [        SS[Q        U5      5      s SnA$ SnAf[V         a6  n['        UR(                  5        [        SSUR                  5      s SnA$ SnAf[X         a<    ['        UR(                  5        [Z        R\                  " SU5        [        SSS5      s $ f = f7f)'z/Multipart/form-data endpoint for Asset uploads.)check_hash_existsN)r_   rX   r`   rt   rv   rx   rP   r   zValidation failed: r   models   r4   re   zunknown models category ''Tr   r   r   r   r   r   MISSING_INPUTz-Provided hash not found and no file uploaded.)		temp_pathrX   r_   r`   client_filenamer   expected_hashrv   rx   BAD_REQUESTHASH_MISMATCHr%   DEPENDENCY_MISSINGz#upload_asset failed for owner_id=%sr   r   r   r   r   r   rR   r   rL   rD   )6r   r   r   r(   rF   rG   rH   r    r   r   UploadAssetSpecr   tags_rawprovided_nameuser_metadata_rawprovided_hashprovided_mime_typeprovided_preview_idr   r   tmp_pathrR   r_   r7   folder_pathsfolder_names_and_pathsrt   provided_hash_existsr   rX   r   r`   rv   rx   r   r   r   r   file_client_namer
   r   r   r   r   r   r   r   r   r   r   r   r   r   rM   )r"   parsedr   r   specrN   categoryrq   r}   r   rF   s              r*   upload_assetr    s	    B-gVV //8H
))88,,!'!9!9,,#66$88	
  yyTYYq\X-		NQyy|<#F#FF&v7'*499~':tyy|H(^'@
!%L 5R9944<%YY>499??3#:1#=YY"006B!..??F ~*6??;,*nTYYK,W  'v7 ??"''..*I*I,#C  + //YYYY"006B & 7 7!"ii..??
F8 "&)E** 



&&K &&SCF[33d3S\bcc W B$QXXqvvqyyAAB   
"6??3$#6rwwyk!B
 	

n   :"6??3$S!&&#a&99 A"6??3$S-Q@@ C"6??3$S/3q6BB! K"6??3$S*>		JJ R"6??3?J$S*6PQQRs!  T'M MM T'A"N B.T'CO T'O #T'$AO /T'0A*O A6T'M 
N*NNT'NT'
O2OOT'OT'
T$)4P#T$T'#T$0*Q T$T' T$-*RT$T'T$*+ST$T'AT$!T'#T$$T'c                 ^  #    [        [        R                  " U R                  S   5      5      n [        R
                  R                  U R                  5       I S h  vN 5      n [        UUR                  UR                  [        R!                  U 5      UR"                  S9n[%        U5      n[.        R0                  " UR3                  SSS9SS9$  Nu! [         a  n[        SU5      s S nA$ S nAf[         a    [        SSS5      s $ f = f! [&         a#  n[        SS[        U5      SU05      s S nA$ S nAf[(         a#  n[        S	S
[        U5      SU05      s S nA$ S nAf[         a;    [*        R,                  " SU[        R!                  U 5      5        [        SSS5      s $ f = f7f)Nrs   r   rP   r   r   )r   rX   r`   r   rx     	FORBIDDENr   r   z4update_asset failed for reference_id=%s, owner_id=%sr   r   r   rR   Tr   r   rL   )r   r   r   r   r   UpdateAssetBodyr   rR   r   rT   r   r(   r   rX   r`   r    r   rx   r   PermissionErrorr   r   r   r   rM   r   )r"   r   r   rN   rq   r   pes          r*   update_asset_router    s     tyy!3!3D!9:;L
))88w||~9MNR&%,,!55g>
 (/ W//V$/OX[\\= :N D/CC 
$!C
 	

  V$S+s2w|@TUU 
$"CGdL-A
 	
  RB,,W5	

 %S*6PQQRs   -F-,C CC &A	D /#F-C 
DC/)D*F-/D	F-DF-
F*D71F*2F-7F*E"F*F-"AF*'F-)F**F-c                   #    [        [        R                  " U R                  S   5      5      n [	        U[
        R                  U 5      SS9nU(       d  [        SS	S
U S35      $ [        R                  " SS9$ ! [         a;    [        R                  " SU[
        R                  U 5      5        [        SSS5      s $ f = f7f)Nrs   F)r   r   delete_content_if_orphanz>delete_asset_reference failed for reference_id=%s, owner_id=%sr   r   r   r   r   r   z not found.   rL   )r   r   r   r   r   r    r   r   r   r   r(   r   r0   )r"   r   deleteds      r*   delete_asset_router#    s      tyy!3!3D!9:;LR )%!55g>%*
 $"ol^;$O
 	
 <<s##  RL,,W5	

 %S*6PQQRs)   -CA: ,C:AB?<C>B??Cz	/api/tagsc                   #    [        U R                  R                  5      n [        R                  R                  U5      n[        UR                  UR                  UR                  UR                  UR                  [         R#                  U 5      S9u  pEU VVs/ s H  u  pg[$        R&                  " XgS9PM     nnn[$        R(                  " XUR                  [+        U5      -   U:  S9n	[,        R.                  " U	R1                  S	S
S95      $ ! [         a<  n[        SSSS[        R                  " UR                  5       5      05      s SnA$ SnAff = fs  snnf 7f)z9
GET request to list all tags based on query parameters.
rP   r   zInvalid query parametersrQ   N)prefixr   r   r   include_zeror   )rX   count)r_   r   r   rR   Tr   )dictrel_urlr5   r   TagsListQueryr   r   r(   rR   rS   r   r%  r   r   r   r&  r    r   r   TagUsageTagsListr7   r   rM   r   )
r"   	query_mapr5   r   rowsr   rX   r'  r_   r   s
             r*   get_tagsr/  0  s5     W__**+I
((77	B ||kk||kk''11':KD "!MT 	$4! 	  ""%,,T*Be)KG W//V$/OPP1  
$&tzz!&&(+,	
 	

"sB    E D AE  E<AE 
E1EEE E	E z}/tagsc           	        #    [        [        R                  " U R                  S   5      5      n U R	                  5       I S h  vN n[
        R                  R                  U5      n [        UUR                  S[        R                  U 5      S	9n[         R                  " UR"                  UR$                  UR&                  S
9n[0        R2                  " UR5                  SSS9SS9$  N! [         a(  n[        SSSSUR                  5       05      s S nA$ S nAf[         a    [        SSS5      s $ f = f! [(         a#  n[        SS[        U5      SU05      s S nA$ S nAf[*         a#  n[        SS[        U5      SU05      s S nA$ S nAf[         a;    [,        R.                  " SU[        R                  U 5      5        [        SSS5      s $ f = f7f)Nrs   rP   r   zInvalid JSON body for tags add.rQ   r   r   manual)r   r_   originr   )addedalready_present
total_tagsr  r  r   r   z9add_tags_to_asset failed for reference_id=%s, owner_id=%sr   r   r   rR   Tr   r   rL   )r   r   r   r   rR   r   TagsAddr   r   r(   rQ   r   r   r_   r    r   r   r3  r4  r5  r  r   r   r   r   rM   r   r"   r   json_payloaddatarN   rq   r   r  s           r*   add_asset_tagsr:  U  s     tyy!3!3D!9:;L
$\\^+!!00>R%!55g>	
 %%,,"22((
& W//V$/OX[\\Q , 
$-ryy{#	
 	
  
$!C
 	

"  V$S+s2w|@TUU 
$"CGdL-A
 	
  RG,,W5	

 %S*6PQQRs   -GC* C(#C* (AD7 #G(C* *
D44DD4GD41G3D44G7
GEGGG,F
GG
AGGGGc           	        #    [        [        R                  " U R                  S   5      5      n U R	                  5       I S h  vN n[
        R                  R                  U5      n [        UUR                  [        R                  U 5      S9n[         R                  " UR"                  UR$                  UR&                  S	9n[0        R2                  " UR5                  SSS9SS9$  N! [         a(  n[        SSSSUR                  5       05      s S nA$ S nAf[         a    [        SSS5      s $ f = f! [(         a#  n[        S
S[        U5      SU05      s S nA$ S nAf[*         a#  n[        SS[        U5      SU05      s S nA$ S nAf[         a;    [,        R.                  " SU[        R                  U 5      5        [        SSS5      s $ f = f7f)Nrs   rP   r   z"Invalid JSON body for tags remove.rQ   r   r   )r   r_   r   )removednot_presentr5  r  r  r   r   z>remove_tags_from_asset failed for reference_id=%s, owner_id=%sr   r   r   rR   Tr   r   rL   )r   r   r   r   rR   r   
TagsRemover   r   r(   rQ   r   r   r_   r    r   r   r<  r=  r5  r  r   r   r   r   rM   r   r7  s           r*   delete_asset_tagsr?    s     tyy!3!3D!9:;L
$\\^+$$33LAR%!55g>

 ((NN**((
& W//V$/OX[\\O , 
$0ryy{#	
 	
  
$!C
 	

   V$S+s2w|@TUU 
$"CGdL-A
 	
  RL,,W5	

 %S*6PQQRs   -GC) C'#C) (AD6 #G'C) )
D33DD3GD30G2D33G6
G EGGG+F	GG	AGGGGz/api/assets/tags/refinec           	        #    [        U 5      n [        R                  R                  U5      n[        [        R                  U 5      UR                  UR                  UR                  UR                  UR                  S9n[        R                  " US9n[         R"                  " UR%                  SSS9SS	9$ ! [         a  n[        SU5      s SnA$ SnAff = f7f)
z5GET request to get tag histogram for filtered assets.r   N)r   r   r   r   r   r   )
tag_countsrR   Tr   r   rL   )r<   r   TagsRefineQueryr   r   rT   r   r    r   r   r   r   r   r   r   TagHistogramr   rM   r   )r"   r;   r   rN   rA  r   s         r*   get_tags_refinerD    s       (JE&&55jA $11':^^^^oo))ggJ &&*=GW//V$/OX[\\  E/DDEs4   CB8 B
C8
CCCCCCz/api/assets/seedc                   #     U R                  5       I Sh  vN nUR                  S/ SQ5      n[        S U 5       5      nU(       d  [	        SSS5      $ U R
                  R                  SS	5      R                  5       nUS
;   n[        R                  " US9nU(       d  [        R                  " SS0SS9$ U(       Ga  [        R                  " [        R                  5      I Sh  vN   [        R                  " 5       n[        R                  " SUR                  (       a  UR                  R                   OSUR                  (       a  UR                  R"                  OSUR                  (       a  UR                  R$                  OSUR                  (       a  UR                  R&                  OSS.UR(                  S.SS9$ [        R                  " SS0SS9$  GN! [         a    / SQn GNf = f GN7f)a   Trigger asset seeding for specified roots (models, input, output).

Query params:
    wait: If "true", block until scan completes (synchronous behavior for tests)

Returns:
    202 Accepted if scan started
    409 Conflict if scan already running
    200 OK with final stats if wait=true
Nrootsr   rc   rd   c              3   4   #    U  H  oS ;   d  M
  Uv   M     g7f)rG  NrD   ).0rs     r*   	<genexpr>seed_assets.<locals>.<genexpr>  s     O5a1N,N5s   		rP   r   zNo valid roots specifiedwaitre   )true1yes)rF  rF   already_running  rL   	completedr   scannedr   createdskipped)rF   progressrQ   r   started   )rR   r9   r   tupler(   r5   r\   r   startr   rM   asyncio	to_threadrM  
get_statusrX  rU  r   rV  rW  rQ   )r"   r   rF  valid_roots
wait_paramshould_waitrY  rF   s           r*   seed_assetsrc    s    .&G%BC O5OOK$S.:TUU""62.446J 44K  {3G  (,=!>sKK 1 1222((*  %:@//v66q6<ooV__221:@//v66q:@//v66q	 !--	 
 	
 h	23??C ' .-. 	3sE   G6G GG B6G6&G3'C4G6G G0,G6/G00G6z/api/assets/seed/statusc                 r  #    [         R                  " 5       n[        R                  " UR                  R
                  UR                  (       aW  UR                  R                  UR                  R                  UR                  R                  UR                  R                  S.OSUR                  S.SS9$ 7f)z%Get current scan status and progress.rT  N)staterX  rQ   r   rL   )r   r_  r   rM   re  valuerX  rU  r   rV  rW  rQ   )r"   rF   s     r*   get_seed_statusrg    s      $$&F\\''  "??22..!??22!??22	 mm	
  s   B5B7z/api/assets/seed/cancelc                    #    [         R                  " 5       nU(       a  [        R                  " SS0SS9$ [        R                  " SS0SS9$ 7f)z)Request cancellation of in-progress scan.rF   
cancellingr   rL   idle)r   cancelr   rM   )r"   	cancelleds     r*   cancel_seedrm    sH      ##%I  (L!9#FFh/<<s   AAz/api/assets/prunec                    #     [         R                  " 5       n[        R                  " SUS.SS9$ ! [         a    [        R                  " SSS.SS9s $ f = f7f)aW  Mark assets as missing when outside all known root prefixes.

This is a non-destructive soft-delete operation. Assets and metadata
are preserved, but references are flagged as missing. They can be
restored if the file reappears in a future scan.

Returns:
    200 OK with count of marked assets
    409 Conflict if a scan is currently running
scan_runningr   )rF   markedrR  rL   rS  r   )r   mark_missing_outside_prefixesr   r   rM   )r"   rp  s     r*   mark_missing_assetsrr    s`     
;;= vFsSS  
  %3
 	

s%   A1 A"AAAA)N)r#   N)ar]  r-   rR   r   r   urllib.parseri   r   typingr   aiohttpr   pydanticr   r  r=   r   app.assets.apir   r   app.assets.servicesr	   app.assets.api.schemas_inr
   r   app.assets.helpersr   app.assets.api.uploadr   r   app.assets.seederr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   app.assets.services.cursorr   app.assets.services.taggingr   RouteTableDefrA   r    UserManager__annotations__r'   r1   UUID_REr/   r(  r   r<   ApplicationrB   rE   r   r0   r(   rT   r^   listrp   AssetDetailResultUploadResultr~   r   headr   r9   r   r   r   postr   r  putr  deleter#  r/  r:  r?  rD  rc  rg  rm  rr  rD   r2   r*   <module>r     s       	     $   2 ' 4 @    : :				04l&&- 4 YCKK DcN , >B	'33d: 
 BF%(37$;\\V3 VO V V
C$J 3 tCy c3hRVAV [^ae[e 4'";";g>R>R"R WbWhWh > &' 	7ckk 	7cll 	7 ! (	7 M .QS[[ .QS\\ .Q ! .Qb y+, ]3;; ]3<< ] ! -]B y
34 =#++ =#,, = ! 5=@ $% #a #a #a ! &#aL ] bd bd bd ! bdJ y+, !]ckk !]cll !] ! -!]H "7)2./ $ckk $cll $ ! 0$4 K  QCKK  QCLL  Q !  QF  	12 +]#++ +]#,, +] ! 3+]\ "7)734 *]S[[ *]S\\ *] ! 5*]Z %& ]3;; ]3<< ] ! '](   -@s{{ -@s|| -@ ! !-@` %& 3;; 3<<  ! '( &' =s{{ =s|| = ! (=  ! Ts{{ Ts|| T ! "Tr2   