
    \jC                        d Z ddlmZmZmZ ddlmZ ddlmZm	Z	m
Z
mZ  G d d      Z G d d	      Z G d
 d      Z G d de      Z G d d      Z G d d      Z G d d      Z G d d      Z G d d      Z G d d      Z G d d      Zy)z
This submodule contains interfaces for various components of the SDK.

They may be useful in writing new implementations of these components, or for testing.
    )ABCMetaabstractmethodabstractproperty   )VersionedDataKind)AnyCallableMappingOptionalc            
           e Zd ZdZeZed fdedede	e
ge
f   de
fd       Zed fdede	e
ge
f   de
fd	       Zed
eeeeef   f   fd       Zedededefd       Zededefd       Zedefd       Zy)FeatureStorea!  
    Interface for a versioned store for feature flags and related objects received from LaunchDarkly.
    Implementations should permit concurrent access and updates.

    An "object", for ``FeatureStore``, is simply a dict of arbitrary data which must have at least
    three properties: ``key`` (its unique key), ``version`` (the version number provided by
    LaunchDarkly), and ``deleted`` (True if this is a placeholder for a deleted object).

    Delete and upsert requests are versioned: if the version number in the request is less than
    the currently stored version of the object, the request should be ignored.

    These semantics support the primary use case for the store, which synchronizes a collection
    of objects based on update messages that may be received out-of-order.
    c                     | S N xs    =/root/env/lib/python3.12/site-packages/ldclient/interfaces.py<lambda>zFeatureStore.<lambda>   s    ^_     kindkeycallbackreturnc                      y)a  
        Retrieves the object to which the specified key is mapped, or None if the key is not found
        or the associated object has a ``deleted`` property of True. The retrieved object, if any (a
        dict) can be transformed by the specified callback.

        :param kind: The kind of object to get
        :param key: The key whose associated object is to be returned
        :param callback: A function that accepts the retrieved data and returns a transformed value
        :return: The result of executing callback
        Nr   )selfr   r   r   s       r   getzFeatureStore.get       r   c                     | S r   r   r   s    r   r   zFeatureStore.<lambda>*   s    TU r   c                      y)aD  
        Retrieves a dictionary of all associated objects of a given kind. The retrieved dict of keys
        to objects can be transformed by the specified callback.

        :param kind: The kind of objects to get
        :param callback: A function that accepts the retrieved data and returns a transformed value
        Nr   )r   r   r   s      r   allzFeatureStore.all)   r   r   all_datac                      y)az  
        Initializes (or re-initializes) the store with the specified set of objects. Any existing entries
        will be removed. Implementations can assume that this set of objects is up to date-- there is no
        need to perform individual version comparisons between the existing objects and the supplied data.

        :param all_data: All objects to be stored
        Nr   r   r!   s     r   initzFeatureStore.init3   r   r   versionc                      y)a  
        Deletes the object associated with the specified key, if it exists and its version is less than
        the specified version. The object should be replaced in the data store by a
        placeholder with the specified version and a "deleted" property of TErue.

        :param kind: The kind of object to delete
        :param key: The key of the object to be deleted
        :param version: The version for the delete operation
        Nr   )r   r   r   r%   s       r   deletezFeatureStore.delete=   r   r   itemc                      y)aO  
        Updates or inserts the object associated with the specified key. If an item with the same key
        already exists, it should update it only if the new item's version property is greater than
        the old one.

        :param kind: The kind of object to update
        :param item: The object to update or insert
        Nr   r   r   r(   s      r   upsertzFeatureStore.upsertI   r   r   c                      y)zK
        Returns whether the store has been initialized yet or not
        Nr   r   s    r   initializedzFeatureStore.initializedT   r   r   N)__name__
__module____qualname____doc__r   __metaclass__r   r   strr	   r   r   r    r
   dictr$   intr'   r+   r   boolr.   r   r   r   r   r      s    MT_ 
) 
 
xs
?S 
dg 
 
 JU ) XseSj5I Z]   W%6T	8J%JK   	, 	3 	 	 	 , D   T  r   r   c                       e Zd ZdZeZededede	fd       Z
