
    \j]                        d Z ddlmZmZmZmZmZ ddlm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 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 ddlmZ ddlm Z 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+ ddl,m-Z-m.Z. ddl/m0Z0m1Z1m2Z2 ddl3m4Z4m5Z5m6Z6 ddlm2Z2 ddlm7Z7  G d de2      Z8de6de9defdZ: G d d      Z;dd gZ<y)!zW
This submodule contains the client class that provides most of the SDK functionality.
    )OptionalAnyDictMappingUnion   )AnyNumN)Config)Context)_FeatureStoreDataSetSorter)EvaluationDetailFeatureFlagsState)BigSegmentStoreManager)FeatureRequesterImpl)PollingUpdateProcessor)StreamingUpdateProcessor)	Evaluatorerror_reason)create_diagnostic_id_DiagnosticAccumulator)DefaultEventProcessor)EventFactory)NullEventProcessorNullUpdateProcessor)check_uwsgilog)BigSegmentStoreStatusProviderFeatureRequesterFeatureStore)FEATURESSEGMENTSVersionedDataKind)r   )Lockc                   t    e Zd ZdZdefdZdeeeee	e
e
f   f   f   fdZd Zd Zd Zd	 Zed
efd       Zy)_FeatureStoreClientWrapperzProvides additional behavior that the client requires before or after feature store operations.
    Currently this just means sorting the data set for init(). In the future we may also use this
    to provide an update listener capability.
    storec                     || _         y N)r&   )selfr&   s     9/root/env/lib/python3.12/site-packages/ldclient/client.py__init__z#_FeatureStoreClientWrapper.__init__+   s	    
    all_datac                 ^    | j                   j                  t        j                  |            S r(   )r&   initr   sort_all_collections)r)   r-   s     r*   r/   z_FeatureStoreClientWrapper.init.   s!    zz9NNxXYYr,   c                 <    | j                   j                  |||      S r(   )r&   get)r)   kindkeycallbacks       r*   r2   z_FeatureStoreClientWrapper.get1   s    zz~~dC22r,   c                 :    | j                   j                  ||      S r(   )r&   all)r)   r3   r5   s      r*   r7   z_FeatureStoreClientWrapper.all4   s    zz~~dH--r,   c                 <    | j                   j                  |||      S r(   )r&   delete)r)   r3   r4   versions       r*   r9   z!_FeatureStoreClientWrapper.delete7   s    zz  sG44r,   c                 :    | j                   j                  ||      S r(   )r&   upsert)r)   r3   items      r*   r<   z!_FeatureStoreClientWrapper.upsert:   s    zz  t,,r,   returnc                 .    | j                   j                  S r(   )r&   initializedr)   s    r*   r@   z&_FeatureStoreClientWrapper.initialized=   s    zz%%%r,   N)__name__
__module____qualname____doc__r   r+   r   r"   strr   r   r/   r2   r7   r9   r<   propertyboolr@    r,   r*   r%   r%   %   sm    
l ZW%6T#s(^@S8T%TU Z3.5- &T & &r,   r%   r3   r4   r>   c                 p    | j                  ||d       }t        |t              r|j                  |      S |S )Nc                     | S r(   rI   xs    r*   <lambda>z!_get_store_item.<locals>.<lambda>F   s    ! r,   )r2   
isinstancedictdecode)r&   r3   r4   r=   s       r*   _get_store_itemrR   B   s3     99T3,D *4 64;;t@D@r,   c            
       l   e Zd ZdZddedefdZd Zd Zde	e
   fdZd	 Zd
 Zd Zd Z	 	 d de
deeef   de	e   de	e   fdZdeeef   fdZdefdZdefdZd Zde
deeef   dedefdZde
deeef   dedefdZde
deeef   defdZdeeef   defdZ deeef   de
fdZ!e"de#fd       Z$y)!LDClienta  The LaunchDarkly SDK client object.

    Applications should configure the client at startup time and continue to use it throughout the lifetime
    of the application, rather than creating instances on the fly. The best way to do this is with the
    singleton methods :func:`ldclient.set_config()` and :func:`ldclient.get()`. However, you may also call
    the constructor directly if you need to maintain multiple instances.

    Client instances are thread-safe.
    config
