o
    ;ijM                     @   s  d dl Z d dlZd dlZd dlmZ d dlmZmZmZm	Z	m
Z
mZmZmZ er,d dlZd dlZd dlmZ d dlmZ d dlmZ d dlmZ dd	lmZ dd
lmZ ddlmZ ddlmZm Z m!Z! dZ"dZ#dZ$ej%j&eej%j'e(ej%j)e*ej%j+e,ej%j-e,ej%j.e/ej%j0e(ej%j1e2ej%j3e4ej%j5e6ej%j7e8ej%j9e8ej%j:e8ej%j;e8iZ<ede=e>Z?d ddde	e@ de	e@ ddfddZAd ddde>de	e@ de	e@ ddf
ddZBG dd dejCZDeG dd dZEG dd dee? ZFeeAZGeeBZHeeFZIdS )!    N)	dataclass)TYPE_CHECKINGAsyncIteratorGenericOptionalSequenceTypeVarUnioncast)StreamTerminatedError)TaskContext)ClientClosed)api_pb2   )synchronize_apideprecation_error)_Client)FilesystemExecutionErrorInternalErrorServiceErrori   i   @i  @Tfile_FileIOstartendreturnc                       t dd dS )2mdmd:hidden
    This method has been removed.
    i        zdelete_bytes has been removed.Nr   )r   r   r    r"   A/home/ubuntu/.local/lib/python3.10/site-packages/modal/file_io.py_delete_bytes0      r$   datac                    r   )r   r   zreplace_bytes has been removed.Nr   )r   r&   r   r   r"   r"   r#   _replace_bytes7   r%   r'   c                   @   s    e Zd ZdZdZdZdZdZdS )FileWatchEventTypeUnknownAccessCreateModifyRemoveN)__name__
__module____qualname__r)   r*   r+   r,   r-   r"   r"   r"   r#   r(   >   s    r(   c                   @   s"   e Zd ZU ee ed< eed< dS )FileWatchEventpathstypeN)r.   r/   r0   liststr__annotations__r(   r"   r"   r"   r#   r1   F   s   
 r1   c                   @   s  e Zd ZU dZdZdZdZdZdZdZ	e
ed< dZe
ed< eed< g Zeeee ef  ed< d	ed
e
ddfddZde
ddfddZde
deeee ef  fddZde
ddfddZdedee fddZde
defddZdeee
f ddfddZde
de
ddfd d!Zede
ded" d	ed
e
dd f
d#d$Zd%ee  defd&d'Z!dSd%ee  de"fd(d)Z#de"fd*d+Z$de%e" fd,d-Z&deee
f ddfd.d/Z'dTd0d1Z(d2e fd3d4Z)dUd6e d2e ddfd7d8Z*ede
d	ed
e
dee
 fd9d:Z+edVde
d	ed
e
d;e,ddf
d<d=Z-edVde
d	ed
e
d>e,ddf
d?d@Z.e			dWde
d	ed
e
dAeee/  d>e,dBee  dee fdCdDZ0dTdEdFZ1dTdGdHZ2dTdIdJZ3dTdKdLZ4dTdMdNZ5dXdOdPZ6dTdQdRZ7dS )Yr   a  [Alpha] FileIO handle, used in the Sandbox filesystem API.

    The API is designed to mimic Python's io.FileIO.

    Currently this API is in Alpha and is subject to change. File I/O operations
    may be limited in size to 100 MiB, and the throughput of requests is
    restricted in the current implementation. For our recommendations on large file transfers
    see the Sandbox [filesystem access guide](https://modal.com/docs/guide/sandbox-files).

    **Usage**

    ```python notest
    import modal

    app = modal.App.lookup("my-app", create_if_missing=True)

    sb = modal.Sandbox.create(app=app)
    f = sb.open("/tmp/foo.txt", "w")
    f.write("hello")
    f.close()
    ```
    FT _task_id_file_descriptor_client_watch_output_bufferclienttask_idr   Nc                 C   s   || _ || _g | _d S N)r:   r8   r;   )selfr<   r=   r"   r"   r#   __init__q   s   
