
    &`ig                        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 d dl	m
Z
 d dlmZmZ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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%m&Z&m'Z' d dl(m)Z)  ej*        e+          Z,dZ- e.ej/        0                    de                    Z1dZ2dZ3dZ4dZ5de6de7fdZ8de7de7fdZ9 G d d          Z:de;de;de;fdZ<e,fded ee         d!ed"e=d#eej>                 f
d$Z?e,fd%ed&ed#eej>                 de;fd'Z@e,fd%ed&ed#eej>                 de;fd(ZAe,fd)ed&ed ee         d"e=d#eej>                 de;fd*ZBd+e7ddfd,ZCd-e7deee7f         fd.ZDd/e7de=fd0ZEd/e7de=fd1ZFd/e7de=fd2ZGded ee7         defd3ZHded4e7dee         fd5ZIe,fded"e=d#eej>                 dee         fd6ZJdd7d/e7d8ee.         ddfd9ZKe,fd-e7d:e;d#eej>                 de.fd;ZLd<e7d-e7de7fd=ZMd>e,fd?e7d ee7         d@e7d"e=dAe=d#eej>                 ddfdBZNd-e7de=fdCZOdDede7fdEZPdFe7de7fdGZQ	 d`dHe7d"e=d eee7                  de7fdIZRd-e7dJe;ddfdKZSd>de,fdLe7dMed"e=dAe=d eee7                  d#eej>                 fdNZTd>de,fd-e7d<e7dLe7d"e=dAe=d eee7                  d#eej>                 de=fdOZUd/e7d<e7defdPZVe)de,d>fd-e7d<e7dQee#         d#eej>                 dRe=de7fdS            ZWdTe7fdUZXdVe7dWe7fdXZYe,fdTe7dYe7dZe=d[e=d#eej>                 ddfd\ZZd-e7d<e7dee=e.f         fd]Z[e,fd^e7dYe7d#eej>                 ddfd_Z\dS )a    N)Path)TemporaryDirectory)CallableListOptionalTuple)urlparse)ZipFile)FileLock)is_path)GRPC_CPP_MAX_MESSAGE_SIZE,RAY_RUNTIME_ENV_URI_PIN_EXPIRATION_S_DEFAULT,RAY_RUNTIME_ENV_URI_PIN_EXPIRATION_S_ENV_VAR)exec_cmd_stream_to_logger)Protocol)PathSpec)	GcsClient)_internal_kv_exists_internal_kv_put_pin_runtime_env_uri)DeveloperAPIi   RAY_max_grpc_message_size	_ray_pkg_'RAY_RUNTIME_ENV_FAIL_UPLOAD_FOR_TESTING)RAY_RUNTIME_ENV_FAIL_DOWNLOAD_FOR_TESTING__MACOSX	num_bytesreturnc                 2    t          | dz            }|ddS )Ni   z.2fMiB)float)r   size_mibs     v/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/ray/_private/runtime_env/packaging.py_mib_stringr$   8   s&    Y())H    pathc                 B   t          |           } t          j        dk    r| S t          j                            t          j                            |                     }d}|                    |          r|S |                    d          r|dz   |dd         z   S ||z   S )a  Convert paths to extended-length format if needed on Windows
    if needed. Paths on other platforms are returned unchanged.

    Extended-length paths (\\?\) support paths up to 32,767 characters on Windows
    instead of 260. Extended-length paths must be normalized (i.e., no "." or ".."
    components) so this function normalizes the path before applying the prefix.

    Args:
        path: The path to convert.

    Returns:
        The path with extended-length prefixed path on Windows, unchanged on other platforms.
    win32z\\?\z\\UNC   N)strsysplatformosr&   normpathabspath
