o
    Dg                     @   s  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Zd dlmZmZ d dl	m
Z
mZmZ d dl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mZmZ d d
lmZmZ d dl m!Z! d dl"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z) d dl*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3 d dl4m5Z5m6Z6m7Z7m8Z8 d dl9m:Z: zd dl;Z;W n e<y   d dl=Z;Y nw ej>eefZ?dZ@dd ZAdeBeCe
f fddZDG dd deEZFdd ZGdd ZHdS )    N)datetime	timedelta)AnyOptionalUnion)UUIDuuid4)tzutc)string_types)Consumer)ExceptionCapture)exc_info_from_errorexceptions_from_error_tuplehandle_in_app)InconclusiveMatchErrormatch_feature_flag_properties)Poller)DEFAULT_HOSTAPIError
batch_postdecidedetermine_server_hostgetremote_config)	DecideResponseFeatureFlagFlagMetadataFlagsAndPayloads	FlagValuenormalize_decide_responseto_flags_and_payloadsto_payloads	to_values)SizeLimitedDictcleanguess_timezoneremove_trailing_slash)VERSIONiP  c                  C   s   d} d}t j}|dr!d} ttdrt d }|r|}| |fS |dkr:d} ttdr6t d }|r6|}| |fS |d	rQd
} t }|d rM|d }| |fS |dred} ttdrat }| |fS |} ttdrpt }| |fS )zr
    Returns standardized OS name and version information.
    Similar to how user agent parsing works in JS.
     winWindows	win32_verr   darwinzMac OS Xmac_verlinuxLinuxversionfreebsdFreeBSDrelease)	sysplatform
startswithhasattrr+   r-   distroinfor3   )os_name
os_versionplatform_namewin_versionmac_version
linux_info r@   h/var/www/eduai.edurigo.com/doc_train/edurigo_ai/Puru/venv/lib/python3.10/site-packages/posthog/client.pyget_os_info.   s@   






rB   returnc                  C   s*   t  \} }t dtjd d  | |dS )Nz%s.%s.%s   )z$python_runtimez$python_versionz$osz$os_version)rB   r5   python_implementationr4   version_info)r:   r;   r@   r@   rA   system_contextY   s   
rG   c                   @   sn  e Zd ZdZedZ													
															dcddZedd Z	e	j
dd Z	ddddZ	dedeeeeef f fddZ	dedeeef fddZ	dedefddZ	dedefddZ									dfddZdddd Zddd!d"Z								dgd#d$Zddd%d&Z	dhd'd(Z							dhd)d*Zd+d, Zd-d. Zd/d0 Zd1d2 Z d3d4 Z!d5d6 Z"i i i dd7de#fd8d9Z$i i i dddd:d;d<Z%i i i dddd:de&e# fd=d>Z'd?ed@edAeeef dBeeef dCeeef de&e# fdDdEZ(di i i ddddFdGdHZ)d?ed@edAeeef dBeeef dCeeef dIe&e de*e&e+ e&e f fdJdKZ,d@ed?edLe#dMe&e dNedAeeef dIe&e dOe&e dPe&e+ fdQdRZ-d?efdSdTZ.d?edUe#de&e fdVdWZ/i i i dddXde&eeeeef f  fdYdZZ0i i i dddXdefd[d\Z1i i i dd7de*eef fd]d^Z2d_d` Z3dadb Z4dS )iClientzCreate a new PostHog client.posthogNF'  Td         ?rD            c                 C   s  t || _ |p	|| _td| jt || _|| _|| _|| _|p!t	| _
t|| _|	| _|| _d | _d | _d | _d | _|| _|| _d | _ttt| _|| _|| _|| _|| _|| _|| _|| _ d | _!|| _"|d u rzzt#$ }W n t%yy   d }Y nw || _&|| _'|rt()  | j*+t(j, n| j*+t(j- | jrt.| | j d| _!|rd | _/d S |rt01| j2 t3|D ]"}g | _/t4| j | j| j||||	|
||d
}| j/5| |r|6  qd S )Napi_key)integrations)hoston_errorflush_atflush_intervalgzipretriestimeouthistorical_migration)7queueQueuerP   requirer
   rS   debugsend	sync_moder   raw_hostr   rR   rV   rX   _feature_flagsfeature_flags_by_keygroup_type_mappingcohortspoll_interval%feature_flags_request_timeout_secondspollerr#   MAX_DICT_SIZEset#distinct_ids_feature_flags_reporteddisableddisable_geoiprY   super_propertiesenable_exception_autocapturelog_captured_exceptions"exception_autocapture_integrationsexception_captureprivacy_modeosgetcwd	Exceptionproject_rootpersonal_api_keyloggingbasicConfiglogsetLevelDEBUGWARNINGr   	consumersatexitregisterjoinranger   appendstart)selfrP   rR   r]   max_queue_sizer^   rS   rT   rU   rV   max_retriesr_   rX   threadre   rw   project_api_keyrk   rl   rY   rf   rm   rn   ro   rp   rv   rr   nconsumerr@   r@   rA   __init__i   s   