start_waitc                    t                || _        | j                  j                          d| _        t	               | _        t        d      | _        t        d      | _        t        | j                  j                        | _        t        | j                  j                        | _        t        fdfdfdt               | _        | j                  j$                  rt!        j&                  d       | j                  j(                  rt!        j&                  d       | j+                  | j                        }t-        j.                         }| j1                  | j                  | j                  ||      | _        | j2                  j5                          |d	kD  ra| j                  j$                  sK| j                  j(                  s5t!        j&                  d
t7        |      z   dz          |j9                  |       | j2                  j;                         du rt!        j&                  d       yt!        j<                  d       y)zConstructs a new LDClient instance.

        :param config: optional custom configuration
        :param start_wait: the number of seconds to wait for a successful connection to LaunchDarkly
        NFTc                 &    t        t        |       S r(   )rR   r    r4   r&   s    r*   rN   z#LDClient.__init__.<locals>.<lambda>k       x= r,   c                 &    t        t        |       S r(   )rR   r!   rY   s    r*   rN   z#LDClient.__init__.<locals>.<lambda>l   rZ   r,   c                 &    j                  |       S r(   )get_user_membership)r4   big_segment_store_managers    r*   rN   z#LDClient.__init__.<locals>.<lambda>m   s    1EEcJ r,   z+Started LaunchDarkly Client in offline modez'Started LaunchDarkly Client in LDD moder   zWaiting up to z1 seconds for LaunchDarkly client to initialize...zStarted LaunchDarkly Client: OKzuInitialization timeout exceeded for LaunchDarkly Client or an error occurred. Feature Flags may not yet be available.)r   _config	_validate_event_processorr#   _lockr   _event_factory_default_event_factory_with_reasonsr%   feature_store_storer   big_segments$_LDClient__big_segment_store_managerr   r   
_evaluatorofflineinfouse_ldd_set_event_processor	threadingEvent_make_update_processor_update_processorstartrF   waitr@   warning)r)   rU   rV   diagnostic_accumulatorupdate_processor_readyr^   r&   s        @@r*   r+   zLDClient.__init__T   s    	  $V
&25&9#+7+=(*4<<+E+EF$:4<<;T;T$U!+D(#==J	
 <<HHBC<<HH>?!%!:!:4<<!H!*!2!%!<!<T\\4;;Xn  qG  "H$$&>$,,"6"6t||?S?SHH%J7:mmn"''
3!!--/47HH67KK ? @r,   c                    |j                   s|j                  st               | _        y |j                  s8t        |      }|j                  rd n
t        |      }t        ||      | _        |S |j	                  |      | _        y )N)ru   )	rj   send_eventsr   ra   event_processor_classr   diagnostic_opt_outr   r   )r)   rU   diagnostic_idru   s       r*   rm   zLDClient._set_event_processor   su    >>!3!3$6$8D!++08M-3-F-FTLbcpLq"$9&[q$rD!)) & < <V Dr,   c                    |j                   r>t        j                  dt        |j                         z          |j                  |||      S |j                  s|j
                  rt        |||      S |j                  rt        ||||      S t        j                  d       t        j                  d       |j                  r|j                  |      }nt        |      }t        ||||      S )Nz'Using user-specified update processor: zDisabling streaming APIzXYou should only disable the streaming API if instructed to do so by LaunchDarkly support)update_processor_classr   rk   rF   rj   rl   r   streamr   rt   feature_requester_classr   r   )r)   rU   r&   readyru   feature_requesters         r*   rp   zLDClient._make_update_processor   s    ((HH>VEbEbAccd00FF>>V^^&vue<<==+FE5BXYY*+no)) & > >v F 4V <%f.?NNr,   r>   c                 .    | j                   j                  S )z(Returns the configured SDK key.
        )r_   sdk_keyrA   s    r*   get_sdk_keyzLDClient.get_sdk_key        ||###r,   c                     t        j                  d       | j                  j                          | j                  j                          | j
                  j                          y)zReleases all threads and network connections used by the LaunchDarkly client.

        Do not attempt to use the client after calling this method.
        zClosing LaunchDarkly client..N)r   rk   ra   stoprq   rh   rA   s    r*   closezLDClient.close   sG    
 	01""$##%((--/r,   c                     | S r(   rI   rA   s    r*   	__enter__zLDClient.__enter__   s    r,   c                 $    | j                          y r(   )r   )r)   typevalue	tracebacks       r*   __exit__zLDClient.__exit__   s    

