
    ɯei-Q                        d dl mZ d dlZd dlZd dlZd dlmZmZ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Zej&                  dk  rd dlmZ nd dlmZ d	Zd
ZddgZddgZ ej4                  e      Z G d de      Zy)    )annotationsN)	RawIOBaseUnsupportedOperationBufferedReaderSEEK_SETSEEK_ENDSEEK_CUR)SNOWFLAKE_PATH_PREFIXES)Sequence)get_active_session)   	   )IterablezISnowflakeFile currently doesn't support write APIs in local testing mode.z/Not yet supported in UDF and Stored Procedures.rrbwwbc                  Z    e Zd ZdZ	 	 d!ddd	 	 	 	 	 	 	 	 	 	 	 d" fdZe	 	 d!dd	 	 	 	 	 	 	 	 	 d#d       Zed$d%d       Zd&d	Zd&d
Z	d&dZ
d'dZd&dZd&dZd(dZd&dZd)dZd*d+dZd*d+dZd)dZd,dZd'dZd'dZd*d+dZd*d-dZefd.dZd)dZd(dZd/d0dZd'dZd)dZd1d Z  xZ!S )2SnowflakeFilea  
    SnowflakeFile provides an interface to operate on files as Python IOBase-like objects in UDFs and stored procedures.
    SnowflakeFile supports most operations supported by Python IOBase objects.
    A SnowflakeFile object can be used as a Python IOBase object.

    The constructor of this class is not supposed to be called directly. Call :meth:`~snowflake.snowpark.file.SnowflakeFile.open` to create a read-only SnowflakeFile object, and call :meth:`~snowflake.snowpark.file.SnowflakeFile.open_new_result` to create a write-only SnowflakeFile object.

    This class is used to read and write files in UDFs and stored procedures. On Snowflake, it is used to read and write stage files. It also
    supports Python IOBase and BufferedBase methods such as :meth:`read`, :meth:`write`, :meth:`close`.

    To read from a staged file, use the following API:

    Example::
        >>> from snowflake.snowpark.files import SnowflakeFile
        >>> from snowflake.snowpark.functions import udf
        >>> @udf
        ... def read_file(url: str) -> str:
        ...     file = SnowflakeFile.open(url, "r")
        ...     return file.read()

    To write to a staged file first write to a result file via the following example.
    The result file will return as a scoped URL which can be copied to a permanent stage
    with `copy files <https://docs.snowflake.com/en/sql-reference/sql/copy-files>`_ or read directly via another call to SnowflakeFile.read() in another UDF invocation.
    See `writing files from Snowpark Python UDFs <https://docs.snowflake.com/en/developer-guide/snowpark/python/creating-udfs#label-snowpark-python-udf-write-files>`_ for more details.

    Example::
        >>> from snowflake.snowpark.files import SnowflakeFile
        >>> from snowflake.snowpark.functions import udf
        >>> @udf
        ... def write_file(content: str) -> str:
        ...     file = SnowflakeFile.open_new_result("w")
        ...     file.write(content)
        ...     return file # file must be returned to be accessible

    These examples are using the client, but this same pattern can be used inside SQL-defined UDFs.

    We provide a local implementation of SnowflakeFile to aid in local testing.
    This currently supports using read APIs on relative paths, mocked stages
    (sessions in local testing mode that aren't connected to a real stage), and Snowflake stages.
    Scoped and Stage URLs (https://) are not yet supported.

    Note:
        1. All of the implementation in this file is for local testing purposes.

        2. There may be slight implementation differences between local testing and Snowflake execution environments, which we call out below when we can.
        If any issues or these differences block your testing workflow, please file a bug report at https://github.com/snowflakedb/snowpark-python/issues.

        3. UDF implementation is dependent on the Snowflake release. Therefore, this documentation may not always be up to date.
    FTrequire_scoped_urlfrom_result_apic               
   t         	|           || _        || _        || _        || _        d | _        d | _        d | _        d}d| _	        | j                  j                  d      rt        d      | j                  j                  t        t                    rdnd| _        | j                   | _        d| _        | j                  r|t"        v r||dk(  rdnd }t%        t'        | j                  | j                  |	      |      | _        t'        | j                  d
      }|j+                  dt,              | _        |j/                          y | j                  r|t"        v rxt1               j2                  j5                  | j                        | _        | j(                  j+                  dt,              | _        | j(                  j+                  dt6               y |t8        v r&t'        | j                  | j                        | _        y y )Ni   r   zhttps://z,Scoped and Stage URLs are not yet supported.TFr   zutf-8)encodingr   )super__init___file_location_mode_is_owner_file_require_scoped_urlbufferr   errors_pos
