kameleoon-client-python 3.10.0__tar.gz → 3.12.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 (184) hide show
  1. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/PKG-INFO +1 -1
  2. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/conversion.py +34 -2
  3. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/custom_data.py +1 -7
  4. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/data.py +1 -0
  5. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/manager/visitor.py +18 -1
  6. kameleoon-client-python-3.12.0/kameleoon/data/personalization.py +30 -0
  7. kameleoon-client-python-3.12.0/kameleoon/helpers/domain.py +83 -0
  8. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/helpers/string_utils.py +5 -4
  9. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/kameleoon_client.py +12 -13
  10. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/kameleoon_client_config.py +40 -14
  11. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/managers/remote_data/remote_visitor_data.py +24 -7
  12. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/network_manager_factory.py +1 -0
  13. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/network_manager_factory_impl.py +5 -2
  14. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/query_builder.py +2 -0
  15. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/url_provider.py +45 -20
  16. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/sdk_version.py +2 -2
  17. kameleoon-client-python-3.12.0/kameleoon/targeting/conditions/exclusive_experiment_condition.py +55 -0
  18. kameleoon-client-python-3.12.0/kameleoon/targeting/conditions/target_experiment_condition.py +35 -0
  19. kameleoon-client-python-3.12.0/kameleoon/targeting/conditions/target_personalization_condition.py +23 -0
  20. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/targeting_condition.py +3 -0
  21. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/targeting_manager.py +13 -0
  22. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/tree_condition_factory.py +12 -0
  23. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/types/remote_visitor_data_filter.py +9 -1
  24. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon_client_python.egg-info/PKG-INFO +1 -1
  25. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon_client_python.egg-info/SOURCES.txt +4 -0
  26. kameleoon-client-python-3.10.0/kameleoon/helpers/domain.py +0 -45
  27. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/MANIFEST.in +0 -0
  28. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/README.md +0 -0
  29. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/__init__.py +0 -0
  30. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/client_readiness/__init__.py +0 -0
  31. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/client_readiness/async_readiness.py +0 -0
  32. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/client_readiness/threading_readiness.py +0 -0
  33. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/configuration/__init__.py +0 -0
  34. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/configuration/custom_data_info.py +0 -0
  35. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/configuration/data_file.py +0 -0
  36. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/configuration/experiment.py +0 -0
  37. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/configuration/feature_flag.py +0 -0
  38. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/configuration/me_group.py +0 -0
  39. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/configuration/rule.py +0 -0
  40. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/configuration/rule_type.py +0 -0
  41. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/configuration/settings.py +0 -0
  42. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/configuration/variable.py +0 -0
  43. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/configuration/variation.py +0 -0
  44. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/configuration/variation_by_exposition.py +0 -0
  45. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/__init__.py +0 -0
  46. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/browser.py +0 -0
  47. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/cbscores.py +0 -0
  48. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/cookie.py +0 -0
  49. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/device.py +0 -0
  50. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/geolocation.py +0 -0
  51. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/kcs_heat.py +0 -0
  52. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/manager/__init__.py +0 -0
  53. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/manager/assigned_variation.py +0 -0
  54. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/manager/forced_experiment_variation.py +0 -0
  55. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/manager/forced_feature_variation.py +0 -0
  56. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/manager/forced_variation.py +0 -0
  57. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/manager/page_view_visit.py +0 -0
  58. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/manager/visitor_manager.py +0 -0
  59. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/manager/visitor_slot.py +0 -0
  60. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/mapping_identifier.py +0 -0
  61. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/operating_system.py +0 -0
  62. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/page_view.py +0 -0
  63. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/unique_identifier.py +0 -0
  64. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/user_agent.py +0 -0
  65. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/data/visitor_visits.py +0 -0
  66. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/defaults.py +0 -0
  67. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/exceptions.py +0 -0
  68. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/helpers/__init__.py +0 -0
  69. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/helpers/functions.py +0 -0
  70. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/helpers/hasher.py +0 -0
  71. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/helpers/logger.py +0 -0
  72. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/helpers/multi_threading.py +0 -0
  73. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/helpers/nonce.py +0 -0
  74. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/helpers/repeat_timer.py +0 -0
  75. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/helpers/scheduler.py +0 -0
  76. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/helpers/visitor_code.py +0 -0
  77. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/hybrid/__init__.py +0 -0
  78. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/hybrid/hybrid_manager.py +0 -0
  79. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/hybrid/hybrid_manager_impl.py +0 -0
  80. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/kameleoon_client_factory.py +0 -0
  81. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/logging/__init__.py +0 -0
  82. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/logging/kameleoon_logger.py +0 -0
  83. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/logging/log_level.py +0 -0
  84. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/logging/logger.py +0 -0
  85. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/managers/__init__.py +0 -0
  86. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/managers/asyncexec/__init__.py +0 -0
  87. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/managers/asyncexec/async_executor.py +0 -0
  88. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/managers/data/__init__.py +0 -0
  89. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/managers/data/data_manager.py +0 -0
  90. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/managers/evaluation/__init__.py +0 -0
  91. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/managers/evaluation/evaluated_experiment.py +0 -0
  92. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/managers/remote_data/__init__.py +0 -0
  93. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/managers/remote_data/remote_data_manager.py +0 -0
  94. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/managers/tracking/__init__.py +0 -0
  95. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/managers/tracking/tracking_builder.py +0 -0
  96. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/managers/tracking/tracking_manager.py +0 -0
  97. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/managers/tracking/visitor_tracking_registry.py +0 -0
  98. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/managers/warehouse/__init__.py +0 -0
  99. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/managers/warehouse/warehouse_manager.py +0 -0
  100. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/middleware.py +0 -0
  101. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/__init__.py +0 -0
  102. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/access_token_source.py +0 -0
  103. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/access_token_source_factory.py +0 -0
  104. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/activity_event.py +0 -0
  105. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/cookie/__init__.py +0 -0
  106. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/cookie/cookie_manager.py +0 -0
  107. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/net_provider.py +0 -0
  108. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/net_provider_impl.py +0 -0
  109. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/network_manager.py +0 -0
  110. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/network_manager_impl.py +0 -0
  111. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/query_encodable.py +0 -0
  112. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/sendable.py +0 -0
  113. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/service_initialize_context.py +0 -0
  114. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/service_initialize_context_impl.py +0 -0
  115. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/services/__init__.py +0 -0
  116. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/services/automation_service.py +0 -0
  117. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/services/automation_service_impl.py +0 -0
  118. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/services/configuration_service.py +0 -0
  119. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/services/configuration_service_impl.py +0 -0
  120. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/services/data_service.py +0 -0
  121. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/services/data_service_impl.py +0 -0
  122. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/services/service.py +0 -0
  123. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/services/service_impl.py +0 -0
  124. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/network/uri_helper.py +0 -0
  125. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/real_time/__init__.py +0 -0
  126. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/real_time/real_time_configuration_service.py +0 -0
  127. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/real_time/real_time_event.py +0 -0
  128. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/storage/__init__.py +0 -0
  129. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/storage/cache.py +0 -0
  130. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/storage/cache_factory.py +0 -0
  131. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/storage/cache_factory_impl.py +0 -0
  132. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/storage/cache_impl.py +0 -0
  133. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/__init__.py +0 -0
  134. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/__init__.py +0 -0
  135. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/browser_condition.py +0 -0
  136. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/constants.py +0 -0
  137. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/conversion_condition.py +0 -0
  138. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/cookie_condition.py +0 -0
  139. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/custom_datum.py +0 -0
  140. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/device_condition.py +0 -0
  141. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/exclusive_feature_flag_condition.py +0 -0
  142. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/geolocation_condition.py +0 -0
  143. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/kcs_heat_range_condition.py +0 -0
  144. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/number_condition.py +0 -0
  145. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/operating_system_condition.py +0 -0
  146. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/page_title_condition.py +0 -0
  147. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/page_url_condition.py +0 -0
  148. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/page_view_number_condition.py +0 -0
  149. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/previous_page_condition.py +0 -0
  150. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/sdk_language_condition.py +0 -0
  151. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/segment_condition.py +0 -0
  152. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/string_value_condition.py +0 -0
  153. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/target_feature_flag_condition.py +0 -0
  154. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/time_elapsed_since_visit_condition.py +0 -0
  155. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/unknown_condition.py +0 -0
  156. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/visit_number_today_condition.py +0 -0
  157. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/visit_number_total_condition.py +0 -0
  158. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/visitor_code_condition.py +0 -0
  159. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/conditions/visitor_new_return_condition.py +0 -0
  160. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/models.py +0 -0
  161. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/targeting/tree_builder.py +0 -0
  162. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/types/__init__.py +0 -0
  163. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/types/variable.py +0 -0
  164. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon/types/variation.py +0 -0
  165. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon_client_python.egg-info/dependency_links.txt +0 -0
  166. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon_client_python.egg-info/requires.txt +11 -11
  167. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/kameleoon_client_python.egg-info/top_level.txt +0 -0
  168. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/setup.cfg +0 -0
  169. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/setup.py +0 -0
  170. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/tests/integration/proj/__init__.py +0 -0
  171. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/tests/integration/proj/kameleoon_app/__init__.py +0 -0
  172. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/tests/integration/proj/kameleoon_app/admin.py +0 -0
  173. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/tests/integration/proj/kameleoon_app/apps.py +0 -0
  174. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/tests/integration/proj/kameleoon_app/migrations/__init__.py +0 -0
  175. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/tests/integration/proj/kameleoon_app/models.py +0 -0
  176. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/tests/integration/proj/kameleoon_app/tests.py +0 -0
  177. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/tests/integration/proj/kameleoon_app/views.py +0 -0
  178. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/tests/integration/proj/manage.py +0 -0
  179. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/tests/integration/proj/proj/__init__.py +0 -0
  180. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/tests/integration/proj/proj/asgi.py +0 -0
  181. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/tests/integration/proj/proj/settings.py +0 -0
  182. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/tests/integration/proj/proj/urls.py +0 -0
  183. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.0}/tests/integration/proj/proj/wsgi.py +0 -0
  184. {kameleoon-client-python-3.10.0 → kameleoon-client-python-3.12.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.10.0
3
+ Version: 3.12.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
@@ -1,6 +1,11 @@
1
1
  # pylint: disable=duplicate-code
2
2
  """Conversion data"""
3
+
4
+ import json
5
+ from typing import Optional, Iterable
6
+ from kameleoon.data.custom_data import CustomData
3
7
  from kameleoon.data.data import Data, DataType
8
+ from kameleoon.helpers.string_utils import StringUtils
4
9
  from kameleoon.network.sendable import DuplicationSafeSendableBase
5
10
  from kameleoon.network.query_builder import QueryBuilder, QueryParam, QueryParams
6
11
 
@@ -11,7 +16,13 @@ class Conversion(Data, DuplicationSafeSendableBase):
11
16
 
12
17
  EVENT_TYPE = "conversion"
13
18
 
14
- def __init__(self, goal_id: int, revenue: float = 0.0, negative: bool = False) -> None:
19
+ def __init__(
20
+ self,
21
+ goal_id: int,
22
+ revenue: float = 0.0,
23
+ negative: bool = False,
24
+ metadata: Optional[Iterable[CustomData]] = None,
25
+ ) -> None:
15
26
  """
16
27
  :param goal_id: Id of the goal associated to the conversion
17
28
  :type goal_id: int
@@ -19,6 +30,8 @@ class Conversion(Data, DuplicationSafeSendableBase):
19
30
  :type revenue: float
20
31
  :param negative: Optional field - If the revenue is negative. By default it's positive, defaults to False
21
32
  :type negative: bool
33
+ :param metadata: Optional field - Metadata of the conversion. `None` by default.
34
+ :type metadata: Optional[Iterable[CustomData]]
22
35
 
23
36
  Example:
24
37
 
@@ -31,6 +44,7 @@ class Conversion(Data, DuplicationSafeSendableBase):
31
44
  self.__goal_id = goal_id
32
45
  self.__revenue = revenue
33
46
  self.__negative = negative
47
+ self.__metadata = metadata
34
48
 
35
49
  @property
36
50
  def goal_id(self) -> int:
@@ -47,6 +61,11 @@ class Conversion(Data, DuplicationSafeSendableBase):
47
61
  """Returns negative flag state"""
48
62
  return self.__negative
49
63
 
64
+ @property
65
+ def metadata(self) -> Optional[Iterable[CustomData]]:
66
+ """Returns metadata"""
67
+ return self.__metadata
68
+
50
69
  @property
51
70
  def data_type(self) -> DataType:
52
71
  return DataType.CONVERSION
@@ -60,10 +79,23 @@ class Conversion(Data, DuplicationSafeSendableBase):
60
79
  QueryParam(QueryParams.REVENUE, str(self.revenue)),
61
80
  QueryParam(QueryParams.NEGATIVE, "true" if self.negative else "false"),
62
81
  )
82
+ if self.metadata:
83
+ query_builder.append(QueryParam(QueryParams.METADATA, self.__encode_metadata()))
84
+
85
+ def __encode_metadata(self) -> str:
86
+ metadata = {}
87
+ if self.metadata is not None:
88
+ added_indices = set()
89
+ for mcd in self.metadata:
90
+ if isinstance(mcd, CustomData) and (mcd.id not in added_indices):
91
+ metadata[mcd.id] = mcd.values
92
+ added_indices.add(mcd.id)
93
+ return json.dumps(metadata, separators=(",", ":"))
63
94
 
64
95
  def __str__(self):
65
96
  return (
66
97
  f"Conversion{{goal_id:{self.__goal_id},"
67
98
  f"revenue:{self.__revenue},"
68
- f"negative:{self.__negative}}}"
99
+ f"negative:{self.__negative},"
100
+ f"metadata:{StringUtils.object_to_string(self.__metadata)}}}"
69
101
  )
@@ -45,9 +45,6 @@ class CustomData(Data, DuplicationUnsafeSendableBase):
45
45
  def data_type(self) -> DataType:
46
46
  return DataType.CUSTOM_DATA
47
47
 
48
- def encode_query(self) -> str:
49
- return super().encode_query() if len(self.__values) > 0 else ""
50
-
51
48
  def _add_query_params(self, query_builder: QueryBuilder) -> None:
52
49
  str_values = json.dumps({v: 1 for v in self.__values}, separators=(",", ":"))
53
50
  query_builder.extend(
@@ -58,7 +55,4 @@ class CustomData(Data, DuplicationUnsafeSendableBase):
58
55
  )
59
56
 
60
57
  def __str__(self):
61
- return (
62
- f"CustomData{{id:{self.__id},"
63
- f"values:{self.__values}}}"
64
- )
58
+ return f"CustomData{{id:{self.__id},values:{self.__values}}}"
@@ -23,6 +23,7 @@ class DataType(IntEnum):
23
23
  FORCED_EXPERIMENT_VARIATION = 14
24
24
  FORCED_FEATURE_VARIATION = 15
25
25
  CBS = 16
26
+ PERSONALIZATION = 17
26
27
 
27
28
 
28
29
  class BaseData:
@@ -15,6 +15,7 @@ from kameleoon.data.kcs_heat import KcsHeat
15
15
  from kameleoon.data.mapping_identifier import MappingIdentifier
16
16
  from kameleoon.data.operating_system import OperatingSystem
17
17
  from kameleoon.data.page_view import PageView
18
+ from kameleoon.data.personalization import Personalization
18
19
  from kameleoon.data.unique_identifier import UniqueIdentifier
19
20
  from kameleoon.data.user_agent import UserAgent
20
21
  from kameleoon.data.manager.assigned_variation import AssignedVariation
@@ -127,6 +128,13 @@ class Visitor: # pylint: disable=R0904
127
128
  KameleoonLogger.debug('CALL/RETURN: Visitor.variations -> (variations: %s)', variations)
128
129
  return variations
129
130
 
131
+ @property
132
+ def personalizations(self) -> Dict[int, Personalization]:
133
+ """Returns the personalizations associated with this Visitor."""
134
+ personalizations = EMPTY_DICT if self._data.personalizations is None else self._data.personalizations.copy()
135
+ KameleoonLogger.debug('CALL/RETURN: Visitor.personalizations -> (personalizations: %s)', personalizations)
136
+ return personalizations
137
+
130
138
  def get_forced_feature_variation(self, feature_key: str) -> Optional[ForcedFeatureVariation]:
131
139
  """
132
140
  Returns an associated forced feature variation by its feature key if it is present.
@@ -266,6 +274,7 @@ class Visitor: # pylint: disable=R0904
266
274
  self.page_view_visits: Optional[Dict[str, PageViewVisit]] = None
267
275
  self.conversions: Optional[List[Conversion]] = None
268
276
  self.variations: Optional[Dict[int, AssignedVariation]] = None
277
+ self.personalizations: Optional[Dict[int, Personalization]] = None
269
278
  self.forced_variations: Optional[Dict[int, ForcedExperimentVariation]] = None
270
279
  self.simulated_variations: Optional[Dict[str, ForcedFeatureVariation]] = None
271
280
  self.kcs_heat: Optional[KcsHeat] = None
@@ -343,9 +352,16 @@ class Visitor: # pylint: disable=R0904
343
352
  variation = cast(AssignedVariation, context.data)
344
353
  if self._data.variations is None:
345
354
  self._data.variations = {}
346
- if context.overwrite or variation.experiment_id not in self.variations:
355
+ if context.overwrite or variation.experiment_id not in self._data.variations:
347
356
  self._data.variations[variation.experiment_id] = variation
348
357
 
358
+ def _add_personalization(self, context: DataAddingContext) -> None:
359
+ personalization = cast(Personalization, context.data)
360
+ if self._data.personalizations is None:
361
+ self._data.personalizations = {}
362
+ if context.overwrite or personalization.id not in self._data.personalizations:
363
+ self._data.personalizations[personalization.id] = personalization
364
+
349
365
  def _add_forced_feature_variation(self, context: DataAddingContext) -> None:
350
366
  ffv = cast(ForcedFeatureVariation, context.data)
351
367
  if self._data.simulated_variations is None:
@@ -441,6 +457,7 @@ class Visitor: # pylint: disable=R0904
441
457
  CBScores: _set_cbscores,
442
458
  VisitorVisits: _set_visitor_visits,
443
459
  AssignedVariation: _add_variation,
460
+ Personalization: _add_personalization,
444
461
  ForcedFeatureVariation: _add_forced_feature_variation,
445
462
  ForcedExperimentVariation: _add_forced_experiment_variation,
446
463
  UniqueIdentifier: _set_is_unique_identifier,
@@ -0,0 +1,30 @@
1
+ """Personalization"""
2
+
3
+ from kameleoon.data import DataType
4
+ from kameleoon.data.data import BaseData
5
+
6
+
7
+ class Personalization(BaseData):
8
+ """Personalization"""
9
+
10
+ def __init__(self, id_: int, variation_id: int) -> None:
11
+ super().__init__()
12
+ self.__id = id_
13
+ self.__variation_id = variation_id
14
+
15
+ @property
16
+ def id(self) -> int: # pylint: disable=C0103
17
+ """Returns personalization ID"""
18
+ return self.__id
19
+
20
+ @property
21
+ def variation_id(self) -> int:
22
+ """Returns variation ID"""
23
+ return self.__variation_id
24
+
25
+ @property
26
+ def data_type(self) -> DataType:
27
+ return DataType.PERSONALIZATION
28
+
29
+ def __str__(self):
30
+ return f"Personalization{{id:{self.__id},variation_id:{self.__variation_id}}}"
@@ -0,0 +1,83 @@
1
+ """Helper for domain"""
2
+ import re
3
+ from typing import Optional
4
+
5
+ from kameleoon.logging.kameleoon_logger import KameleoonLogger
6
+
7
+ HTTP = "http://"
8
+ HTTPS = "https://"
9
+ REGEX_DOMAIN = (
10
+ r"^(\.?(([a-zA-Z\d][a-zA-Z\d-]*[a-zA-Z\d])|[a-zA-Z\d]))"
11
+ r"(\.(([a-zA-Z\d][a-zA-Z\d-]*[a-zA-Z\d])|[a-zA-Z\d])){1,126}$"
12
+ )
13
+ LOCALHOST = "localhost"
14
+
15
+
16
+ def validate_top_level_domain(top_level_domain: str) -> str:
17
+ """
18
+ Validate the given top-level domain.
19
+
20
+ Args:
21
+ top_level_domain (str): The top-level domain to validate.
22
+
23
+ Returns:
24
+ str: The validated top-level domain.
25
+ """
26
+ if top_level_domain == "":
27
+ return top_level_domain
28
+
29
+ top_level_domain = check_and_trim_protocol(top_level_domain.lower())
30
+
31
+ if not re.match(REGEX_DOMAIN, top_level_domain) and top_level_domain != LOCALHOST:
32
+ KameleoonLogger.error(
33
+ f"The top-level domain '{top_level_domain}' is invalid. The value has been set as provided, but it does "
34
+ f"not meet the required format for proper SDK functionality. Please check the domain for correctness.")
35
+ return top_level_domain
36
+
37
+ return top_level_domain
38
+
39
+
40
+ def validate_network_domain(network_domain: Optional[str]) -> Optional[str]:
41
+ """
42
+ Validate the given network domain.
43
+
44
+ Args:
45
+ network_domain: The network domain to validate.
46
+
47
+ Returns:
48
+ str or None: The validated network domain, or None if invalid.
49
+ """
50
+ if not network_domain:
51
+ return None
52
+
53
+ network_domain = check_and_trim_protocol(network_domain.lower())
54
+
55
+ # Replace first and last dot
56
+ network_domain = re.sub(r"^\.+|\.+$", "", network_domain)
57
+
58
+ if not re.match(REGEX_DOMAIN, network_domain) and network_domain != LOCALHOST:
59
+ KameleoonLogger.error(f"The network domain '{network_domain}' is invalid.")
60
+ return None
61
+
62
+ return network_domain
63
+
64
+
65
+ def check_and_trim_protocol(domain: str) -> str:
66
+ """
67
+ Check if the domain contains a protocol and trim it if it does.
68
+
69
+ Args:
70
+ domain: The domain to check and trim.
71
+
72
+ Returns:
73
+ str: The domain after trimming the protocol.
74
+ """
75
+ protocols = [HTTP, HTTPS]
76
+ for protocol in protocols:
77
+ if domain.startswith(protocol):
78
+ domain = domain[len(protocol):]
79
+ KameleoonLogger.warning(
80
+ f"The domain contains '{protocol}'. Domain after protocol trimming: '{domain}'"
81
+ )
82
+ return domain
83
+ return domain
@@ -1,5 +1,6 @@
1
1
  """Helper class for work with string values"""
2
2
 
3
+ import collections.abc
3
4
  from typing import Any, Optional
4
5
 
5
6
 
@@ -31,6 +32,8 @@ class StringUtils:
31
32
  @staticmethod
32
33
  def object_to_string(data: Any) -> str:
33
34
  """Convert various data types into their string representation."""
35
+ if data is None:
36
+ return "None"
34
37
  if isinstance(data, str):
35
38
  return f"'{data}'"
36
39
  result = StringUtils._collection_to_string(data)
@@ -38,19 +41,17 @@ class StringUtils:
38
41
  return result
39
42
  if isinstance(data, bool):
40
43
  return StringUtils.bool_to_string_lower_case(data)
41
- if data is None:
42
- return "None"
43
44
  if hasattr(data, '__str__'):
44
45
  return str(data)
45
46
  return repr(data)
46
47
 
47
48
  @staticmethod
48
49
  def _collection_to_string(data: Any) -> Optional[str]:
49
- if isinstance(data, (list, tuple)):
50
- return "[" + ",".join(StringUtils.object_to_string(item) for item in data) + "]"
51
50
  if isinstance(data, dict):
52
51
  return "{" + ",".join(
53
52
  f"{StringUtils.object_to_string(key)}: {StringUtils.object_to_string(value)}"
54
53
  for key, value in data.items()
55
54
  ) + "}"
55
+ if isinstance(data, collections.abc.Iterable):
56
+ return "[" + ",".join(StringUtils.object_to_string(item) for item in data) + "]"
56
57
  return None
@@ -142,6 +142,7 @@ class KameleoonClient:
142
142
  config.default_timeout_second,
143
143
  NetProviderImpl(),
144
144
  atsf,
145
+ config.network_domain,
145
146
  )
