§
    y›j2  ã                  óâ  — d Z ddlmZ ddl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mZ ddlmZ erdd	lmZ  e
d
d¦  «        j        Z	 dZdZdZ G d„ de¦  «        Z G d„ de¦  «        Z G d„ de¦  «        Z G d„ de¦  «        Z G d„ de¦  «        Z G d„ de¦  «        Z G d„ de¦  «        ZdZ ed¬¦  «        Zd;d#„Z d<d'„Z! G d(„ d)¦  «        Z" G d*„ d+¦  «        Z#	 	 d=eded-œd>d:„Z$dS )?u+  PEP 249 (DB API 2.0) interface for Logfire query data.

This module provides a DB API 2.0 compatible interface wrapping the
`LogfireQueryClient`, enabling Logfire query data to work with any tool that
supports DB API 2.0 connections â€” e.g. marimo SQL cells, pandas `read_sql()`,
and Jupyter `%%sql` magic.

Usage:
    import logfire.db_api

    conn = logfire.db_api.connect(read_token='pylf_v1_us_...')
    cursor = conn.cursor()
    cursor.execute('SELECT start_timestamp, message FROM records LIMIT 10')
    rows = cursor.fetchall()
    conn.close()
é    )ÚannotationsN)ÚSequence)ÚdatetimeÚ	timedeltaÚtimezone)ÚEnum)ÚTYPE_CHECKINGÚAny)ÚLogfireQueryClient)ÚColumnDetailsÚ_UNSETÚUNSETz2.0é   Úpyformatc                  ó   — e Zd ZdZdS )ÚWarningz>Exception raised for important warnings, e.g. data truncation.N©Ú__name__Ú
__module__Ú__qualname__Ú__doc__© ó    úK/home/lighthouse/health/venv/lib/python3.11/site-packages/logfire/db_api.pyr   r   0   ó   € € € € € ØHÐHÐHÐHr   r   c                  ó   — e Zd ZdZdS )ÚErrorz!Base class for all DB API errors.Nr   r   r   r   r   r   4   s   € € € € € Ø+Ð+Ð+Ð+r   r   c                  ó   — e Zd ZdZdS )ÚInterfaceErrorz>Exception raised for errors related to the database interface.Nr   r   r   r   r   r   8   r   r   r   c                  ó   — e Zd ZdZdS )ÚDatabaseErrorz4Exception raised for errors related to the database.Nr   r   r   r   r!   r!   <   s   € € € € € Ø>Ð>Ð>Ð>r   r!   c                  ó   — e Zd ZdZdS )ÚOperationalErrorz@Exception raised for errors related to the database's operation.Nr   r   r   r   r#   r#   @   s   € € € € € ØJÐJÐJÐJr   r#   c                  ó   — e Zd ZdZdS )ÚProgrammingErrorzOException raised for programming errors, e.g. bad SQL or using a closed cursor.Nr   r   r   r   r%   r%   D   s   € € € € € ØYÐYÐYÐYr   r%   c                  ó   — e Zd ZdZdS )ÚNotSupportedErrorz<Exception raised when an unsupported operation is attempted.Nr   r   r   r   r'   r'   H   s   € € € € € ØFÐFÐFÐFr   r'   i'  )ÚdaysÚvaluer
   ÚreturnÚstrc                óJ  — | €dS t          | t          ¦  «        r| rdndS t          | t          t          f¦  «        rt	          | ¦  «        S t          | t          ¦  «        rd|                      dd¦  «        z   dz   S dt	          | ¦  «                             dd¦  «        z   dz   S )z¼Escape a Python value for safe interpolation into SQL.

    This is client-side escaping. The Logfire query API is read-only so
    injection risk is limited to the caller's own data.
    NÚNULLÚTRUEÚFALSEú'z'')Ú
isinstanceÚboolÚintÚfloatr+   Úreplace)r)   s    r   Ú_escape_valuer6   Y   s§   € ð €}ØˆvÝ�%�ÑÔð ,ØÐ+ˆvˆv GÐ+Ý�%�#�u˜Ñ&Ô&ð Ý�5‰zŒzÐÝ�%�ÑÔð 4à�U—]’] 3¨Ñ-Ô-Ñ-°Ñ3Ð3à•�U‘”×#Ò# C¨Ñ.Ô.Ñ.°Ñ4Ð4r   Ú	operationÚ
parametersúdict[str, Any] | Sequence[Any]c                ó  — t          |t          ¦  «        r#d„ |                     ¦   «         D ¦   «         }| |z  S t          |t          t          t
          f¦  «        rt          d¦  «        ‚t          d„ |D ¦   «         ¦  «        }| |z  S )zýSubstitute parameters into the SQL operation string.

    For `pyformat` paramstyle, `parameters` should be a dict and the SQL
    should contain `%(name)s` placeholders.  Sequence parameters are also
    supported for positional `%s` placeholders.
    c                ó4   — i | ]\  }}|t          |¦  «        “ŒS r   ©r6   )Ú.0ÚkeyÚvals      r   ú