startswith
ValueErrortupler
   _is_stage_file_is_local_file
_file_size_READ_MODESr   open_file_streamseekr   closer   file
get_streamr   _WRITE_MODES)
selffile_locationmodeis_owner_filer   r   _DEFAULT_READ_BUFFER_SIZEr   	temp_file	__class__s
            Z/var/www/html/glpi_dashboard/venv/lib/python3.12/site-packages/snowflake/snowpark/files.pyr   zSnowflakeFile.__init___   s    	#0
+#5   %.!	))*5KLL ""--e4K.LM  	
 #'"5"554;#6"&#+w4H .T(($**xH)!D T00$7I'nnQ9DOOO  T[%8 2 4 9 9 D D##!D #//44QADO""1h/\! $T%8%8$** ED "    r   c               H    |t         vrt        d| d       | ||||      S )af  
        Used to create a :class:`~snowflake.snowpark.file.SnowflakeFile` which can only be used for read-based IO operations on the file.

        In UDFs and Stored Procedures, the object works like a read-only Python IOBase object and as a wrapper for an IO stream of remote files.

        All files are accessed in the context of the UDF owner (with the exception of caller's rights stored procedures which use the caller's context).
        UDF callers should use scoped URLs to allow the UDF to access their files. By accepting only scoped URLs the UDF owner can ensure
        the UDF caller had access to the provided file. Removing the requirement that the URL is a scoped URL (require_scoped_url=False) allows the caller
        to provide URLs that may be only accessible by the UDF owner.

        is_owner_file is marked for deprecation. For Snowflake release 7.8 and onwards please use require_scoped_url instead.

        Args:
            file_location: scoped URL, file URL, or string path for files located in a stage
            mode: A string used to mark the type of an IO stream. Supported modes are "r" for text read and "rb" for binary read.
            is_owner_file: (Deprecated) A boolean value, if True, the API is intended to access owner's files and all URI/URL are allowed. If False, the API is intended to access files passed into the function by the caller and only scoped URL is allowed.
            require_scoped_url: A boolean value, if True, file_location must be a scoped URL. A scoped URL ensures that the caller cannot access the UDF owners files that the caller does not have access to.
        Invalid mode 'z;' for SnowflakeFile.open. Supported modes are 'r' and 'rb'.r;   )r*   r%   )clsr3   r4   r5   r   s        r9   r+   zSnowflakeFile.open   s?    6 {" &ab  4CU
 	
r:   c                    |t         vrt        d| d       | t        j                         j                  |dd      S )a>  
        Used to create a :class:`~snowflake.snowpark.file.SnowflakeFile` which can only be used for write-based IO operations. UDFs/Stored Procedures should return the file to materialize it, and it is then made accessible via a scoped URL returned in the query results.

        In UDFs and Stored Procedures, the object works like a write-only Python IOBase object and as a wrapper for an IO stream of remote files.

        Args:
            mode: A string used to mark the type of an IO stream. Supported modes are "w" for text write and "wb" for binary write.
        r=   zF' for SnowflakeFile.open_new_result. Supported modes are 'w' and 'wb'.r   Tr   )r1   r%   tempfileNamedTemporaryFilename)r>   r4   s     r9   open_new_resultzSnowflakeFile.open_new_result   sP     |# &lm  '')..  	
 	