146
147
  self._targeting_manager = TargetingManager(self._data_manager, self._visitor_manager)
147
148
  self._warehouse_manager = WarehouseManager(self._network_manager, self._visitor_manager)
@@ -354,7 +355,8 @@ class KameleoonClient:
354
355
  KameleoonLogger.info("RETURN: KameleoonClient.add_data(visitor_code: %s, args: %s)", visitor_code, args)
355
356
 
356
357
  def track_conversion(
357
- self, visitor_code: str, goal_id: int, revenue: float = 0.0, is_unique_identifier: Optional[bool] = None
358
+ self, visitor_code: str, goal_id: int, revenue: float = 0.0, is_unique_identifier: Optional[bool] = None,
359
+ negative=False, metadata: Optional[Iterable[CustomData]] = None,
358
360
  ) -> None:
359
361
  """
360
362
  To track conversion, use the track_conversion() method. This method requires visitor_code and goal_id to track
@@ -372,28 +374,25 @@ class KameleoonClient:
372
374
  :param is_unique_identifier: (Deprecated) Parameter that specifies whether the visitorCode is
373
375
  a unique identifier.
374
376
  :type is_unique_identifier: Optional[bool]
375
- :return: None
377
+ :param negative: Defines if the revenue is positive or negative. This field is optional (`False` by default).
378
+ :type negative: bool
379
+ :param metadata: Metadata of the conversion. This field is optional (`None` by default).
380
+ :type metadata: Optional[Iterable[CustomData]]
376
381
  """