<dictcomp>z&_substitute_params.<locals>.<dictcomp>t   s&   € ÐNÐNÐN©x¨s°C�3� cÑ*Ô*ÐNÐNÐNr   zPparameters must be a sequence (e.g. list or tuple) or a dict, not a string/bytesc              3  ó4   K  — | ]}t          |¦  «        V — Œd S ©Nr<   )r=   r?   s     r   ú	<genexpr>z%_substitute_params.<locals>.<genexpr>y   s*   è è € ÐAÐA¨s� cÑ*Ô*ÐAÐAÐAÐAÐAÐAr   )r1   ÚdictÚitemsr+   ÚbytesÚ	bytearrayr%   Útuple)r7   r8   ÚescapedÚescaped_seqs       r   Ú_substitute_paramsrK   l   s�   € õ �*�dÑ#Ô#ð #ØNÐN¸:×;KÒ;KÑ;MÔ;MÐNÑNÔNˆØ˜7Ñ"Ð"Ý�*�s¥E­9Ð5Ñ6Ô6ð sÝÐqÑrÔrÐråÐAÐA°jÐAÑAÔAÑAÔA€KØ�{Ñ"Ð"r   c                  óT   — e Zd ZdZededœdd„Zdd„Zdd„Zdd„Z	dd„Z
dd„Zdd„ZdS )Ú
Connectionz3PEP 249 Connection wrapping a `LogfireQueryClient`.N©Úmin_timestampÚmax_timestampÚlimitÚclientr   rO   údatetime | timedelta | NonerP   údatetime | NonerQ   r3   r*   ÚNonec               óê   — || _         | j                              ¦   «          d| _        t          |t          ¦  «        r!t          j        t          j        ¦  «        |z
  }|| _	        || _
        || _        d S )NF)rR   Ú	__enter__Úclosedr1   r   r   Únowr   ÚutcrO   rP   rQ   )ÚselfrR   rO   rP   rQ   s        r   Ú__init__zConnection.__init__…   sj   € ð ˆŒØŒ×ÒÑÔÐØˆŒÝ�m¥YÑ/Ô/ð 	GÝ$œL­¬Ñ6Ô6¸ÑFˆMØ*ˆÔØ*ˆÔØˆŒ
ˆ
ˆ
r   c                ó^   — | j         s%| j                             ddd¦  «         d| _         dS dS )z4Close the connection and the underlying HTTP client.NT)rX   rR   Ú__exit__©r[   s    r   ÚclosezConnection.close˜   s;   € àŒ{ð 	ØŒK× Ò   t¨TÑ2Ô2Ð2ØˆDŒKˆKˆKð	ð 	r   c                ó   — dS ©zNo-op (read-only connection).Nr   r_   s    r   ÚcommitzConnection.commitž   ó   € € € r   c                ó   — dS rb   r   r_   s    r   ÚrollbackzConnection.rollback¡   rd   r   ÚCursorc                óL   — | j         rt          d¦  «        ‚t          | ¦  «        S )z4Create a new cursor associated with this connection.úConnection is closed)rX   r%   rg   r_   s    r   ÚcursorzConnection.cursor¤   s'   € àŒ;ð 	;Ý"Ð#9Ñ:Ô:Ð:Ý�d‰|Œ|Ðr   c                ó   — | S rB   r   r_   s    r   rW   zConnection.__enter__¬   ó   € Øˆr   Úargsr
   c                ó.   — |                       ¦   «          d S rB   ©r`   ©r[   rm   s     r   r^   zConnection.__exit__¯   ó   € Ø�
Š
‰Œˆˆˆr   )
rR   r   rO   rS   rP   rT   rQ   r3   r*   rU   ©r*   rU   ©r*   rg   )r*   rM   ©rm   r
   r*   rU   )r   r   r   r   ÚDEFAULT_MIN_TIMESTAMP_AGEÚDEFAULT_LIMITr\   r`   rc   rf   rj   rW   r^   r   r   r   rM   rM   ‚   s¼   € € € € € Ø=Ð=ð 6OØ)-Ø"ðð ð ð ð ð ð&ð ð ð ð,ð ,ð ,ð ,ð,ð ,ð ,ð ,ðð ð ð ðð ð ð ðð ð ð ð ð r   rM   c                  óˆ   — e Zd ZdZd#d„Zed$d„¦   «         Zd%d&d„Zd'd„Zd(d„Z	d%d)d„Z
