
    Yi&1                        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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jN                        ejP                  ejR                  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`                   e1ee,      e-f       6 g dZ2de3de3fdZ4e G d d             Z5 G d de      Z6dDdee"   dejn                  fdZ8	 dDdee"   dejn                  fdZ9 e8       a: e9       a;da<ee"   e+d<   d a=dejn                  fd!Z>dejn                  fd"Z?dee"   ddfd#Z@dEd$ZAdEd%ZBd&ZCd'ZDeCZEd(ez   ZFd)ee3   de3fd*ZG	 	 	 	 	 dFd+e3d)ee3   d,eHd-e d.eejn                     dej                  fd/ZJd d0d1ej                  d2e3d3eHdeej                  ef   fd4ZK	 	 	 dGd+e3d)ee3   d,eHd-e def
d5ZL	 	 	 dGd+e3d)ee3   d,eHd-e def
d6ZM	 	 	 dHd7e3d8e3d)ee3   d9e3d-e defd:ZN	 	 	 dGd+e3d)ee3   d,eHd-e dej                  f
d;ZO	 	 	 dId+e3de3d)ee3   d-ee    d<ee3   de5fd=ZP G d> d?eQ      ZR G d@ dAeR      ZSej                  j                  ZVej                  j                  ZX G dB dCe j                        ZZy)J    N)	dataclass)datedatetimetimezone)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    Y/mnt/e/genesis-system/.venvs/browser-army/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_optionsr3   c                2    || _         t        |   |i | y N)r3   super__init__)selfr3   argskwargs	__class__s       r    r7   z%HTTPAdapterWithSocketOptions.__init__A   s    ,$)&)r"   c                 Z    | j                   | j                   |d<   t        |   |i | y )Nr3   )r3   r6   init_poolmanager)r8   r9   r:   r;   s      r    r=   z-HTTPAdapterWithSocketOptions.init_poolmanagerE   s2    *'+':':F#$ $1&1r"   )	r(   r)   r*   r+   r   SocketOptionsr7   r=   __classcell__)r;   s   @r    r1   r1   >   s$    7HL *h}.E *2 2r"   r1   r3   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_retriesr3   https://)r1   r   requestsSessionmountr3   adaptersessions      r    _build_sessionrN   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).
    rA   g      ?POST)rB   rC   rD   backoff_factorstatus_forcelistallowed_methodsrE   rG   )r1   r   RETRY_STATUS_FORCELISTrH   rI   rJ   rK   s      r    _build_flags_sessionrU   Z   sR     +3#H
 &
G  GMM*g&Nr"   _socket_optionsTc                  8    t         rt        S t        t              S r5   )_pooling_enabled_sessionrN   rV   r/   r"   r    _get_sessionrZ   {   s    /**r"   c                  8    t         rt        S t        t              S r5   )rX   _flags_sessionrU   rV   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)rV   rN   rY   rU   r\   r2   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_alivera      s    01r"   c                      da y)zGDisable connection reuse, creating a fresh connection for each request.FN)rX   r/   r"   r    disable_connection_reuserc      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)rd   host_or_defaulttrimmed_hosts      r    determine_server_hostrk      s:    *lO(9LLL$$	1	1$$r"   api_keygziptimeoutrM   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sentAtrl   )clszmaking request: %s to url: %szapplication/json)zContent-Type
User-Agentrm   zContent-Encodingw)fileobjmodezutf-8N)r%   headersrn      data uploaded successfully)logging	getLoggerr   nowr   	isoformatr   rf   jsondumpsDatetimeSerializerdebug
USER_AGENTr   r   writeencodegetvaluerZ   poststatus_code)rl   rd   pathrm   rn   rM   r:   logbodyr   r%   rx   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                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)Nrp   ry   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listwarningQuotaLimitErrorrx   getfloat
ValueError	TypeErroremail.utilsr   maxr   r}   r   utc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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   rl   rd   rm   rn   r:   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=2rM   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=)r   r%   )r   r   rd   r   rn   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/rz   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
    rp   z	Bearer %s)Authorizationrt   zIf-None-Match)rx   rn   i0  zGET z returned 304 Not ModifiedETagNT)r%   r&   r'   z completed successfullyr   F)r{   r|   r   rf   r   rZ   r   r!   r   r   rx   r$   r   )rl   r   rd   rn   r&   r   full_urlrx   r   
masked_urlresponse_etagr%   s               r    r   r   J  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deeef   dedee   fdZd Z	y)r   Nstatusmessager   c                 .    || _         || _        || _        y r5   )r   r   r   )r8   r   r   r   s       r    r7   zAPIError.__init__r  s     &r"   c                 R    d}|j                  | j                  | j                        S )Nz[PostHog] {0} ({1}))formatr   r   )r8   msgs     r    __str__zAPIError.__str__y  s     #zz$,,44r"   r5   )
r(   r)   r*   r   intr-   r   r   r7   r   r/   r"   r    r   r   q  s3    TX'CHo'03'BJ5/'5r"   r   c                       e Zd Zy)r   N)r(   r)   r*   r/   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 r5   )r   r   r   r~   r   JSONEncoderdefault)r8   r   s     r    r   zDatetimeSerializer.default  s6    cD(+,==?"''c22r"   N)r(   r)   r*   r	   r   r/   r"   r    r   r     s    33 3r"   r   r5   )r   N)NNF   N)NFr   )N r   )NNN)[r   r{   r   socketdataclassesr   r   r   r   rm   r   ior   typingr	   r
   r   r   r   rH   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getattrrT   r-   r!   r$   r1   rI   rN   rU   rY   r\   rV   rX   rZ   r]   r_   ra   rc   rg   rh   rf   r   rk   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-K			-K-0-KBF-K
8c!"-Kd 		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"   