startswith)r&   abs_pathextended_prefixs      r#   _to_extended_length_pathr4   =   s     t99D
|w w 5 566H  O ?++  6"" 6&!""55 X%%r%   c                   *    e Zd ZdZdefdZd Zd ZdS )_AsyncFileLockz4Asyncio version used to prevent blocking event loop.	lock_filec                 .    t          |          | _        d S N)r   file)selfr7   s     r#   __init__z_AsyncFileLock.__init__g   s    Y''			r%   c                    K   	 	 | j                             d           d S # t          $ r t          j        d           d {V  Y nw xY wI)NTr   )timeoutg?)r:   acquireTimeoutErrorasynciosleep)r;   s    r#   
__aenter__z_AsyncFileLock.__aenter__j   sv      	))	!!!!,,, ) ) )mC((((((((((()		)s   " $A	A	c                 <   K   | j                                          d S r9   )r:   release)r;   exc_typeexctbs       r#   	__aexit__z_AsyncFileLock.__aexit__r   s       	r%   N)__name__
__module____qualname____doc__r+   r<   rC   rI    r%   r#   r6   r6   d   sS        >>(# ( ( ( () ) )    r%   r6   leftrightc                 `    | r)|r't          d t          | |          D                       S | p|S )Nc              3   &   K   | ]\  }}||z  V  d S r9   rN   ).0abs      r#   	<genexpr>z_xor_bytes.<locals>.<genexpr>x   s*      ::v1QU::::::r%   )byteszip)rO   rP   s     r#   
_xor_bytesrY   v   sB     ; ;::T5)9)9::::::=5r%   excludeshandlerinclude_gitignoreloggerc                     t           ||          }|                    |           t           fd|D                       }|sx	  |            n,# t          $ r}|                    d             |d}~ww xY w                                 r+                                 D ]}t          |||||           t          t          |                    D ]}	|
                                 dS )zTravels the path recursively, calling the handler on each subpath.

    Respects excludes, which will be called to check if this path is skipped.
    r\   r]   c              3   .   K   | ]} |          V  d S r9   rN   )rS   er&   s     r#   rV   z_dir_travel.<locals>.<genexpr>   s+      ))1qqww))))))r%   zIssue with path: N)get_excludes_from_ignore_filesextendany	Exceptionerroris_diriterdir_dir_travelrangelenpop)
r&   rZ   r[   r\   r]   new_excludesskipra   sub_path_s
   `         r#   ri   ri   |   s@    2 1&  L OOL!!!)))))))))D 	GDMMMM 	 	 	LL3T33444G	 ;;== 	 LLNN  &7!     3|$$%%   s   A 
A<A77A<filepathrelative_pathc                    d}t          j                    }|                    t          |                     |                                                               |                                 s	 |                     d          }	 |                    |          }t          |          dk    r=|                    |           |                    |          }t          |          dk    =|
                                 nK# |
                                 w xY w# t          $ r%}|                    d|  d|            Y d}~nd}~ww xY w|                                S )zHelper function to create hash of a single file or directory.

    This function hashes the path of the file or directory,
    and if it's a file, then it hashes its content too.
    i  @ rbr   zSkipping contents of file zD when calculating package hash because the file couldn't be opened: N)hashlibsha1updater+   relative_toencoderg   openreadrk   closere   debugdigest)rq   rr   r]   BUF_SIZErv   fdatara   s           r#   $_hash_file_content_or_directory_namer      sj    H<>>DKKH((7788??AABBB?? 	d##Avvh''$ii1nnKK%%%66(++D $ii1nn 								  	 	 	LL<X < <89< <       	 ;;==s%   2D A%D D
E
%EE
c                 F    t          | ||          }t          |d          S )zHelper function to create hash of a single file.

    It hashes the path of the file and its content to create a hash value.
    r]      00000000r   rY   )rq   rr   r]   	file_hashs       r#   
_hash_filer      s1     5-  I i***r%   rootc                 d    ddt           ffd}|g n|g}t          | |||           S )zHelper function to create hash of a directory.

    It'll go through all the files in the directory and xor
    hash(file_name, file_content) to create a hash value.
    r   r&   c                 L    t          |           }t          |          d S )Nr   r   )r&   r   hash_valr]   rr   s     r#   r[   z _hash_directory.<locals>.handler   s3    8-
 
 
	 h	22r%   Nr_   )r   ri   )r   rr   rZ   r\   r]   r[   r   s    `  ` @r#   _hash_directoryr      sw     H3d 3 3 3 3 3 3 3 3 %rrH:Hh3DV    Or%   pkg_pathc                     t          |           }	 |                    d           dS # t          $ r t          | d          w xY w)z5Parse the path to check it is well-formed and exists.T)strictz is not a valid path.N)r   resolveOSError
ValueError)r   r&   s     r#   
parse_pathr      s^    >>D9D!!!!! 9 9 9D7778889s	   ) Apkg_uric           	      v   t          |           rt          d|            t          |           }	 t          |j                  }n4# t          $ r'}t          d|  dt          j         d|           d}~ww xY w|t          j                    v r|j                            d          r!|j        	                    d          d         }nl|j
         d	|j         |j         }g d
}|D ]}|                    |d	          }|                    dd	|                    d          dz
            }n|j        }||fS )a  
    Parse package uri into protocol and package name based on its format.
    Note that the output of this function is not for handling actual IO, it's
    only for setting up local directory folders by using package name as path.

    >>> parse_uri("https://test.com/file.zip")
    (<Protocol.HTTPS: 'https'>, 'https_test_com_file.zip')

    >>> parse_uri("https://test.com/file.whl")
    (<Protocol.HTTPS: 'https'>, 'file.whl')

    zExpected URI but received path z&Invalid protocol for runtime_env URI "z". Supported protocols: z. Original error: N.whl/rp   )r   :@+ ().r*   )r   r   r	   r   scheme_member_names_remote_protocolsr&   endswithsplitvaluenetlocreplacecount)r   uriprotocolra   package_namedisallowed_charsdisallowed_chars          r#   	parse_urir      s    w FD7DDEEE
7

C
CJ'' 
 
 
SW S S$,$;S SOPS S
 
 	

 8,....8V$$ 	W 8>>#..r2LL&nEEszE38EELBBB#3 J J+33OSII (//S,:L:LS:Q:QTU:UVVLLzl##s   A 
A8"A33A8r   c                 |    	 t          |           \  }}n# t          $ r Y dS w xY wt          |          j        dk    S )NF.zipr   r   r   suffix)r   r   r&   s      r#   
is_zip_urir   &  sP    "3$$   uu ::&&    
##c                 |    	 t          |           \  }}n# t          $ r Y dS w xY wt          |          j        dk    S )NFr   r   r   rp   r&   s      r#   
is_whl_urir   /  P    C..44   uu ::&&r   c                 |    	 t          |           \  }}n# t          $ r Y dS w xY wt          |          j        dk    S )NF.jarr   r   s      r#   
is_jar_urir   8  r   r   c                 x                                        t          j        d|          dt          f fd}|S )Ngitwildmatchpc                     t          |                                                                         }                    |          S r9   r+   absoluterx   
match_filer   path_strr&   pathspecs     r#   matchz_get_excludes.<locals>.matchE  s:    qzz||//5566""8,,,r%   )r   r   
from_linesr   )r&   rZ   r   r   s   `  @r#   _get_excludesr   A  sT    ==??D">8<<H- - - - - - - - Lr%   ignore_filec                 ,                                        |z  }|                                rd|                    d          5 }t          j        d|                                          ddd           n# 1 swxY w Y   dt          f fd}|S dS )aX  Returns a function that returns True if the path should be excluded.

    Returns None if there is no ignore_file in the path.

    Args:
        path: The path to the directory to check for an ignore file.
        ignore_file: The name of the ignore file.

    Returns:
        A function that returns True if the path should be excluded.
    rr   Nr   c                     t          |                                                                         }                    |          S r9   r   r   s     r#   r   z_get_ignore_file.<locals>.match_  s:    1::<<33D99::H&&x000r%   )r   is_filerz   r   r   	readlinesr   )r&   r   r   r   r   s   `   @r#   _get_ignore_filer   L  s     ==??D$K 