z_FileIO.__init__modec                    s   t  fdddD std  d v pd v | _d v p*d v p*d	 v p*d v | _d v | _d
 v | _tdt fdd D rLtd  tdd  D }|dkr]tdt } D ]}||v rotd  || qbd S )Nc                 3   s    | ]}| v V  qd S r>   r"   .0char)rA   r"   r#   	<genexpr>w       z)_FileIO._validate_mode.<locals>.<genexpr>rwaxzInvalid file mode: r+waxbzrwaxb+c                 3   s    | ]}| vV  qd S r>   r"   rB   )valid_charsr"   r#   rE      rF   c                 s   s    | ]	}|d v rdV  qdS )rG   r   Nr"   )rC   cr"   r"   r#   rE      s    r   z6must have exactly one of create/read/write/append mode)	any
ValueError	_readable	_writable	_appended_binarysetsumadd)r?   rA   
mode_count
seen_charsrD   r"   )rA   rN   r#   _validate_modev   s$   "

z_FileIO._validate_modeexec_idc                 C  s   t j|dd}| jjj|2 z,3 d H W }|jrd V   d S |dr3t	|j
jt}||j
jV  |jD ]}|V  q6q6 d S )N7   )r\   timeouterror)r   'ContainerFilesystemExecGetOutputRequestr:   stub ContainerFilesystemExecGetOutputunary_streameofHasFieldERROR_MAPPINGgetr_   
error_coder   error_messageoutput)r?   r\   reqbatcherror_classmessager"   r"   r#   _consume_output   s    

z_FileIO._consume_outputc                    s   d}d}|sqz|  |}|2 z3 d H W }| j| |d u r#d} nq6 W nF ttttfyl } z6|dkrf|d8 }t|ttfrOt	dI d H  W Y d }~qt|trZW Y d }~qt|trfW Y d }~d S |d }~ww |rd S d S NF
   Tr   r   g      ?)
ro   r;   appendr   r   r   r   
isinstanceasynciosleep)r?   r\   	completedretries_remainingiteratorrn   excr"   r"   r#   _consume_watch_output   s8   


z_FileIO._consume_watch_outputeventc              
      sH   zt | }tt|d |d dW S  t jttfy#   Y d S w )N
event_typer2   r3   r2   )jsonloadsdecoder1   r(   JSONDecodeErrorKeyErrorrQ   )r?   r{   
event_jsonr"   r"   r#   _parse_watch_output   s   z_FileIO._parse_watch_outputc              
      s   t  }d}d}|siz#| |2 z3 d H W }|d u rd} nt|tr&||| q6 W n8 tttfyf } z)|dkra|d8 }t|ttfrVt	
dI d H  W Y d }~q	t|traW Y d }~q	 d }~ww |r| S rp   )ioBytesIOro   rs   	Exceptionwriter   r   r   rt   ru   getvalue)r?   r\   output_bufferrv   rw   r&   ry   r"   r"   r#   _wait   s8   

z_FileIO._waitr&   c                 C   s8   | j rt|trtd| j st|trtdd S d S )Nz"Expected bytes when in binary modezExpected str when in text mode)rU   rs   r5   	TypeErrorbytes)r?   r&   r"   r"   r#   _validate_type   s
   z_FileIO._validate_typepathc                    s\   | j jtjtj||d| jdI d H }|dstd|j	| _
| |jI d H  d S )N)r   rA   )file_open_requestr=   file_descriptorzFailed to open file)r:   ra   ContainerFilesystemExecr   ContainerFilesystemExecRequestContainerFileOpenRequestr8   re   r   r   r9   r   r\   )r?   r   rA   respr"   r"   r#   
_open_file   s   

z_FileIO._open_file)z_typeshed.OpenTextModez_typeshed.OpenBinaryModec                    s2   t ||}|| |||I dH  d|_|S )zCreate a new FileIO handle.NF)r   r[   r   _closed)clsr   rA   r<   r=   r?   r"   r"   r#   create   s   

z_FileIO.createnc                    s@   | j jtjtj| j|d| jdI d H }| |j	I d H S )N)r   r   )file_read_requestr=   )
r:   ra   r   r   r   ContainerFileReadRequestr9   r8   r   r\   )r?   r   r   r"   r"   r#   _make_read_request   s   
z_FileIO._make_read_requestc                    sZ   |    |   |dur|tkrtd| |I dH }| jr%tt|S tt|dS )zRRead n bytes from the current position, or the entire remaining file if n is None.Nz*Read request payload exceeds 100 MiB limitutf-8)	_check_closed_check_readableREAD_FILE_SIZE_LIMITrQ   r   rU   r
   r   r   )r?   r   rj   r"   r"   r#   read   s   