r:   c                X    | j                   t        vrt        d| j                          y)zo
        Internal function to validate read mode of the file object before performing an IO operation.
        zNot readable mode=N)r   r*   r   r2   s    r9   _raise_if_not_readz SnowflakeFile._raise_if_not_read   s,     ::[(&);DJJ<'HII )r:   c                X    | j                   t        vrt        d| j                          y)zo
        Internal function to validate write mode of the file object before performing a IO operation.
        zNot writable mode=N)r   r1   r   rE   s    r9   _raise_if_not_writez!SnowflakeFile._raise_if_not_write   s,     ::\)&);DJJ<'HII *r:   c                F    | j                   j                  rt        d      y)zq
        Internal function to validate open status of the file object before performing an IO operation.
        zI/O operation on closed file.N)r,   closedr%   rE   s    r9   _raise_if_closedzSnowflakeFile._raise_if_closed   s$     ##<== $r:   c                    t        |      }|dk(  ry| j                  |      }t        |      }| xj                  |j                  z  c_        ||d| |j                  S )z
        Internal function to read bytes into a pre-allocated, writable bytes-like object buffer.
        This is used by readinto and readinto1 methods.
        r   N)lenread1
memoryviewr#   nbytes)r2   b
buffer_lencontentsizes        r9   _read_into_bufferzSnowflakeFile._read_into_buffer   sV    
 V
?**Z('"		T[[ 	 +:{{r:   c                8    | j                   j                          y)z
        See https://docs.python.org/3/library/io.html#io.IOBase.close

        Closes the underlying IO Stream of the SnowflakeFile.
        N)r,   r.   rE   s    r9   r.   zSnowflakeFile.close   s     	!r:   c                8    | j                          t        d      )z
        Not yet supported in UDF and Stored Procedures.

        See https://docs.python.org/3/library/io.html#io.BufferedIOBase.detach
        z)Detaching stream from file is unsupported)rK   r   rE   s    r9   detachzSnowflakeFile.detach   s     	"#NOOr:   c                8    | j                          t        d      )zd
        Getting a file descriptor number is not supported in Snowflake. Raises an OSError.
        z*This object does not use a file descriptor)rK   OSErrorrE   s    r9   filenozSnowflakeFile.fileno  s     	BCCr:   c                $    | j                          y)z=
        Fail if the stream is closed. Does nothing.
        NrK   rE   s    r9   flushzSnowflakeFile.flush  s     	r:   c                $    | j                          y)zo
        Returns False, file streams in stored procedures and UDFs are never interactive in Snowflake.
        Fr]   rE   s    r9   isattyzSnowflakeFile.isatty  s     	r:   c                r   | j                          | j                          | j                  r&| j                  j                  j                  |      }nF| j                  r:| j                  j                  |      }| j                  dk(  r|j                         }| xj                  t              z  c_	        |S )am  
        From https://docs.python.org/3/library/io.html#io.RawIOBase.read

        Read up to size bytes from the object and return them. As a convenience, if size is unspecified or -1,
        all bytes until EOF are returned.
        Fewer than size bytes may be returned.

        If 0 bytes are returned, and size was not 0, this indicates end of file.
        r   )rK   rF   r(   r,   rawreadr'   r   decoder#   rM   r2   rT   rS   s      r9   rc   zSnowflakeFile.read  s     	!''++006G  '',,T2GzzS !..*		S\!	r:   c                   | j                          | j                          | j                  rZ| j                  dk(  r | j	                  |      j                         }nR| j                  dk(  rC| j                  j                  |      }n'| j                  r| j                  j                  |      }| xj                  t              z  c_	        |S )uQ  
        From https://docs.python.org/3/library/io.html#io.BufferedIOBase.read1

        Read and return up to size bytes, with at most one call to the underlying raw stream’s read() (or readinto()) method.

        If size is -1 (the default), an arbitrary number of bytes are returned (more than zero unless EOF is reached).
        r   r   )rK   rF   r(   r   rc   encoder,   rN   r'   r#   rM   re   s      r9   rN   zSnowflakeFile.read12  s     	!zzS ))D/002t#++11$7  ''--d3G		S\!	r:   c                V    | j                          | j                  j                         S )z
        From https://docs.python.org/3/library/io.html#io.IOBase.readable

        Returns whether or not the stream is readable.
        )rK   r,   readablerE   s    r9   ri   zSnowflakeFile.readableF  %     	  ))++r:   c                $    | j                  d      S )z
        From https://docs.python.org/3/library/io.html#io.RawIOBase.readall

        Read and return all the bytes from the stream until EOF, using multiple calls to the stream if necessary.
        )rc   rE   s    r9   readallzSnowflakeFile.readallO  s     yy
 	
