
    jKj"9                        U 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	mZm
Z
 d dlmZ d dlmZ d dlmZmZmZmZmZm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" eee#e#ee#e$f   f      Z%dZ&dZ'dZ( e)ejT                        ejV                  ejX                  dfgz   Z-e%e.d<   de&fde'fde(ffD ]4  \  Z/Z0 e1ee/      se-je                  ejf                   e4ee/      e0f       6 dZ5ddhZ6de7de7fdZ8e G d d             Z9 G d de      Z:dPdee%   dejv                  fdZ<	 dPdee%   dejv                  fd Z= e<       a> e=       a?da@ee%   e.d!<   d"aAdejv                  fd#ZBdejv                  fd$ZCdQd%ZDdee%   ddfd&ZEdQd'ZFdQd(ZGd)ZHd*ZIeHZJd+e"z   ZK e        d,ee7   de7fd-ZLd,ee7   de7fd.ZM	 	 	 	 	 dRd1e7d,ee7   d2ee7   d3eNd4e#d5eejv                     dej                  fd6ZPd"d7d8ej                  d9e7d:eNdeej                  ef   fd;ZQd<e#deRfd=ZS	 	 	 	 dSd1e7d,ee7   d3eNd4e#d>e#defd?ZT	 	 	 dTd@e7dAe7d,ee7   dBe7d4e#defdCZUdDZVdEZWdeNfdFZXdd/d0eVfd1e7d,ee7   d3eNd4e#d2e7dej                  fdGZY	 	 	 dUd1e7de7d,ee7   d4ee#   dHee7   de9fdIZZ G dJ dKe[      Z\ G dL dMe\      Z]ej                  j                  Z`ej                  j                  Zb G dN dOe j                        Zdy)V    N)	dataclass)datedatetimetimezone)GzipFile)BytesIO)AnyListOptionalTupleUnioncast)HTTPAdapter)HTTPConnection)Retry)_configure_posthog_logging)remove_trailing_slash)VERSION<         KEEP_ALIVE_SOCKET_OPTIONSTCP_KEEPIDLETCP_KEEPINTVLTCP_KEEPCNTg333333?i  i  urlreturnc                 0    t        j                  dd|       S )zKMask token values in URLs for safe logging, keeping first 10 chars visible.z(token=)([^&]{10})[^&]*z\1\2...)resub)r   s    `/Users/ahmed/devFolder/Ultron/claude-voice/.venv/lib/python3.12/site-packages/posthog/request.py_mask_tokens_in_urlr"   2   s    66,j#>>    c                   >    e Zd ZU dZeed<   dZee   ed<   dZ	e