c"" 	Ja*>1;;==IIH	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J	1T 	1 	1 	1 	1 	1 	1 	1 ts   (A99A= A=c                 F   g }g }|r@t          | d          }|-|                    |           |                    | dz             t          | d          }|-|                    |           |                    | dz             |r|                    d|            |S )a  Get exclusion functions from .gitignore and .rayignore files in the current path.

    Args:
        path: The path to check for ignore files.
        include_gitignore: Whether to respect .gitignore files.
        logger: Logger to use.

    Returns:
        List[Callable]: List of exclusion functions. Each function takes a Path
            and returns True if the path should be excluded based on the ignore
            patterns in the respective ignore file.
    z
.gitignore)r   Nz
.rayignorez,Ignoring upload to cluster for these files: )r   appendinfo)r&   r\   r]   ignore_files	to_ignoregr   s          r#   rb   rb   h  s    " L*,I 5T|<<<=Q| 3444<888A}D</000 SQ<QQRRRr%   expiration_sr   c                H   |8t          t          j                            t          t
                              }n5t          |t                     s t          dt          |           d          |dk     rt          d| d          |dk    rt          | |           dS dS )a  Pin a reference to a runtime_env URI in the GCS on a timeout.

    This is used to avoid premature eviction in edge conditions for job
    reference counting. See https://github.com/ray-project/ray/pull/24719.

    Packages are uploaded to GCS in order to be downloaded by a runtime env plugin
    (e.g. working_dir, py_modules) after the job starts.

    This function adds a temporary reference to the package in the GCS to prevent
    it from being deleted before the job starts. (See #23423 for the bug where
    this happened.)

    If this reference didn't have an expiration, then if the script exited
    (e.g. via Ctrl-C) before the job started, the reference would never be
    removed, so the package would never be deleted.
    Nz!expiration_s must be an int, got r   r   zexpiration_s must be >= 0, got r   )