zClient.__init__c                 C      | j S )z9
        Get the local evaluation feature flags.
        )ra   r   r@   r@   rA   feature_flags   s   zClient.feature_flagsc                 C   s2   |pg | _ dd | j D | _| jdusJ ddS )z9
        Set the local evaluation feature flags.
        c                 S   s$   i | ]}| d dur|d  |qS )keyNr   ).0flagr@   r@   rA   
<dictcomp>   s   $ z(Client.feature_flags.<locals>.<dictcomp>NDfeature_flags_by_key should be initialized when feature_flags is set)ra   rb   )r   flagsr@   r@   rA   r      s
   
c                 C   T   |d urt jdtdd |pi }td|t td|t |||d|d}| ||S )NNThe 'context' parameter is deprecated and will be removed in a future version.   
stackleveldistinct_id
propertiesz	$identify	timestampr   $seteventuuidwarningswarnDeprecationWarningr\   ID_TYPESdict_enqueuer   r   r   contextr   r   rl   msgr@   r@   rA   identify       zClient.identifyrC   c                 C      |  |||||}t|pi S )zP
        Get feature flag variants for a distinct_id by calling decide.
        )
get_decider"   r   r   groupsperson_propertiesgroup_propertiesrl   	resp_datar@   r@   rA   get_feature_variants     zClient.get_feature_variantsc                 C   r   )zP
        Get feature flag payloads for a distinct_id by calling decide.
        )r   r!   r   r@   r@   rA   get_feature_payloads  r   zClient.get_feature_payloadsc                 C   s   |  |||||}t|S )zU
        Get feature flags and payloads for a distinct_id by calling decide.
        )r   r    )r   r   r   r   r   rl   respr@   r@   rA   get_feature_flags_and_payloads  s   z%Client.get_feature_flags_and_payloadsc                 C   sd   t d|t |d u r| j}|rt d|t ni }|||||d}t| j| jfd| ji|}t|S )Nr   r   )r   r   r   r   rl   rX   )	r\   r   rl   r   r   rP   rR   rf   r   )r   r   r   r   r   rl   request_datar   r@   r@   rA   r     s   zClient.get_decidec
              
   C   s`  |d urt jdtdd i |pi t }td|t td|t td|t |||||d}
|r=td|t ||
d d	< i }i }|riz
| j|||	d
}W n- t	yh } z| j
d|  W Y d }~nd }~ww | jr{|dkr{| j||pvi |	dd}|p~i  D ]\}}||d| < qdd |pi  D }|r||d< |ri ||
d |
d< | |
|	S )Nr   r   r   r   r   r   )r   r   r   r   r   r   z$groups)rl   z0[FEATURE FLAGS] Unable to get feature variants: $feature_flag_calledT)r   rl   only_evaluate_locally	$feature/c                 S   s   g | ]
\}}|d ur|qS )Fr@   )r   r   valuer@   r@   rA   
<listcomp>m  s    z"Client.capture.<locals>.<listcomp>z$active_feature_flags)r   r   r   rG   r\   r   r   r
   r   ru   rz   	exceptionr   get_all_flagsitemsr   )r   r   r   r   r   r   r   r   send_feature_flagsrl   r   extra_propertiesfeature_variantsefeaturevariantactive_feature_flagsr@   r@   rA   capture7  sP   zClient.capturec                 C   r   )Nr   r   r   r   r   r   r   r   r   r@   r@   rA   ri   v  r   z
Client.setc                 C   r   )Nr   r   r   r   r   	$set_once)r   r   r   r   r   r   r   r@   r@   rA   set_once  r   zClient.set_oncec	           
      C   s   |d urt jdtdd |pi }td|t td|t td|t |r+td|t nd||}d	|||d
|||d}	| |	|S )Nr   r   r   
group_type	group_keyr   r   z${}_{}z$groupidentify)z$group_type
$group_keyz
$group_set)r   r   r   r   r   )r   r   r   r\   r   r   formatr   )
r   r   r   r   r   r   r   rl   r   r   r@   r@   rA   group_identify  s.   zClient.group_identifyc                 C   sP   |d urt jdtdd td|t td|t ||d|d|d}| ||S )	Nr   r   r   previous_idr   )r   aliasz$create_alias)r   r   r   r   )r   r   r   r\   r   r   )r   r   r   r   r   r   rl   r   r@   r@   rA   r     s    
zClient.aliasc           	      C   sh   |d urt jdtdd |pi }td|t td|t td|t ||d< d||||d	}| ||S )
Nr   r   r   r   r   urlz$current_urlz	$pageview)r   r   r   r   r   )r   r   r   r\   r   r   r
   r   )	r   r   r   r   r   r   r   rl   r   r@   r@   rA   page  s$   zClient.pagec              
   K   sZ  |d urt jdtdd z|pi }|d u rd|d< t }td|t td|t |d ur1t|}	nt	 }	|	d u s=|	dkrF| j
d	 W d S t|	}
td
d|
ii| jd}|d
 d }|d d|d d|t| j d| j d| d|}| jr| j
j||d | |d|||||W S  ty } z| j
d|  W Y d }~d S d }~ww )Nr   r   r   Fz$process_person_profiler   r   )NNNz"No exception information availabler   values)rv   r   typer   z	/project/z/person/)z$exception_typez$exception_messagez$exception_listz$exception_personURL)extraz
$exceptionzFailed to capture exception: )r   r   r   r   r\   r   r   r   r4   exc_inforz   warningr   r   rv   r   r&   r`   rP   ro   r   r   ru   )r   r   r   r   r   r   r   r   kwargsr   all_exceptions_with_tracer   $all_exceptions_with_trace_and_in_appr   r@   r@   rA   capture_exception  sT   
 zClient.capture_exceptionc                 C   s  | j rdS |d }|du rtjt d}td|t t|}| |d< d|v r5|d}|r5t||d< |	ds>i |d< d|d d< t
