
    Qi).                        U 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 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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jL                        ejN                  ejP                  dfgz   Z)e!e*d<   de"fde#fde$ffD ]4  \  Z+Z, e-ee+      se)j]                  ej^                   e0ee+      e,f       6 g dZ1de2de2fdZ3e G d d             Z4 G d de      Z5dDdee!   dejl                  fdZ7	 dDdee!   dejl                  fdZ8 e7       a9 e8       a:da;ee!   e*d<   d a<dejl                  fd!Z=dejl                  fd"Z>dee!   ddfd#Z?dEd$Z@dEd%ZAd&ZBd'ZCeBZDd(ez   ZEd)ee2   de2fd*ZF	 	 	 	 	 dFd+e2d)ee2   d,eGd-ed.eejl                     dej                  fd/ZId d0d1ej                  d2e2d3eGdeej                  ef   fd4ZJ	 	 	 dGd+e2d)ee2   d,eGd-edef
d5ZK	 	 	 dGd+e2d)ee2   d,eGd-edef
d6ZL	 	 	 dHd7e2d8e2d)ee2   d9e2d-edefd:ZM	 	 	 dGd+e2d)ee2   d,eGd-edej                  f
d;ZN	 	 	 dId+e2de2d)ee2   d-ee   d<ee2   de4fd=ZO G d> d?eP      ZQ G d@ dAeQ      ZRej                  j                  ZUej                  j                  ZW G dB dCe j                        ZYy)J    N)	dataclass)datedatetime)GzipFile)BytesIO)AnyListOptionalTupleUnion)tzutc)HTTPAdapter)HTTPConnection)Retry)remove_trailing_slash)VERSION<         KEEP_ALIVE_SOCKET_OPTIONSTCP_KEEPIDLETCP_KEEPINTVLTCP_KEEPCNT)i  i  i  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    K/mnt/e/genesis-system/.venv/lib/python3.12/site-packages/posthog/request.py_mask_tokens_in_urlr    0   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#   5   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_optionsr2   c                2    || _         t        |   |i | y N)r2   super__init__)selfr2   argskwargs	__class__s       r   r6   z%HTTPAdapterWithSocketOptions.__init__A   s    ,$)&)r!   c                 Z    | j                   | j                   |d<   t        |   |i | y )Nr2   )r2   r5   init_poolmanager)r7   r8   r9   r:   s      r   r<   z-HTTPAdapterWithSocketOptions.init_poolmanagerE   s2    *'+':':F#$ $1&1r!   )	r'   r(   r)   r*   r
   SocketOptionsr6   r<   __classcell__)r:   s   @r   r0   r0   >   s$    7HL *h}.E *2 2r!   r0   r2   c                     t        t        ddd      |       }t        j                         }|j	                  d|       |S )z;Build a session for general requests (batch, decide, etc.).   )totalconnectreadmax_retriesr2   https://)r0   r   requestsSessionmountr2   adaptersessions      r   _build_sessionrM   K   sE    *

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

    Feature flag requests are idempotent (read-only), so retrying POST
    requests is safe. This session retries on transient server errors
    (408, 5xx) and network failures with exponential backoff
    (0.5s, 1s delays between retries).
    r@   g      ?POST)rA   rB   rC   backoff_factorstatus_forcelistallowed_methodsrD   rF   )r0   r   RETRY_STATUS_FORCELISTrG   rH   rI   rJ   s      r   _build_flags_sessionrT   Z   sR     +3#H
 &