ed<   y)GetResponsez.Response from a GET request with ETag support.dataNetagFnot_modified)__name__
__module____qualname____doc__r	   __annotations__r'   r   strr(   bool r#   r!   r%   r%   7   s"    8
ID(3-L$r#   r%   c                   >     e Zd ZdZdddee   f fdZ fdZ xZS )HTTPAdapterWithSocketOptionsz-HTTPAdapter with configurable socket options.Nsocket_optionsr4   c                2    || _         t        |   |i | y N)r4   super__init__)selfr4   argskwargs	__class__s       r!   r8   z%HTTPAdapterWithSocketOptions.__init__C   s    ,$)&)r#   c                 Z    | j                   | j                   |d<   t        |   |i | y )Nr4   )r4   r7   init_poolmanager)r9   r:   r;   r<   s      r!   r>   z-HTTPAdapterWithSocketOptions.init_poolmanagerG   s2    *'+':':F#$ $1&1r#   )	r)   r*   r+   r,   r   SocketOptionsr8   r>   __classcell__)r<   s   @r!   r2   r2   @   s$    7HL *h}.E *2 2r#   r2   r4   c                     t        t        ddd      |       }t        j                         }|j	                  d|       |S )zBBuild a session for general requests (batch, remote config, etc.).   )totalconnectreadmax_retriesr4   https://r2   r   requestsSessionmountr4   adaptersessions      r!   _build_sessionrP   M   sE    *

 &G  GMM*g&Nr#   c                     t        t        dddd      |       }t        j                         }|j	                  d|       |S )zBuild a session for feature flag requests.

    /flags retries are handled explicitly in ``flags()`` so that only
    transport failures and contract-defined transient HTTP responses are retried.
    r   )rC   rD   rE   statusrF   rH   rI   rM   s      r!   _build_flags_sessionrS   \   sB     +11Q?%G  GMM*g&Nr#   _socket_optionsTc                  8    t         rt        S t        t              S r6   )_pooling_enabled_sessionrP   rT   r0   r#   r!   _get_sessionrX   s   s    /**r#   c                  8    t         rt        S t        t              S r6   )rV   _flags_sessionrS   rT   r0   r#   r!   _get_flags_sessionr[   y   s    00r#   c                      t         rt         j                          t        rt        j                          t        t              a t        t              ay)z
    Reset the global sessions. This should be called after a fork to ensure
    that the child process does not use the parent's connection pool.
    N)rW   closerZ   rP   rT   rS   r0   r#   r!   reset_sessionsr^      s4     o.H)/:Nr#   c                 H    | t         k(  ry| a t        |       at        |       ay)a  
    Configure socket options for all SDK HTTP connections.

    Call this during initialization, before making API requests. Pass ``None``
    to reset to the default socket behavior.

    Args:
        socket_options: A list of ``(level, option, value)`` tuples accepted by
            urllib3/``socket.setsockopt()``, or ``None`` to reset defaults.

    Example:
        from posthog import set_socket_options
        set_socket_options([(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)])
    N)rT   rP   rW   rS   rZ   r3   s    r!   set_socket_optionsr`      s(      ($On-H).9Nr#   c                  "    t        t               y)z
    Enable TCP keepalive for SDK HTTP connections.

    This helps prevent idle pooled connections from being dropped by network
    infrastructure. Call during initialization, before making API requests.
    N)r`   r   r0   r#   r!   enable_keep_aliverb      s     01r#   c                      da y)a  
    Disable HTTP connection reuse for SDK requests.

    Each request will create a fresh connection. This can avoid issues with
    environments that terminate pooled connections, but adds per-request
    overhead. Call during initialization, before making API requests.
    FN)rV   r0   r#   r!   disable_connection_reuserd      s
     r#   zhttps://us.i.posthog.comzhttps://eu.i.posthog.comzposthog-python/hostc                 >    | xs dj                         }|st        S |S )zENormalize a configured host, defaulting blank values to DEFAULT_HOST. )stripDEFAULT_HOST)re   normalized_hosts     r!   normalize_hostrk      s#    zr((*Or#   c                 \    t        |       }t        |      }|dv rt        S |dk(  rt        S |S )z"Determines the server host to use.)zhttps://app.posthog.comzhttps://us.posthog.comzhttps://eu.posthog.com)rk   r   US_INGESTION_ENDPOINTEU_INGESTION_ENDPOINT)re   host_or_defaulttrimmed_hosts      r!   determine_server_hostrq      s:    $T*O(9LLL$$	1	1$$r#   F   api_keypathgziptimeoutrO   c                 :   t        j                  d      }|}t        j                  t        j
                        j                         |d<   t        t        |            }	|	t        t        |      z   }
| |d<   t        j                  |t              }|j                  d||
       dt        d}|rd	 t!               }t#        |d	
      5 }|j%                  t        t        |      j'                  d             ddd       |j)                         }d|d<   |xs
 t3               j5                  |
|||      }|j6                  dk(  r|j                  d       |S # 1 sw Y   axY w# t*        t,        j.                  f$ r}|j1                  d|       Y d}~d}~ww xY w)zPost the `kwargs` to the APIposthog)tzsent_atrs   )clszmaking request: %s to url: %szapplication/json)zContent-Type
User-Agentw)fileobjmodezutf-8Nru   zContent-Encodingz5failed to gzip request body, sending uncompressed: %s)r&   headersrv      data uploaded successfully)logging	getLoggerr   nowr   utc	isoformatr   rk   r   r.   jsondumpsDatetimeSerializerdebug
USER_AGENTr   r   writeencodegetvalueOSErrorzliberrorwarningrX   poststatus_code)rs   re   rt   ru   rv   rO   r;   logbodyrp   r   r&   r   bufgzexcress                    r!   r   r      sc    