r:   c                b   | j                          | j                          | j                  rF| j                  dk(  r| j	                  |      S | j
                  j                  j                  |      }n'| j                  r| j
                  j                  |      }| xj                  z  c_	        |S )z
        From https://docs.python.org/3/library/io.html#io.RawIOBase.readinto

        Read bytes into a pre-allocated, writable bytes-like object b, and return the number of bytes read. For example, b might
        be a bytearray.
        r   )
rK   rF   r(   r   rU   r,   rb   readintor'   r#   r2   rQ   rT   s      r9   ro   zSnowflakeFile.readintoY  s     	!zzS --a00$$((11!4D  $$--a0D		T	r:   c                N   | j                          | j                          | j                  r<| j                  dk(  r| j	                  |      S | j
                  j                  |      }n'| j                  r| j
                  j                  |      }| xj                  z  c_        |S )z
        From https://docs.python.org/3/library/io.html#io.BufferedIOBase.readinto1

        Read bytes into a pre-allocated, writable bytes-like object b. Return the number of bytes read.
        r   )	rK   rF   r(   r   rU   r,   	readinto1r'   r#   rp   s      r9   rr   zSnowflakeFile.readinto1k  s     	!zzS --a00$$..q1D  $$..q1D		T	r:   c                r   | j                          | j                          | j                  r&| j                  j                  j                  |      }nF| j                  r:| j                  j                  |      }| j                  dk(  r|j                         }| xj                  t              z  c_	        |S )z
        From https://docs.python.org/3/library/io.html#io.IOBase.readline

        Read and return one line from the stream. If size is specified, at most size bytes will be read.
        r   )rK   rF   r(   r,   rb   readliner'   r   rd   r#   rM   re   s      r9   rt   zSnowflakeFile.readline|  s     	!''++44T:G  ''006GzzS !..*		S\!	r:   c                   | j                          | j                          | j                  r&| j                  j                  j                  |      }nS| j                  rG| j                  j                  |      }| j                  dk(  r|D cg c]  }|j                          }}| xj                  t        d D              z  c_	        |S c c}w )u  
        From https://docs.python.org/3/library/io.html#io.IOBase.readlines

        Read and return a list of lines from the stream. hint can be specified to control the number of lines read: no more
        lines will be read if the total size (in bytes/characters) of all lines so far exceeds hint.

        hint values of 0 or less, as well as None, are treated as no hint.

        Note that it’s already possible to iterate on file objects using for line in file: ... without calling file.readlines().
        r   c              3  2   K   | ]  }t        |        y wN)rM   ).0lines     r9   	<genexpr>z*SnowflakeFile.readlines.<locals>.<genexpr>  s     7tT7s   )rK   rF   r(   r,   rb   	readlinesr'   r   rd   r#   sum)r2   hintrS   ry   s       r9   r{   zSnowflakeFile.readlines  s     	!''++55d;G  ''11$7GzzS 5<=T4;;===		S7w777	 >s   Cc                ~   | j                          | j                          |t        k(  r|}nN|t        k(  r| j                  j                         |z   }n'|t        k(  r| j                  |z   }nt        d|       |dk  rt        d|       || _
        | j                  j                  | j                  t              S )a  
        See https://docs.python.org/3/library/io.html#io.IOBase.seek

        Move the stream position to a new location given an offset and a starting position. SEEK_SET/0
        indicates a position relative to the start of the file. SEEK_CUR/1 indicates a position relative
        to the current stream position. SEEK_END/2 indicates a position relative to the end of the file.
        Only supported in read mode.

        Returns the new stream position. Not supported in write mode.
        zUnsupported whence value r   zNegative seek position )rK   rF   r   r	   r,   tellr   r)   NotImplementedErrorr%   r#   r-   )r2   offsetwhenceposs       r9   r-   zSnowflakeFile.seek  s     	!XCx##((*V3Cx//F*C%(A&&JKK76se<==	  %%dii::r:   c                F    | j                          | j                  t        v S )z
        See https://docs.python.org/3/library/io.html#io.IOBase.seekable

        Returns whether or not the stream is seekable.
        )rK   r   r*   rE   s    r9   seekablezSnowflakeFile.seekable  s     	zz[((r:   c                Z    | j                          | j                          | j                  S )z
        See https://docs.python.org/3/library/io.html#io.IOBase.tell

        Gets the current stream position. Not supported in write mode.
        )rK   rF   r#   rE   s    r9   r   zSnowflakeFile.tell  s&     	!yyr:   c                `    | j                          | j                          t        t              )zA
        Not yet supported in UDF and Stored Procedures.
        )rK   rH   r   _DEFER_IMPLEMENTATION_ERR_MSG)r2   rT   s     r9   truncatezSnowflakeFile.truncate  s(     	  "!"?@@r:   c                     t        t              )a  
        See https://docs.python.org/3/library/io.html#io.RawIOBase.write

        Write the given bytes-like object, b, to the underlying raw stream, and return the number of bytes-like objects
        written (e.g. unicode characters provided to a text input count as 1). The number of bytes should equal the input
        bytes, since all bytes are written directly to the stream. Local testing support is not implemented yet.
        r   _WRITE_MODE_ERR_MSG)r2   rQ   s     r9   writezSnowflakeFile.write  s     ""566r:   c                V    | j                          | j                  j                         S )z
        See https://docs.python.org/3/library/io.html#io.IOBase.writable

        Returns whether or not the stream is writable.
        )rK   r,   writablerE   s    r9   r   zSnowflakeFile.writable  rj   r:   c                     t        t              )a+  
        From https://docs.python.org/3/library/io.html#io.IOBase.writelines

        Write a list of lines to the stream. Line separators are not added, so it is usual for each of the lines provided to
        have a line separator at the end. Local testing support is not implemented yet.
        r   )r2   liness     r9   