edeee	f   fd       Zedeeeee	f   f   fd       Zeded	e	de	fd
       Zedefd       Zy)FeatureStoreCorea  
    Interface for a simplified subset of the functionality of :class:`FeatureStore`, to be used
    in conjunction with :class:`ldclient.feature_store_helpers.CachingStoreWrapper`. This allows
    developers of custom ``FeatureStore`` implementations to avoid repeating logic that would
    commonly be needed in any such implementation, such as caching. Instead, they can implement
    only ``FeatureStoreCore`` and then create a ``CachingStoreWrapper``.
    r   r   r   c                      y)a  
        Returns the object to which the specified key is mapped, or None if no such item exists.
        The method should not attempt to filter out any items based on their deleted property,
        nor to cache any items.

        :param kind: The kind of object to get
        :param key: The key of the object
        :return: The object to which the specified key is mapped, or None
        Nr   )r   r   r   s      r   get_internalzFeatureStoreCore.get_internale   r   r   c                      y)a(  
        Returns a dictionary of all associated objects of a given kind. The method should not attempt
        to filter out any items based on their deleted property, nor to cache any items.

        :param kind: The kind of objects to get
        :return: A dictionary of keys to items
        Nr   )r   r   s     r   get_all_internalz!FeatureStoreCore.get_all_internalq   r   r   r!   c                      y)a  
        Initializes (or re-initializes) the store with the specified set of objects. Any existing entries
        will be removed. Implementations can assume that this set of objects is up to date-- there is no
        need to perform individual version comparisons between the existing objects and the supplied
        data.

        :param all_data: A dictionary of data kinds to item collections
        Nr   r#   s     r   init_internalzFeatureStoreCore.init_internal{   r   r   r(   c                      y)a  
        Updates or inserts the object associated with the specified key. If an item with the same key
        already exists, it should update it only if the new item's version property is greater than
        the old one. It should return the final state of the item, i.e. if the update succeeded then
        it returns the item that was passed in, and if the update failed due to the version check
        then it returns the item that is currently in the data store (this ensures that
        ``CachingStoreWrapper`` will update the cache correctly).

        :param kind: The kind of object to update
        :param item: The object to update or insert
        :return: The state of the object after the update
        Nr   r*   s      r   upsert_internalz FeatureStoreCore.upsert_internal   r   r   c                      y)a  
        Returns true if this store has been initialized. In a shared data store, it should be able to
        detect this even if initInternal was called in a different process, i.e. the test should be
        based on looking at what is in the data store. The method does not need to worry about caching
        this value; ``CachingStoreWrapper`` will only call it when necessary.
        Nr   r-   s    r   initialized_internalz%FeatureStoreCore.initialized_internal   r   r   N)r/   r0   r1   r2   r   r3   r   r   r4   r5   r;   r
   r=   r?   rA   r7   rC   r   r   r   r9   r9   [   s     M	!2 	 	 	 	 GCI,>   g.?dAS.S&T   $5 T d   d  r   r9   c                   $    e Zd Zd Zd ZdefdZy)BackgroundOperationc                      y)zb
        Starts an operation in the background.  Should return immediately and not block.
        Nr   r-   s    r   startzBackgroundOperation.start        	r   c                      y)zu
        Stops an operation running in the background.  May return before the operation is actually stopped.
        Nr   r-   s    r   stopzBackgroundOperation.stop   rH   r   r   c                      y)z?
        Returns whether the operation is alive or not
        Tr   r-   s    r   is_alivezBackgroundOperation.is_alive   s     r   N)r/   r0   r1   rG   rJ   r7   rL   r   r   r   rE   rE      s    $ r   rE   c                        e Zd ZdZeZdefdZy)UpdateProcessora;  
    Interface for the component that obtains feature flag data in some way and passes it to a
    :class:`FeatureStore`. The built-in implementations of this are the client's standard streaming
    or polling behavior. For testing purposes, there is also :func:`ldclient.integrations.Files.new_data_source()`.
    r   c                      y)zx
        Returns whether the update processor has received feature flags and has initialized its feature store.
        Nr   r-   s    r   r.   zUpdateProcessor.initialized   r   r   N)r/   r0   r1   r2   r   r3   r7   r.   r   r   r   rN   rN      s    
 MT r   rN   c                   D    e Zd ZdZeZed        Zed        Zed        Z	y)EventProcessorz
    Interface for the component that buffers analytics events and sends them to LaunchDarkly.
    The default implementation can be replaced for testing purposes.
    c                      y)z>
        Processes an event to be sent at some point.
        Nr   )r   events     r   