d*d„Zd+d„Zd,d„Zd%d-d„Zd.d „Zd/d"„Zd	S )0rg   zPPEP 249 Cursor that executes queries via `LogfireQueryClient.query_json_rows()`.Ú
connectionrM   r*   rU   c                ó¾   — || _         d| _        g | _        g | _        d| _        d | _        d| _        d| _        t          | _	        t          | _
        t          | _        d S )NFr   éÿÿÿÿr   )Ú_connectionÚ_closedÚ_rowsÚ_columnsÚ
_row_indexÚ_descriptionÚrowcountÚ	arraysizer   rO   rP   rQ   )r[   rx   s     r   r\   zCursor.__init__»   sY   € Ø%ˆÔØˆŒØ,.ˆŒ
Ø13ˆŒØˆŒØ:>ˆÔØˆŒØˆŒõ /5ˆÔÝ.4ˆÔÝ ˆŒ
ˆ
ˆ
r   úlist[tuple[Any, ...]] | Nonec                ó   — | j         S )z¦Column description as a list of 7-tuples per PEP 249.

        Each tuple: (name, type_code, display_size, internal_size,
        precision, scale, null_ok).
        )r€   r_   s    r   ÚdescriptionzCursor.descriptionÌ   s   € ð Ô Ð r   Nr7   r+   r8   ú%dict[str, Any] | Sequence[Any] | Nonec                óÚ  ‡ — ‰ j         rt          d¦  «        ‚‰ j        j        rt          d¦  «        ‚|}|�t	          ||¦  «        }‰ j        j                             |‰ j        t          ur‰ j        n‰ j        j        ‰ j	        t          ur‰ j	        n‰ j        j	        ‰ j
        t          ur‰ j
        n‰ j        j
        ¬¦  «        }|d         ‰ _        ˆ fd„|d         D ¦   «         ‰ _        d‰ _        t          ‰ j        ¦  «        ‰ _        d	„ ‰ j        D ¦   «         ‰ _        ‰ j
        t          ur‰ j
        n‰ j        j
        }‰ j        |k    rt#          j        d
|› d�d¬¦  «         dS dS )zÅExecute a SQL query.

        Args:
            operation: SQL query string, optionally with `%(name)s` placeholders.
            parameters: Parameter dict (or sequence) for substitution.
        úCursor is closedri   N)ÚsqlrO   rP   rQ   Úcolumnsc                óR   •‡— g | ]"Št          ˆfd „‰j        D ¦   «         ¦  «        ‘Œ#S )c              3  ó4   •K  — | ]}‰|d                   V — ŒdS )ÚnameNr   )r=   ÚcolÚrows     €r   rC   z,Cursor.execute.<locals>.<listcomp>.<genexpr>ï   s,   øè è € ÐFÐF°˜C  F¤Ô,ÐFÐFÐFÐFÐFÐFr   )rH   r~   )r=   r�   r[   s    @€r   ú