377
382
  KameleoonLogger.info(
378
383
  "CALL: KameleoonClient.track_conversion(visitor_code: %s, goal_id: %s, revenue: %s, "
379
- "is_unique_identifier: %s)",
380
- visitor_code,
381
- goal_id,
382
- revenue,
383
- is_unique_identifier,
384
+ "is_unique_identifier: %s, negative: %s, metadata: %s)",
385
+ visitor_code, goal_id, revenue, is_unique_identifier, negative, metadata
384
386
  )
385
387
  validate_visitor_code(visitor_code)
386
388
  if is_unique_identifier is not None:
387
389
  self.__set_unique_identifier(visitor_code, is_unique_identifier)
388
- self.add_data(visitor_code, Conversion(goal_id, revenue))
390
+ self.add_data(visitor_code, Conversion(goal_id, revenue, negative, metadata))
389
391
  self._tracking_manager.add_visitor_code(visitor_code)
390
392
  KameleoonLogger.info(
391
393
  "RETURN: KameleoonClient.track_conversion(visitor_code: %s, goal_id: %s, revenue: %s, "
392
- "is_unique_identifier: %s)",
393
- visitor_code,
394
- goal_id,
395
- revenue,
396
- is_unique_identifier,
394
+ "is_unique_identifier: %s, negative: %s, metadata: %s)",
395
+ visitor_code, goal_id, revenue, is_unique_identifier, negative, metadata
397
396
  )
