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.
Files changed (107) hide show
  1. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/PKG-INFO +79 -94
  2. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/README.md +77 -90
  3. kameleoon-client-python-3.2.0/kameleoon/configuration/__init__.py +9 -0
  4. kameleoon-client-python-3.2.0/kameleoon/configuration/custom_data_info.py +51 -0
  5. kameleoon-client-python-3.2.0/kameleoon/configuration/data_file.py +111 -0
  6. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/configuration/rule.py +2 -0
  7. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/configuration/settings.py +10 -3
  8. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/configuration/variable.py +4 -0
  9. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/data/__init__.py +7 -0
  10. kameleoon-client-python-3.2.0/kameleoon/data/cookie.py +32 -0
  11. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/data/custom_data.py +3 -0
  12. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/data/data.py +5 -0
  13. kameleoon-client-python-3.2.0/kameleoon/data/geolocation.py +100 -0
  14. kameleoon-client-python-3.2.0/kameleoon/data/operating_system.py +52 -0
  15. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/data/page_view.py +6 -5
  16. kameleoon-client-python-3.2.0/kameleoon/data/visitor_visits.py +29 -0
  17. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/helpers/functions.py +17 -0
  18. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/helpers/scheduler.py +1 -1
  19. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/kameleoon_client.py +300 -145
  20. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/sdk_version.py +1 -1
  21. kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/cookie_condition.py +53 -0
  22. kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/exclusive_feature_flag_condition.py +42 -0
  23. kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/geolocation_condition.py +30 -0
  24. kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/number_condition.py +34 -0
  25. kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/operating_system_condition.py +22 -0
  26. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/page_title_condition.py +2 -1
  27. kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/page_view_number_condition.py +18 -0
  28. kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/previous_page_condition.py +27 -0
  29. kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/segment_condition.py +45 -0
  30. kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/target_feature_flag_condition.py +67 -0
  31. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/targeting_condition.py +25 -3
  32. kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/time_elapsed_since_visit_condition.py +27 -0
  33. kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/visit_number_today_condition.py +28 -0
  34. kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/visit_number_total_condition.py +18 -0
  35. kameleoon-client-python-3.2.0/kameleoon/targeting/conditions/visitor_new_return_condition.py +31 -0
  36. kameleoon-client-python-3.2.0/kameleoon/targeting/targeting_manager.py +102 -0
  37. kameleoon-client-python-3.2.0/kameleoon/targeting/tree_condition_factory.py +102 -0
  38. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon_client_python.egg-info/PKG-INFO +79 -94
  39. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon_client_python.egg-info/SOURCES.txt +19 -2
  40. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/setup.py +1 -3
  41. kameleoon-client-python-3.0.0/kameleoon/configuration/data_file.py +0 -63
  42. kameleoon-client-python-3.0.0/kameleoon/targeting/conditions/exclusive_experiment.py +0 -26
  43. kameleoon-client-python-3.0.0/kameleoon/targeting/conditions/target_experiment.py +0 -33
  44. kameleoon-client-python-3.0.0/kameleoon/targeting/tree_condition_factory.py +0 -58
  45. kameleoon-client-python-3.0.0/tests/integration/proj/proj/__init__.py +0 -0
  46. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/MANIFEST.in +0 -0
  47. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/__init__.py +0 -0
  48. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/configuration/feature_flag.py +0 -0
  49. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/configuration/rule_type.py +0 -0
  50. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/configuration/variation.py +0 -0
  51. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/configuration/variation_by_exposition.py +0 -0
  52. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/data/browser.py +0 -0
  53. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/data/conversion.py +0 -0
  54. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/data/device.py +0 -0
  55. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/data/user_agent.py +0 -0
  56. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/defaults.py +0 -0
  57. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/exceptions.py +0 -0
  58. {kameleoon-client-python-3.0.0/kameleoon/configuration → kameleoon-client-python-3.2.0/kameleoon/helpers}/__init__.py +0 -0
  59. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/helpers/logger.py +0 -0
  60. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/helpers/multi_threading.py +0 -0
  61. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/helpers/nonce.py +0 -0
  62. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/helpers/repeat_timer.py +0 -0
  63. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/helpers/visitor_code.py +0 -0
  64. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/kameleoon_client_config.py +0 -0
  65. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/kameleoon_client_factory.py +0 -0
  66. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/middleware.py +0 -0
  67. {kameleoon-client-python-3.0.0/kameleoon/helpers → kameleoon-client-python-3.2.0/kameleoon/real_time}/__init__.py +0 -0
  68. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/real_time/real_time_configuration_service.py +0 -0
  69. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/real_time/real_time_event.py +0 -0
  70. {kameleoon-client-python-3.0.0/kameleoon/real_time → kameleoon-client-python-3.2.0/kameleoon/storage}/__init__.py +0 -0
  71. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/storage/cache.py +0 -0
  72. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/storage/cache_factory.py +0 -0
  73. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/storage/cache_factory_impl.py +0 -0
  74. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/storage/cache_impl.py +0 -0
  75. {kameleoon-client-python-3.0.0/kameleoon/storage → kameleoon-client-python-3.2.0/kameleoon/targeting}/__init__.py +0 -0
  76. {kameleoon-client-python-3.0.0/kameleoon/targeting → kameleoon-client-python-3.2.0/kameleoon/targeting/conditions}/__init__.py +0 -0
  77. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/browser_condition.py +0 -0
  78. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/constants.py +0 -0
  79. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/conversion_condition.py +0 -0
  80. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/custom_datum.py +0 -0
  81. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/device_condition.py +0 -0
  82. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/page_url_condition.py +0 -0
  83. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/sdk_language_condition.py +0 -0
  84. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/string_value_condition.py +0 -0
  85. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/unknown_condition.py +0 -0
  86. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/conditions/visitor_code_condition.py +0 -0
  87. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/models.py +0 -0
  88. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon/targeting/tree_builder.py +0 -0
  89. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon_client_python.egg-info/dependency_links.txt +0 -0
  90. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon_client_python.egg-info/requires.txt +13 -13
  91. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/kameleoon_client_python.egg-info/top_level.txt +0 -0
  92. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/setup.cfg +0 -0
  93. {kameleoon-client-python-3.0.0/kameleoon/targeting/conditions → kameleoon-client-python-3.2.0/tests/integration/proj}/__init__.py +0 -0
  94. {kameleoon-client-python-3.0.0/tests/integration/proj → kameleoon-client-python-3.2.0/tests/integration/proj/kameleoon_app}/__init__.py +0 -0
  95. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/tests/integration/proj/kameleoon_app/admin.py +0 -0
  96. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/tests/integration/proj/kameleoon_app/apps.py +0 -0
  97. {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
  98. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/tests/integration/proj/kameleoon_app/models.py +0 -0
  99. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/tests/integration/proj/kameleoon_app/tests.py +0 -0
  100. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/tests/integration/proj/kameleoon_app/views.py +0 -0
  101. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/tests/integration/proj/manage.py +0 -0
  102. {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
  103. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/tests/integration/proj/proj/asgi.py +0 -0
  104. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/tests/integration/proj/proj/settings.py +0 -0
  105. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/tests/integration/proj/proj/urls.py +0 -0
  106. {kameleoon-client-python-3.0.0 → kameleoon-client-python-3.2.0}/tests/integration/proj/proj/wsgi.py +0 -0
  107. {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.0.0
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.6.0
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
- * `client_id: String`: a client_id is required for authentication to the Kameleoon service.
45
- * `client_secret: String`: a client_secret is required for authentication to the Kameleoon service.
46
- * `actions_configuration_refresh_interval: int`: this specifies the refresh interval, in minutes,
47
- of the configuration for experiments and feature flags (the active experiments and feature
48
- flags are fetched from the Kameleoon servers). It means that once you launch an experiment,
49
- pause it, or stop it the changes can take (at most) the duration of this interval to be
50
- propagated in production to your servers. If not specified, the default interval
51
- is 60 minutes.
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
- kameleoon_client = KameleoonClient(SITE_CODE)
75
-
76
- kameleoon_client = KameleoonClient(SITE_CODE, configuration_path='/etc/kameleoon/client.yaml')
77
-
78
- kameleoon_client = KameleoonClient(SITE_CODE)
79
-
80
- kameleoon_client = KameleoonClient(SITE_CODE, logger=MyLogger)
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
- ### Triggering an experiment
91
+ ### Use Feature flag
84
92
 
85
- Running an A/B experiment on your Python application means bucketing your visitors
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(cookies_readonly=request.COOKIES)
96
- variation_id = 0
97
- try:
98
- variation_id = kameleoon_client.trigger_experiment(visitor_code, 135471)
99
- except NotAllocated as ex:
100
- # The user triggered the experiment, but did not activate it.
101
- # Usually, this happens because the user has been associated
102
- # with excluded traffic
103
- variation_id = 0
104
- client.logger.error(ex)
105
- except NotTargeted as ex:
106
- # The user did not trigger the experiment, as the associated
107
- # targeting segment conditions were not fulfilled.
108
- # He should see the reference variation
109
- variation_id = 0
110
- client.logger.error(ex)
111
- except ExperimentConfigurationNotFound as ex:
112
- # The user will not be counted into the experiment,
113
- # but should see the reference variation
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
- visitor_code = client.get_visitor_code(cookies_readonly=request.COOKIES)
202
- variation_id = 0
203
- try:
204
- variation_id = client.trigger_experiment(visitor_code, 135471)
205
- except NotAllocated as ex:
206
- # The user triggered the experiment, but did not activate it.
207
- # Usually, this happens because the user has been associated
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
- if variation_id == 148382:
227
- # We are changing number of recommended products for this variation to 10
228
- recommended_products_number = 10
229
- elif variation_id == 187791:
230
- # We are changing number of recommended products for this variation to 8
231
- recommended_products_number = 8
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(**kameleoon_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(cookies_readonly=request.COOKIES)
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
- * `client_id: String`: a client_id is required for authentication to the Kameleoon service.
22
- * `client_secret: String`: a client_secret is required for authentication to the Kameleoon service.
23
- * `actions_configuration_refresh_interval: int`: this specifies the refresh interval, in minutes,
24
- of the configuration for experiments and feature flags (the active experiments and feature
25
- flags are fetched from the Kameleoon servers). It means that once you launch an experiment,
26
- pause it, or stop it the changes can take (at most) the duration of this interval to be
27
- propagated in production to your servers. If not specified, the default interval
28
- is 60 minutes.
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
- kameleoon_client = KameleoonClient(SITE_CODE)
52
-
53
- kameleoon_client = KameleoonClient(SITE_CODE, configuration_path='/etc/kameleoon/client.yaml')
54
-
55
- kameleoon_client = KameleoonClient(SITE_CODE)
56
-
57
- kameleoon_client = KameleoonClient(SITE_CODE, logger=MyLogger)
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
- ### Triggering an experiment
70
+ ### Use Feature flag
61
71
 
62
- Running an A/B experiment on your Python application means bucketing your visitors
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(cookies_readonly=request.COOKIES)
73
- variation_id = 0
74
- try:
75
- variation_id = kameleoon_client.trigger_experiment(visitor_code, 135471)
76
- except NotAllocated as ex:
77
- # The user triggered the experiment, but did not activate it.
78
- # Usually, this happens because the user has been associated
79
- # with excluded traffic
80
- variation_id = 0
81
- client.logger.error(ex)
82
- except NotTargeted as ex:
83
- # The user did not trigger the experiment, as the associated
84
- # targeting segment conditions were not fulfilled.
85
- # He should see the reference variation
86
- variation_id = 0
87
- client.logger.error(ex)
88
- except ExperimentConfigurationNotFound as ex:
89
- # The user will not be counted into the experiment,
90
- # but should see the reference variation
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
- visitor_code = client.get_visitor_code(cookies_readonly=request.COOKIES)
179
- variation_id = 0
180
- try:
181
- variation_id = client.trigger_experiment(visitor_code, 135471)
182
- except NotAllocated as ex:
183
- # The user triggered the experiment, but did not activate it.
184
- # Usually, this happens because the user has been associated
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
- if variation_id == 148382:
204
- # We are changing number of recommended products for this variation to 10
205
- recommended_products_number = 10
206
- elif variation_id == 187791:
207
- # We are changing number of recommended products for this variation to 8
208
- recommended_products_number = 8
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(**kameleoon_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(cookies_readonly=request.COOKIES)
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,9 @@
1
+ """ Imports kameleoon configurations objects """
2
+
3
+ from .variable import Variable
4
+ from .variation import Variation
5
+
6
+ __all__ = [
7
+ "Variable",
8
+ "Variation",
9
+ ]
@@ -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