z_FileIO.readc                    sn   |    |   | jjtjtj| jd| j	dI dH }| 
|jI dH }| jr/tt|S tt|dS )z-Read a single line from the current position.r   )file_read_line_requestr=   Nr   )r   r   r:   ra   r   r   r   ContainerFileReadLineRequestr9   r8   r   r\   rU   r
   r   r   )r?   r   rj   r"   r"   r#   readline  s   

z_FileIO.readlinec                    s   |    |   | dI dH }| jr6|d}dd |dd D |d r,|d gng  }ttt |S |dd}dd |dd D |d rQ|d gng  }ttt |S )	z)Read all lines from the current position.N   
c                 S      g | ]}|d  qS )r   r"   rC   liner"   r"   r#   
<listcomp>      z%_FileIO.readlines.<locals>.<listcomp>r   
c                 S   r   )r   r"   r   r"   r"   r#   r   !  r   )	r   r   r   rU   splitr
   r   r   r   )r?   rj   lines_bytesreturn_byteslinesreturn_strsr"   r"   r#   	readlines  s   
,,z_FileIO.readlinesc                    s   |    |   | | t|tr|d}t|tkr"tdt	dt|t
D ])}|||t
  }| jjtjtj| j|d| jdI dH }| |jI dH  q*dS )zWrite data to the current position.

        Writes may not appear until the entire buffer is flushed, which
        can be done manually with `flush()` or automatically when the file is
        closed.
        r   z)Write request payload exceeds 1 GiB limitr   )r   r&   )file_write_requestr=   N)r   _check_writabler   rs   r5   encodelenWRITE_FILE_SIZE_LIMITrQ   rangeWRITE_CHUNK_SIZEr:   ra   r   r   r   ContainerFileWriteRequestr9   r8   r   r\   )r?   r&   ichunkr   r"   r"   r#   r   $  s*   



	z_FileIO.writec                    sR   |    |   | jjtjtj| jd| j	dI dH }| 
|jI dH  dS )zFlush the buffer to disk.r   )file_flush_requestr=   N)r   r   r:   ra   r   r   r   ContainerFileFlushRequestr9   r8   r   r\   r?   r   r"   r"   r#   flush?  s   
z_FileIO.flushwhencec                 C   s>   |dkrt jjS |dkrt jjS |dkrt jjS td| )Nr   r      zInvalid whence value: )r   
SeekWhenceSEEK_SETSEEK_CURSEEK_ENDrQ   )r?   r   r"   r"   r#   _get_whenceK  s   z_FileIO._get_whencer   offsetc              	      sT   |    | jjtjtj| j|| |d| j	dI dH }| 
|jI dH  dS )zMove to a new position in the file.

        `whence` defaults to 0 (absolute file positioning); other values are 1
        (relative to the current position) and 2 (relative to the file's end).
        )r   r   r   )file_seek_requestr=   N)r   r:   ra   r   r   r   ContainerFileSeekRequestr9   r   r8   r   r\   )r?   r   r   r   r"   r"   r#   seekU  s   

z_FileIO.seekc                    st   t ||}|jjtjtj|d|dI dH }||jI dH }zt	
|dd W S  t	jy9   tdw )z,List the contents of the provided directory.)r   )file_ls_requestr=   Nr   r2   zfailed to parse list output)r   r:   ra   r   r   r   ContainerFileLsRequestr   r\   r~   r   r   r   r   )r   r   r<   r=   r?   r   rj   r"   r"   r#   lsh  s   


z
_FileIO.lsparentsc                    L   t ||}|jjtjtj||d|jdI dH }||j	I dH  dS )zCreate a new directory.)r   make_parents)file_mkdir_requestr=   N)
r   r:   ra   r   r   r   ContainerFileMkdirRequestr8   r   r\   )r   r   r<   r=   r   r?   r   r"   r"   r#   mkdirx     

z_FileIO.mkdir	recursivec                    r   )z*Remove a file or directory in the Sandbox.)r   r   )file_rm_requestr=   N)
r   r:   ra   r   r   r   ContainerFileRmRequestr8   r   r\   )r   r   r<   r=   r   r?   r   r"   r"   r#   rm  r   z
_FileIO.rmfilterr^   c                 C  s  t ||}|jjtjtj|||d|jdI d H }dtdt	j
dtdtfdd}	t 4 I d H }
|
||j t	
 }	 t|jd