|d d	< |du rQ| j}|rYd
|d d< | jrgi |d | j|d< t|	dd|d< t|}| jd| | jsd
|fS | jr| jd|d  t| j| j| j| j|g| jd d
|fS z| jj|dd | jd|d  d
|fW S  tjy   | jd d|f Y S w )z8Push a new `msg` onto the queue, return `(success, msg)`)Frk   r   Ntzr   r   zposthog-pythonz$libz$lib_versionTz$geoip_disabler   zqueueing: %szenqueued with blocking %s.r   )rV   rX   batchrY   F)blockzenqueued %s.zanalytics-python queue is full)rk   r   nowr	   r\   r%   	isoformatpopstringify_idr   r'   rl   rm   r$   rz   r]   r^   r_   r   rP   rR   rV   rX   rY   rZ   putFullr   )r   r   rl   r   r   r@   r@   rA   r   C  s\   

	
zClient._enqueuec                 C   s(   | j }| }|  | jd| dS )z4Forces a flush from the internal queue to the serverz$successfully flushed about %s items.N)rZ   qsizer   rz   r]   )r   rZ   sizer@   r@   rA   flush  s   zClient.flushc              	   C   sJ   | j D ]}|  z|  W q ty   Y qw | jr#| j  dS dS )zbEnds the consumer thread once the queue is empty.
        Blocks execution until finished
        N)r~   pauser   RuntimeErrorrg   stop)r   r   r@   r@   rA   r     s   