I
&CDllhll3==?DO()=>L
c4
(CDO

4-?@DII-tS91LG		V)C#C0B c4//89 1 <<>D*0G&' $ln
*
*$ + C #		./J! 10 $ 	VKKOQTUU	Vs0   3E% 
/E9E% E"E% %F>FF)return_jsonr   success_messager   c                j   t        j                  d      }| j                  dk(  r||j                  |       |r| j	                         n| }t        |t              rEd|v rAt        |d   t              r.d|d   v r'|j                  d       t        | j                  d      |S d }| j                  j                  d      }|r	 t        |      }	 | j	                         }|j                  d|       t/        | j                  |d   |      # t        t        f$ rd 	 dd	lm} t#        d
 ||      t%        j&                  t(        j*                        z
  j-                               }n# t        t        f$ r Y nw xY wY w xY w# t0        t        f$ r# t/        | j                  | j2                  |      w xY w)Nrx   r   quotaLimitedfeature_flagsz[FEATURE FLAGS] PostHog feature flags quota limited, resetting feature flag data.  Learn more about billing limits at https://posthog.com/docs/billing/limits-alertszFeature flags quota limitedzRetry-Afterr   )parsedate_to_datetimeg        zreceived response: %sdetail)retry_after)r   r   r   r   r   
isinstancedictlistr   QuotaLimitErrorr   getfloat
ValueError	TypeErroremail.utilsr   maxr   r   r   r   total_secondsAPIErrorKeyErrortext)	r   r   r   r   responser   retry_after_headerr   payloads	            r!   _process_responser      s    

I
&C
#		/"!,388:#
 x&(*8N3T:8N#;;KK w "#//3PQQK7	 23KK((*		)73s(9{SS# I& 	=!-.@A",,x||45#mo 	* 	$ j! KskJJKsC   D
 =F  
E=A
E%$E=%E74E=6E77E=<E= 2F2failed_attemptc                     t         d| z  z  S )NrB   )$_FEATURE_FLAGS_RETRY_BACKOFF_SECONDS)r   s    r!   _feature_flags_retry_delayr   0  s    /1n3DEEr#   rG   c                    t        d|      }d}	 	 t        | |d||fdt               i|}t        |d      S # t        j
                  j                  t        j
                  j                  f$ r	 ||k\  r Y n-t        $ r"}	|	j                  t        vs||k\  r Y d}	~	nd}	~	ww xY wt        j                  t        |             |dz  })zIPost the kwargs to the flags API endpoint with bounded transient retries.r   z/flags/?v=2rO   z$Feature flags evaluated successfullyr   Nr   )r   r   r[   r   rJ   
exceptionsConnectionErrorTimeoutr   rR   "_FEATURE_FLAGS_RETRY_HTTP_STATUSEStimesleepr   )
rs   re   ru   rv   rG   r;   retriesr   r   r   s
             r!   flagsr   4  s     ![!GN
	 +, C %%K  ##33X5H5H5P5PQ 	( ) 	

"DD!W, -	 	

-n=>!1 s   &8 =B!7B!?BB!personal_api_keyproject_api_keykeyc                 B    t        | d| d| ||      }|j                  S )z<Get remote config flag value from remote_config API endpointz%/api/projects/@current/feature_flags/z/remote_config?token=)r   r&   )r   r   re   r   rv   r   s         r!   remote_configr   [  s5     
/u4I/IZ[	H ==r#   z/batch/z/i/v0/ai/batch/c                 H    t        | t              xr | j                  d      S )Nz$ai_)r   r.   
startswith)
event_names    r!   is_ai_eventr   p  s    j#&H:+@+@+HHr#   c                 >    t        | ||||fi |}t        |dd      S )z6Post the `kwargs` to the batch API endpoint for eventsr   F)r   r   )r   r   )rs   re   ru   rv   rt   r;   r   s          r!   
batch_postr   t  s0     wdD'
<V
<C9u r#   r'   c                    t        j                  d      }t        t        |            }||z   }d| z  t        d}|r||d<   t               j                  |||      }	t        |      }
|	j                  dk(  rB|j                  d|
 d       |	j                  j                  d	      }t        d
|xs |d      S t        |	d|
 d      }|	j                  j                  d	      }t        ||d      S )a  
    Make a GET request with optional ETag support.

    If an etag is provided, sends If-None-Match header. Returns GetResponse with:
    - not_modified=True and data=None if server returns 304
    - not_modified=False and data=response if server returns 200
    rx   z	Bearer %s)Authorizationr|   zIf-None-Match)r   rv   i0  zGET z returned 304 Not ModifiedETagNT)r&   r'   r(   z completed successfullyr   F)r   r   r   rk   r   rX   r   r"   r   r   r   r%   r   )rs   r   re   rv   r'   r   rp   full_urlr   r   