kr|jd
}|d u rRnYt|trY||| t|tseJ |	||ddrz#t|   }tt|d |d d}|r|j|v r|V  W n tjtt fy   Y nw t	
 }nt!"dI d H  q@W d   I d H  d S 1 I d H sw   Y  d S )N)r   r   timeout_secs)file_watch_requestr=   itembufferboundary_tokenr   c                 S   sL   |  dsdS t|}| |k rdS || tj |||kr$dS dS )Nr   FT)endswithr   tellr   r   r   r   )r   r   r   boundary_token_sizer"   r"   r#   end_of_event  s   
z#_FileIO.watch.<locals>.end_of_eventTr   s   

)r   r|   r2   r}   g?)#r   r:   ra   r   r   r   ContainerFileWatchRequestr8   r   r   r   boolr   create_taskrz   r\   r   r;   poprs   r   r   r~   r   r   stripr   r1   r(   r3   r   r   rQ   rt   ru   )r   r   r<   r=   r   r   r^   r?   r   r   tcitem_bufferr   r   r{   r"   r"   r#   watch  sV   





.z_FileIO.watchc                    sH   | j jtjtj| jd| jdI d H }d| _| 	|j
I d H  d S )Nr   )file_close_requestr=   T)r:   ra   r   r   r   ContainerFileCloseRequestr9   r8   r   r   r\   r   r"   r"   r#   _close  s   
z_FileIO._closec                    s   |   I dH  dS )z$Flush the buffer and close the file.Nr   r?   r"   r"   r#   close  s   z_FileIO.closec                 C      | j stdd S )Nznot writeable)rS   r   UnsupportedOperationr   r"   r"   r#   r        
z_FileIO._check_writablec                 C   r   )Nznot readable)rR   r   r   r   r"   r"   r#   r     r   z_FileIO._check_readablec                 C   s   | j rtdd S )NzI/O operation on closed file)r   rQ   r   r"   r"   r#   r     s   z_FileIO._check_closedc                    s   | S r>   r"   r   r"   r"   r#   
__aenter__  s   z_FileIO.__aenter__c                    s   |   I d H  d S r>   r   )r?   exc_type	exc_value	tracebackr"   r"   r#   	__aexit__  s   z_FileIO.__aexit__r>   )r   N)r   )F)NFN)r   r   )8r.   r/   r0   __doc__rU   rR   rS   rT   r   r8   r5   r6   r9   r   r;   r4   r	   r   r   r   r@   r[   r   ro   rz   r1   r   r   r   r   classmethodr   intr   r   r   r   r   r   r   r   r   r   r   r   r   r   r(   r   r   r   r   r   r   r   r   r"   r"   r"   r#   r   N   s   
 "
	

 ""

>




)NN)Jrt   enumr   dataclassesr   typingr   r   r   r   r   r   r	   r
   	_typeshedr~   grpclib.exceptionsr   modal._utils.async_utilsr   modal.exceptionr   modal_protor   _utils.async_utilsr   _utils.deprecationr   r<   r   	exceptionr   r   r   r   r   r   SystemErrorCodeSYSTEM_ERROR_CODE_UNSPECIFIEDSYSTEM_ERROR_CODE_PERMPermissionErrorSYSTEM_ERROR_CODE_NOENTFileNotFoundErrorSYSTEM_ERROR_CODE_IOIOErrorSYSTEM_ERROR_CODE_NXIOSYSTEM_ERROR_CODE_NOMEMMemoryErrorSYSTEM_ERROR_CODE_ACCESSYSTEM_ERROR_CODE_EXISTFileExistsErrorSYSTEM_ERROR_CODE_NOTDIRNotADirectoryErrorSYSTEM_ERROR_CODE_ISDIRIsADirectoryErrorSYSTEM_ERROR_CODE_INVALOSErrorSYSTEM_ERROR_CODE_MFILESYSTEM_ERROR_CODE_FBIGSYSTEM_ERROR_CODE_NOSPCrf   r5   r   r   r   r$   r'   Enumr(   r1   r   delete_bytesreplace_bytesFileIOr"   r"   r"   r#   <module>   s^   ($(   )