writelineszSnowflakeFile.writelines  s     ""566r:   )r   F)r3   strr4   r   r5   boolr   r   r   r   returnNone)
r3   r   r4   r   r5   r   r   r   r   r   )r   )r4   r   r   r   )r   r   )rQ   zbytes | bytearray | array.arrayr   int)r   r   )r   r   )rl   )rT   r   r   r   )r   r   )r}   r   r   zlist[Sequence])r   r   r   r   r   r   rw   )rT   z
int | Noner   r   )r   zIterable[str] | list[str]r   r   )"__name__
__module____qualname____doc__r   classmethodr+   rC   rF   rH   rK   rU   r.   rX   r[   r^   r`   rc   rN   ri   rm   ro   rr   rt   r{   r   r-   r   r   r   r   r   r   __classcell__)r8   s   @r9   r   r   ,   sS   0j #	;F $( %;F;F ;F 	;F !;F ;F 
;Fz  #	 
 $( 
 
  
 	 
 ! 
 
 
  
D 
 
(JJ>"PD*(,
$"", /7 ;4)A7,7r:   r   )
__future__r   arraysysr@   ior   r   r   r   r   r	   "snowflake.snowpark._internal.utilsr
   typingr   snowflake.snowpark.contextr   loggingversion_infor   collections.abcr   r   r*   r1   	getLoggerr   _loggerr    r:   r9   <module>r      s    #  
    9 
 v( P  !R DkT{
'

H
%F7I F7r:   