r,   c                 :    | j                   j                  |       y r(   )ra   
send_event)r)   events     r*   _send_eventzLDClient._send_event   s    ((/r,   N
event_namecontextdatametric_valuec                 :   t        |t              s/t        j                  dt               t        j
                  |      }|j                  s#t        j                  d|j                  z         y| j                  | j                  j                  ||||             y)a  Tracks that an application-defined event occurred.

        This method creates a "custom" analytics event containing the specified event name (key)
        and context properties. You may attach arbitrary data or a metric value to the event with the
        optional ``data`` and ``metric_value`` parameters.

        Note that event delivery is asynchronous, so the event may not actually be sent until later;
        see :func:`flush()`.

        If you pass a dictionary of user attributes instead of a :class:`ldclient.Context`,
        the SDK will convert the user to a Context. There is some overhead to this conversion,
        so it is more efficient to pass a Context.

        DEPRECATED: This method will no longer accept a dictionary for the context parameter starting in 9.0.0

        :param event_name: the name of the event
        :param context: the evaluation context or user associated with the event
        :param data: optional additional data associated with the event
        :param metric_value: a numeric value used by the LaunchDarkly experimentation feature in
          numeric custom metrics; can be omitted if this event is used by only non-numeric metrics
        z.track will require a Context instance in 9.0.0zInvalid context for track (%s)N)rO   r   warningswarnDeprecationWarning	from_dictvalidr   rt   errorr   rc   new_custom_event)r)   r   r   r   r   s        r*   trackzLDClient.track   su    . '7+MMJL^_''0G}}KK87==HIT88II*|- .r,   c                    t        |t              s/t        j                  dt               t        j
                  |      }|j                  s#t        j                  d|j                  z         y|j                  dk(  r"|j                  st        j                  d       y| j                  | j                  j                  |             y)a  Reports details about an evaluation context.

        This method simply creates an analytics event containing the context properties, to
        that LaunchDarkly will know about that context if it does not already.

        Evaluating a flag, by calling :func:`variation()` or :func:`variation_detail()`, also
        sends the context information to LaunchDarkly (if events are enabled), so you only
        need to use :func:`identify()` if you want to identify the context without evaluating a
        flag.

        If you pass a dictionary of user attributes instead of a :class:`ldclient.Context`,
        the SDK will convert the user to a Context. There is some overhead to this conversion,
        so it is more efficient to pass a Context.

        DEPRECATED: This method will no longer accept a dictionary for the context parameter starting in 9.0.0

        :param context: the context to register
        z1identify will require a Context instance in 9.0.0z!Invalid context for identify (%s) zEmpty user key for identifyN)rO   r   r   r   r   r   r   r   rt   r   r4   multipler   rc   new_identify_eventr)   r   s     r*   identifyzLDClient.identify   s    & '7+MMMOab''0G}}KK;gmmKL[[Bw'7'7 KK56T88KKGTUr,   c                 .    | j                   j                  S )z7Returns true if the client is in offline mode.
        )r_   rj   rA   s    r*   
