Skip to content

Commit 1d9769b

Browse files
LaunchDarklyReleaseBoteli-darklyLaunchDarklyCIapache-hbgangeli
authored
prepare 8.0.0 release (#190)
* make verify_ssl=False turn off certificate verification too (#129) * add more TLS config options and collect HTTP/HTTPS config options in a class (#130) * make stream retry/backoff/jitter behavior consistent with other SDKs + improve testing (#131) * streams shouldn't use the same read timeout as the rest of the SDK (#132) * implement our own retry logic & logging for event posts, don't use urllib3.Retry (#133) * remove support for indirect/patch and indirect/put * remove unused logic for individual flag/segment poll for indirect/patch * Ehaisley/84082/remove python2 (#136) * remove all references to six and remove queue fallback imports * remove NullHandler logger backwards compat * update circleci config to remove python 2.7 tests * remove ordereddict backwards compat * update setup.py to no longer list python 2.7 as compatible * no longer inherit from object for python 2 backwards compat * update readme and manifest to reflect python 2.7 removal * remove unicode type compatibility * remove 2.7 support from circleci * Allow authenticating with proxy This commit allows for authenticating with a proxy configured with the `http_proxy` environment variable. Authentication requires passing a header, and is not parsed by urllib3 from the proxy_url. * reimplement proxy tests for DRY and add test of proxy auth params * doc comment on auth params in proxy URL * add type hints to some of the public facing api. update some docs * Revert "add type hints to some of the public facing api." This reverts commit c35fa61. * Ehaisley/ch86857/type hints (#138) * add typehints to the public API * validate typehints in the public api and tests with mypy * remove all current deprecations (#139) * remove all currently deprecated classes, methods, arguments, and tests * also update semver usage to remove calls to deprecated functions and classes * remove global set_sdk_key, make SDK key required in Config (#140) * Removed the guides link * Pinning mypy and running it against different python versions (#141) * fix time zone mishandling that could make event debugging not work (#142) * fix 6.x build (#143) * fix time zone mishandling that could make event debugging not work (6.x) (#144) * prepare 6.13.3 release (#154) * Releasing version 6.13.3 * [ch99756] Add alias events (#145) * add support for experiment rollouts * fix unit test * address PR comments * use Releaser v2 config * Use newer docker images (#147) * Updates docs URLs * Add support for 3.10 (#150) * started work on FlagBuilder in as part of test data source implementation * finished FlagBuilder implementation and added FlagRuleBuilder implementation * added initial TestData interface and updated tests to not rely on test data internals * started data source implementation * changed FlagBuilder to public class; changed FlagBuilder attributes to be initialized in __init__ and eliminated use of try ... except: pass for handling empty attributes * (big segments 1) add public config/interface types * added implementation of test data source * docstring * formatting * ensure property doesn't return None * (big segments 2) implement evaluation, refactor eval logic & modules * linting * (big segments 3) implement big segment status tracking, wire up components * typing fixes * typing fixes * implement SSE contract tests * fix CI * fix CI again * fix CI * disable SSE tests in Python 3.5 * make test service port configurable * better SSE implementation that fixes linefeed and multi-byte char issues * fix constructor parameters in test service * comment * test improvements * rm obsolete default config logic * (big segments 4) implement big segment stores in Redis+DynamoDB, refactor db tests (#158) * converted ldclient.integrations module from file to directory; started moving public classes out of ldclient.impl.integrations.test_data* and instead into ldclient.integrations.test_data*; started adding TestData documentation * removed setup/teardown functions leftover from test scaffold * added TestData, FlagBuilder, and FlagRuleBuilder documentation; minor adjustments to implementation details * removed warning supression from TestData tests * fix big segments user hash algorithm to use SHA256 * update mypy version * updates to tests and related bug fixes * always cache Big Segment query result even if it's None * fix test assertion * lint * fix big segment ref format * fix big segments cache TTL being set to wrong value * fixed structure of fallthrough variation in result of FlagBuilder.build() * moved __test__ attribute into TestData class definition to prevent mypy from complaining about a missing class attribute * minor doc comment fix * Apply suggestions related to Sphinx docstring formatting from code review Co-authored-by: Eli Bishop <[email protected]> * fixed errors in the implementation of FlagBuilder's fallthrough_variation and off_variation when passing boolean variation values; updated tests to assert the expected behavior * added missing value_for_all_users() method to FlagBuilder class * Fix operator parsing errors (#169) * identify should not emit event if user key is empty (#164) * secondary should be treated as built-in attribute (#168) * URIs should have trailing slashes trimmed (#165) * all_flags_state should always include flag version (#166) * output event should not include a null prereqOf key (#167) * Account for traffic allocation on all flags (#171) * Add SDK contract tests (#170) * misc fixes to test data docs + add type hints * more type hints * remove some methods from the public test_data API * can't use "x|y" shortcut in typehints in older Pythons; use Union * fix misc type mistakes because I forgot to run the linter * update CONTRIBUTING.md and provide make targets * fixed a bug with flag rule clause builder internals; added unit test to verify rule evaluation * added ready argument to _TestDataSource class and indicated ready upon start to avoid delays in TestData initialization * Update contract tests to latest flask version (#176) Our contract tests depend on flask v1, which in turn depends on Jinja 2. Both of these are terribly dated and no longer supported. Jinja depends on markupsafe. markupsafe recently updated its code to no longer provide soft_unicode which in turn broke Jinja. Updating to the latest flask keeps all transitive dependencies better aligned and addresses this mismatch. * Adds link to Relay Proxy docs * Handle explicit None values in test payload (#179) The test harness may send explicit None values which should be treated the same as if the value was omitted entirely. * Fix "unhandled response" error in test harness (#180) When we return a `('', 204)` response from the flask handler, [Werkzeug intentionally removes the 'Content-Type' header][1], which causes the response to be created as a chunked response. The test harness is likely seeing a 204 response and isn't trying to read anything more from the stream. But since we are re-using connections, the next time it reads from the stream, it sees the `0\r\n\r\n` chunk and outputs an error: > 2022/04/20 14:23:39 Unsolicited response received on idle HTTP channel starting with "0\r\n\r\n"; err=<nil> Changing this response to 202 causes Werkzeug to return an empty response and silences the error. [1]: https://github.com/pallets/werkzeug/blob/560dd5f320bff318175f209595d42f5a80045417/src/werkzeug/wrappers/response.py#L540 * Exclude booleans when getting bucketable value (#181) When calculating a bucket, we get the bucketable value from the specified bucket by attribute. If this value is a string or an int, we can use it. Otherwise, we return None. Python considers a bool an instance of an int, which isn't what we want. So we need to add an explicit exclusion for this. * master -> main (#182) * Loosen restriction on expiringdict (#183) Originally this was pinned to a max version to deal with the incompatibility of Python 3.3 and the `typing` package. See [this PR][1]. Now that we now only support >=3.5, we can safely relax this restriction again. [1]: launchdarkly/python-server-sdk-private#120 * Fix mypy type checking (#184) A [customer requested][original-pr] that we start including a py.typed file in our repository. This would enable mypy to take advantage of our typehints. Unfortunately, this didn't completely solve the customers issue. A [second pr][second-pr] was opened to address the missing step of including the py.typed file in the `Manifest.in` file. However, this change alone is not sufficient. According to the [documentation][include_package_data], you must also include the `include_package_data=True` directive so that files specified in the `Manifest.in` file are included in distribution. [original-pr]: #166 [second-pr]: #172 [include_package_data]: https://setuptools.pypa.io/en/latest/userguide/datafiles.html#include-package-data * Add support for extra Redis connection parameters (#185) * Include wheel artifact when publishing package (#186) * remove warn-level logging done for every Big Segments query * skip tests that use a self-signed TLS cert in Python 3.7 * (U2C 1) drop EOL Python versions (#189) * drop EOL Python versions * misc cleanup, show Python version in CI * add Python 3.11 CI job * add Python 3.11 to package metadata * (U2C 2) remove alias event functionality (#187) * (U2C 3) remove inline users in events (#188) * (U2C 4) remove deprecated things (#192) * remove warn-level logging done for every Big Segments query (#190) * remove warn-level logging done for every Big Segments query * skip tests that use a self-signed TLS cert in Python 3.7 * implement context model * fix exports * specify exports * add copy constructor * minimal changes for SDK methods & evaluator to accept Context * update tests, add subscript method * lint * in type hints, must use Dict[A, B] rather than dict[A, B] for Python <3.9 * support context kind in clauses + enable v2 contract tests * misc fixes * misc fixes * support contextTargets * support contextKind in rollouts/experiments * support includedContexts/excludedContexts in segment * comment copyedit Co-authored-by: Matthew M. Keeler <[email protected]> * comment fixes * rm unused Co-authored-by: Matthew M. Keeler <[email protected]> * fix create_multi to support flattening * lint * use custom classes for flag/segment data model * use store adapter for safety * misc cleanup * misc fixes for persistent stores * more database store fixes * support attribute reference lookups in evaluations * pass logger from client * context kind logic for big segments + enable big segment contract tests * formatting fixes + test cleanup * prerequisite cycle detection * segment recursion * define custom classes for event data * add module init file * linting * fix prereq stack logic * (U2C 17) U2C changes for events, not including private attributes (#205) * private attribute redaction * move a lot of code out of top-level modules * TestData changes for contexts * general doc comment fixes for 8.0 * U2C configuration updates * update release metadata * store flag/segment target lists as sets * fix type hint * preprocess clause values for time/regex/semver operators * fix type checking for matches operator Co-authored-by: Eli Bishop <[email protected]> Co-authored-by: LaunchDarklyCI <[email protected]> Co-authored-by: Elliot <[email protected]> Co-authored-by: Gabor Angeli <[email protected]> Co-authored-by: Elliot <[email protected]> Co-authored-by: Ben Woskow <[email protected]> Co-authored-by: LaunchDarklyCI <[email protected]> Co-authored-by: hroederld <[email protected]> Co-authored-by: Robert J. Neal <[email protected]> Co-authored-by: Robert J. Neal <[email protected]> Co-authored-by: Ember Stevens <[email protected]> Co-authored-by: ember-stevens <[email protected]> Co-authored-by: Matthew M. Keeler <[email protected]> Co-authored-by: charukiewicz <[email protected]> Co-authored-by: LaunchDarklyReleaseBot <[email protected]> Co-authored-by: Christian Charukiewicz <[email protected]> Co-authored-by: Matthew M. Keeler <[email protected]>
1 parent 92f86e9 commit 1d9769b

File tree

100 files changed

+6083
-3629
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+6083
-3629
lines changed

.circleci/config.yml

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,6 @@ orbs:
66
workflows:
77
test:
88
jobs:
9-
- test-linux:
10-
name: Python 3.5
11-
docker-image: cimg/python:3.5
12-
skip-sse-contract-tests: true # the test service app has dependencies that aren't available in 3.5, which is EOL anyway
13-
skip-contract-tests: true # the test service app has dependencies that aren't available in 3.5, which is EOL anyway
14-
- test-linux:
15-
name: Python 3.6
16-
docker-image: cimg/python:3.6
179
- test-linux:
1810
name: Python 3.7
1911
docker-image: cimg/python:3.7
@@ -26,6 +18,9 @@ workflows:
2618
- test-linux:
2719
name: Python 3.10
2820
docker-image: cimg/python:3.10
21+
- test-linux:
22+
name: Python 3.11
23+
docker-image: cimg/python:3.11
2924
- test-windows:
3025
name: Windows Python 3
3126
py3: true
@@ -57,6 +52,7 @@ jobs:
5752
- image: consul
5853
steps:
5954
- checkout
55+
- run: python --version
6056
- run:
6157
name: install requirements
6258
command: |
@@ -142,6 +138,7 @@ jobs:
142138
- run:
143139
name: install Python 3
144140
command: choco install python --no-progress
141+
- run: python --version
145142
- run:
146143
name: set up DynamoDB
147144
command: |

.ldrelease/config.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ publications:
1212

1313
branches:
1414
- name: main
15-
description: 7.x
15+
description: 8.x
16+
- name: 7.x
1617
- name: 6.x
1718

1819
jobs:

.readthedocs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
version: 2
22

33
python:
4-
version: 3.5
4+
version: 3.7
55
install:
66
- requirements: docs/requirements.txt
77
- requirements: requirements.txt

Makefile

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ docs:
1818

1919
TEMP_TEST_OUTPUT=/tmp/contract-test-service.log
2020

21+
# TEST_HARNESS_PARAMS can be set to add -skip parameters for any contract tests that cannot yet pass
22+
# TEST_HARNESS_PARAMS := $(TEST_HARNESS_PARAMS) \
23+
24+
2125
# port 8000 and 9000 is already used in the CI environment because we're
2226
# running a DynamoDB container and an SSE contract test
2327
PORT=10000
@@ -33,8 +37,8 @@ start-contract-test-service-bg:
3337
@make start-contract-test-service >$(TEMP_TEST_OUTPUT) 2>&1 &
3438

3539
run-contract-tests:
36-
@curl -s https://raw.githubusercontent.com/launchdarkly/sdk-test-harness/v1.0.0/downloader/run.sh \
37-
| VERSION=v1 PARAMS="-url http://localhost:$(PORT) -debug -stop-service-at-end $(TEST_HARNESS_PARAMS)" sh
40+
curl -s https://raw.githubusercontent.com/launchdarkly/sdk-test-harness/v2/downloader/run.sh \
41+
| VERSION=v2 PARAMS="-url http://localhost:$(PORT) -debug -stop-service-at-end $(TEST_HARNESS_PARAMS)" sh
3842

3943
contract-tests: build-contract-tests start-contract-test-service-bg run-contract-tests
4044

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
## Supported Python versions
1515

16-
This version of the LaunchDarkly SDK is compatible with Python 3.5 through 3.10. It is tested with the most recent patch releases of those versions. Python versions 2.7 to 3.4 are no longer supported.
16+
This version of the LaunchDarkly SDK is compatible with Python 3.7 through 3.11. It is tested with the most recent patch releases of those versions. Python versions 2.7 to 3.6 are no longer supported.
1717

1818
## Getting started
1919

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import json
2+
import os
3+
import sys
4+
from typing import Optional
5+
import urllib3
6+
7+
# Import ldclient from parent directory
8+
sys.path.insert(1, os.path.join(sys.path[0], '..'))
9+
from ldclient.interfaces import BigSegmentStore, BigSegmentStoreMetadata
10+
11+
12+
http = urllib3.PoolManager()
13+
14+
15+
class BigSegmentStoreFixture(BigSegmentStore):
16+
def __init__(self, callback_uri: str):
17+
self._callback_uri = callback_uri
18+
19+
def get_metadata(self) -> BigSegmentStoreMetadata:
20+
resp_data = self._post_callback('/getMetadata', None)
21+
return BigSegmentStoreMetadata(resp_data.get("lastUpToDate"))
22+
23+
def get_membership(self, context_hash: str) -> Optional[dict]:
24+
resp_data = self._post_callback('/getMembership', {'contextHash': context_hash})
25+
return resp_data.get("values")
26+
27+
def _post_callback(self, path: str, params: Optional[dict]) -> dict:
28+
url = self._callback_uri + path
29+
resp = http.request('POST', url,
30+
body=None if params is None else json.dumps(params),
31+
headers=None if params is None else {'Content-Type': 'application/json'})
32+
if resp.status != 200:
33+
raise Exception("HTTP error %d from callback to %s" % (resp.status, url))
34+
return json.loads(resp.data.decode('utf-8'))
35+
36+
def stop(self):
37+
pass

contract-tests/client_entity.py

Lines changed: 81 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1+
import json
12
import logging
23
import os
34
import sys
5+
from typing import Optional
6+
7+
from big_segment_store_fixture import BigSegmentStoreFixture
8+
9+
from ldclient.config import BigSegmentsConfig
410

511
# Import ldclient from parent directory
612
sys.path.insert(1, os.path.join(sys.path[0], '..'))
@@ -16,8 +22,7 @@ def __init__(self, tag, config):
1622
streaming = config["streaming"]
1723
if streaming.get("baseUri") is not None:
1824
opts["stream_uri"] = streaming["baseUri"]
19-
if streaming.get("initialRetryDelayMs") is not None:
20-
opts["initial_reconnect_delay"] = streaming["initialRetryDelayMs"] / 1000.0
25+
_set_optional_time_prop(streaming, "initialRetryDelayMs", opts, "initial_reconnect_delay")
2126

2227
if config.get("events") is not None:
2328
events = config["events"]
@@ -28,13 +33,22 @@ def __init__(self, tag, config):
2833
opts["diagnostic_opt_out"] = not events.get("enableDiagnostics", False)
2934
opts["all_attributes_private"] = events.get("allAttributesPrivate", False)
3035
opts["private_attribute_names"] = events.get("globalPrivateAttributes", {})
31-
if events.get("flushIntervalMs") is not None:
32-
opts["flush_interval"] = events["flushIntervalMs"] / 1000.0
33-
if events.get("inlineUsers") is not None:
34-
opts["inline_users_in_events"] = events["inlineUsers"]
36+
_set_optional_time_prop(events, "flushIntervalMs", opts, "flush_interval")
3537
else:
3638
opts["send_events"] = False
3739

40+
if config.get("bigSegments") is not None:
41+
big_params = config["bigSegments"]
42+
big_config = {
43+
"store": BigSegmentStoreFixture(big_params["callbackUri"])
44+
}
45+
if big_params.get("userCacheSize") is not None:
46+
big_config["context_cache_size"] = big_params["userCacheSize"]
47+
_set_optional_time_prop(big_params, "userCacheTimeMs", big_config, "context_cache_time")
48+
_set_optional_time_prop(big_params, "statusPollIntervalMs", big_config, "status_poll_interval")
49+
_set_optional_time_prop(big_params, "staleAfterMs", big_config, "stale_after")
50+
opts["big_segments"] = BigSegmentsConfig(**big_config)
51+
3852
start_wait = config.get("startWaitTimeMs") or 5000
3953
config = Config(**opts)
4054

@@ -43,41 +57,90 @@ def __init__(self, tag, config):
4357
def is_initializing(self) -> bool:
4458
return self.client.is_initialized()
4559

46-
def evaluate(self, params) -> dict:
60+
def evaluate(self, params: dict) -> dict:
4761
response = {}
4862

4963
if params.get("detail", False):
50-
detail = self.client.variation_detail(params["flagKey"], params["user"], params["defaultValue"])
64+
detail = self.client.variation_detail(params["flagKey"], params["context"], params["defaultValue"])
5165
response["value"] = detail.value
5266
response["variationIndex"] = detail.variation_index
5367
response["reason"] = detail.reason
5468
else:
55-
response["value"] = self.client.variation(params["flagKey"], params["user"], params["defaultValue"])
69+
response["value"] = self.client.variation(params["flagKey"], params["context"], params["defaultValue"])
5670

5771
return response
5872

59-
def evaluate_all(self, params):
73+
def evaluate_all(self, params: dict):
6074
opts = {}
6175
opts["client_side_only"] = params.get("clientSideOnly", False)
6276
opts["with_reasons"] = params.get("withReasons", False)
6377
opts["details_only_for_tracked_flags"] = params.get("detailsOnlyForTrackedFlags", False)
6478

65-
state = self.client.all_flags_state(params["user"], **opts)
79+
state = self.client.all_flags_state(params["context"], **opts)
6680

6781
return {"state": state.to_json_dict()}
6882

69-
def track(self, params):
70-
self.client.track(params["eventKey"], params["user"], params["data"], params.get("metricValue", None))
71-
72-
def identify(self, params):
73-
self.client.identify(params["user"])
83+
def track(self, params: dict):
84+
self.client.track(params["eventKey"], params["context"], params["data"], params.get("metricValue", None))
7485

75-
def alias(self, params):
76-
self.client.alias(params["user"], params["previousUser"])
86+
def identify(self, params: dict):
87+
self.client.identify(params["context"])
7788

7889
def flush(self):
7990
self.client.flush()
8091

92+
def secure_mode_hash(self, params: dict) -> dict:
93+
return {"result": self.client.secure_mode_hash(params["context"])}
94+
95+
def context_build(self, params: dict) -> dict:
96+
if params.get("multi"):
97+
b = Context.multi_builder()
98+
for c in params.get("multi"):
99+
b.add(self._context_build_single(c))
100+
return self._context_response(b.build())
101+
return self._context_response(self._context_build_single(params["single"]))
102+
103+
def _context_build_single(self, params: dict) -> Context:
104+
b = Context.builder(params["key"])
105+
if "kind" in params:
106+
b.kind(params["kind"])
107+
if "name" in params:
108+
b.name(params["name"])
109+
if "anonymous" in params:
110+
b.anonymous(params["anonymous"])
111+
if "custom" in params:
112+
for k, v in params.get("custom").items():
113+
b.set(k, v)
114+
if "private" in params:
115+
for attr in params.get("private"):
116+
b.private(attr)
117+
return b.build()
118+
119+
def context_convert(self, params: dict) -> dict:
120+
input = params["input"]
121+
try:
122+
props = json.loads(input)
123+
return self._context_response(Context.from_dict(props))
124+
except Exception as e:
125+
return {"error": str(e)}
126+
127+
def _context_response(self, c: Context) -> dict:
128+
if c.valid:
129+
return {"output": c.to_json_string()}
130+
return {"error": c.error}
131+
132+
def get_big_segment_store_status(self) -> dict:
133+
status = self.client.big_segment_store_status_provider.status
134+
return {
135+
"available": status.available,
136+
"stale": status.stale
137+
}
138+
81139
def close(self):
82140
self.client.close()
83141
self.log.info('Test ended')
142+
143+
def _set_optional_time_prop(params_in: dict, name_in: str, params_out: dict, name_out: str):
144+
if params_in.get(name_in) is not None:
145+
params_out[name_out] = params_in[name_in] / 1000.0
146+
return None

contract-tests/service.py

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
default_port = 8000
1414

15+
1516
# logging configuration
1617
dictConfig({
1718
'version': 1,
@@ -30,11 +31,10 @@
3031
'level': 'INFO',
3132
'handlers': ['console']
3233
},
33-
'ldclient.util': {
34-
'level': 'INFO',
35-
'handlers': ['console']
36-
},
3734
'loggers': {
35+
'ldclient': {
36+
'level': 'INFO', # change to 'DEBUG' to enable SDK debug logging
37+
},
3838
'werkzeug': { 'level': 'ERROR' } # disable irrelevant Flask app logging
3939
}
4040
})
@@ -53,6 +53,7 @@ def handle_exception(e):
5353
if isinstance(e, HTTPException):
5454
return e
5555

56+
app.logger.exception(e)
5657
return str(e), 500
5758

5859
@app.route('/', methods=['GET'])
@@ -63,6 +64,9 @@ def status():
6364
'all-flags-with-reasons',
6465
'all-flags-client-side-only',
6566
'all-flags-details-only-for-tracked-flags',
67+
'big-segments',
68+
'context-type',
69+
'secure-mode-hash',
6670
]
6771
}
6872
return (json.dumps(body), 200, {'Content-type': 'application/json'})
@@ -102,26 +106,35 @@ def post_client_command(id):
102106
if client is None:
103107
return ('', 404)
104108