send_eventzEventProcessor.send_event   r   r   c                      y)ah  
        Specifies that any buffered events should be sent as soon as possible, rather than waiting
        for the next flush interval. This method is asynchronous, so events still may not be sent
        until a later time. However, calling ``stop()`` will synchronously deliver any events that were
        not yet delivered prior to shutting down.
        Nr   r-   s    r   flushzEventProcessor.flush   r   r   c                      y)z[
        Shuts down the event processor after first delivering all pending events.
        Nr   r-   s    r   rJ   zEventProcessor.stop   r   r   N)
r/   r0   r1   r2   r   r3   r   rT   rV   rJ   r   r   r   rQ   rQ      sH     M 
    r   rQ   c                       e Zd ZdZeZd Zy)FeatureRequesterz
    Interface for the component that acquires feature flag data in polling mode. The default
    implementation can be replaced for testing purposes.
    c                      y)z)
        Gets all feature flags.
        Nr   r-   s    r   get_allzFeatureRequester.get_all   rH   r   N)r/   r0   r1   r2   r   r3   r[   r   r   r   rY   rY      s     Mr   rY   c                   &    e Zd ZdZedefd       Zy)DiagnosticDescriptionzP
    Optional interface for components to describe their own configuration.
    r   c                      y)z
        Used internally by the SDK to inspect the configuration.
        :param config: the full configuration, in case this component depends on properties outside itself
        :return: a string describing the type of the component, or None
        Nr   )r   configs     r   describe_configurationz,DiagnosticDescription.describe_configuration        	r   N)r/   r0   r1   r2   r   r4   r`   r   r   r   r]   r]      s"       r   r]   c                   >    e Zd ZdZdee   fdZedee   fd       Zy)BigSegmentStoreMetadatazD
    Values returned by :func:`BigSegmentStore.get_metadata()`.
    last_up_to_datec                     || _         y r   )_BigSegmentStoreMetadata__last_up_to_date)r   rd   s     r   __init__z BigSegmentStoreMetadata.__init__  s    !0r   r   c                     | j                   S )z
        The Unix epoch millisecond timestamp of the last update to the ``BigSegmentStore``. It is
        None if the store has never been updated.
        rf   r-   s    r   rd   z'BigSegmentStoreMetadata.last_up_to_date  s     %%%r   N)	r/   r0   r1   r2   r   r6   rh   propertyrd   r   r   r   rc   rc      s6      &# & &r   rc   c                   V    e Zd ZdZedefd       Zededee	   fd       Z
ed        Zy)BigSegmentStorea  
    Interface for a read-only data store that allows querying of user membership in Big Segments.

    Big Segments are a specific type of user segments. For more information, read the LaunchDarkly
    documentation: https://docs.launchdarkly.com/home/users/big-segments
    r   c                      y)z
        Returns information about the overall state of the store. This method will be called only
        when the SDK needs the latest state, so it should not be cached.

        :return: the store metadata
        Nr   r-   s    r   get_metadatazBigSegmentStore.get_metadata       	r   context_hashc                      y)a{  
        Queries the store for a snapshot of the current segment state for a specific context.
    
        The context_hash is a base64-encoded string produced by hashing the context key as defined
        by the Big Segments specification; the store implementation does not need to know the details
        of how this is done, because it deals only with already-hashed keys, but the string can be
        assumed to only contain characters that are valid in base64.
    
        The return value should be either a ``dict``, or None if the context is not referenced in any big
        segments. Each key in the dictionary is a "segment reference", which is how segments are
        identified in Big Segment data. This string is not identical to the segment key-- the SDK
        will add other information. The store implementation should not be concerned with the
        format of the string. Each value in the dictionary is True if the context is explicitly included
        in the segment, False if the context is explicitly excluded from the segment-- and is not also
        explicitly included (that is, if both an include and an exclude existed in the data, the
        include would take precedence). If the context's status in a particular segment is undefined,
        there should be no key or value for that segment.
    
        This dictionary may be cached by the SDK, so it should not be modified after it is created.
        It is a snapshot of the segment membership state at one point in time.

        :param context_hash: the hashed context key
        :return: True/False values for Big Segments that reference this context
        Nr   )r   rp   s     r   get_membershipzBigSegmentStore.get_membership"  s    4 	r   c                      y)zX
        Shuts down the store component and releases and resources it is using.
        Nr   r-   s    r   rJ   zBigSegmentStore.stop>  s    
 	r   N)r/   r0   r1   r2   r   rc   rn   r4   r   r5   rr   rJ   r   r   r   rl   rl     s]     5   3 8D>  6  r   rl   c                   L    e Zd ZdZdedefdZedefd       Zedefd       Zy)	BigSegmentStoreStatusa  
    Information about the state of a Big Segment store, provided by :class:`BigSegmentStoreStatusProvider`.

    Big Segments are a specific type of user segments. For more information, read the LaunchDarkly
    documentation: https://docs.launchdarkly.com/home/users/big-segments
    	availablestalec                      || _         || _        y r   )!_BigSegmentStoreStatus__available_BigSegmentStoreStatus__stale)r   rv   rw   s      r   rh   zBigSegmentStoreStatus.__init__L  s    $r   r   c                     | j                   S )a  
        True if the Big Segment store is able to respond to queries, so that the SDK can evaluate
        whether a user is in a segment or not.
    
        If this property is False, the store is not able to make queries (for instance, it may not have
        a valid database connection). In this case, the SDK will treat any reference to a Big Segment
        as if no users are included in that segment. Also, the :func:`ldclient.evaluation.EvaluationDetail.reason`
        associated with with any flag evaluation that references a Big Segment when the store is not
        available will have a ``bigSegmentsStatus`` of ``"STORE_ERROR"``.
        )ry   r-   s    r   rv   zBigSegmentStoreStatus.availableP  s     r   c                     | j                   S )az  
        True if the Big Segment store is available, but has not been updated within the amount of time
        specified by {BigSegmentsConfig#stale_after}.

        This may indicate that the LaunchDarkly Relay Proxy, which populates the store, has stopped
        running or has become unable to receive fresh data from LaunchDarkly. Any feature flag
        evaluations that reference a Big Segment will be using the last known data, which may be out
        of date. Also, the :func:`ldclient.evaluation.EvaluationDetail.reason` associated with those evaluations
        will have a ``bigSegmentsStatus`` of ``"STALE"``.
        )rz   r-   s    r   rw   zBigSegmentStoreStatus.stale^  s     ||r   N)	r/   r0   r1   r2   r7   rh   rj   rv   rw   r   r   r   ru   ru   E  sP    $ t   4     t  r   ru   c                   r    e Zd ZdZedefd       Zedeegdf   ddfd       Z	edeegdf   ddfd       Z
y)BigSegmentStoreStatusProvidera  
    An interface for querying the status of a Big Segment store.
    
    The Big Segment store is the component that receives information about Big Segments, normally
    from a database populated by the LaunchDarkly Relay Proxy. Big Segments are a specific type
    of user segments. For more information, read the LaunchDarkly documentation:
    https://docs.launchdarkly.com/home/users/big-segments
    
    An implementation of this abstract class is returned by :func:`ldclient.client.LDClient.big_segment_store_status_provider`.
    Application code never needs to implement this interface.
    
    There are two ways to interact with the status. One is to simply get the current status; if its
    ``available`` property is true, then the SDK is able to evaluate user membership in Big Segments,
    and the ``stale`` property indicates whether the data might be out of date.
    
    The other way is to subscribe to status change notifications. Applications may wish to know if
    there is an outage in the Big Segment store, or if it has become stale (the Relay Proxy has
    stopped updating it with new data), since then flag evaluations that reference a Big Segment
    might return incorrect values. Use :func:`add_listener()` to register a callback for notifications.
    r   c                      y)zT
        Gets the current status of the store.

        :return: the status
        Nr   r-   s    r   statusz$BigSegmentStoreStatusProvider.status  ra   r   listenerNc                      y)z
        Subscribes for notifications of status changes.

        The listener is a function or method that will be called with a single parameter: the
        new ``BigSegmentStoreStatus``.

        :param listener: the listener to add
        Nr   r   r   s     r   add_listenerz*BigSegmentStoreStatusProvider.add_listener  s     	r   c                      y)z
        Unsubscribes from notifications of status changes.

        :param listener: a listener that was previously added with :func:`add_listener()`; if it was not,
            this method does nothing
        Nr   r   s     r   remove_listenerz-BigSegmentStoreStatusProvider.remove_listener  ro   r   )r/   r0   r1   r2   r   ru   r   r   r	   r   r   r   r   r   r~   r~   m  s    * -   	X/D.Et.K%L 	QU 	 	 2G1H$1N(O TX  r   r~   N)r2   abcr   r   r   versioned_data_kindr   typingr   r	   r
   r   r   r9   rE   rN   rQ   rY   r]   rc   rl   ru   r~   r   r   r   <module>r      s    : 9 2 3 3M M`A AJ .)  :  & &"3 3j% %P3 3r   