Skip to content

Commit 1115afb

Browse files
authored
feat: Add support for payload filtering (#323)
1 parent 5d27941 commit 1115afb

File tree

6 files changed

+35
-1
lines changed

6 files changed

+35
-1
lines changed

contract-tests/client_entity.py

+4
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,16 @@ def __init__(self, tag, config):
2727
streaming = config["streaming"]
2828
if streaming.get("baseUri") is not None:
2929
opts["stream_uri"] = streaming["baseUri"]
30+
if streaming.get("filter") is not None:
31+
opts["payload_filter_key"] = streaming["filter"]
3032
_set_optional_time_prop(streaming, "initialRetryDelayMs", opts, "initial_reconnect_delay")
3133
else:
3234
opts['stream'] = False
3335
polling = config["polling"]
3436
if polling.get("baseUri") is not None:
3537
opts["base_uri"] = polling["baseUri"]
38+
if polling.get("filter") is not None:
39+
opts["payload_filter_key"] = polling["filter"]
3640
_set_optional_time_prop(polling, "pollIntervalMs", opts, "poll_interval")
3741

3842
if config.get("events") is not None:

contract-tests/service.py

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ def status():
6565
'all-flags-details-only-for-tracked-flags',
6666
'big-segments',
6767
'context-type',
68+
'filtering',
6869
'secure-mode-hash',
6970
'tags',
7071
'migrations',

ldclient/config.py

+23
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ def __init__(
182182
hooks: Optional[List[Hook]] = None,
183183
enable_event_compression: bool = False,
184184
omit_anonymous_contexts: bool = False,
185+
payload_filter_key: Optional[str] = None,
185186
):
186187
"""
187188
:param sdk_key: The SDK key for your LaunchDarkly account. This is always required.
@@ -250,6 +251,7 @@ def __init__(
250251
:param hooks: Hooks provide entrypoints which allow for observation of SDK functions.
251252
:param enable_event_compression: Whether or not to enable GZIP compression for outgoing events.
252253
:param omit_anonymous_contexts: Sets whether anonymous contexts should be omitted from index and identify events.
254+
:param payload_filter_key: The payload filter is used to selectively limited the flags and segments delivered in the data source payload.
253255
"""
254256
self.__sdk_key = sdk_key
255257

@@ -285,6 +287,7 @@ def __init__(
285287
self.__hooks = [hook for hook in hooks if isinstance(hook, Hook)] if hooks else []
286288
self.__enable_event_compression = enable_event_compression
287289
self.__omit_anonymous_contexts = omit_anonymous_contexts
290+
self.__payload_filter_key = payload_filter_key
288291
self._data_source_update_sink: Optional[DataSourceUpdateSink] = None
289292

290293
def copy_with_new_sdk_key(self, new_sdk_key: str) -> 'Config':
@@ -484,6 +487,26 @@ def omit_anonymous_contexts(self) -> bool:
484487
"""
485488
return self.__omit_anonymous_contexts
486489

490+
@property
491+
def payload_filter_key(self) -> Optional[str]:
492+
"""
493+
LaunchDarkly Server SDKs historically downloaded all flag configuration
494+
and segments for a particular environment during initialization.
495+
496+
For some customers, this is an unacceptably large amount of data, and
497+
has contributed to performance issues within their products.
498+
499+
Filtered environments aim to solve this problem. By allowing customers
500+
to specify subsets of an environment's flags using a filter key, SDKs
501+
will initialize faster and use less memory.
502+
503+
This payload filter key only applies to the default streaming and
504+
polling data sources. It will not affect TestData or FileData data
505+
sources, nor will it be applied to any data source provided through the
506+
{#data_source} config property.
507+
"""
508+
return self.__payload_filter_key
509+
487510
@property
488511
def data_source_update_sink(self) -> Optional[DataSourceUpdateSink]:
489512
"""

ldclient/impl/datasource/feature_requester.py

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import json
66
from collections import namedtuple
7+
from urllib import parse
78

89
import urllib3
910

@@ -24,6 +25,8 @@ def __init__(self, config):
2425
self._http = _http_factory(config).create_pool_manager(1, config.base_uri)
2526
self._config = config
2627
self._poll_uri = config.base_uri + LATEST_ALL_URI
28+
if config.payload_filter_key is not None:
29+
self._poll_uri += '?%s' % parse.urlencode({'filter': config.payload_filter_key})
2730

2831
def get_all_data(self):
2932
uri = self._poll_uri

ldclient/impl/datasource/streaming.py

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from collections import namedtuple
44
from threading import Thread
55
from typing import Optional
6+
from urllib import parse
67

78
from ld_eventsource import SSEClient
89
from ld_eventsource.actions import Event, Fault
@@ -35,6 +36,8 @@ def __init__(self, config, store, ready, diagnostic_accumulator):
3536
Thread.__init__(self, name="ldclient.datasource.streaming")
3637
self.daemon = True
3738
self._uri = config.stream_base_uri + STREAM_ALL_PATH
39+
if config.payload_filter_key is not None:
40+
self._uri += '?%s' % parse.urlencode({'filter': config.payload_filter_key})
3841
self._config = config
3942
self._data_source_update_sink = config.data_source_update_sink
4043
self._store = store

ldclient/impl/http.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from os import environ
2-
from typing import Tuple
2+
from typing import Optional, Tuple
33
from urllib.parse import urlparse
44

55
import certifi

0 commit comments

Comments
 (0)