<listcomp>z"Cursor.execute.<locals>.<listcomp>ï   s9   øø€ ÐaÐaÐaÈ3•eÐFÐFÐFÐF¸¼ÐFÑFÔFÑFÔFÐaÐaÐar   Úrowsr   c                ó^   — g | ]*}|d          |d         dddd|                      d¦  «        f‘Œ+S )r�   ÚdatatypeNÚnullable)Úget)r=   rŽ   s     r   r�   z"Cursor.execute.<locals>.<listcomp>ò   sH   € ð 
ð 
ð 
Ø\_ˆS�Œ[˜#˜jœ/¨4°°t¸TÀ3Ç7Â7È:ÑCVÔCVÐWð
ð 
ð 
r   zQuery returned z^ rows which is the limit. There may be more results. Use LIMIT/OFFSET in your SQL to paginate.é   )Ú
stacklevel)r|   r%   r{   rX   rK   rR   Úquery_json_rowsrO   r   rP   rQ   r~   r}   r   Úlenr�   r€   ÚwarningsÚwarn)r[   r7   r8   r‰   ÚresultÚeffective_limits   `     r   ÚexecutezCursor.execute×   s¯  ø€ ð Œ<ð 	7Ý"Ð#5Ñ6Ô6Ð6ØÔÔ"ð 	;Ý"Ð#9Ñ:Ô:Ð:àˆØÐ!Ý$ Y°
Ñ;Ô;ˆCàÔ!Ô(×8Ò8ØØ04Ô0BÍ&Ð0PÐ0P˜$Ô,Ð,ÐVZÔVfÔVtØ04Ô0BÍ&Ð0PÐ0P˜$Ô,Ð,ÐVZÔVfÔVtØ $¤
µ&Ð 8Ð 8�$”*�*¸dÔ>NÔ>Tð	 9ñ 
ô 
ˆð ˜yÔ)ˆŒØaÐaÐaÐaÐRXÐY_ÔR`ÐaÑaÔaˆŒ
ØˆŒÝ˜DœJ™œˆŒð
ð 
ØcgÔcpð
ñ 
ô 
ˆÔð )-¬
½&Ð(@Ð(@˜$œ*˜*ÀdÔFVÔF\ˆØŒ=˜OÒ+Ð+ÝŒMðW /ð Wð Wð Wàðñ ô ð ð ð ð ,Ð+r   Úseq_of_parametersú(Sequence[dict[str, Any] | Sequence[Any]]c                ó<   — |D ]}|                       ||¦  «         ŒdS )z«Execute the same query with each set of parameters.

        Note: for a read-only API this is of limited utility, but is included
        for PEP 249 compliance.
        N)rž   )r[   r7   rŸ   r8   s       r   ÚexecutemanyzCursor.executemanyþ   s4   € ð ,ð 	0ð 	0ˆJØ�LŠL˜ JÑ/Ô/Ð/Ð/ð	0ð 	0r   útuple[Any, ...] | Nonec                ó´   — | j         rt          d¦  «        ‚| j        t          | j        ¦  «        k    rdS | j        | j                 }| xj        dz  c_        |S )z<Fetch the next row, or `None` if no more rows are available.rˆ   Nr   )r|   r%   r   r™   r}   )r[   r�   s     r   ÚfetchonezCursor.fetchone  sX   € àŒ<ð 	7Ý"Ð#5Ñ6Ô6Ð6ØŒ?�c $¤*™oœoÒ-Ð-Ø�4ØŒj˜œÔ)ˆØˆŒ˜1ÑˆŒØˆ
r   Úsizeú
int | Noneúlist[tuple[Any, ...]]c                óŽ   — | j         rt          d¦  «        ‚|€| j        }| j        |z   }| j        | j        |…         }|| _        |S )z2Fetch the next `size` rows (default: `arraysize`).rˆ   )r|   r%   r‚   r   r}   )r[   r¦   Úendr‘   s       r   Ú	fetchmanyzCursor.fetchmany  sR   € àŒ<ð 	7Ý"Ð#5Ñ6Ô6Ð6Øˆ<Ø”>ˆDØŒo Ñ$ˆØŒz˜$œ/¨CÐ/Ô0ˆØˆŒØˆr   c                óŒ   — | j         rt          d¦  «        ‚| j        | j        d…         }t	          | j        ¦  «        | _        |S )zFetch all remaining rows.rˆ   N)r|   r%   r}   r   r™   )r[   r‘   s     r   ÚfetchallzCursor.fetchall  sC   € àŒ<ð 	7Ý"Ð#5Ñ6Ô6Ð6ØŒz˜$œ/Ð+Ð+Ô,ˆÝ˜dœj™/œ/ˆŒØˆr   c                ó   — d| _         dS )zMark the cursor as closed.TN)r|   r_   s    r   r`   zCursor.close$  s   € àˆŒˆˆr   Ú_sizesr
   c                ó   — dS ©zNo-op (PEP 249 optional).Nr   )r[   r¯   s     r   ÚsetinputsizeszCursor.setinputsizes(  rd   r   Ú_sizeÚ_columnc                ó   — dS r±   r   )r[   r³   r´   s      r   ÚsetoutputsizezCursor.setoutputsize+  rd   r   c                ó   — | S rB   r   r_   s    r   rW   zCursor.__enter__0  rl   r   rm   c                ó.   — |                       ¦   «          d S rB   ro   rp   s     r   r^   zCursor.__exit__3  rq   r   )rx   rM   r*   rU   )r*   rƒ   rB   )r7   r+   r8   r†   r*   rU   )r7   r+   rŸ   r    r*   rU   )r*   r£   )r¦   r§   r*   r¨   )r*   r¨   rr   )r¯   r
   r*   rU   )r³   r
   r´   r
   r*   rU   rs   rt   )r   r   r   r   r\   Úpropertyr…   rž   r¢   r¥   r«   r­   r`   r²   r¶   rW   r^   r   r   r   rg   rg   ¸   s&  € € € € € ØZÐZð!ð !ð !ð !ð" ð!ð !ð !ñ „Xð!ð%ð %ð %ð %ð %ðN0ð 0ð 0ð 0ðð ð ð ð	ð 	ð 	ð 	ð 	ðð ð ð ðð ð ð ð(ð (ð (ð (ð(ð (ð (ð (ð (ð
ð ð ð ðð ð ð ð ð r   rg   ç      >@rN   Ú
read_tokenÚbase_urlú
str | NoneÚtimeoutr4   rO   rS   rP   rT   rQ   r3   Úkwargsc               óf   — ddl m} t          d| | ||¦  «        dœ|¤Ž}t          ||||¬¦  «        S )a’  Create a PEP 249 connection to the Logfire query API.

    Args:
        read_token: A Logfire read token for authentication.
        base_url: Override the default API base URL (inferred from token region).
        timeout: HTTP request timeout in seconds.
        min_timestamp: Default lower bound for `start_timestamp` filtering.
            Accepts a `datetime` for an exact bound, a `timedelta` for a
            relative window (computed as `now - timedelta`), or `None` to
            disable the filter.  Defaults to 1 day ago.
        max_timestamp: Default upper bound for `start_timestamp` filtering.
        limit: Default row limit per query (max 10,000). When the number of
            returned rows equals the limit a warning is emitted.
        **kwargs: Additional keyword arguments forwarded to the underlying
            `httpx.Client`.

    Returns:
        A PEP 249 `Connection` object.
    r   )ÚTimeout)r»   r¼   r¾   rN   r   )ÚhttpxrÁ   r   rM   )	r»   r¼   r¾   rO   rP   rQ   r¿   ÚHttpxTimeoutrR   s	            r   ÚconnectrÄ   <  sq   € ð: .Ð-Ð-Ð-Ð-Ð-åð ØØØ�˜WÑ%Ô%ðð ð ð	ð €Fõ ØØ#Ø#Øð	ñ ô ð r   )r)   r
   r*   r+   )r7   r+   r8   r9   r*   r+   )Nrº   )r»   r+   r¼   r½   r¾   r4   rO   rS   rP   rT   rQ   r3   r¿   r
   r*   rM   )%r   Ú
__future__r   rš   Úcollections.abcr   r   r   r   Úenumr   Útypingr	   r
   Ú!logfire.experimental.query_clientr   r   r   r   ÚapilevelÚthreadsafetyÚ
paramstyleÚ	Exceptionr   r   r   r!   r#   r%   r'   rv   ru   r6   rK   rM   rg   rÄ   r   r   r   ú<module>rÎ      s  ððð ð" #Ð "Ð "Ð "Ð "Ð "à €€€Ø $Ð $Ð $Ð $Ð $Ð $Ø 2Ð 2Ð 2Ð 2Ð 2Ð 2Ð 2Ð 2Ð 2Ð 2Ø Ð Ð Ð Ð Ð Ø %Ð %Ð %Ð %Ð %Ð %Ð %Ð %à @Ð @Ð @Ð @Ð @Ð @àð @Ø?Ð?Ð?Ð?Ð?Ð?ð 
ˆˆh˜Ñ	 Ô	 Ô	&€Ø @ð €Ø€Ø€
ðIð Ið Ið Ið Iˆiñ Iô Ið Ið,ð ,ð ,ð ,ð ,ˆIñ ,ô ,ð ,ðIð Ið Ið Ið I�Uñ Iô Ið Ið?ð ?ð ?ð ?ð ?�Eñ ?ô ?ð ?ðKð Kð Kð Kð K�}ñ Kô Kð KðZð Zð Zð Zð Z�}ñ Zô Zð ZðGð Gð Gð Gð G˜ñ Gô Gð Gð €Ø%˜I¨1Ð-Ñ-Ô-Ð ð5ð 5ð 5ð 5ð&#ð #ð #ð #ð,.ð .ð .ð .ð .ñ .ô .ð .ðl|ð |ð |ð |ð |ñ |ô |ð |ðL  Øð*ð
 2KØ%)Øð*ð *ð *ð *ð *ð *ð *ð *r   