intr.   environgetr   r   
isinstancer   typer   )r   r   s     r#   pin_runtime_env_urir     s    $ JNN<< 
 
 c** TRT,=O=ORRRSSSaJ<JJJKKK			S|<<<<<< 
	r%   r   c                 8   t          |          }t          |          }t          |          t          k    r(t          d| dt          t                     d          |                    d|  d| d           	 t
          j                            t                    rt          d          t          | |           n4# t          $ r'}t          d|  d	| d
|dd          d          |d}~ww xY w|                    d|  d           t          |          S )a  Stores package data in the Global Control Store (GCS).

    Args:
        pkg_uri: The GCS key to store the data in.
        data: The serialized package's bytes to store in the GCS.
        logger (Optional[logging.Logger]): The logger used by this function.

    Return:
        int: Size of data

    Raises:
        RuntimeError: If the upload to the GCS fails.
        ValueError: If the data's size exceeds GCS_STORAGE_MAX_SIZE.
    zPackage size (z) exceeds the maximum size of a  . You can exclude large files using the 'excludes' option to the runtime_env or provide a remote URI of a zip file using protocols such as 's3://', 'https://' and so on, refer to https://docs.ray.io/en/latest/ray-core/handling-dependencies.html#api-reference.zPushing file package 'z' (z) to Ray cluster...z:Simulating failure to upload package for testing purposes.z1Failed to store package in the GCS.
  - GCS URI: z
  - Package data (z): N   z...
