o
    ;i5                     @   sd  d dl Z d dlZd dlZd dlmZ d dlmZmZ d dlm	Z	m
Z
mZmZmZ d dlmZ d dlZd dlmZ ddlmZ dd	lmZmZmZmZmZ dd
lmZ ddlmZmZm Z m!Z!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/m0Z0 ddl1m2Z2 dZ3de4e5e6df  de4ej7 fddZ8G dd deddZ9e"e9Z:dS )    N)AsyncIterator)PathPurePosixPath)AnyBinaryIOCallableOptionalUnion)asynccontextmanager)api_pb2   )LoadContext) EPHEMERAL_OBJECT_HEARTBEAT_SLEEP_get_environment_name_Objectlive_methodlive_method_gen)Resolver)TaskContextaclosing	async_mapsync_or_async_itersynchronize_api)LARGE_FILE_LIMIT	blob_iterblob_upload_file)warn_if_passing_namespace)get_sha256_hex)check_object_name)_Client)InvalidError)	FileEntryiX  validated_network_file_systems_NetworkFileSystemreturnc                 C   s,   g }| D ]\}}| tj||jd q|S )N)
mount_pathshared_volume_id)appendr   SharedVolumeMount	object_id)r"   network_file_system_mountspathvolume r-   M/home/ubuntu/.local/lib/python3.10/site-packages/modal/network_file_system.py network_file_system_mount_protos%   s   r/   c                   @   s  e Zd ZdZeddddddedee dedee d	d f
d
dZ	e
eddefded  dee dee ded	ed  f
ddZe			d)dedee dee d	efddZed*dedee dee fddZed+dededeedef  d	efddZeded	ee fddZeded	ee fddZe		d*d eeef deeee df  deedef  fd!d"Z!e		d*d eeef deeee df  deedef  fd#d$Z"eded	e#e fd%d&Z$ed,defd'd(Z%dS )-r#   a  A shared, writable file system accessible by one or more Modal functions.

    By attaching this file system as a mount to one or more functions, they can
    share and persist data with each other.

    **Note: `NetworkFileSystem` has been deprecated and will be removed.**

    **Usage**

    ```python
    import modal

    nfs = modal.NetworkFileSystem.from_name("my-nfs", create_if_missing=True)
    app = modal.App()

    @app.function(network_file_systems={"/root/foo": nfs})
    def f():
        pass

    @app.function(network_file_systems={"/root/goo": nfs})
    def g():
        pass
    ```

    Also see the CLI methods for accessing network file systems:

    ```
    modal nfs --help
    ```

    A `NetworkFileSystem` can also be useful for some local scripting scenarios, e.g.:

    ```python notest
    nfs = modal.NetworkFileSystem.from_name("my-network-file-system")
    for chunk in nfs.read_file("my_db_dump.csv"):
        ...
    ```
    NF)	namespaceenvironment_namecreate_if_missingclientnamer1   r2   r3   r$   c             	      sR   t d t|d dtdtdtdtt f fdd}tj|d	d
t||ddS )a  Reference a NetworkFileSystem by its name, creating if necessary.

        This is a lazy method that defers hydrating the local object with
        metadata from Modal servers until the first time it is actually
        used.

        ```python notest
        nfs = NetworkFileSystem.from_name("my-nfs", create_if_missing=True)

        @app.function(network_file_systems={"/data": nfs})
        def f():
            pass
        ```
        NetworkFileSystemz!modal.NetworkFileSystem.from_nameselfresolverload_contextexisting_object_idc              
      s   t j|j rt jnd d}z|jj|I d H }| |j|jd  W d S  t	j
jyE } z|jd dkr@td dd  d }~ww )Ndeployment_namer1   object_creation_typer   zApp has wrong entity vozAttempted to mount: `z` as a NetworkFileSystem z which already exists as a Volume)r   SharedVolumeGetOrCreateRequestr1   &OBJECT_CREATION_TYPE_CREATE_IF_MISSINGr3   stubSharedVolumeGetOrCreate_hydrater&   modal	exceptionNotFoundErrorargsr    )r6   r7   r8   r9   reqresponseexcr2   r4   r-   r.   _loadv   s"   z+_NetworkFileSystem.from_name.<locals>._loadzNetworkFileSystem()T)r1   r3   )hydrate_lazilyload_context_overrides)r   r   r#   r   r   r   str_from_loader)r4   r0   r1   r2   r3   rJ   r-   rI   r.   	from_name\   s"   