398
397
 
399
398
  def flush(
@@ -1,11 +1,12 @@
1
1
  """Kameleoon Client Configuration"""
2
+
2
3
  import logging
3
4
  import os
4
5
  from typing import Any, Dict, Optional
5
6
  import yaml
6
7
 
7
8
  from kameleoon.exceptions import ConfigCredentialsInvalid, ConfigFileNotFound
8
- from kameleoon.helpers.domain import validate_top_level_domain
9
+ from kameleoon.helpers.domain import validate_top_level_domain, validate_network_domain
9
10
  from kameleoon.helpers.logger import Logger
10
11
  from kameleoon.helpers.string_utils import StringUtils
11
12
  from kameleoon.logging.kameleoon_logger import KameleoonLogger
@@ -22,7 +23,7 @@ DEFAULT_CONFIGURATION_PATH = "/etc/kameleoon/client-python.yaml"
22
23
  class KameleoonClientConfig:
23
24
  """Client configuration which can be used instead of external configuration file"""
24
25
 
25
- # pylint: disable=R0913
26
+ # pylint: disable=R0913, R0904
26
27
  def __init__(
27
28
  self,
28
29
  client_id: str,
@@ -35,6 +36,7 @@ class KameleoonClientConfig:
35
36
  logger: Optional[logging.Logger] = None,
36
37
  multi_threading: Optional[bool] = None,
37
38
  tracking_interval_millisecond=DEFAULT_TRACKING_INTERVAL_MILLISECONDS,
39
+ network_domain: Optional[str] = None,
38
40
  ) -> None:
39
41
  """
40
42
  :param logger: (Deprecated)
@@ -67,6 +69,7 @@ class KameleoonClientConfig:
67
69
  self.__multi_threading = False
68
70
  if multi_threading is not None:
69
71
  self.set_multi_threading(multi_threading)
72
+ self.set_network_domain(network_domain)
70
73
 
71
74
  @staticmethod
72
75
  def read_from_yaml(config_path=DEFAULT_CONFIGURATION_PATH) -> "KameleoonClientConfig":
@@ -104,6 +107,8 @@ class KameleoonClientConfig:
104
107
  kwargs["top_level_domain"] = top_level_domain
105
108
  if isinstance(multi_threading := config_dict.get("multi_threading"), bool):
106
109
  kwargs["multi_threading"] = multi_threading
110
+ if isinstance(network_domain := config_dict.get("network_domain"), str):
111
+ kwargs["network_domain"] = network_domain
107
112
  return KameleoonClientConfig(client_id, client_secret, **kwargs)
108
113
 
109
114
  @property
@@ -137,9 +142,11 @@ class KameleoonClientConfig:
137
142
  def set_refresh_interval_minute(self, value: float) -> None:
138
143
  """Sets the refresh interval in minutes"""
139
144
  if value <= 0:
140
- KameleoonLogger.warning("Configuration refresh interval must have positive value. "
141
- "Default refresh interval (%s minutes) was applied.",
142
- DEFAULT_REFRESH_INTERVAL_MINUTES)
145
+ KameleoonLogger.warning(
146
+ "Configuration refresh interval must have positive value. "
147
+ "Default refresh interval (%s minutes) was applied.",
148
+ DEFAULT_REFRESH_INTERVAL_MINUTES,
149
+ )
143
150
  value = DEFAULT_REFRESH_INTERVAL_MINUTES
144
151
  self.__refresh_interval_second = value * 60.0
145
152
 
@@ -151,8 +158,10 @@ class KameleoonClientConfig:
151
158
  def set_session_duration_minute(self, value: float) -> None:
152
159
  """Sets the session duration in minutes"""
153
160
  if value <= 0:
154
- KameleoonLogger.warning("Session duration must have positive value. Default session duration "
155
- "(%s minutes) was applied.", DEFAULT_SESSION_DURATION_MINUTES)
161
+ KameleoonLogger.warning(
162
+ "Session duration must have positive value. Default session duration " "(%s minutes) was applied.",
163
+ DEFAULT_SESSION_DURATION_MINUTES,
164
+ )
156
165
  value = DEFAULT_SESSION_DURATION_MINUTES
157
166
  self.__session_duration_second = value * 60.0
158
167
 
@@ -164,8 +173,10 @@ class KameleoonClientConfig:
164
173
  def set_default_timeout_millisecond(self, value: int) -> None:
165
174
  """Sets the default timeout in milliseconds"""
166
175
  if value <= 0:
167
- KameleoonLogger.warning("Default timeout must have positive value. Default value (%s ms) was applied.",
168
- DEFAULT_DEFAULT_TIMEOUT_MILLISECONDS)
176
+ KameleoonLogger.warning(
177
+ "Default timeout must have positive value. Default value (%s ms) was applied.",
178
+ DEFAULT_DEFAULT_TIMEOUT_MILLISECONDS,
179
+ )
169
180
  value = DEFAULT_DEFAULT_TIMEOUT_MILLISECONDS
170
181
  self.__default_timeout_second = value / 1000.0
171
182
 
@@ -179,12 +190,14 @@ class KameleoonClientConfig:
179
190
  if value < MIN_TRACKING_INTERVAL_MILLISECONDS:
180
191
  KameleoonLogger.warning(
181
192
  "Tracking interval must not be shorter than (%s ms). Minimum possible interval was applied.",
182
- MIN_TRACKING_INTERVAL_MILLISECONDS)
193
+ MIN_TRACKING_INTERVAL_MILLISECONDS,
194
+ )
183
195
  value = MIN_TRACKING_INTERVAL_MILLISECONDS
184
196
  elif value > MAX_TRACKING_INTERVAL_MILLISECONDS:
185
197
  KameleoonLogger.warning(
186
198
  "Tracking interval must not be longer than (%s ms). Maximum possible interval was applied.",
187
- MAX_TRACKING_INTERVAL_MILLISECONDS)
199
+ MAX_TRACKING_INTERVAL_MILLISECONDS,
200
+ )
188
201
  value = MAX_TRACKING_INTERVAL_MILLISECONDS
189
202
  self.__tracking_interval_second = value / 1000.0
190
203
 
@@ -205,8 +218,10 @@ class KameleoonClientConfig:
205
218
  def set_top_level_domain(self, value: str) -> None:
206
219
  """Sets the top level domain"""
207
220
  if not value:
208
- KameleoonLogger.warning("Setting top level domain is strictly recommended, "
209
- "otherwise you may have problems when using subdomains.")
221
+ KameleoonLogger.warning(
222
+ "Setting top level domain is strictly recommended, "
223
+ "otherwise you may have problems when using subdomains."
224
+ )
210
225
  self.__top_level_domain = validate_top_level_domain(value)
211
226
 
212
227
  @property
@@ -219,6 +234,15 @@ class KameleoonClientConfig:
219
234
  self.__multi_threading = value
220
235
  KameleoonLogger.warning("Configuration parameter 'multi_threading' is deprecated.")
221
236
 
237
+ @property
238
+ def network_domain(self) -> Optional[str]:
239
+ """Returns the network domain"""
240
+ return self.__network_domain
241
+
242
+ def set_network_domain(self, value: Optional[str]) -> None:
243
+ """Sets the network domain"""
244
+ self.__network_domain = validate_network_domain(value)
245
+
222
246
  def __str__(self):
223
247
  return (
224
248
  f"KameleoonClientConfig{{"
@@ -228,4 +252,6 @@ class KameleoonClientConfig:
228
252
  f"session_duration_second:{self.__session_duration_second},"
229
253
  f"environment:'{self.__environment}',"
230
254
  f"default_timeout_millisecond:{self.__default_timeout_second},"
231
- f"top_level_domain:'{self.__top_level_domain}'}}")
255
+ f"top_level_domain:{self.__top_level_domain},"
256
+ f"network_domain:'{self.__network_domain}'}}"
257
+ )
@@ -12,6 +12,7 @@ from kameleoon.configuration.rule_type import RuleType
12
12
  from kameleoon.data.visitor_visits import VisitorVisits
13
13
  from kameleoon.data.kcs_heat import KcsHeat
14
14
  from kameleoon.data.cbscores import CBScores, ScoredVarId
15
+ from kameleoon.data.personalization import Personalization
15
16
  from kameleoon.data.manager.assigned_variation import AssignedVariation
16
17
  from kameleoon.data.manager.page_view_visit import PageViewVisit
17
18
  from kameleoon.data import (
@@ -40,6 +41,7 @@ class RemoteVisitorData:
40
41
  self.__page_view_visits: Optional[Dict[str, PageViewVisit]] = None
41
42
  self.__custom_data_dict: Optional[Dict[int, CustomData]] = None
42
43
  self.__experiments: Optional[Dict[int, AssignedVariation]] = None
44
+ self.__personalizations: Optional[Dict[int, Personalization]] = None
43
45
  self.__conversions: Optional[List[Conversion]] = None
44
46
  self.__previous_visitor_visits: Optional[VisitorVisits] = None
45
47
  self.__visitor_code: Optional[str] = None
@@ -71,6 +73,8 @@ class RemoteVisitorData:
71
73
  data_to_add += self.__page_view_visits.values()
72
74
  if self.__experiments:
73
75
  data_to_add += self.__experiments.values()
76
+ if self.__personalizations:
77
+ data_to_add += self.__personalizations.values()
74
78
  if self.__conversions:
75
79
  data_to_add += self.__conversions
76
80
  data_to_add += self.__single_data()
@@ -134,6 +138,9 @@ class RemoteVisitorData:
134
138
  static_data_event = json_visit.get("staticDataEvent")
135
139
  if static_data_event:
136
140
  self.__parse_static_data(static_data_event)
141
+ personalization_events = json_visit.get("personalizationEvents")
142
+ if personalization_events:
143
+ self.__parse_personalizations(personalization_events)
137
144
 
138
145
  def __parse_custom_data(self, custom_data_events: List[Dict[str, Any]]) -> None:
139
146
  if self.__custom_data_dict is None:
@@ -214,17 +221,27 @@ class RemoteVisitorData:
214
221
  if operating_system_type is not None:
215
222
  self.__operating_system = OperatingSystem(operating_system_type)
216
223
 
217
- def __single_data(self) -> List[Data]:
218
- objects: List[Data] = []
224
+ def __parse_personalizations(self, personalization_events: List[Dict[str, Any]]) -> None:
225
+ if self.__personalizations is None:
226
+ self.__personalizations = {}
227
+ for personalization_event in reversed(personalization_events):
228
+ data = personalization_event.get("data")
229
+ if data is not None:
230
+ index = data.get("id")
231
+ variation_id = data.get("variationId")
232
+ if index is not None and variation_id is not None:
233
+ if index not in self.__personalizations:
234
+ self.__personalizations[index] = Personalization(index, variation_id)
235
+
236
+ def __single_data(self) -> Iterable[Data]:
219
237
  if self.__device:
220
- objects.append(self.__device)
238
+ yield self.__device
221
239
  if self.__browser:
222
- objects.append(self.__browser)
240
+ yield self.__browser
223
241
  if self.__operating_system:
224
- objects.append(self.__operating_system)
242
+ yield self.__operating_system
225
243
  if self.__geolocation:
226
- objects.append(self.__geolocation)
227
- return objects
244
+ yield self.__geolocation
228
245
 
229
246
  @staticmethod
230
247
  def __parse_kcs_heat(kcs: Optional[Any]) -> Optional[KcsHeat]:
@@ -15,6 +15,7 @@ class NetworkManagerFactory:
15
15
  call_timeout: float,
16
16
  net_provider: NetProvider,
17
17
  access_token_source_factory: AccessTokenSourceFactory,
18
+ network_domain: Optional[str],
18
19
  ) -> NetworkManager:
19
20
  """Creates and returns an instance of `NetworkManager` with the specified parameters."""
20
21
  raise NotImplementedError()
@@ -1,4 +1,5 @@
1
1
  """Network"""
2
+
2
3
  from typing import Optional
3
4
  from kameleoon.network.access_token_source_factory import AccessTokenSourceFactory
4
5
  from kameleoon.network.url_provider import UrlProvider
@@ -16,18 +17,20 @@ from kameleoon.network.services.data_service_impl import DataServiceImpl
16
17
 
17
18
  class NetworkManagerFactoryImpl(NetworkManagerFactory):
18
19
  """Network manager factory implementation"""
20
+
19
21
  # fmt is disabled due issue in pylint, disabling R0801 doesn’t work
20
22
  # fmt: off
21
23
  # pylint: disable=R0913
22
24
  def create(
23
25
  self,
24
26
  site_code: str,
25
- environment: Optional[str], call_timeout: float,
27
+ environment: Optional[str], call_timeout: float, # don`t change this line
26
28
  net_provider: NetProvider,
27
29
  access_token_source_factory: AccessTokenSourceFactory,
30
+ network_domain: Optional[str],
28
31
  ) -> NetworkManager:
29
32
  # fmt: on
30
- url_provider = UrlProvider(site_code, UrlProvider.DEFAULT_DATA_API_DOMAIN)
33
+ url_provider = UrlProvider(site_code, network_domain)
31
34
  network_manager = NetworkManagerImpl(
32
35
  url_provider, environment, call_timeout, net_provider, access_token_source_factory,
33
36
  )
@@ -25,9 +25,11 @@ class QueryParams(str, Enum):
25
25
  KCS = "kcs"
26
26
  KEY = "key"
27
27
  MAX_NUMBER_PREVIOUS_VISITS = "maxNumberPreviousVisits"
28
+ METADATA = "metadata"
28
29
  NEGATIVE = "negative"
29
30
  NONCE = "nonce"
30
31
  OVERWRITE = "overwrite"
32
+ PERSONALIZATION = "personalization"
31
33
  REFERRERS_INDICES = "referrersIndices"
32
34
  REVENUE = "revenue"
33
35
  SDK_NAME = "sdkName"