z"Successfully pushed file package ''.)rk   r$   GCS_STORAGE_MAX_SIZEr   r   r.   r   r   /RAY_RUNTIME_ENV_FAIL_UPLOAD_FOR_TESTING_ENV_VARRuntimeErrorr   re   )r   r   r]   	file_sizesize_strra   s         r#   _store_package_in_gcsr     s{   ( D		I9%%H
4yy(((_X _ _/00_ _ _
 
 	
 KKRRRXRRRSSS:>>IJJ 	L   	$''''   ?#? ?!)? ?.23B3i? ? ?
 
 		 KK@W@@@AAAt99s   <AC   
C1
"C,,C1base_directoryc                 f    t          |          \  }}t          j                            | |          S r9   )r   r.   r&   join)r   r   rp   pkg_names       r#   _get_local_pathr     s)    G$$KAx7<<111r%   Fr   output_pathinclude_parent_dirc                   
 t          |                                          }t          t          |                    }t	          |dd          5 t          |                                           }|
|                                r|j        
dt           f
fd}	t          ||          g}t          |||	|           ddd           dS # 1 swxY w Y   dS )aV  Zip the target file or directory and write it to the output_path.

    path_str: The file or directory to zip.
    excludes (List(str)): The directories or file to be excluded.
    output_path: The output path for the zip file.
    include_parent_dir: If true, includes the top-level directory as a
        directory inside the zip file.
    wF)strict_timestampsr&   c           	         |                                  r"t          |                                 d           |                                 r|                                 j        }|t          k    r,                    d|  dt          |           d|  d           | 	                              }r
j
        |z  }                    | |           d S d S )NFile z is very large (zt). Consider adding this file to the 'excludes' list to skip uploading it: `ray.init(..., runtime_env={'excludes': ['z']})`)rg   nextrh   r   statst_sizeFILE_SIZE_WARNINGwarningr$   rx   namewrite)r&   r   to_pathdir_pathr   r]   zip_handlers      r#   r[   z_zip_files.<locals>.handler  s    {{}} 1dllnnd!;!;!Ct||~~!C IIKK/	 111NND D D'	22D D 8<	D D D   **844% 6&mg5G!!$00000 "D!Cr%   r_   N)	r   r   r4   r+   r
   r   parentr   ri   )r   rZ   r   r\   r   r]   pkg_fileextended_pkg_file	file_pathr[   r   r   s       ``    @@r#   
_zip_filesr    sR     K  ))++H0X??	"C5	A	A	A 
[NN++--	 	( 'H	1$ 	1 	1 	1 	1 	1 	1 	1 	1 	1" ")X667/	
 	
 	
 	
3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
s   A4CCCc                     t          |           \  }}|t          j        k    rt          |           S t	          d| d          )zCheck whether the package with given URI exists or not.

    Args:
        pkg_uri: The uri of the package

    Return:
        True for package existing and False for not.
    	Protocol  is not supported)r   r   GCSr   NotImplementedError)r   r   r   s      r#   package_existsr	    sK     #7++Hh8<"7+++!"Ih"I"I"IJJJr%   packagec                 :   | j         dk    r+d                    t          j        j        | j                  S t          j        |                                           	                                }d                    t          j        j        t          |z             S )z8Get a content-addressable URI from a package's contents.r   z{protocol}://{whl_filename})r   whl_filename{protocol}://{pkg_name}.zipr   r   )r   formatr   r  r   r   ru   rv   
read_bytes	hexdigestRAY_PKG_PREFIX)r
  r   s     r#   get_uri_for_packager  *  s     ~ -33\'gl 4 
 
 	
 < 2 2 4 455??AA,33\'.82K 4 
 
 	
r%   r:   c                 d   t          |                                           }|                                r|                                st	          d| d          t          ||j                  }d                    t          j	        j
        t          |                                z             S )a#  Get a content-addressable URI from a file's content.

    This function generates the name of the package by the file.
    The final package name is _ray_pkg_<HASH_VAL>.zip of this package,
    where HASH_VAL is the hash value of the file.
    For example: _ray_pkg_029f88d5ecc55e1e4d64fc6e388fd103.zip

    Examples:

        >>> get_uri_for_file("/my_file.py")  # doctest: +SKIP
        _ray_pkg_af2734982a741.zip

    Args:
        file: The file.

    Returns:
        URI (str)

    Raises:
        ValueError: If the file doesn't exist.
    r   z must be an existing filer  r  )r   r   existsr   r   r   r   r  r   r  r   r  hex)r:   rq   r   s      r#   get_uri_for_filer  :  s    , Dzz""$$H?? FH$4$4$6$6 FDDDDEEE(HO44H(//#nx||~~.M 0   r%   	directoryc                    |g }t          |                                           } |                                 r|                                 st	          d|  d          t          | | t          | |          |          }d                    t          j	        j
        t          |                                z             S )a  Get a content-addressable URI from a directory's contents.

    This function generates the name of the package by the directory.
    It'll go through all the files in the directory and hash the contents
    of the files to get the hash value of the package.
    The final package name is _ray_pkg_<HASH_VAL>.zip of this package.
    For example: _ray_pkg_029f88d5ecc55e1e4d64fc6e388fd103.zip

    Examples:

        >>> get_uri_for_directory("/my_directory")  # doctest: +SKIP
        _ray_pkg_af2734982a741.zip

    Args:
        directory: The directory.
        include_gitignore: Whether to respect .gitignore files.
        excludes (list[str]): The dir or files that should be excluded.

    Returns:
        URI (str)

    Raises:
        ValueError: If the directory doesn't exist.
    Nz
directory z must be an existing directory)r\   r  r  )r   r   r  rg   r   r   r   r  r   r  r   r  r  )r  r\   rZ   r   s       r#   get_uri_for_directoryr  [  s    : Y((**I QY%5%5%7%7 QOiOOOPPPi**+	  H )//#nx||~~.M 0   r%   	pkg_bytesc                     t          |           \  }}|t          j        k    rt          | |           dS |t          j                    v rt          d          t          d| d          )a  Upload a local package to GCS.

    Args:
        pkg_uri: The URI of the package, e.g. gcs://my_package.zip
        pkg_bytes: The data to be uploaded.

    Raises:
        RuntimeError: If the upload fails.
        ValueError: If the pkg_uri is a remote path or if the data's
            size exceeds GCS_STORAGE_MAX_SIZE.
        NotImplementedError: If the protocol of the URI is not supported.

    z>upload_package_to_gcs should not be called with a remote path.r  r  N)r   r   r  r   r   r   r  )r   r  r   r   s       r#   upload_package_to_gcsr    s~     #7++Hh8<gy11111	X.00	0	0L
 
 	
 ""Ih"I"I"IJJJr%   module_pathtarget_pathc                     |g }|t           }|                                s=|                    d|  d           t          | |t	          |          |||           d S d S )Nz*Creating a file package for local module 'r   )r\   r   r]   )default_loggerr  r   r  r+   )r  r  r\   r   rZ   r]   s         r#   create_packager"    s     ~ 	
PPPPQQQ/1	
 	
 	
 	
 	
 	
	
 	
r%   c                    |g }|t           }t          |            t          |           rdS t          t	          ||                     }|                    t          j                     dt          j	                     d|j
                   }t          |||||           |                                }|                                 t          | |           dS )a  Upload the contents of the directory under the given URI.

    This will first create a temporary zip file under the passed
    base_directory.

    If the package already exists in storage, this is a no-op.

    Args:
        pkg_uri: URI of the package to upload.
        base_directory: Directory where package files are stored.
        module_path: The module to be uploaded, either a single .py file or a directory.
        include_parent_dir: If true, includes the top-level directory as a
            directory inside the zip file.
        excludes: List specifying files to exclude.
        include_gitignore: Whether to respect .gitignore files. Default is True.

    Raises:
        RuntimeError: If the upload fails.
        ValueError: If the pkg_uri is a remote path or if the data's
            size exceeds GCS_STORAGE_MAX_SIZE.
        NotImplementedError: If the protocol of the URI is not supported.
    NFrp   )r\   r   rZ   T)r!  r   r	  r   r   	with_nametimetime_nsr.   getpidr   r"  r  unlinkr  )	r   r   r  r\   r   rZ   r]   package_filepackage_file_bytess	            r#   upload_package_if_neededr+    s    > ~   g u@@AAL  ))<>>==BIKK==,*;== L +-    &0022'#56664r%   c                 j    t          t          ||                     }|                    d          }|S )z5Return the local directory corresponding to this URI. )r   r   with_suffix)r   r   r   	local_dirs       r#   get_local_dir_from_urir0     s2    ONC8899H$$R((Ir%   
gcs_client	overwritec           
      N  K   t          t          ||                     }|j        dk    rt          d|  d          t	          t          |          dz             4 d{V  |t          }|                    d|             t          | |          }||k    s
J d            d}|	                                r&|s$d	}|
                                sJ | d
            nC|	                                r/|                    d| d|            t          j        |           |rt          |           \  }}	|                    d|  d| d|            |t          j        k    r|t          d          |                    |                                 dd           d{V }
t&          j                            t,                    rd}
|
#t/          d|  dt0           dt2           d          |
pd}
|                    |
           t7          |           rt9          ||d	d|           nt          |          cddd          d{V  S |t          j                    v rz|                    | |           |j        dv rt9          ||dd|           nX|j        dk    r!t          |          cddd          d{V  S t?          d|j         dd          t?          d| d          t          |          cddd          d{V  S # 1 d{V swxY w Y   dS ) a  Download the package corresponding to this URI and unpack it if zipped.

    Will be written to a file or directory named {base_directory}/{uri}.
    Returns the path to this file or directory.

    Args:
        pkg_uri: URI of the package to download.
        base_directory: Directory to use as the parent directory of the target
            directory for the unpacked files.
        gcs_client: Client to use for downloading from the GCS.
        logger: The logger to use.
        overwrite: If True, overwrite the existing package.

    Returns:
        Path to the local directory containing the unpacked package files.

    Raises:
        IOError: If the download fails.
        ImportError: If smart_open is not installed and a remote URI is used.
        NotImplementedError: If the protocol of the URI is not supported.
        ValueError: If the GCS client is not provided when downloading from GCS,
                    or if package URI is invalid.

    r-  zInvalid package URI: z:.URI must have a file extension and the URI must be valid..lockNzFetching package for URI: zInvalid pkg_file!TFz is not a directoryz	Removing z with pkg_file zDownloading package from  to z with protocol z1GCS client must be provided to download from GCS.)	namespacer>   z,Failed to download runtime_env file package z from the GCS to the Ray worker node. The package may have prematurely been deleted from the GCS due to a long upload time or a problem with Ray. Try setting the environment variable zD  to a value larger than the upload time in seconds (the default is zW). If this fails, try re-running after making any change to a file in the file package.r%   )package_path
target_dirremove_top_level_directory
unlink_zipr]   )
source_uri	dest_file)r   r   r   zPackage format z is z"not supported for remote protocolsr  r  ) r   r   r   r   r6   r+   r!  r}   r0  r  rg   r   shutilrmtreer   r   r  async_internal_kv_getry   r.   r   r   1RAY_RUNTIME_ENV_FAIL_DOWNLOAD_FOR_TESTING_ENV_VARIOErrorr   r   write_bytesr   unzip_packager   download_remote_urir  )r   r   r1  r]   r2  r   r/  download_packager   rp   codes              r#   download_and_unpack_packagerG    sa     @ ONG<<==H"HG H H H
 
 	

 c(mmg566 S S S S S S S S>#F;';;<<<*7NCC	H$$$&9$$$!% 	%i 	%$##%%HH)'H'H'HHH%H 	%KKHIHHhHHIIIM)$$$ @	S#G,,KHaKK,G , , , ,!), ,   8<''%$K  
 (==NN$$d >         :>>"STT  D<!
Qw 
Q 
Q
 H
Q 
Q H
Q 
Q 
Q   {s$$T***g&& 	)!%-#,38#'%     x=={S S S S S S S S S S S S S S| X68888,,8,TTT?&666!%-#,37#'%     _..x==US S S S S S S S S S S S S SX .?(/???<  
 **Qh*Q*Q*QRRR9~~gS S S S S S S S S S S S S S S S S S S S S S S S S S S S S Ss    #GLA#L:L
L!Lr7  c                     t          | d          }d}d }d }|                                D ]N}|( ||          r dS  ||          }|t          k    r)|}, ||          s ||          |t          fvr dS O|S )z
    If compressed package at package_path contains a single top-level
    directory, returns the name of the top-level directory. Otherwise,
    returns None.

    Ignores a second top-level directory if it is named __MACOSX.
    r   Nc                 
    d| vS )Nr   rN   	file_names    r#   is_top_level_filezDget_top_level_dir_from_compressed_package.<locals>.is_top_level_file  s    )##r%   c                 8    |                      d          d         S )Nr   r   )r   rJ  s    r#   base_dir_namez@get_top_level_dir_from_compressed_package.<locals>.base_dir_name  s    s##A&&r%   )r
   namelistMAC_OS_ZIP_HIDDEN_DIR_NAME)r7  package_ziptop_level_directoryrL  rN  rK  dir_names          r#   )get_top_level_dir_from_compressed_packagerT    s     ,,,K$ $ $' ' ' !))++  	& ! ++ /tt )=33999&.## ! ++ }}Y/G/G#*P 0 0 tt	0 r%   base_dirrdirc           	      (   t                      5 }t          |          }t          j        t          j                            | |          t          j                            ||                     t	          j        t          j                            ||                    }|D ]T}t          j        t          j                            |||          t          j                            | |                     U	 ddd           dS # 1 swxY w Y   dS )a  
    base_dir: String path of the directory containing rdir
    rdir: String path of directory relative to base_dir whose contents should
          be moved to its base_dir, its parent directory

    Removes rdir from the filepaths of all files and directories inside it.
    In other words, moves all the files inside rdir to the directory that
    contains rdir. Assumes base_dir's contents and rdir's contents have no
    name conflicts.
    N)r   r4   r=  mover.   r&   r   listdir)rU  rV  tmp_dirextended_tmp_dirrdir_childrenchilds         r#   remove_dir_from_filepathsr^    s-    
		 3G<< 	BGLL400"',,?OQU2V2VWWW 
27<<0@$#G#GHH" 	 	EK-tU;;Xu--   	                 s   C*DDDr8  r9  r:  c           	      l   t          |          }	 t          j        |           n)# t          $ r |                    d| d           Y nw xY w|                    d|  d|            t          t          |           d          5 }|                                D ]}t          j	        
                    ||          }t          |          }	 t          j	                            ||g          }	|	                    |          s|                    d|            n(# t          $ r |                    d|            Y w xY w|                    d| d|            |                    |          }
|                    d	          rt          j        |d
           t          j	                            |          }|rt          j        |d
           |                    |          5 }t'          |d          5 }t)          j        ||           ddd           n# 1 swxY w Y   ddd           n# 1 swxY w Y   |
j        r!|
j        dz	  }|rt          j        ||           	 ddd           n# 1 swxY w Y   |rt1          |           }|ut          t          j	        
                    |t2                              }t          j	                            |          rt)          j        |           t9          ||           |r#t;          |                                            dS dS )a  
    Unzip the compressed package contained at package_path to target_dir.

    If remove_top_level_directory is True and the top level consists of a
    a single directory (or possibly also a second hidden directory named
    __MACOSX at the top level arising from macOS's zip command), the function
    will automatically remove the top-level directory and store the contents
    directly in target_dir.

    Otherwise, if remove_top_level_directory is False or if the top level
    consists of multiple files or directories (not counting __MACOS),
    the zip contents will be stored in target_dir.

    Args:
        package_path: String path of the compressed package to unzip.
        target_dir: String path of the directory to store the unzipped contents.
        remove_top_level_directory: Whether to remove the top-level directory
            from the zip contents.
        unlink_zip: Whether to unlink the zip file stored at package_path.
        logger: Optional logger to use for logging.

    zDirectory at z already existsz
Unpacking r5  r   zSkipping unsafe path in zip: z)Skipping path on different drive in zip: zExtracting r   T)exist_okwbN   )r4   r.   mkdirFileExistsErrorr   r}   r
   r+   rO  r&   r   
commonpathr1   r   r   getinfor   makedirsdirnamerz   r=  copyfileobjexternal_attrchmodrT  rP  isdirr>  r^  r   r(  )r7  r8  r9  r:  r]   extended_target_dirzip_refmembermember_pathcommonzip_info
parent_dirsourcetargetmoderR  	macos_dirs                    r#   rC  rC    s7   < 3:>>A
$%%%% A A A?J???@@@@@A LLElEE0CEEFFF	\""C	(	( .4G &&(( *	4 *	4F',,':FCCK2;??K
++-@+,NOO(()<== NN#K6#K#KLLL    S6SSTTT
 LL@v@@;@@AAA v..H s## 4K$77777  W__[99
 ;K
T:::: \\&)) 7VT+t5L5L 7PV&vv6667 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
 ) 4#1R7D 4d333U*	4	.4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4^ " PGUU* 1Z)CDD I w}}Y'' )i((( &&9;NOOO $\!!#####$ $s   & #AAAI<ADI<"EI<EB,I<0H:H#	H:#H''H:*H'+H:.I<:H>>I<H>-I<<J J c                    d}t          t          ||                     }t          t          |          dz             5  |                    d          }|                                r`|                                r6|                                s"t          j	        t          |                     n|
                                 d}ddd           n# 1 swxY w Y   |S )zDeletes a specific URI from the local filesystem.

    Args:
        pkg_uri: URI to delete.

    Returns:
        bool: True if the URI was successfully deleted, else False.
    Fr4  r-  TN)r   r   r   r+   r.  r  rg   
is_symlinkr=  r>  r(  )r   r   deletedr&   s       r#   delete_packager{  5  s    G8899D	#d))g%	&	&  ##;;== 	{{}} T__%6%6 c$ii((((G               Ns   B
CCC	wheel_uric           
        K   dd| d| g}|                     dt          |                     	 t          ||          \  }}t          |           }|                                rJ|                                rt          j        |            n!t          |                                            |dk    rMt          |                                          rt          j        |           t          d|  d| d|           d	S # t          |           }|                                rJ|                                rt          j        |            n!t          |                                            |dk    rMt          |                                          rt          j        |           t          d|  d| d|           w xY w)
zHInstall packages in the wheel URI, and then delete the local wheel file.pipinstallz	--target=z,Running py_modules wheel install command: %sr   z#Failed to install py_modules wheel zto z:
N)
r   r+   r   r   r  rg   r=  r>  r(  r   )r|  r8  r]   pip_install_cmd	exit_codeoutputwheel_uri_paths          r#   install_wheel_packager  M  s      	 J  	O KK>O@T@TUUU5ovNN	6i  "" 	)$$&& )i((((Y&&(((>>J&&(( *j))).i . . . .%+. .   > i  "" 	)$$&& )i((((Y&&(((>>J&&(( *j))).i . . . .%+. .      s   D CGr9   )]rA   ru   loggingr.   r=  r,   r%  pathlibr   tempfiler   typingr   r   r   r   urllib.parser	   zipfiler
   filelockr   ray._private.path_utilsr   ray._private.ray_constantsr   r   r   $ray._private.runtime_env.conda_utilsr   !ray._private.runtime_env.protocolr    ray._private.thirdparty.pathspecr   ray._rayletr   ray.experimental.internal_kvr   r   r   ray.util.annotationsr   	getLoggerrJ   r!  r   r   r   r   r   r  r   r@  rP  r!   r+   r$   r4   r6   rW   rY   boolLoggerri   r   r   r   r   r   r   r   r   r   r   rb   r   r   r   r  r	  r  r  r  r  r"  r+  r0  rG  rT  r^  rC  r{  r  rN   r%   r#   <module>r     s

      				  



        ' ' ' ' ' ' 2 2 2 2 2 2 2 2 2 2 2 2 ! ! ! ! ! !             + + + + + +         
 K J J J J J 6 6 6 6 6 6 5 5 5 5 5 5 ! ! ! ! ! !         
 . - - - - -""8,, %  sJNN.0IJJ    . 0 0 2 (  5  S        
$&3 $&3 $& $& $& $&N       $U 5 U     (6" "
"8n" " 	"
 W^$" " " "P (6      W^$  	       L (6+ +++ W^$+ 	+ + + +( (6 
 x  	
 W^$    89 9 9 9 9 9+$s +$uXs]3 +$ +$ +$ +$\'C 'D ' ' ' ''C 'D ' ' ' ''C 'D ' ' ' ' S	 h    4 c hx6H    > (6" "
"" W^$" 
(^	" " " "J DH = = =S =8C= =D = = = =J (6. ..
. W^$. 		. . . .b2C 2# 2# 2 2 2 2  %'52
 2
2
3i2
 2
 	2

 2
 W^$2
 
2
 2
 2
 2
jKC KD K K K K 
 
# 
 
 
 
 3 3    H %)- --- tCy!- 		- - - -`K3 K5 KT K K K K:  %$('5
 


 
 	

 tCy!
 W^$
 
 
 
>  %$('5? ??? ? 	?
 ? tCy!? W^$? 
? ? ? ?D S T      '+'5y yyy #y W^$	y
 y 	y y y yx'C ' ' ' 'T 3    H (6e$ e$e$e$ !%e$ 	e$
 W^$e$ 
e$ e$ e$ e$PC  tSy9I    6 (6      W^$  
	           r%   