kameleoon-client-python 3.0.0__tar.gz → 3.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/PKG-INFO +79 -94
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/README.md +77 -90
- kameleoon-client-python-3.2.0/kameleoon/configuration/__init__.py +9 -0
- kameleoon-client-python-3.2.0/kameleoon/configuration/custom_data_info.py +51 -0
- kameleoon-client-python-3.2.0/kameleoon/configuration/data_file.py +111 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/configuration/rule.py +2 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/configuration/settings.py +10 -3
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/configuration/variable.py +4 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/data/__init__.py +7 -0
- kameleoon-client-python-3.2.0/kameleoon/data/cookie.py +32 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/data/custom_data.py +3 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/data/data.py +5 -0
- kameleoon-client-python-3.2.0/kameleoon/data/geolocation.py +100 -0
- kameleoon-client-python-3.2.0/kameleoon/data/operating_system.py +52 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/data/page_view.py +6 -5
- kameleoon-client-python-3.2.0/kameleoon/data/visitor_visits.py +29 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/helpers/functions.py +17 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/helpers/scheduler.py +1 -1
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/kameleoon_client.py +300 -145
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/sdk_version.py +1 -1
- kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/cookie_condition.py +53 -0
- kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/exclusive_feature_flag_condition.py +42 -0
- kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/geolocation_condition.py +30 -0
- kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/number_condition.py +34 -0
- kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/operating_system_condition.py +22 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/page_title_condition.py +2 -1
- kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/page_view_number_condition.py +18 -0
- kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/previous_page_condition.py +27 -0
- kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/segment_condition.py +45 -0
- kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/target_feature_flag_condition.py +67 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/targeting_condition.py +25 -3
- kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/time_elapsed_since_visit_condition.py +27 -0
- kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/visit_number_today_condition.py +28 -0
- kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/visit_number_total_condition.py +18 -0
- kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/visitor_new_return_condition.py +31 -0
- kameleoon-client-python-3.2.0/kameleoon/targeting/targeting_manager.py +102 -0
- kameleoon-client-python-3.2.0/kameleoon/targeting/tree_condition_factory.py +102 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon_client_python.egg-info/PKG-INFO +79 -94
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon_client_python.egg-info/SOURCES.txt +19 -2
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/setup.py +1 -3
- kameleoon-client-python-3.0.0/kameleoon/configuration/data_file.py +0 -63
- kameleoon-client-python-3.0.0/kameleoon/targeting/conditions/exclusive_experiment.py +0 -26
- kameleoon-client-python-3.0.0/kameleoon/targeting/conditions/target_experiment.py +0 -33
- kameleoon-client-python-3.0.0/kameleoon/targeting/tree_condition_factory.py +0 -58
- kameleoon-client-python-3.0.0/tests/integration/proj/proj/__init__.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/MANIFEST.in +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/__init__.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/configuration/feature_flag.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/configuration/rule_type.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/configuration/variation.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/configuration/variation_by_exposition.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/data/browser.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/data/conversion.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/data/device.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/data/user_agent.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/defaults.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/exceptions.py +0 -0
- {kameleoon-client-python-3.0.0/kameleoon/configuration → kameleoon-client-python-3.2.0/kameleoon/helpers}/__init__.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/helpers/logger.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/helpers/multi_threading.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/helpers/nonce.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/helpers/repeat_timer.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/helpers/visitor_code.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/kameleoon_client_config.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/kameleoon_client_factory.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/middleware.py +0 -0
- {kameleoon-client-python-3.0.0/kameleoon/helpers → kameleoon-client-python-3.2.0/kameleoon/real_time}/__init__.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/real_time/real_time_configuration_service.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/real_time/real_time_event.py +0 -0
- {kameleoon-client-python-3.0.0/kameleoon/real_time → kameleoon-client-python-3.2.0/kameleoon/storage}/__init__.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/storage/cache.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/storage/cache_factory.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/storage/cache_factory_impl.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/storage/cache_impl.py +0 -0
- {kameleoon-client-python-3.0.0/kameleoon/storage → kameleoon-client-python-3.2.0/kameleoon/targeting}/__init__.py +0 -0
- {kameleoon-client-python-3.0.0/kameleoon/targeting → kameleoon-client-python-3.2.0/kameleoon/targeting/conditions}/__init__.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/browser_condition.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/constants.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/conversion_condition.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/custom_datum.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/device_condition.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/page_url_condition.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/sdk_language_condition.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/string_value_condition.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/unknown_condition.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/visitor_code_condition.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/models.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/tree_builder.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon_client_python.egg-info/dependency_links.txt +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon_client_python.egg-info/requires.txt +13 -13
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon_client_python.egg-info/top_level.txt +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/setup.cfg +0 -0
- {kameleoon-client-python-3.0.0/kameleoon/targeting/conditions → kameleoon-client-python-3.2.0/tests/integration/proj}/__init__.py +0 -0
- {kameleoon-client-python-3.0.0/tests/integration/proj → kameleoon-client-python-3.2.0/tests/integration/proj/kameleoon_app}/__init__.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/tests/integration/proj/kameleoon_app/admin.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/tests/integration/proj/kameleoon_app/apps.py +0 -0
- {kameleoon-client-python-3.0.0/tests/integration/proj/kameleoon_app → kameleoon-client-python-3.2.0/tests/integration/proj/kameleoon_app/migrations}/__init__.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/tests/integration/proj/kameleoon_app/models.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/tests/integration/proj/kameleoon_app/tests.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/tests/integration/proj/kameleoon_app/views.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/tests/integration/proj/manage.py +0 -0
- {kameleoon-client-python-3.0.0/tests/integration/proj/kameleoon_app/migrations → kameleoon-client-python-3.2.0/tests/integration/proj/proj}/__init__.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/tests/integration/proj/proj/asgi.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/tests/integration/proj/proj/settings.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/tests/integration/proj/proj/urls.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/tests/integration/proj/proj/wsgi.py +0 -0
- {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/tests/resources/config.yml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: kameleoon-client-python
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.2.0
|
|
4
4
|
Summary: Kameleoon Client Python Software Development Kit.
|
|
5
5
|
Home-page: https://developers.kameleoon.com/python-sdk.html
|
|
6
6
|
Author: Kameleoon
|
|
@@ -9,14 +9,12 @@ License: GPLv3
|
|
|
9
9
|
Platform: UNKNOWN
|
|
10
10
|
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
11
11
|
Classifier: Programming Language :: Python
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.6
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
14
12
|
Classifier: Programming Language :: Python :: 3.8
|
|
15
13
|
Classifier: Programming Language :: Python :: 3.9
|
|
16
14
|
Classifier: Programming Language :: Python :: 3.10
|
|
17
15
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
18
16
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
19
|
-
Requires-Python: >=3.
|
|
17
|
+
Requires-Python: >=3.8.0
|
|
20
18
|
Description-Content-Type: text/markdown
|
|
21
19
|
Provides-Extra: test
|
|
22
20
|
|
|
@@ -31,7 +29,6 @@ Our SDK gives you the possibility of running experiments and activating feature
|
|
|
31
29
|
|
|
32
30
|
You can refer to the [SDK reference](https://developers.kameleoon.com/python-sdk.html#reference) to check out all possible features of the SDK. Also make sure you check out our [Getting started tutorial](https://developers.kameleoon.com/python-sdk.html#getting-started) which we have prepared to walk you through the installation and implementation.
|
|
33
31
|
|
|
34
|
-
|
|
35
32
|
#### Additional configuration
|
|
36
33
|
|
|
37
34
|
You should provide credentials for the Kameleoon SDK via a configuration file,
|
|
@@ -41,17 +38,14 @@ file can be obtained here. We suggest to install this file to the default path o
|
|
|
41
38
|
passing the path as an argument to the KameleoonClient class.
|
|
42
39
|
With the current version of the Python SDK, those are the available keys:
|
|
43
40
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
* `visitor_data_maximum_size: int`: this specifies the maximum amount of memory that the hash
|
|
53
|
-
holding all the visitor data (in particular custom data) can take (in MB).
|
|
54
|
-
If not specified, the default size is 500MB.
|
|
41
|
+
- **client_id**: a `client_id` is required for authentication to the Kameleoon service.
|
|
42
|
+
- **client_secret**: a `client_secret` is required for authentication to the Kameleoon service.
|
|
43
|
+
- **refresh_interval_minute**: specifies the refresh interval, in minutes, of the configuration for feature flags (the active feature flags are fetched from the Kameleoon servers). It means that once you launch an experiment, pause it, or stop it, the changes can take (at most) the duration of this interval to be propagated in production to your servers. If not specified, the default interval is 60 minutes.
|
|
44
|
+
- **session_duration_minute**: sets the time interval that Kameleoon stores the visitor and their associated data in memory (RAM). Note that increasing the session duration increases the amount of RAM that needs to be allocated to store visitor data. The default session duration is 30 minutes.
|
|
45
|
+
- **default_timeout_millisecond**: specifies the timeout, in milliseconds for network requests from the SDK. It is recommended to set the value to 30 seconds or more if you do not have a stable connection. The default value is 10 seconds. Some methods have their own parameters for timeouts, but if you do not specify them explicitly, this value is used.
|
|
46
|
+
- **top_level_domain**: the current top-level domain for your website. Kameleoon uses this information to set the corresponding cookie on the top-level domain. This field is mandatory.
|
|
47
|
+
- **environment**: an option specifying which feature flag configuration will be used, by default each feature flag is split into **production**, **staging**, **development**. If not specified, will be set to **default value** of **production**. [More information](https://www.kameleoon.com/en/blog/configure-your-feature-flags-and-launch-your-releases-using-next-level-multi-environment)
|
|
48
|
+
- **multi_threading**: an option of type **bool** indicating whether threads can be used for network requests. By default, the option is **False** and everything is executed in one thread to avoid performance issues with GIL if (C)Python interpreter is using. Possible values: **True** , **False**.
|
|
55
49
|
|
|
56
50
|
|
|
57
51
|
### Initializing the Kameleoon client
|
|
@@ -67,22 +61,36 @@ between your application and the Kameleoon platform.
|
|
|
67
61
|
It includes all the methods and properties you will need to run an experiment.
|
|
68
62
|
|
|
69
63
|
```python
|
|
70
|
-
from kameleoon import KameleoonClient
|
|
64
|
+
from kameleoon import KameleoonClient, KameleoonClientConfig, KameleoonClientFactory
|
|
71
65
|
|
|
72
66
|
SITE_CODE = 'a8st4f59bj'
|
|
73
67
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
kameleoon_client =
|
|
68
|
+
# Option 1
|
|
69
|
+
kameleoon_client = KameleoonClientFactory.create(SITE_CODE, config_path='/etc/kameleoon/client-python.yaml')
|
|
70
|
+
|
|
71
|
+
# Option 2
|
|
72
|
+
configuration_object = KameleoonClientConfig.read_from_yaml('/etc/kameleoon/client-python.yaml')
|
|
73
|
+
configuration_object.set_logger(my_logger)
|
|
74
|
+
kameleoon_client = KameleoonClientFactory.create(SITE_CODE, configuration_object)
|
|
75
|
+
|
|
76
|
+
# Option 3
|
|
77
|
+
configuration_object = KameleoonClientConfig(
|
|
78
|
+
"client-id", # required
|
|
79
|
+
"client-secret", # required
|
|
80
|
+
refresh_interval_minute=60, # (in minutes) optional, default: 60 minutes
|
|
81
|
+
session_duration_minute=30, # (in minutes) optional, default: 30 minutes
|
|
82
|
+
default_timeout_millisecond=10000, # (in milliseconds) optional, default: 10000 milliseconds
|
|
83
|
+
environment="production", # optional, possible values: "production" / "staging" / "development" / "staging", default: None
|
|
84
|
+
top_level_domain="example.com",
|
|
85
|
+
multi_threading=False, # optional, default: False
|
|
86
|
+
logger=my_logger, # optional, default: standard kameleoon logger
|
|
87
|
+
)
|
|
88
|
+
kameleoon_client = KameleoonClientFactory.create(SITE_CODE, configuration_object)
|
|
81
89
|
```
|
|
82
90
|
|
|
83
|
-
###
|
|
91
|
+
### Use Feature flag
|
|
84
92
|
|
|
85
|
-
Running an
|
|
93
|
+
Running an feature flag on your Python application means bucketing your visitors
|
|
86
94
|
into several groups (one per variation). The SDK takes care of this bucketing (and the associated reporting)
|
|
87
95
|
automatically.
|
|
88
96
|
|
|
@@ -92,41 +100,25 @@ variation (most likely a returning visitor that has already been exposed to the
|
|
|
92
100
|
then it will return the previous variation assigned for the given experiment.
|
|
93
101
|
|
|
94
102
|
```python
|
|
95
|
-
visitor_code = kameleoon_client.get_visitor_code(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
#
|
|
114
|
-
variation_id = 0
|
|
115
|
-
client.logger.error(ex)
|
|
116
|
-
|
|
117
|
-
recommended_products_number = 5
|
|
118
|
-
# This is the default / reference number of products to display
|
|
119
|
-
|
|
120
|
-
if variation_id == 148382:
|
|
121
|
-
# We are changing number of recommended products for this variation to 10
|
|
122
|
-
recommended_products_number = 10
|
|
123
|
-
elif variation_id == 187791:
|
|
124
|
-
# We are changing number of recommended products for this variation to 8
|
|
125
|
-
recommended_products_number = 8
|
|
126
|
-
|
|
127
|
-
# Here you should have code to generate the HTML page back to the client,
|
|
128
|
-
# where recommendedProductsNumber will be used
|
|
129
|
-
response = JsonResponse({...})
|
|
103
|
+
visitor_code = kameleoon_client.get_visitor_code(request.COOKIES)
|
|
104
|
+
|
|
105
|
+
feature_key = "feature_key"
|
|
106
|
+
variation_key = ""
|
|
107
|
+
|
|
108
|
+
try
|
|
109
|
+
variation_key = kameleoon_client.get_feature_variation_key(visitor_code, feature_key)
|
|
110
|
+
if variation_key == 'on':
|
|
111
|
+
# main variation key is selected for visitorCode
|
|
112
|
+
elif variation_key == 'alternative_variation':
|
|
113
|
+
# alternative variation key
|
|
114
|
+
else:
|
|
115
|
+
# default variation key
|
|
116
|
+
except FeatureNotFound as ex:
|
|
117
|
+
# The user will not be counted into the experiment, but should see the reference variation
|
|
118
|
+
except VisitorCodeInvalid as ex:
|
|
119
|
+
# The visitor code which you passed to the method isn't valid and can't be accepted by SDK
|
|
120
|
+
except FeatureEnvironmentDisabled as ex:
|
|
121
|
+
# The feature flag is disabled for certain environments
|
|
130
122
|
```
|
|
131
123
|
|
|
132
124
|
### How to use Kameleoon SDK with Django
|
|
@@ -192,49 +184,44 @@ client = kameleoon_app.kameleoon_client
|
|
|
192
184
|
from django.apps import apps
|
|
193
185
|
from django.http import JsonResponse
|
|
194
186
|
|
|
195
|
-
from kameleoon.exceptions import NotAllocated, NotTargeted, ExperimentConfigurationNotFound
|
|
196
187
|
|
|
197
188
|
kameleoon_app = apps.get_app_config('your_app')
|
|
198
189
|
client = kameleoon_app.kameleoon_client
|
|
199
190
|
|
|
200
191
|
def view(request):
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
# with excluded traffic
|
|
209
|
-
variation_id = 0
|
|
210
|
-
client.logger.error(ex)
|
|
211
|
-
except NotTargeted as ex:
|
|
212
|
-
# The user did not trigger the experiment, as the associated
|
|
213
|
-
# targeting segment conditions were not fulfilled.
|
|
214
|
-
# He should see the reference variation
|
|
215
|
-
variation_id = 0
|
|
216
|
-
client.logger.error(ex)
|
|
217
|
-
except ExperimentConfigurationNotFound as ex:
|
|
218
|
-
# The user will not be counted into the experiment,
|
|
219
|
-
# but should see the reference variation
|
|
220
|
-
variation_id = 0
|
|
221
|
-
client.logger.error(ex)
|
|
192
|
+
simple_cookies = SimpleCookie()
|
|
193
|
+
simple_cookies.load(request.COOKIES)
|
|
194
|
+
|
|
195
|
+
visitor_code = kameleoon_client.get_visitor_code(cookies=simple_cookies)
|
|
196
|
+
|
|
197
|
+
feature_key = "feature_key"
|
|
198
|
+
variation_key = ""
|
|
222
199
|
|
|
223
200
|
recommended_products_number = 5
|
|
224
201
|
# This is the default / reference number of products to display
|
|
225
202
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
203
|
+
try
|
|
204
|
+
variation_key = kameleoon_client.get_feature_variation_key(visitor_code, feature_key)
|
|
205
|
+
if variation_key == 'on':
|
|
206
|
+
# We are changing number of recommended products for this variation to 10
|
|
207
|
+
recommended_products_number = 10
|
|
208
|
+
elif variation_key == 'alternative_variation':
|
|
209
|
+
# We are changing number of recommended products for this variation to 20
|
|
210
|
+
recommended_products_number = 20
|
|
211
|
+
else:
|
|
212
|
+
# default variation key
|
|
213
|
+
except FeatureNotFound as ex:
|
|
214
|
+
# The user will not be counted into the experiment, but should see the reference variation
|
|
215
|
+
except VisitorCodeInvalid as ex:
|
|
216
|
+
# The visitor code which you passed to the method isn't valid and can't be accepted by SDK
|
|
217
|
+
except FeatureEnvironmentDisabled as ex:
|
|
218
|
+
# The feature flag is disabled for certain environments
|
|
232
219
|
|
|
233
220
|
# Here you should have code to generate the HTML page back to the client,
|
|
234
221
|
# where recommendedProductsNumber will be used
|
|
235
222
|
response = JsonResponse({...})
|
|
236
223
|
# set a cookie
|
|
237
|
-
response.set_cookie(
|
|
224
|
+
response.set_cookie(simple_cookies.output())
|
|
238
225
|
|
|
239
226
|
return response
|
|
240
227
|
```
|
|
@@ -250,11 +237,9 @@ You need to pass the visitor_code and goal_id parameters so we can correctly
|
|
|
250
237
|
track conversions for this particular visitor.
|
|
251
238
|
|
|
252
239
|
```python
|
|
253
|
-
visitor_code = client.get_visitor_code(
|
|
240
|
+
visitor_code = client.get_visitor_code(request.COOKIES)
|
|
254
241
|
goal_id = 83023
|
|
255
|
-
client.track_conversion(visitor_code, goal_id
|
|
242
|
+
client.track_conversion(visitor_code, goal_id)
|
|
256
243
|
```
|
|
257
244
|
|
|
258
245
|
|
|
259
|
-
|
|
260
|
-
|
|
@@ -8,7 +8,6 @@ Our SDK gives you the possibility of running experiments and activating feature
|
|
|
8
8
|
|
|
9
9
|
You can refer to the [SDK reference](https://developers.kameleoon.com/python-sdk.html#reference) to check out all possible features of the SDK. Also make sure you check out our [Getting started tutorial](https://developers.kameleoon.com/python-sdk.html#getting-started) which we have prepared to walk you through the installation and implementation.
|
|
10
10
|
|
|
11
|
-
|
|
12
11
|
#### Additional configuration
|
|
13
12
|
|
|
14
13
|
You should provide credentials for the Kameleoon SDK via a configuration file,
|
|
@@ -18,17 +17,14 @@ file can be obtained here. We suggest to install this file to the default path o
|
|
|
18
17
|
passing the path as an argument to the KameleoonClient class.
|
|
19
18
|
With the current version of the Python SDK, those are the available keys:
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
* `visitor_data_maximum_size: int`: this specifies the maximum amount of memory that the hash
|
|
30
|
-
holding all the visitor data (in particular custom data) can take (in MB).
|
|
31
|
-
If not specified, the default size is 500MB.
|
|
20
|
+
- **client_id**: a `client_id` is required for authentication to the Kameleoon service.
|
|
21
|
+
- **client_secret**: a `client_secret` is required for authentication to the Kameleoon service.
|
|
22
|
+
- **refresh_interval_minute**: specifies the refresh interval, in minutes, of the configuration for feature flags (the active feature flags are fetched from the Kameleoon servers). It means that once you launch an experiment, pause it, or stop it, the changes can take (at most) the duration of this interval to be propagated in production to your servers. If not specified, the default interval is 60 minutes.
|
|
23
|
+
- **session_duration_minute**: sets the time interval that Kameleoon stores the visitor and their associated data in memory (RAM). Note that increasing the session duration increases the amount of RAM that needs to be allocated to store visitor data. The default session duration is 30 minutes.
|
|
24
|
+
- **default_timeout_millisecond**: specifies the timeout, in milliseconds for network requests from the SDK. It is recommended to set the value to 30 seconds or more if you do not have a stable connection. The default value is 10 seconds. Some methods have their own parameters for timeouts, but if you do not specify them explicitly, this value is used.
|
|
25
|
+
- **top_level_domain**: the current top-level domain for your website. Kameleoon uses this information to set the corresponding cookie on the top-level domain. This field is mandatory.
|
|
26
|
+
- **environment**: an option specifying which feature flag configuration will be used, by default each feature flag is split into **production**, **staging**, **development**. If not specified, will be set to **default value** of **production**. [More information](https://www.kameleoon.com/en/blog/configure-your-feature-flags-and-launch-your-releases-using-next-level-multi-environment)
|
|
27
|
+
- **multi_threading**: an option of type **bool** indicating whether threads can be used for network requests. By default, the option is **False** and everything is executed in one thread to avoid performance issues with GIL if (C)Python interpreter is using. Possible values: **True** , **False**.
|
|
32
28
|
|
|
33
29
|
|
|
34
30
|
### Initializing the Kameleoon client
|
|
@@ -44,22 +40,36 @@ between your application and the Kameleoon platform.
|
|
|
44
40
|
It includes all the methods and properties you will need to run an experiment.
|
|
45
41
|
|
|
46
42
|
```python
|
|
47
|
-
from kameleoon import KameleoonClient
|
|
43
|
+
from kameleoon import KameleoonClient, KameleoonClientConfig, KameleoonClientFactory
|
|
48
44
|
|
|
49
45
|
SITE_CODE = 'a8st4f59bj'
|
|
50
46
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
kameleoon_client =
|
|
47
|
+
# Option 1
|
|
48
|
+
kameleoon_client = KameleoonClientFactory.create(SITE_CODE, config_path='/etc/kameleoon/client-python.yaml')
|
|
49
|
+
|
|
50
|
+
# Option 2
|
|
51
|
+
configuration_object = KameleoonClientConfig.read_from_yaml('/etc/kameleoon/client-python.yaml')
|
|
52
|
+
configuration_object.set_logger(my_logger)
|
|
53
|
+
kameleoon_client = KameleoonClientFactory.create(SITE_CODE, configuration_object)
|
|
54
|
+
|
|
55
|
+
# Option 3
|
|
56
|
+
configuration_object = KameleoonClientConfig(
|
|
57
|
+
"client-id", # required
|
|
58
|
+
"client-secret", # required
|
|
59
|
+
refresh_interval_minute=60, # (in minutes) optional, default: 60 minutes
|
|
60
|
+
session_duration_minute=30, # (in minutes) optional, default: 30 minutes
|
|
61
|
+
default_timeout_millisecond=10000, # (in milliseconds) optional, default: 10000 milliseconds
|
|
62
|
+
environment="production", # optional, possible values: "production" / "staging" / "development" / "staging", default: None
|
|
63
|
+
top_level_domain="example.com",
|
|
64
|
+
multi_threading=False, # optional, default: False
|
|
65
|
+
logger=my_logger, # optional, default: standard kameleoon logger
|
|
66
|
+
)
|
|
67
|
+
kameleoon_client = KameleoonClientFactory.create(SITE_CODE, configuration_object)
|
|
58
68
|
```
|
|
59
69
|
|
|
60
|
-
###
|
|
70
|
+
### Use Feature flag
|
|
61
71
|
|
|
62
|
-
Running an
|
|
72
|
+
Running an feature flag on your Python application means bucketing your visitors
|
|
63
73
|
into several groups (one per variation). The SDK takes care of this bucketing (and the associated reporting)
|
|
64
74
|
automatically.
|
|
65
75
|
|
|
@@ -69,41 +79,25 @@ variation (most likely a returning visitor that has already been exposed to the
|
|
|
69
79
|
then it will return the previous variation assigned for the given experiment.
|
|
70
80
|
|
|
71
81
|
```python
|
|
72
|
-
visitor_code = kameleoon_client.get_visitor_code(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
#
|
|
91
|
-
variation_id = 0
|
|
92
|
-
client.logger.error(ex)
|
|
93
|
-
|
|
94
|
-
recommended_products_number = 5
|
|
95
|
-
# This is the default / reference number of products to display
|
|
96
|
-
|
|
97
|
-
if variation_id == 148382:
|
|
98
|
-
# We are changing number of recommended products for this variation to 10
|
|
99
|
-
recommended_products_number = 10
|
|
100
|
-
elif variation_id == 187791:
|
|
101
|
-
# We are changing number of recommended products for this variation to 8
|
|
102
|
-
recommended_products_number = 8
|
|
103
|
-
|
|
104
|
-
# Here you should have code to generate the HTML page back to the client,
|
|
105
|
-
# where recommendedProductsNumber will be used
|
|
106
|
-
response = JsonResponse({...})
|
|
82
|
+
visitor_code = kameleoon_client.get_visitor_code(request.COOKIES)
|
|
83
|
+
|
|
84
|
+
feature_key = "feature_key"
|
|
85
|
+
variation_key = ""
|
|
86
|
+
|
|
87
|
+
try
|
|
88
|
+
variation_key = kameleoon_client.get_feature_variation_key(visitor_code, feature_key)
|
|
89
|
+
if variation_key == 'on':
|
|
90
|
+
# main variation key is selected for visitorCode
|
|
91
|
+
elif variation_key == 'alternative_variation':
|
|
92
|
+
# alternative variation key
|
|
93
|
+
else:
|
|
94
|
+
# default variation key
|
|
95
|
+
except FeatureNotFound as ex:
|
|
96
|
+
# The user will not be counted into the experiment, but should see the reference variation
|
|
97
|
+
except VisitorCodeInvalid as ex:
|
|
98
|
+
# The visitor code which you passed to the method isn't valid and can't be accepted by SDK
|
|
99
|
+
except FeatureEnvironmentDisabled as ex:
|
|
100
|
+
# The feature flag is disabled for certain environments
|
|
107
101
|
```
|
|
108
102
|
|
|
109
103
|
### How to use Kameleoon SDK with Django
|
|
@@ -169,49 +163,44 @@ client = kameleoon_app.kameleoon_client
|
|
|
169
163
|
from django.apps import apps
|
|
170
164
|
from django.http import JsonResponse
|
|
171
165
|
|
|
172
|
-
from kameleoon.exceptions import NotAllocated, NotTargeted, ExperimentConfigurationNotFound
|
|
173
166
|
|
|
174
167
|
kameleoon_app = apps.get_app_config('your_app')
|
|
175
168
|
client = kameleoon_app.kameleoon_client
|
|
176
169
|
|
|
177
170
|
def view(request):
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
# with excluded traffic
|
|
186
|
-
variation_id = 0
|
|
187
|
-
client.logger.error(ex)
|
|
188
|
-
except NotTargeted as ex:
|
|
189
|
-
# The user did not trigger the experiment, as the associated
|
|
190
|
-
# targeting segment conditions were not fulfilled.
|
|
191
|
-
# He should see the reference variation
|
|
192
|
-
variation_id = 0
|
|
193
|
-
client.logger.error(ex)
|
|
194
|
-
except ExperimentConfigurationNotFound as ex:
|
|
195
|
-
# The user will not be counted into the experiment,
|
|
196
|
-
# but should see the reference variation
|
|
197
|
-
variation_id = 0
|
|
198
|
-
client.logger.error(ex)
|
|
171
|
+
simple_cookies = SimpleCookie()
|
|
172
|
+
simple_cookies.load(request.COOKIES)
|
|
173
|
+
|
|
174
|
+
visitor_code = kameleoon_client.get_visitor_code(cookies=simple_cookies)
|
|
175
|
+
|
|
176
|
+
feature_key = "feature_key"
|
|
177
|
+
variation_key = ""
|
|
199
178
|
|
|
200
179
|
recommended_products_number = 5
|
|
201
180
|
# This is the default / reference number of products to display
|
|
202
181
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
182
|
+
try
|
|
183
|
+
variation_key = kameleoon_client.get_feature_variation_key(visitor_code, feature_key)
|
|
184
|
+
if variation_key == 'on':
|
|
185
|
+
# We are changing number of recommended products for this variation to 10
|
|
186
|
+
recommended_products_number = 10
|
|
187
|
+
elif variation_key == 'alternative_variation':
|
|
188
|
+
# We are changing number of recommended products for this variation to 20
|
|
189
|
+
recommended_products_number = 20
|
|
190
|
+
else:
|
|
191
|
+
# default variation key
|
|
192
|
+
except FeatureNotFound as ex:
|
|
193
|
+
# The user will not be counted into the experiment, but should see the reference variation
|
|
194
|
+
except VisitorCodeInvalid as ex:
|
|
195
|
+
# The visitor code which you passed to the method isn't valid and can't be accepted by SDK
|
|
196
|
+
except FeatureEnvironmentDisabled as ex:
|
|
197
|
+
# The feature flag is disabled for certain environments
|
|
209
198
|
|
|
210
199
|
# Here you should have code to generate the HTML page back to the client,
|
|
211
200
|
# where recommendedProductsNumber will be used
|
|
212
201
|
response = JsonResponse({...})
|
|
213
202
|
# set a cookie
|
|
214
|
-
response.set_cookie(
|
|
203
|
+
response.set_cookie(simple_cookies.output())
|
|
215
204
|
|
|
216
205
|
return response
|
|
217
206
|
```
|
|
@@ -227,9 +216,7 @@ You need to pass the visitor_code and goal_id parameters so we can correctly
|
|
|
227
216
|
track conversions for this particular visitor.
|
|
228
217
|
|
|
229
218
|
```python
|
|
230
|
-
visitor_code = client.get_visitor_code(
|
|
219
|
+
visitor_code = client.get_visitor_code(request.COOKIES)
|
|
231
220
|
goal_id = 83023
|
|
232
|
-
client.track_conversion(visitor_code, goal_id
|
|
221
|
+
client.track_conversion(visitor_code, goal_id)
|
|
233
222
|
```
|
|
234
|
-
|
|
235
|
-
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""Custom data info"""
|
|
2
|
+
|
|
3
|
+
from logging import Logger
|
|
4
|
+
from typing import Optional, Dict, Union, Any, List
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CustomDataInfo:
|
|
8
|
+
"""Custom data info"""
|
|
9
|
+
|
|
10
|
+
SCOPE_VISITOR = "VISITOR"
|
|
11
|
+
|
|
12
|
+
def __init__(
|
|
13
|
+
self, custom_data: Optional[List[Dict[str, Union[str, int, Any]]]], logger: Optional[Logger] = None
|
|
14
|
+
) -> None:
|
|
15
|
+
super().__init__()
|
|
16
|
+
self.__mapping_identifier_index = None
|
|
17
|
+
self.__local_only = set()
|
|
18
|
+
self.__visitor_scope = set()
|
|
19
|
+
if custom_data is not None:
|
|
20
|
+
for data in custom_data:
|
|
21
|
+
index = data.get("index")
|
|
22
|
+
if index is not None:
|
|
23
|
+
index = int(index)
|
|
24
|
+
if data.get("localOnly"):
|
|
25
|
+
self.__local_only.add(index)
|
|
26
|
+
if data.get("scope") == self.SCOPE_VISITOR:
|
|
27
|
+
self.__visitor_scope.add(index)
|
|
28
|
+
if data.get("isMappingIdentifier"):
|
|
29
|
+
if bool(self.__mapping_identifier_index is not None) and logger is not None:
|
|
30
|
+
logger.info(
|
|
31
|
+
"More than one mapping identifier is set. Undefined behavior may occur" +
|
|
32
|
+
" on cross-device reconciliation."
|
|
33
|
+
)
|
|
34
|
+
self.__mapping_identifier_index = index
|
|
35
|
+
|
|
36
|
+
def is_local_only(self, index: int) -> bool:
|
|
37
|
+
"""Check for local only"""
|
|
38
|
+
return index in self.__local_only
|
|
39
|
+
|
|
40
|
+
def is_mapping_identifier(self, index: int) -> bool:
|
|
41
|
+
"""Check for mapping identifier"""
|
|
42
|
+
return self.__mapping_identifier_index == index
|
|
43
|
+
|
|
44
|
+
def is_visitor_scope(self, index: int) -> bool:
|
|
45
|
+
"""Check for visitor scope"""
|
|
46
|
+
return index in self.__visitor_scope
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def mapping_identifier_index(self) -> Optional[int]:
|
|
50
|
+
"""Take mapping identifier index"""
|
|
51
|
+
return self.__mapping_identifier_index
|