is_offlinezLDClient.is_offline   r   r,   c                     | j                         xs2 | j                  j                  xs | j                  j	                         S )a  Returns true if the client has successfully connected to LaunchDarkly.

        If this returns false, it means that the client has not yet successfully connected to LaunchDarkly.
        It might still be in the process of starting up, or it might be attempting to reconnect after an
        unsuccessful attempt, or it might have received an unrecoverable error (such as an invalid SDK key)
        and given up.
        )r   r_   rl   rq   r@   rA   s    r*   is_initializedzLDClient.is_initialized  s4      `DLL$8$8`D<R<R<^<^<``r,   c                 d    | j                   j                  ry| j                  j                         S )a  Flushes all pending analytics events.

        Normally, batches of events are delivered in the background at intervals determined by the
        ``flush_interval`` property of :class:`ldclient.config.Config`. Calling ``flush()``
        schedules the next event delivery to be as soon as possible; however, the delivery still
        happens asynchronously on a worker thread, so this method will return immediately.
        N)r_   rj   ra   flushrA   s    r*   r   zLDClient.flush  s)     <<$$**,,r,   r4   defaultc                 R    | j                  |||| j                        j                  S )a  Calculates the value of a feature flag for a given context.

        If you pass a dictionary of user attributes instead of a :class:`ldclient.Context`,
        the SDK will convert the user to a Context. There is some overhead to this conversion,
        so it is more efficient to pass a Context.

        DEPRECATED: This method will no longer accept a dictionary for the context parameter starting in 9.0.0

        :param key: the unique key for the feature flag
        :param context: the evaluation context or user
        :param default: the default value of the flag, to be used if the value is not
          available from LaunchDarkly
        :return: the variation for the given context, or the ``default`` value if the flag cannot be evaluated
        )_evaluate_internalrc   r   r)   r4   r   r   s       r*   	variationzLDClient.variation  s'     &&sGWd>Y>YZ```r,   c                 >    | j                  |||| j                        S )a  Calculates the value of a feature flag for a given context, and returns an object that
        describes the way the value was determined.

        The ``reason`` property in the result will also be included in analytics events, if you are
        capturing detailed event data for this flag.

        If you pass a dictionary of user attributes instead of a :class:`ldclient.Context`,
        the SDK will convert the user to a Context. There is some overhead to this conversion,
        so it is more efficient to pass a Context.

        DEPRECATED: This method will no longer accept a dictionary for the context parameter starting in 9.0.0

        :param key: the unique key for the feature flag
        :param context: the evaluation context or user
        :param default: the default value of the flag, to be used if the value is not
          available from LaunchDarkly
        :return: an :class:`ldclient.evaluation.EvaluationDetail` object that includes the feature
          flag value and evaluation reason
        )r   rd   r   s       r*   variation_detailzLDClient.variation_detail,  s!    ( &&sGWd>^>^__r,   c           	      4   | j                   j                  ||      }| j                   j                  rt        |d t	        d            S | j                         s| j                  j                  rt        j                  d|z          nbt        j                  dt        |      z   dz   |z          t	        d      }| j                  |j                  ||||             t        |d |      S t        |t              s/t        j                   dt"               t        j$                  |      }|j&                  s8t        j                  d|j(                  z         t        |d t	        d            S 	 t+        | j                  t,        |      }|s;t	        d      }| j                  |j                  ||||             t        |d |      S 	 | j8                  j;                  |||      }|j<                  xs g D ]  }	| j                  |	        |j>                  }
|
jA                         rt        |d |
jB                        }
| j                  |jE                  |||
|             |
S # t.        $ r}t        j(                  d|d	t1        |             t        j2                  t5        j6                                t	        d
      }| j                  |j                  ||||             t        |d |      cY d }~S d }~ww xY w# t.        $ r}t        j(                  d|d	t1        |             t        j2                  t5        j6                                t	        d
      }| j                  |jG                  ||||             t        |d |      cY d }~S d }~ww xY w)NCLIENT_NOT_READYz~Feature Flag evaluation attempted before client has initialized - using last known values from feature store for feature key: zpFeature Flag evaluation attempted before client has initialized! Feature store unavailable - returning default: z for feature key: z:variation methods will require a Context instance in 9.0.0zEContext was invalid for flag evaluation (%s); returning default valueUSER_NOT_SPECIFIEDz0Unexpected error while retrieving feature flag "z": 	EXCEPTIONFLAG_NOT_FOUNDz0Unexpected error while evaluating feature flag ")$r_   get_defaultrj   r   r   r   rf   r@   r   rt   rF   r   new_unknown_flag_eventrO   r   r   r   r   r   r   r   rR   r    	Exceptionreprdebugr   