G  GMM*g&Nr!   _socket_optionsTc                  8    t         rt        S t        t              S r4   )_pooling_enabled_sessionrM   rU   r.   r!   r   _get_sessionrY   {   s    /**r!   c                  8    t         rt        S t        t              S r4   )rW   _flags_sessionrT   rU   r.   r!   r   _get_flags_sessionr\      s    00r!   c                 H    | t         k(  ry| a t        |       at        |       ay)z
    Configure socket options for all HTTP connections.

    Example:
        from posthog import set_socket_options
        set_socket_options([(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)])
    N)rU   rM   rX   rT   r[   r1   s    r   set_socket_optionsr^      s(     ($On-H).9Nr!   c                  "    t        t               y)zDEnable TCP keepalive to prevent idle connections from being dropped.N)r^   r   r.   r!   r   enable_keep_aliver`      s    01r!   c                      da y)zGDisable connection reuse, creating a fresh connection for each request.FN)rW   r.   r!   r   disable_connection_reuserb      s
     r!   zhttps://us.i.posthog.comzhttps://eu.i.posthog.comzposthog-python/hostc                 Z    | xs 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)DEFAULT_HOSTr   US_INGESTION_ENDPOINTEU_INGESTION_ENDPOINT)rc   host_or_defaulttrimmed_hosts      r   determine_server_hostrj      s:    *lO(9LLL$$	1	1$$r!   api_keygziptimeoutrL   c                 ~   t        j                  d      }|}t        j                  t	                     j                         |d<   t        |xs t              |z   }	| |d<   t        j                  |t              }
|j                  d|
|	       dt        d}|rUd	|d
<   t               }t        |d      5 }|j                  |
j!                  d             ddd       |j#                         }
|xs
 t%               j'                  |	|
||      }|j(                  dk(  r|j                  d       |S # 1 sw Y   \xY w)zPost the `kwargs` to the APIposthog)tzsentAtrk   )clszmaking request: %s to url: %szapplication/json)zContent-Type
User-Agentrl   zContent-Encodingw)fileobjmodezutf-8N)r$   headersrm      data uploaded successfully)logging	getLoggerr   nowr   	isoformatr   re   jsondumpsDatetimeSerializerdebug
USER_AGENTr   r   writeencodegetvaluerY   poststatus_code)rk   rc   pathrl   rm   rL   r9   logbodyr   r$   rw   bufgzress                  r   r   r      s    

I
&CD\\UW-779DN
 4
5
<CDO::d 23DII-tS91LG&,"#ic, 	+ HHT[[)*	+ ||~$ln
*
*$ + C #		./J	+ 	+s   7!D33D<)return_jsonr   success_messager   c                    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 	 | j	                         }|j                  d|       t        | j                  |d         # t        t        f$ r! t        | j                  | j                        w xY w)	Nro   rx   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received response: %sdetail)rz   r{   r   r   r~   
isinstancedictlistwarningQuotaLimitErrorAPIErrorKeyError
ValueErrortext)r   r   r   r   responsepayloads         r   _process_responser      s     

I
&C
#		/"!,388:#
 x&(*8N3T:8N#;;KK w "#//3PQQ2((*		)73s(9::j! 2s112s   ";C 0Dc                 <    t        | |d||fi |}t        |d      S )z+Post the `kwargs to the decide API endpointz/decide/?v=4z"Feature flags decided successfullyr   r   r   rk   rc   rl   rm   r9   r   s         r   decider      s)     wndG
Fv
FCS2VWWr!   c                 P    t        | |d||fdt               i|}t        |d      S )zAPost the kwargs to the flags API endpoint with automatic retries.z/flags/?v=2rL   z$Feature flags evaluated successfullyr   )r   r\   r   r   s         r   flagsr     sI      #$ C C r!   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=)getr$   )r   r   rc   r   rm   r   s         r   remote_configr     s5     
/u4I/IZ[	H ==r!   c                 >    t        | |d||fi |}t        |dd      S )z6Post the `kwargs` to the batch API endpoint for eventsz/batch/ry   F)r   r   r   r   s         r   
batch_postr   )  s0     wiw
A&
AC9u r!   r%   c                    t        j                  d      }t        |xs 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
    ro   z	Bearer %s)Authorizationrs   zIf-None-Match)rw   rm   i0  zGET z returned 304 Not ModifiedETagNT)r$   r%   r&   z completed successfullyr   F)rz   r{   r   re   r   rY   r   r    r   r   rw   r#   r   )rk   r   rc   rm   r%   r   full_urlrw   r   
masked_urlresponse_etagr$   s               r   r   r   7  s     

I
&C$T%9\:S@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eeef   defdZd Zy)r   statusmessagec                      || _         || _        y r4   )r   r   )r7   r   r   s      r   r6   zAPIError.__init___  s    r!   c                 R    d}|j                  | j                  | j                        S )Nz[PostHog] {0} ({1}))formatr   r   )r7   msgs     r   __str__zAPIError.__str__c  s     #zz$,,44r!   N)r'   r(   r)   r   intr,   r6   r   r.   r!   r   r   r   ^  s"    uS#X  5r!   r   c                       e Zd Zy)r   N)r'   r(   r)   r.   r!   r   r   r   h  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 r4   )r   r   r   r}   r~   JSONEncoderdefault)r7   r   s     r   r   zDatetimeSerializer.defaults  s6    cD(+,==?"''c22r!   N)r'   r(   r)   r   r   r.   r!   r   r   r   r  s    33 3r!   r   r4   )r   N)NNF   N)NFr   )N r   )NNN)Zr~   rz   r   socketdataclassesr   r   r   rl   r   ior   typingr   r	   r
   r   r   rG   dateutil.tzr   requests.adaptersr   urllib3.connectionr   urllib3.util.retryr   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getattrrS   r,   r    r#   r0   rH   rM   rT   rX   r[   rU   rW   rY   r\   r^   r`   rb   rf   rg   re   r   rj   r-   Responser   r   r   r   r   r   r   	Exceptionr   r   
exceptionsTimeoutRequestsTimeoutConnectionErrorRequestsConnectionErrorr   r   r.   r!   r   <module>r      s     	  ! #   4 4   ) - $ / #U3U3:%6678    ,0)), ++Q/, =  +,01)* YKD%
 vt!((&..'&$:OQV)WXY 3 ?S ?S ?
   
2; 
28M#: hFVFV   /3]+6 %'+/-( / +h&& +1H,, 1:x'> :4 : 2
 3 2 $(
	 	# 	 	*.""
3-" 	"
 " h&&'" "L JN2			2-02BF2
8c!"2> 		X	X
3-	X 	X 		X 		X 	
3-  	 	2  3- 
	
  	& 	
3-  	 " !$J$J	$J 3-$J c]	$J
 3-$J $JN5y 5	h 	 %%--"--== 3)) 3r!   