z_NetworkFileSystem.from_namecls_heartbeat_sleepc              	     s    du rt  I dH  tjtjt|d jI dH }t 4 I dH +}tj	|j
d|j fdd|d | j|j
 dddd	V  W d  I dH  dS 1 I dH sWw   Y  dS )
as  Creates a new ephemeral network filesystem within a context manager:

        Usage:
        ```python
        with modal.NetworkFileSystem.ephemeral() as nfs:
            assert nfs.listdir("/") == []
        ```

        ```python notest
        async with modal.NetworkFileSystem.ephemeral() as nfs:
            assert await nfs.listdir("/") == []
        ```
        N)r<   r1   r&   c                      s    j S N)r?   SharedVolumeHeartbeatr-   r3   requestr-   r.   <lambda>   s    z._NetworkFileSystem.ephemeral.<locals>.<lambda>)sleepTz#modal.NetworkFileSystem.ephemeral())is_another_apprep)r   from_envr   r=   OBJECT_CREATION_TYPE_EPHEMERALr   r?   r@   r   SharedVolumeHeartbeatRequestr&   infinite_loop_new_hydrated)rP   r3   r1   rQ   rG   tcr-   rU   r.   	ephemeral   s&   
.z_NetworkFileSystem.ephemeralr;   c                    sZ   t | d t|d |du rt I dH }tj| t|tjd}|j	|I dH }|j
S )zmdmd:hiddenr5   z'modal.NetworkFileSystem.create_deployedNr:   )r   r   r   r[   r   r=   r   *OBJECT_CREATION_TYPE_CREATE_FAIL_IF_EXISTSr?   r@   r&   )r;   r0   r3   r1   rV   respr-   r-   r.   create_deployed   s   

z"_NetworkFileSystem.create_deployedc                    sB   t j| |d|I d H }tj|jd}|jj|I d H  d S )N)r1   rR   )	r#   rO   hydrater   SharedVolumeDeleteRequestr)   _clientr?   SharedVolumeDelete)r4   r3   r1   objrF   r-   r-   r.   delete   s   z_NetworkFileSystem.deleteremote_pathfpprogress_cb.c                    s   |pdd }t |}|dtj | }|d |tkrB|||d}t|| jjt	
|||dI dH }tj| j|||dd}n| }	tj| j||	dd	}t }
t |
 tk rt| jj|I dH }|jrl	 |S t |
 tk s\tjd
| d)a)  Write from a file object to a path on the network file system, atomically.

        Will create any needed parent directories automatically.

        If remote_path ends with `/` it's assumed to be a directory and the
        file will be uploaded with its current name to that directory.
        c                  _   s   d S rS   r-   )___r-   r-   r.   rW      s    z/_NetworkFileSystem.write_file.<locals>.<lambda>r   )r4   size)progress_report_cb
sha256_hexNT)r&   r+   data_blob_idrr   	resumable)r&   r+   datart   zUploading of z
 timed out)r   seekosSEEK_ENDtellr   r   rg   r?   	functoolspartialr   SharedVolumePutFileRequestr)   readtime	monotonic+NETWORK_FILE_SYSTEM_PUT_FILE_CLIENT_TIMEOUTSharedVolumePutFileexistsrB   rC   TimeoutError)r6   rk   rl   rm   sha_hash	data_sizeprogress_task_idblob_idrF   ru   t0rG   r-   r-   r.   
write_file   sB   	


z_NetworkFileSystem.write_filer+   c              
   C  s   t j| j|d}z| jj|I dH }W n tjjy* } zt	|j