zClient.joinc                 C   s(   |    |   | jr| j  dS dS )z2Flush all messages and cleanly shutdown the clientN)r   r   rq   closer   r@   r@   rA   shutdown  s
   zClient.shutdownc              
   C   s>  z&t | jd| j d| jdd}|d pg | _|d pi | _|d p#i | _W nn tyt } zB|jdkrC| j	
d	 | jrBtdd
dn'|jdkra| j	d g | _i | _i | _| jr`tdddn	| j	
d|  W Y d }~n%d }~w ty } z| j	d| j  | j	| W Y d }~nd }~ww tjt d| _d S )Nz*/api/feature_flag/local_evaluation/?token=z&send_cohorts
   rX   r   rc   rd   i  z[FEATURE FLAGS] Error loading feature flags: To use feature flags, please set a valid personal_api_key. More information: https://posthog.com/docs/api/overviewzYou are using a write-only key with feature flags. To use feature flags, please set a personal_api_key More information: https://posthog.com/docs/api/overview)statusmessagei  z[FEATURE FLAGS] PostHog feature flags quota limited, resetting feature flag data.  Learn more about billing limits at https://posthog.com/docs/billing/limits-alertsz#PostHog feature flags quota limitedz-[FEATURE FLAGS] Error loading feature flags: z`[FEATURE FLAGS] Fetching feature flags failed with following error. We will retry in %s seconds.r   )r   rw   rP   rR   r   rc   rd   r   r   rz   errorr]   r   ru   re   r   r   r	   _last_feature_flag_poll)r   responser   r@   r@   rA   _load_feature_flags  s\   

zClient._load_feature_flagsc                 C   s^   | j s| jd g | _d S |   | jr| j s-tt| j	d| jd| _| j
  d S d S )NzL[FEATURE FLAGS] You have to specify a personal_api_key to use feature flags.)seconds)intervalexecute)rw   rz   r   r   r   rg   is_aliver   r   re   r   r   r@   r@   rA   load_feature_flags  s   zClient.load_feature_flagsr   r   r   warn_on_unknown_groupsc                C   s   | ddr
td| dsdS | dpi }| d}|d urk| j t|}	|	s=| jd| d|d	   td
|	|vr_|rQ| jd|d	  d dS | jd|d	  d dS ||	 }
t|||	 |
S t|||| jS )Nensure_experience_continuityFz&Flag has experience continuity enabledactivefiltersaggregation_group_type_indexz)[FEATURE FLAGS] Unknown group type index z for feature flag r   z!Flag has unknown group type indexz2[FEATURE FLAGS] Can't compute group feature flag: z without group names passed in)	r   r   rc   strrz   r   r]   r   rd   )r   feature_flagr   r   r   r   r   flag_filtersr  
group_namefocused_group_propertiesr@   r@   rA   _compute_flag_locally  s4   


zClient._compute_flag_locallyr   r   r   r   send_feature_flag_eventsrl   c          
   
   C   s.   | j ||||||||d}	|	d u rd S t|	S )Nr  )get_feature_flagbool)
r   r   r   r   r   r   r   r  rl   r   r@   r@   rA   feature_enabled  s   zClient.feature_enabledc                C   s  t d|t t d|t t d|t | jrdS | ||||\}}| |||||}	d}
d}|	du}|st|stz"| ||||||\}
}|
rI|
 nd}	| j	
