ó
    Ú°›j)  ã                   óö   • S r SSKrSSKrSSKrSSKJr  SSKJrJrJ	r	  SSK
Jr  SSKrSSKJr  SSKJrJrJr  SS	0rS
\S\4S jrS\4S jrS\S\	\\4   4S jrS\S\\\\   4   S\\   4S jrS\S\4S jrg)zÊ
PodWorker | modules | download.py

Called when inputs are images or zip files.
Downloads them into a temporary directory called "input_objects".
This directory is cleaned up after the job is complete.
é    N)ÚThreadPoolExecutor)ÚListÚUnionÚDict)Úurlparse)ÚRequestException)Úiter_content_cappedÚmax_download_bytesÚsafe_getz
User-Agentz:runpod-python/0.0.0 (https://runpod.io; support@runpod.io)Ú	file_sizeÚreturnc                 ó    • U S::  a  gU S::  a  gg)z3
Calculates the chunk size based on the file size.
i   i   i   @i    © )r   s    Ú`/home/mande/repo/quber/.venv/lib/python3.13/site-packages/runpod/serverless/utils/rp_download.pyÚcalculate_chunk_sizer      s   € ð �KÓØØÐ&Ó&Øàó    c                 óf   •  [        U R                  SS5      5      $ ! [        [        4 a     gf = f)a)  
Reads Content-Length for chunk sizing, tolerating a missing or malformed value.

The header is remote-controlled, so a non-integer value must not abort an
otherwise valid download; 0 simply yields the smallest chunk size. The real
size limit is enforced while streaming by iter_content_capped().
zContent-Lengthr   )ÚintÚgetÚ	TypeErrorÚ
ValueError)Úheaderss    r   Úparse_content_lengthr   (   s5   € ðÜ�7—;‘;Ð/°Ó3Ó4Ð4øÜ”zÐ"ó Ùðús   ‚ �0¯0Úcontent_dispositionc           	      ó  • S U R                  S5       5       nU VVVs0 s H[  nSU;   d  M  UR                  SS5      u  p4UR                  5       R                  5       UR                  5       R                  S5      _M]     nnnnU$ s  snnnf )Nc              3   ó@   #   • U  H  oR                  5       v •  M     g 7f)N)Ústrip)Ú.0Úps     r   Ú	<genexpr>Ú-extract_disposition_params.<locals>.<genexpr>7   s   é € Ð?Ò >˜1�W‰W�YˆYÒ >ùs   ‚Ú;Ú=é   Ú")Úsplitr   Úlower)r   ÚpartsÚpartÚkeyÚvalueÚparamss         r   Úextract_disposition_paramsr-   6   sŽ   € Ù?Ð 3× 9Ñ 9¸#Ô >Ó?€Eñ õâˆDØ�$‰;ó 	ð  Ÿ:™: c¨1Ó-‰JˆCð 	�	‰	‹×ÑÓ˜UŸ[™[›]×0Ñ0°Ó5Ð5ÑÙð ò ð €Mùôs   Ÿ
B­ABÚjob_idÚurlsc                 ó  ^^• [         R                  R                  [         R                  R                  SU S5      5      m[         R                  " TSS9  [
        R                  " [
        R                  [        SS9S[        S[        S	[        4S
 j5       mS[        S	[        4UU4S jjn[        U[        5      (       a  U/n[        5        n[        UR                  X!5      5      nSSS5        U$ ! , (       d  f       W$ = f)zÄ
Accepts a single URL or a list of URLs and downloads the files.
Returns the list of downloaded file absolute paths.
Saves the files in a directory called "downloaded_files" in the job directory.
ÚjobsÚdownloaded_filesT©Úexist_oké   )Ú	max_triesÚurlÚpath_to_saver   c                 óš  • [        U SS[        S9 nUR                  5         UR                  R	                  S5      nSnU(       a=  [        U5      n[        R                  R                  UR	                  SS5      5      S   nU(       d5  [        R                  R                  [        U 5      R                  5      S   n[        [        UR                  5      5      n[        X-   S5       n[        X&[        5       5       H  nUR                  U5        M     S S S 5        UsS S S 5        $ ! , (       d  f       N= f! , (       d  f       g = f)	NTé   ©ÚstreamÚtimeoutr   úContent-DispositionÚ Úfilenamer$   Úwb)r   ÚHEADERSÚraise_for_statusr   r   r-   ÚosÚpathÚsplitextr   r   r   Úopenr	   r
   Úwrite)	r7   r8   Úresponser   Úfile_extensionr,   Ú
chunk_sizeÚ	file_pathÚchunks	            r   Údownload_fileÚ/download_files_from_urls.<locals>.download_fileL   s  € ä�c $°¼7ÒCÀxØ×%Ñ%Ô'Ø"*×"2Ñ"2×"6Ñ"6Ð7LÓ"MÐØˆNÞ"Ü3Ð4GÓH�Ü!#§¡×!1Ñ!1°&·*±*¸ZÈÓ2LÓ!MÈaÑ!P�ö "Ü!#§¡×!1Ñ!1´(¸3³-×2DÑ2DÓ!EÀaÑ!H�ä-Ô.BÀ8×CSÑCSÓ.TÓUˆJô �lÑ3°TÔ:¸iÜ0°ÔGYÓG[Ö\�EØ—O‘O EÖ*ñ ]÷ ;ð "÷' DÑC÷ ;Õ:ú÷ DÕCús$   ‘CD<Ã+-D+Ä	D<Ä+
D9	Ä5D<Ä<
E
c                 ó   >• U c  g [         R                  " 5        n[        R                  R	                  TU5      n T" X5      n[        R                  R                  U U 35      $ ! [
         a  n[        SU  SU 35         S nAg S nAff = f)NzFailed to download z: )ÚuuidÚuuid4rD   rE   Újoinr   ÚprintÚabspath)r7   Ú	file_nameÚoutput_file_pathrJ   ÚerrÚdownload_directoryrN   s        €€r   Údownload_file_to_pathÚ7download_files_from_urls.<locals>.download_file_to_pathc   s‰   ø€ Ø‰;Øä—z’z“|�nˆ	ÜŸ7™7Ÿ<™<Ð(:¸IÓFÐð	Ù*¨3ÓAˆNô
 �w‰w�‰Ð"2Ð!3°NÐ3CÐDÓEÐEøô	  ó 	ÜÐ'¨ u¨B¨s¨eÐ4Ô5Üûð	ús   ½A( Á(
BÁ2BÂBN)rD   rE   rU   rS   ÚmakedirsÚbackoffÚon_exceptionÚexpor   ÚstrÚ
isinstancer   ÚlistÚmap)r.   r/   rZ   Úexecutorr2   rY   rN   s        @@r   Údownload_files_from_urlsre   C   sâ   ù€ ô Ÿ™Ÿ™¬¯©¯©°f¸fÐFXÓ)YÓZÐÜ‡K‚KÐ"¨TÒ2ä×Òœ'Ÿ,™,Ô(8ÀAÑFð"œ3ð "¬cð "´có "ó Gð"ð,F¤3ð F¬3÷ Fð Fô �$œ×ÑØˆvˆä	Ô	 Ü §¡Ð-BÓ IÓJÐ÷ 
ð Ð÷ 
Ô	ð Ðús   ÃC4Ã4
DÚfile_urlc                 óØ  • [         R                  " SSS9  [        U SS[        S9 nUR	                  5         UR
                  R                  S5      nSnU(       a  [        U5      nUR                  SS5      nU(       d4  [        U 5      R                  n[         R                  R                  U5      n[         R                  R                  U5      S	   R                  S
S5      n[        R                  " 5        n[         R                  R                  SU S
U 35      n[!        [#        UR
                  5      5      n	[%        US5       n
['        X[)        5       5       H  nU
R+                  U5        M     SSS5        SSS5        WS:X  a†  [         R                  R                  SW5      n[         R                  " USS9  [,        R.                  " WS5       nUR1                  U5        SSS5        [         R                  R3                  U5      nOSn[         R                  R3                  W5      UWUS.$ ! , (       d  f       NÈ= f! , (       d  f       NÑ= f! , (       d  f       Nv= f)ac  
Downloads a single file from a given URL, file is given a random name.
First checks if the content-disposition header is set, if so, uses the file name from there.
If the file is a zip file, it is extracted into a directory with the same name.

Returns an object that contains:
- The absolute path to the downloaded file
- File type
- Original file name
Ú	job_filesTr3   é   r;   r>   r?   r@   r$   Ú.rA   NÚzipÚr)rL   ÚtypeÚoriginal_nameÚextracted_path)rD   r\   r   rB   rC   r   r   r-   r   rE   ÚbasenamerF   ÚreplacerQ   rR   rS   r   r   rG   r	   r
   rH   ÚzipfileÚZipFileÚ
extractallrU   )rf   Údownload_responser   Úoriginal_file_namer,   Údownload_pathÚ	file_typerV   rW   rK   Úoutput_filerM   Úunzipped_directoryÚzip_refs                 r   Úfiler|   {   sð  € ô ‡K‚K� dÒ+ä	�( 4°¼WÒ	EÐIZð 	×*Ñ*Ô,à/×7Ñ7×;Ñ;Ð<QÓRÐàÐÞÜ/Ð0CÓDˆFà!'§¡¨J¸Ó!;Ðæ!Ü$ XÓ.×3Ñ3ˆMÜ!#§¡×!1Ñ!1°-Ó!@Ðä—G‘G×$Ñ$Ð%7Ó8¸Ñ;×CÑCÀCÈÓLˆ	ä—z’z“|�nˆ	äŸ7™7Ÿ<™<¨¸	°{À!ÀIÀ;Ð5OÓPÐô *Ô*>Ð?P×?XÑ?XÓ*YÓZˆ
ÜÐ" DÔ)¨[Ü,Ð->ÔL^ÓL`Öa�Ø×!Ñ! %Ö(ñ b÷ *÷5 
Fð< �EÓÜŸW™WŸ\™\¨+°yÓAÐÜ
�ŠÐ&°Ò6Ü�_Š_Ð-¨sÔ3°wØ×ÑÐ1Ô2÷ 4äŸW™WŸ_™_Ð-?Ó@Ñà!Ðô —W‘W—_‘_Ð%5Ó6ØØ+Ø,ñ	ð ÷ *Õ)ú÷5 
FÕ	Eú÷B 4Õ3ús0   ¦D$I
Å
-H9Å7I
ÇIÈ9
I	ÉI
É

IÉ
I))Ú__doc__rD   rQ   rr   Úconcurrent.futuresr   Útypingr   r   r   Úurllib.parser   r]   Úrequestsr   Úrunpod.serverless.utils.rp_ssrfr	   r
   r   rB   r   r   r   r`   r-   re   Údictr|   r   r   r   Ú<module>r„      s·   ðñó 
Û Û Ý 1ß $Ñ $Ý !ã Ý %÷ñ ð ÐUÐ
V€ð	 Cð 	¨Cô 	ð Sô ð
°Cð 
¸DÀÀcÀ¹Nô 
ð5 Sð 5°°c¸4À¹9°nÑ0Eð 5È$ÈsÉ)ô 5ðp9�3ð 9˜4õ 9r   