105-
if params.get('command') == "evaluate":
106-
response = client.evaluate(params.get("evaluate"))
107-
return (json.dumps(response), 200)
108-
elif params.get("command") == "evaluateAll":
109-
response = client.evaluate_all(params.get("evaluateAll"))
110-
return (json.dumps(response), 200)
111-
elif params.get("command") == "customEvent":
112-
client.track(params.get("customEvent"))
113-
return ('', 201)
114-
elif params.get("command") == "identifyEvent":
115-
client.identify(params.get("identifyEvent"))
116-
return ('', 201)
117-
elif params.get("command") == "aliasEvent":
118-
client.alias(params.get("aliasEvent"))
119-
return ('', 201)
120-
elif params.get('command') == "flushEvents":
109+
command = params.get('command')
110+
sub_params = params.get(command)
111+
112+
response = None
113+
114+
if command == "evaluate":
115+
response = client.evaluate(sub_params)
116+
elif command == "evaluateAll":
117+
response = client.evaluate_all(sub_params)
118+
elif command == "customEvent":
119+
client.track(sub_params)
120+
elif command == "identifyEvent":
121+
client.identify(sub_params)
122+
elif command == "flushEvents":
121123
client.flush()
124+
elif command == "secureModeHash":
125+
response = client.secure_mode_hash(sub_params)
126+
elif command == "contextBuild":
127+
response = client.context_build(sub_params)
128+
elif command == "contextConvert":
129+
response = client.context_convert(sub_params)
130+
elif command == "getBigSegmentStoreStatus":
131+
response = client.get_big_segment_store_status()
132+
else:
133+
return ('', 400)
134+
135+
if response is None:
122136
return ('', 201)
123-
124-
return ('', 400)
137+
return (json.dumps(response), 200)
125138

126139
@app.route('/clients/<id>', methods=['DELETE'])
127140
def delete_client(id):

docs/api-deprecated.rst

Lines changed: 0 additions & 12 deletions
This file was deleted.

0 commit comments

Comments
 (0)