d| d|	  W n tys } z| j	d|  W Y d}~nd}~ww |r| |||	p}dd|||||
	 |	S )	a#  
        Get a feature flag value for a key by evaluating locally or remotely
        depending on whether local evaluation is enabled and the flag can be
        locally evaluated.

        This also captures the $feature_flag_called event unless send_feature_flag_events is False.
        r   r   r   NFz&Successfully computed flag remotely: #z -> #z-[FEATURE FLAGS] Unable to get flag remotely: )r\   r
   r   r   rk   &_add_local_person_and_group_properties_locally_evaluate_flag%_get_feature_flag_details_from_decide	get_valuerz   r]   ru   r   _capture_feature_flag_called)r   r   r   r   r   r   r   r  rl   r   flag_details
request_idflag_was_locally_evaluatedr   r@   r@   rA   r  *  sH   zClient.get_feature_flagr   r   r   r   r   c           	   
   C   s   | j d u r| jr|   d }| j rv| jd usJ d| j|}|rvz| j|||||d}| jd| d|  W |S  tyZ } z| jd| d|  W Y d }~|S d }~w t	yu } z| j
d|  W Y d }~|S d }~ww |S )Nr   r   r   r   z$Successfully computed flag locally: z -> zFailed to compute flag z
 locally: z7[FEATURE FLAGS] Error while computing variant locally: )r   rw   r   rb   r   r
  rz   r]   r   ru   r   )	r   r   r   r   r   r   r   r   r   r@   r@   rA   r  g  s:   "zClient._locally_evaluate_flag)match_valuer   r   r   r   r  rl   c                C   s  | j rd S |d u r| ||||\}}| |||||}d }
d }d }d }|d ur.| ||}|d u}|sp|spz| ||||||	\}}|rI|jjnd }|rQ| nd}
W n tyo } z| j	
d|  W Y d }~nd }~ww |r| |||
pyd||||	||	 |S )NF:[FEATURE FLAGS] Unable to get feature flags and payloads: )rk   r  r  _compute_payload_locallyr  metadatapayloadr  ru   rz   r   r  )r   r   r   r  r   r   r   r   r  rl   r   r  r  r  r  r   r@   r@   rA   get_feature_flag_payload  sL   zClient.get_feature_flag_payloadrl   c                 C   s@   |  |||||}|d}|d}	|	r|	|nd}
|
|fS )zK
        Calls /decide and returns the flag details and request id
        	requestIdr   N)r   r   )r   r   r   r   r   r   rl   r   r  r   r  r@   r@   rA   r    s
   

z,Client._get_feature_flag_details_from_decider   r  r  r  r  c
                 C   s   | dt | }
|
| j| vrid|d|d|d| |i}|r#||d< |r)||d< t|	trU|	jr;|	jjr;|	jj|d< t|	jtrU|	jjrK|	jj|d	< |	jj	rU|	jj	|d
< | j
|d|||d | j| |
 d S d S )N_z$feature_flagz$feature_flag_responselocally_evaluatedr   z$feature_flag_payloadz$feature_flag_request_idz$feature_flag_reasonz$feature_flag_versionz$feature_flag_idr   )r   rl   )r  rj   
isinstancer   reasondescriptionr  r   r0   idr   add)r   r   r   r   r  r  r   rl   r  r  feature_flag_reported_keyr   r@   r@   rA   r    s8   