masked_urlresponse_etagr&   s                r!   r   r     s     

I
&C()=>Lc!H +g 5ZPG#' 
.

Xw

HC$X.J #		D$>?@/=+@DtTT tJ</FGD KKOOF+MD}5IIr#   c                   :    e Zd Z	 ddeeef   dedee   fdZd Z	y)r   NrR   messager   c                 .    || _         || _        || _        y r6   )r   rR   r   )r9   rR   r   r   s       r!   r8   zAPIError.__init__  s     &r#   c                 R    d}|j                  | j                  | j                        S )Nz[PostHog] {0} ({1}))formatr   rR   )r9   msgs     r!   __str__zAPIError.__str__  s     #zz$,,44r#   r6   )
r)   r*   r+   r   intr.   r   r   r8   r   r0   r#   r!   r   r     s3    TX'CHo'03'BJ5/'5r#   r   c                       e Zd Zy)r   N)r)   r*   r+   r0   r#   r!   r   r     s    r#   r   c                       e Zd ZdefdZy)r   objc                     t        |t        t        f      r|j                         S t        j
                  j                  | |      S r6   )r   r   r   r   r   JSONEncoderdefault)r9   r   s     r!   r   zDatetimeSerializer.default  s6    cD(+,==?"''c22r#   N)r)   r*   r+   r	   r   r0   r#   r!   r   r     s    33 3r#   r   r6   )r   N)NNFrr   N)NFrr   r   )Nrg   rr   )NNN)er   r   r   socketr   r   dataclassesr   r   r   r   ru   r   ior   typingr	   r
   r   r   r   r   rJ   requests.adaptersr   urllib3.connectionr   urllib3.util.retryr   posthog._loggingr   posthog.utilsr   posthog.versionr   r   bytesr?   KEEPALIVE_IDLE_SECONDSKEEPALIVE_INTERVAL_SECONDSKEEPALIVE_PROBE_COUNTr   default_socket_options
SOL_SOCKETSO_KEEPALIVEr   r-   attrvaluehasattrappendSOL_TCPgetattrr   r   r.   r"   r%   r2   rK   rP   rS   rW   rZ   rT   rV   rX   r[   r^   r`   rb   rd   rm   rn   ri   r   rk   rq   r/   Responser   r   r   r   r   r   EVENTS_ENDPOINTAI_EVENTS_ENDPOINTr   r   r   	Exceptionr   r   r   r   RequestsTimeoutr   RequestsConnectionErrorr   r   r0   r#   r!   <module>r      s     	    ! - -   : :  ) - $ 7 / #U3U3:%6678    ,0)), ++Q/, =  +,01)*KD%
 vt!((&..'&$:OQV)WX (+ $&)3Z "?S ?S ?
   
2; 
28M#: hFVFV   /3]+" %'+/-( / +h&& +1H,, 1;:x'> :4 :.2	 3 2 $(
  # 3 	 	# 	 *.&&
3-& 3-& 	&
 & h&&'& &T JN-K			-K-0-KBF-K
8c!"-K`Fs Fu F $$
3-$ $ 	$
 $ 	$T  3- 
	
  	" & It I 
3-  	
  $ !%J%J	%J 3-%J c]	%J
 3-%J %JP
5y 
5	h 	 %%--"--== 3)) 3r#   