format_excri   evaluateeventsdetailis_default_valuereasonnew_eval_eventnew_default_event)r)   r4   r   r   event_factoryr   flageresultr   r   s              r*   r   zLDClient._evaluate_internalB  s   ,,**38<<#GT<@R3STT""${{&&  ]  `c  c  d  Ow<(*>?ADE F%&89  !E!Ec7T[]c!de'v>>'7+MMVXjk''0G}}KK_biboboop#GT<@T3UVV	;"4;;#>D !"23F]AA#wPWY_`a#GT6::?11$O#]]0b ,E$$U+,**,-gtV]]KF  !=!=dGVU\!]^'  	;IIUXZ^_`ZabcIIi**,-!+.F]AA#wPWY_`a#GT6::	;(  ?		Y\^bcd^efg		)..01%k2  !@!@wPWY_!`a'v>>?s?   .I" BK> "	K;+BK60K;6K;>	NBNNNc                 2   | j                   j                  r t        j                  d       t	        d      S | j                         sL| j                  j                  rt        j                  d       n t        j                  d       t	        d      S t        |t              s/t        j                  dt               t        j                  |      }|j                  s-t        j                  d|j                  z         t	        d      S t	        d      }|j!                  dd      }|j!                  d	d      }|j!                  d
d      }	 | j                  j#                  t$        d       }|t'        d      	 |j-                         D ]  \  }	}
|r|
j!                  dd      s	 | j.                  j1                  |
|| j2                        j4                  }t?        j@                  |
|jB                        }|
d   |jD                  |jF                  |jB                  |
d   |
j!                  dd      xs |||
j!                  dd      d}|jI                  |||        |S # t(        $ r6}t        j                  dt+        |      z         t	        d      cY d}~S d}~ww xY w# t(        $ rh}t        j                  d|	dt+        |             t        j6                  t9        j:                                ddd}t=        dd|      }Y d}~8d}~ww xY w)a  Returns an object that encapsulates the state of all feature flags for a given user,
        including the flag values and also metadata that can be used on the front end. See the
        JavaScript SDK Reference Guide on
        `Bootstrapping <https://docs.launchdarkly.com/sdk/features/bootstrapping#javascript>`_.

        This method does not send analytics events back to LaunchDarkly.

        DEPRECATED: This method will no longer accept a dictionary for the context parameter starting in 9.0.0

        :param user: the end user requesting the feature flags
        :param kwargs: optional parameters affecting how the state is computed - see below

        :Keyword Arguments:
          * **client_side_only** (*boolean*) --
            set to True to limit it to only flags that are marked for use with the client-side SDK
            (by default, all flags are included)
          * **with_reasons** (*boolean*) --
            set to True to include evaluation reasons in the state (see :func:`variation_detail()`)
          * **details_only_for_tracked_flags** (*boolean*) --
            set to True to omit any metadata that is normally only used for event generation, such
            as flag versions and evaluation reasons, unless the flag has event tracking or debugging
            turned on

        :return: a FeatureFlagsState object (will never be None; its ``valid`` property will be False
          if the client is offline, has not been initialized, or the user is None or has no key)
        zNall_flags_state() called, but client is in offline mode. Returning empty stateFzlall_flags_state() called before client has finished initializing! Using last known values from feature storezsall_flags_state() called before client has finished initializing! Feature store unavailable - returning empty statez8all_flags_state will require a Context instance in 9.0.0zEContext was invalid for all_flags_state (%s); returning default valueTclient_side_onlywith_reasonsdetails_only_for_tracked_flagsc                     | S r(   rI   rL   s    r*   rN   z*LDClient.all_flags_state.<locals>.<lambda>  s    A r,   Nzfeature store errorz+Unable to read flags for all_flag_state: %s
clientSidezError evaluating flag "z" in all_flags_state: ERRORr   )r3   	errorKindr4   r:   trackEventsdebugEventsUntilDate)r4   r   r   r   r:   r   trackReasonr   )%r_   rj   r   rt   r   r   rf   r@   rO   r   r   r   r   r   r   r   r2   r7   r    
ValueErrorr   r   itemsri   r   rc   r   r   r   r   r   r   is_experimentr   r   variation_indexadd_flag)r)   r   kwargsstateclient_onlyr   details_only_if_tracked	flags_mapr   r4   r   r   r   requires_experiment_data
flag_states                  r*   all_flags_statezLDClient.all_flags_statev  s   6 <<KKhi$U++""${{&&  K  L  R  S(//'7+MMTVhi''0G}}KK_biboboop$U++!$'jj!3U;zz.%8"(**-Mu"U	,+>I  !677 ! #* 	NIC488L%#@>11$A\A\]dd (4'A'A$'V$E{#33 --	?#xxu=YAY7(,1G(N	J NN:|5LM/	N2 ;  	,IICd1gMN$U++	,  >		SVX\]^X_`a		)..01")D)$f=	>s7   .I# (1J%#	J",+JJ"J"%	L.ALLc                    t        |t              s/t        j                  dt               t        j
                  |      }|j                  s#t        j                  d|j                  z         yt        j                  t        | j                  j                        j                         |j                   j                         t"        j$                        j'                         S )a  Creates a hash string that can be used by the JavaScript SDK to identify a context.

        For more information, see the documentation on
        `Secure mode <https://docs.launchdarkly.com/sdk/features/secure-mode#configuring-secure-mode-in-the-javascript-client-side-sdk>`_.

        DEPRECATED: This method will no longer accept a dictionary for the context parameter starting in 9.0.0

        :param context: the evaluation context or user
        :return: the hash string
        z9secure_mode_hash will require a Context instance in 9.0.0zCContext was invalid for secure_mode_hash (%s); returning empty hashr   )rO   r   r   r   r   r   r   r   rt   r   hmacnewrF   r_   r   encodefully_qualified_keyhashlibsha256	hexdigestr   s     r*   secure_mode_hashzLDClient.secure_mode_hash  s     '7+MMUWij''0G}}KK]`g`m`mmnxxDLL00188:G<W<W<^<^<`bibpbpq{{}}r,   c                 .    | j                   j                  S )a=  
        Returns an interface for tracking the status of a Big Segment store.

        The :class:`ldclient.interfaces.BigSegmentStoreStatusProvider` has methods for checking
        whether the Big Segment store is (as far as the SDK knows) currently operational and
        tracking changes in this status.
        )rh   status_providerrA   s    r*   !big_segment_store_status_providerz*LDClient.big_segment_store_status_provider  s     //???r,   )   )NN)%rB   rC   rD   rE   r
   floatr+   rm   rp   r   rF   r   r   r   r   r   r   rP   r   r   r	   r   r   rH   r   r   r   r   r   r   r   r   r   r   rG   r   r   rI   r,   r*   rT   rT   J   s   1@v 1@5 1@f
O*$Xc] $
00 Y]-1. .eD'M.B .(SV- .$V,.@Vgtm 4 V>$D $
a a
-aS a5$+? a# aRU a"`C `%2F `QT `Yi `,2?c 2?E'4-4H 2?SV 2?hRuWd]'; RJ[ Rh~gtm(< ~ ~& @3P @ @r,   rT   r
   )=rE   typingr   r   r   r   r   implr	   r   r   rn   r   r   ldclient.configr
   ldclient.contextr   ldclient.feature_storer   ldclient.evaluationr   r   ldclient.impl.big_segmentsr   *ldclient.impl.datasource.feature_requesterr    ldclient.impl.datasource.pollingr   "ldclient.impl.datasource.streamingr   ldclient.impl.evaluatorr   r    ldclient.impl.events.diagnosticsr   r   $ldclient.impl.events.event_processorr   ldclient.impl.events.typesr   ldclient.impl.stubsr   r   ldclient.impl.utilr   r   ldclient.interfacesr   r   r   ldclient.versioned_data_kindr    r!   r"   r#   r%   rF   rR   rT   __all__rI   r,   r*   <module>r     s    7 6       " $ = C = K C G ; Y F 3 G / ] ] N N / & &:A!2 A A A\@ \@~ x
 r,   