z#Client._capture_feature_flag_calledc              
   C   sv   | j rd S | jd u r| jd d S zt| j| j|| jdW S  ty: } z| jd|  W Y d }~d S d }~ww )Nz`[FEATURE FLAGS] You have to specify a personal_api_key to fetch decrypted feature flag payloads.r   z>[FEATURE FLAGS] Unable to get decrypted feature flag payload: )	rk   rw   rz   r   r   rR   rf   ru   r   )r   r   r   r@   r@   rA   get_remote_config_payload   s$   
 z Client.get_remote_config_payloadr  c                 C   sh   d }| j d u r	|S | j |}|r2|dpi }|dpi }t|tr(|r(dnt|}||d }|S )Nr  payloadstrue)rb   r   r"  r  r  )r   r   r  r  flag_definitionr  flag_payloadslookup_valuer@   r@   rA   r    s   
zClient._compute_payload_locallyr   r   r   r   rl   c                C   s   | j ||||||d}|d S )Nr.  featureFlags)get_all_flags_and_payloads)r   r   r   r   r   r   rl   r   r@   r@   rA   r   $  s   
	zClient.get_all_flagsc             
   C   s   | j rd d dS | ||||\}}| j||||d\}}|rM|sMz| j|||||d}	t|	W S  tyL }
 z| jd|
  W Y d }
~
|S d }
~
ww |S )Nr/  featureFlagPayloadsr  )r   r   r   rl   r  )rk   r  #_get_all_flags_and_payloads_locallyr   r    ru   rz   r   )r   r   r   r   r   r   rl   r   fallback_to_decidedecide_responser   r@   r@   rA   r0  9  s0   



z!Client.get_all_flags_and_payloadsc                C   s   t d|t t d|t | jd u r| jr|   i }i }d}| jrt| jD ]N}	z%| j|	|||||d||	d < | |	d ||	d  }
|
rJ|
||	d < W q$ tyV   d}Y q$ t	yr } z| j
d|  d}W Y d }~q$d }~ww nd}||d|fS )	Nr   r   Fr   r   Tz;[FEATURE FLAGS] Error while computing variant and payload: r1  )r\   r   r   r   rw   r   r
  r  r   ru   rz   r   )r   r   r   r   r   r   r   r)  r4  r   matched_payloadr   r@   r@   rA   r3  ]  s@   
z*Client._get_all_flags_and_payloads_locallyc                 C   r   N)r   r   r@   r@   rA   feature_flag_definitions  s   zClient.feature_flag_definitionsc                 C   sH   d|i|pi }i }|r |D ]}d|| i| |pi ||< q||fS )Nr   r   r   )r   r   r   r   r   all_person_propertiesall_group_propertiesr  r@   r@   rA   r    s   
z-Client._add_local_person_and_group_properties)NNFrJ   TNrK   rL   FrD   FrM   rN   rO   NNFTFrD   NFFNNF)NNNNNN)NNNN)	NNNNNNNFN)NNNNNNNN)NNNNNNN)5__name__
__module____qualname____doc__rx   	getLoggerrz   r   propertyr   setterr   r   r  r   r  r   r   r   r   r   r   r   ri   r   r   r   r   r   r   r   r   r   r   r   r   r
  r  r   r  r  r  tupler   r  r  r(  r  r   r0  r3  r8  r  r@   r@   r@   rA   rH   d   s~   

s













?


)

FB2	
3 
=



'8




	

-	
	
%

&rH   c                 C   s$   t ||sd| ||}t|dS )z8Require that the named `field` has the right `data_type`z{0} must have {1}, got: {2}N)r"  r   AssertionError)namefield	data_typer   r@   r@   rA   r\     s   
r\   c                 C   s"   | d u rd S t | tr| S t| S r7  )r"  r
   r  )valr@   r@   rA   r     s
   
r   )Ir   rx   numbersrs   r5   r4   r   r   r   typingr   r   r   r   r   r   r8   dateutil.tzr	   sixr
   posthog.consumerr   posthog.exception_capturer   posthog.exception_utilsr   r   r   posthog.feature_flagsr   r   posthog.pollerr   posthog.requestr   r   r   r   r   r   r   posthog.typesr   r   r   r   r   r   r    r!   r"   posthog.utilsr#   r$   r%   r&   posthog.versionr'   rZ   ImportErrorr[   Numberr   rh   rB   r   r  rG   objectrH   r\   r   r@   r@   r@   rA   <module>   sT    $,+        8