d d}~ww |ddkr8|jV  dS t|j| jj2 z	3 dH W }|V  q@6 dS )z(Read a file from the network file systemr&   r+   Nr   
data_oneofru   )r   SharedVolumeGetFileRequestr)   rg   r?   SharedVolumeGetFilerB   rC   rD   FileNotFoundErrorrE   
WhichOneofru   r   rs   )r6   r+   rF   rG   rH   ru   r-   r-   r.   	read_file   s   z_NetworkFileSystem.read_filec                 C  sN   t j| j|d}| jjj|2 z3 dH W }|jD ]}t	|V  qq6 dS )a  Iterate over all files in a directory in the network file system.

        * Passing a directory path lists all files in the directory (names are relative to the directory)
        * Passing a file path returns a list containing only that file's listing description
        * Passing a glob path (including at least one * or ** sequence) returns all files matching
        that glob path (using absolute paths)
        r   N)
r   SharedVolumeListFilesRequestr)   rg   r?   SharedVolumeListFilesStreamunary_streamentriesr!   _from_proto)r6   r+   rF   batchentryr-   r-   r.   iterdir  s   	
z_NetworkFileSystem.iterdir
local_pathc                    st   t |}|d u rtd|j }nt| }|d}| j|||dI d H W  d    S 1 s3w   Y  d S )N/rb)rm   )r   r   r4   as_posixopenr   )r6   r   rk   rm   
local_filer-   r-   r.   add_local_file  s   $z!_NetworkFileSystem.add_local_filec              	      s   t | d u rtd j nt   sJ  fdd}dtt tf dtffdd}ttt	| |dd	4 I d H }|2 z3 d H W }qH6 W d   I d H  d S 1 I d H saw   Y  d S )
Nr   c                  3   s>      dD ]} |  rq|   }| t|fV  qd S )N*)rglobis_dirrelative_tor   r   )subpathrelpath_str)_local_pathrk   r-   r.   gen_transfers:  s   z7_NetworkFileSystem.add_local_dir.<locals>.gen_transferspathsr$   c                    s    | d | d  I d H S )Nr   r   )r   )r   )rm   r6   r-   r.   _add_local_fileA  s   z9_NetworkFileSystem.add_local_dir.<locals>._add_local_file   )concurrency)
r   r   r4   r   r   tupleintr   r   r   )r6   r   rk   rm   r   r   streamrn   r-   )r   rm   rk   r6   r.   add_local_dir+  s    ".z _NetworkFileSystem.add_local_dirc                    s   dd |  |2 I dH S )a  List all files in a directory in the network file system.

        * Passing a directory path lists all files in the directory (names are relative to the directory)
        * Passing a file path returns a list containing only that file's listing description
        * Passing a glob path (including at least one * or ** sequence) returns all files matching
        that glob path (using absolute paths)
        c                    s   g | z3 d H W }|q6 S rS   r-   ).0r   r-   r-   r.   
<listcomp>Q  s    z._NetworkFileSystem.listdir.<locals>.<listcomp>N)r   )r6   r+   r-   r-   r.   listdirH  s   	z_NetworkFileSystem.listdirc              
      sZ   t j| j||d}z| jj|I dH  W dS  tjjy, } zt	|j
d d}~ww )z'Remove a file in a network file system.)r&   r+   	recursiveNr   )r   SharedVolumeRemoveFileRequestr)   rg   r?   SharedVolumeRemoveFilerB   rC   rD   r   rE   )r6   r+   r   rF   rH   r-   r-   r.   remove_fileS  s   z_NetworkFileSystem.remove_file)NNN)NNrS   )F)&__name__
__module____qualname____doc__staticmethodrM   r   boolr   rO   classmethodr
   r   typefloatr   ra   rd   rj   r   r   r   r   r   r   r   bytesr   r!   r   r	   r   r   r   r   listr   r   r-   r-   r-   r.   r#   4   s    '2%"*-


sv)type_prefix);rz   rw   r~   collections.abcr   pathlibr   r   typingr   r   r   r   r	   synchronicity.async_wrapr
   rB   modal_protor   _load_contextr   _objectr   r   r   r   r   	_resolverr   _utils.async_utilsr   r   r   r   r   _utils.blob_utilsr   r   r   _utils.deprecationr   _utils.hash_utilsr   _utils.name_utilsr   r3   r   rC   r    r,   r!   r   r   r   rM   r(   r/   r#   r5   r-   r-   r-   r.   <module>   s>   
  +