kameleoon-client-python 3.16.2__tar.gz → 3.17.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 (185) hide show
  1. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/PKG-INFO +17 -17
  2. kameleoon_client_python-3.17.0/kameleoon/configuration/consent_blocking_behaviour.py +16 -0
  3. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/configuration/data_file.py +3 -2
  4. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/configuration/settings.py +9 -0
  5. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/conversion.py +3 -3
  6. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/custom_data.py +3 -2
  7. kameleoon_client_python-3.17.0/kameleoon/data/manager/legal_consent.py +11 -0
  8. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/manager/visitor.py +5 -4
  9. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/manager/visitor_manager.py +32 -9
  10. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/personalization.py +1 -1
  11. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/targeted_segment.py +1 -1
  12. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/exceptions.py +0 -7
  13. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/helpers/functions.py +1 -1
  14. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/kameleoon_client.py +73 -19
  15. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/managers/tracking/tracking_builder.py +4 -1
  16. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/cookie/cookie_manager.py +2 -13
  17. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/network_manager.py +1 -1
  18. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/sdk_version.py +1 -1
  19. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/storage/cache.py +2 -2
  20. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/targeting_condition.py +1 -1
  21. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/time_elapsed_since_visit_condition.py +0 -1
  22. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/visit_number_total_condition.py +0 -1
  23. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/visitor_new_return_condition.py +0 -1
  24. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon_client_python.egg-info/PKG-INFO +17 -17
  25. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon_client_python.egg-info/SOURCES.txt +2 -0
  26. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/MANIFEST.in +0 -0
  27. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/README.md +0 -0
  28. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/__init__.py +0 -0
  29. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/client_readiness/__init__.py +0 -0
  30. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/client_readiness/async_readiness.py +0 -0
  31. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/client_readiness/threading_readiness.py +0 -0
  32. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/configuration/__init__.py +0 -0
  33. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/configuration/custom_data_info.py +0 -0
  34. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/configuration/experiment.py +0 -0
  35. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/configuration/feature_flag.py +0 -0
  36. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/configuration/me_group.py +0 -0
  37. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/configuration/rule.py +0 -0
  38. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/configuration/rule_type.py +0 -0
  39. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/configuration/variable.py +0 -0
  40. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/configuration/variation.py +0 -0
  41. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/configuration/variation_by_exposition.py +0 -0
  42. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/__init__.py +0 -0
  43. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/browser.py +0 -0
  44. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/cbscores.py +0 -0
  45. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/cookie.py +0 -0
  46. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/data.py +0 -0
  47. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/device.py +0 -0
  48. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/geolocation.py +0 -0
  49. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/kcs_heat.py +0 -0
  50. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/manager/__init__.py +0 -0
  51. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/manager/assigned_variation.py +0 -0
  52. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/manager/forced_experiment_variation.py +0 -0
  53. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/manager/forced_feature_variation.py +0 -0
  54. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/manager/forced_variation.py +0 -0
  55. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/manager/page_view_visit.py +0 -0
  56. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/manager/visitor_slot.py +0 -0
  57. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/mapping_identifier.py +0 -0
  58. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/operating_system.py +0 -0
  59. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/page_view.py +0 -0
  60. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/unique_identifier.py +0 -0
  61. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/user_agent.py +0 -0
  62. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/data/visitor_visits.py +0 -0
  63. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/defaults.py +0 -0
  64. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/helpers/__init__.py +0 -0
  65. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/helpers/domain.py +0 -0
  66. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/helpers/hasher.py +0 -0
  67. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/helpers/logger.py +0 -0
  68. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/helpers/multi_threading.py +0 -0
  69. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/helpers/nonce.py +0 -0
  70. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/helpers/repeat_timer.py +0 -0
  71. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/helpers/scheduler.py +0 -0
  72. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/helpers/string_utils.py +0 -0
  73. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/helpers/visitor_code.py +0 -0
  74. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/hybrid/__init__.py +0 -0
  75. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/hybrid/hybrid_manager.py +0 -0
  76. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/hybrid/hybrid_manager_impl.py +0 -0
  77. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/kameleoon_client_config.py +0 -0
  78. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/kameleoon_client_factory.py +0 -0
  79. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/logging/__init__.py +0 -0
  80. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/logging/kameleoon_logger.py +0 -0
  81. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/logging/log_level.py +0 -0
  82. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/logging/logger.py +0 -0
  83. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/managers/__init__.py +0 -0
  84. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/managers/asyncexec/__init__.py +0 -0
  85. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/managers/asyncexec/async_executor.py +0 -0
  86. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/managers/data/__init__.py +0 -0
  87. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/managers/data/data_manager.py +0 -0
  88. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/managers/evaluation/__init__.py +0 -0
  89. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/managers/evaluation/evaluated_experiment.py +0 -0
  90. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/managers/remote_data/__init__.py +0 -0
  91. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/managers/remote_data/remote_data_manager.py +0 -0
  92. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/managers/remote_data/remote_visitor_data.py +0 -0
  93. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/managers/tracking/__init__.py +0 -0
  94. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/managers/tracking/tracking_manager.py +0 -0
  95. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/managers/tracking/visitor_tracking_registry.py +0 -0
  96. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/managers/warehouse/__init__.py +0 -0
  97. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/managers/warehouse/warehouse_manager.py +0 -0
  98. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/middleware.py +0 -0
  99. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/__init__.py +0 -0
  100. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/access_token_source.py +0 -0
  101. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/access_token_source_factory.py +0 -0
  102. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/activity_event.py +0 -0
  103. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/cookie/__init__.py +0 -0
  104. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/net_provider.py +0 -0
  105. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/net_provider_impl.py +0 -0
  106. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/network_manager_factory.py +0 -0
  107. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/network_manager_factory_impl.py +0 -0
  108. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/network_manager_impl.py +0 -0
  109. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/query_builder.py +0 -0
  110. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/query_encodable.py +0 -0
  111. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/sendable.py +0 -0
  112. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/service_initialize_context.py +0 -0
  113. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/service_initialize_context_impl.py +0 -0
  114. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/services/__init__.py +0 -0
  115. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/services/automation_service.py +0 -0
  116. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/services/automation_service_impl.py +0 -0
  117. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/services/configuration_service.py +0 -0
  118. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/services/configuration_service_impl.py +0 -0
  119. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/services/data_service.py +0 -0
  120. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/services/data_service_impl.py +0 -0
  121. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/services/service.py +0 -0
  122. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/services/service_impl.py +0 -0
  123. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/uri_helper.py +0 -0
  124. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/network/url_provider.py +0 -0
  125. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/real_time/__init__.py +0 -0
  126. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/real_time/real_time_configuration_service.py +0 -0
  127. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/real_time/real_time_event.py +0 -0
  128. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/storage/__init__.py +0 -0
  129. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/storage/cache_factory.py +0 -0
  130. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/storage/cache_factory_impl.py +0 -0
  131. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/storage/cache_impl.py +0 -0
  132. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/__init__.py +0 -0
  133. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/__init__.py +0 -0
  134. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/browser_condition.py +0 -0
  135. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/constants.py +0 -0
  136. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/conversion_condition.py +0 -0
  137. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/cookie_condition.py +0 -0
  138. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/custom_datum.py +0 -0
  139. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/device_condition.py +0 -0
  140. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/exclusive_experiment_condition.py +0 -0
  141. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/geolocation_condition.py +0 -0
  142. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/kcs_heat_range_condition.py +0 -0
  143. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/number_condition.py +0 -0
  144. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/operating_system_condition.py +0 -0
  145. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/page_title_condition.py +0 -0
  146. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/page_url_condition.py +0 -0
  147. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/page_view_number_condition.py +0 -0
  148. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/previous_page_condition.py +0 -0
  149. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/sdk_language_condition.py +0 -0
  150. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/segment_condition.py +0 -0
  151. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/string_value_condition.py +0 -0
  152. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/target_experiment_condition.py +0 -0
  153. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/target_feature_flag_condition.py +0 -0
  154. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/target_personalization_condition.py +0 -0
  155. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/unknown_condition.py +0 -0
  156. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/visit_number_today_condition.py +0 -0
  157. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/conditions/visitor_code_condition.py +0 -0
  158. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/models.py +0 -0
  159. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/targeting_manager.py +0 -0
  160. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/tree_builder.py +0 -0
  161. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/targeting/tree_condition_factory.py +0 -0
  162. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/types/__init__.py +0 -0
  163. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/types/remote_visitor_data_filter.py +0 -0
  164. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/types/variable.py +0 -0
  165. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon/types/variation.py +0 -0
  166. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon_client_python.egg-info/dependency_links.txt +0 -0
  167. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon_client_python.egg-info/requires.txt +16 -16
  168. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/kameleoon_client_python.egg-info/top_level.txt +0 -0
  169. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/setup.cfg +0 -0
  170. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/setup.py +0 -0
  171. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/tests/integration/proj/__init__.py +0 -0
  172. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/tests/integration/proj/kameleoon_app/__init__.py +0 -0
  173. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/tests/integration/proj/kameleoon_app/admin.py +0 -0
  174. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/tests/integration/proj/kameleoon_app/apps.py +0 -0
  175. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/tests/integration/proj/kameleoon_app/migrations/__init__.py +0 -0
  176. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/tests/integration/proj/kameleoon_app/models.py +0 -0
  177. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/tests/integration/proj/kameleoon_app/tests.py +0 -0
  178. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/tests/integration/proj/kameleoon_app/views.py +0 -0
  179. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/tests/integration/proj/manage.py +0 -0
  180. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/tests/integration/proj/proj/__init__.py +0 -0
  181. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/tests/integration/proj/proj/asgi.py +0 -0
  182. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/tests/integration/proj/proj/settings.py +0 -0
  183. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/tests/integration/proj/proj/urls.py +0 -0
  184. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/tests/integration/proj/proj/wsgi.py +0 -0
  185. {kameleoon_client_python-3.16.2 → kameleoon_client_python-3.17.0}/tests/resources/config.yml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kameleoon-client-python
3
- Version: 3.16.2
3
+ Version: 3.17.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
@@ -20,27 +20,27 @@ Requires-Dist: requests<3.0.0,>=2.25
20
20
  Requires-Dist: sseclient-py<1.9.0,>=1.7.0
21
21
  Requires-Dist: aiohttp<4.0.0,>=3.8.0
22
22
  Provides-Extra: test
23
- Requires-Dist: pytest-pythonpath==0.7.3; extra == "test"
24
- Requires-Dist: Django==3.2.4; extra == "test"
25
- Requires-Dist: pyyaml<6.1.0,>=5.4.0; extra == "test"
26
- Requires-Dist: aioresponses==0.7.*; extra == "test"
27
- Requires-Dist: pylint==2.12.*; extra == "test"
28
- Requires-Dist: types-python-dateutil==2.8.2; extra == "test"
23
+ Requires-Dist: pytest-asyncio==0.21.*; extra == "test"
24
+ Requires-Dist: aiohttp<4.0.0,>=3.8.0; extra == "test"
29
25
  Requires-Dist: freezegun==1.1.0; extra == "test"
30
- Requires-Dist: wheel==0.36.2; extra == "test"
31
- Requires-Dist: requests<3.0.0,>=2.25; extra == "test"
32
- Requires-Dist: flake8==4.0.1; extra == "test"
33
- Requires-Dist: pytest-cov==2.12.1; extra == "test"
34
- Requires-Dist: types-requests==2.25.0; extra == "test"
35
- Requires-Dist: sseclient-py<1.9.0,>=1.7.0; extra == "test"
36
- Requires-Dist: mypy==0.991; extra == "test"
37
26
  Requires-Dist: twine==3.4.1; extra == "test"
38
- Requires-Dist: types-PyYAML==5.4.3; extra == "test"
27
+ Requires-Dist: wheel==0.36.2; extra == "test"
39
28
  Requires-Dist: Werkzeug==2.0.1; extra == "test"
29
+ Requires-Dist: mypy==0.991; extra == "test"
40
30
  Requires-Dist: pytest-ordering==0.6; extra == "test"
41
- Requires-Dist: pytest-asyncio==0.21.*; extra == "test"
31
+ Requires-Dist: pytest-cov==2.12.1; extra == "test"
32
+ Requires-Dist: sseclient-py<1.9.0,>=1.7.0; extra == "test"
33
+ Requires-Dist: aioresponses==0.7.*; extra == "test"
42
34
  Requires-Dist: pytest-django==4.4.0; extra == "test"
43
- Requires-Dist: aiohttp<4.0.0,>=3.8.0; extra == "test"
35
+ Requires-Dist: Django==3.2.4; extra == "test"
36
+ Requires-Dist: requests<3.0.0,>=2.25; extra == "test"
37
+ Requires-Dist: flake8==4.0.1; extra == "test"
38
+ Requires-Dist: pyyaml<6.1.0,>=5.4.0; extra == "test"
39
+ Requires-Dist: pylint==2.12.*; extra == "test"
40
+ Requires-Dist: types-PyYAML==5.4.3; extra == "test"
41
+ Requires-Dist: pytest-pythonpath==0.7.3; extra == "test"
42
+ Requires-Dist: types-requests==2.25.0; extra == "test"
43
+ Requires-Dist: types-python-dateutil==2.8.2; extra == "test"
44
44
  Dynamic: author
45
45
  Dynamic: author-email
46
46
  Dynamic: classifier
@@ -0,0 +1,16 @@
1
+ """Kameleoon Configuration"""
2
+
3
+ from enum import Enum
4
+ from kameleoon.helpers.functions import enum_from_literal
5
+
6
+
7
+ class ConsentBlockingBehaviour(Enum):
8
+ """Possible Consent Blocking Behaviour types"""
9
+
10
+ PARTIALLY_BLOCKED = "PARTIALLY_BLOCK"
11
+ COMPLETELY_BLOCKED = "FULLY_BLOCK"
12
+
13
+ @staticmethod
14
+ def from_str(s: str) -> "ConsentBlockingBehaviour":
15
+ """Makes ConsentBlockingBehaviour from string"""
16
+ return enum_from_literal(s, ConsentBlockingBehaviour, ConsentBlockingBehaviour.PARTIALLY_BLOCKED)
@@ -48,7 +48,7 @@ class DataFile:
48
48
  configuration: Dict[str, Any], segments: Dict[int, Segment], cdi: CustomDataInfo
49
49
  ) -> Dict[str, FeatureFlag]:
50
50
  return {
51
- (ff := FeatureFlag(jobj, segments, cdi)).feature_key: ff # pylint: disable=C0103
51
+ (ff := FeatureFlag(jobj, segments, cdi)).feature_key: ff
52
52
  for jobj in configuration.get("featureFlags") or []
53
53
  }
54
54
 
@@ -153,7 +153,8 @@ class DataFile:
153
153
  if feature_flag is None:
154
154
  raise FeatureNotFound(feature_key)
155
155
  if not feature_flag.environment_enabled:
156
- raise FeatureEnvironmentDisabled(feature_key, self.__environment)
156
+ env = "default" if self.__environment is None else f"'{self.__environment}'"
157
+ raise FeatureEnvironmentDisabled(f"Feature '{feature_key}' is disabled for {env} environment")
157
158
  return feature_flag
158
159
 
159
160
  @property
@@ -1,6 +1,7 @@
1
1
  """Kameleoon Configuration"""
2
2
 
3
3
  from typing import Any, Dict, Optional
4
+ from kameleoon.configuration.consent_blocking_behaviour import ConsentBlockingBehaviour
4
5
 
5
6
 
6
7
  class Settings:
@@ -17,6 +18,8 @@ class Settings:
17
18
  configuration = {}
18
19
  self.__real_time_update: bool = bool(configuration.get("realTimeUpdate"))
19
20
  self.__is_consent_required = configuration.get("consentType") == self._CONSENT_TYPE_REQUIRED
21
+ self.__blocking_behaviour_if_consent_not_given = \
22
+ ConsentBlockingBehaviour.from_str(configuration.get("consentOptOutBehavior", ""))
20
23
  self.__data_api_domain = configuration.get("dataApiDomain")
21
24
 
22
25
  @property
@@ -29,6 +32,11 @@ class Settings:
29
32
  """Returns consent required flag state"""
30
33
  return self.__is_consent_required
31
34
 
35
+ @property
36
+ def blocking_behaviour_if_consent_not_given(self) -> ConsentBlockingBehaviour:
37
+ """Returns blocking behaviour if consent not given"""
38
+ return self.__blocking_behaviour_if_consent_not_given
39
+
32
40
  @property
33
41
  def data_api_domain(self) -> Any:
34
42
  """Returns Data API domain to be switched to"""
@@ -38,5 +46,6 @@ class Settings:
38
46
  return (
39
47
  f"Settings{{real_time_update:{self.__real_time_update},"
40
48
  f"is_consent_required:{self.__is_consent_required},"
49
+ f"blocking_behaviour_if_consent_not_given:{self.__blocking_behaviour_if_consent_not_given},"
41
50
  f"data_api_domain:'{self.__data_api_domain}'}}"
42
51
  )
@@ -44,7 +44,7 @@ class Conversion(Data, DuplicationSafeSendableBase):
44
44
  self.__goal_id = goal_id
45
45
  self.__revenue = revenue
46
46
  self.__negative = negative
47
- self.__metadata = metadata
47
+ self._metadata = metadata
48
48
 
49
49
  @property
50
50
  def goal_id(self) -> int:
@@ -64,7 +64,7 @@ class Conversion(Data, DuplicationSafeSendableBase):
64
64
  @property
65
65
  def metadata(self) -> Optional[Iterable[CustomData]]:
66
66
  """Returns metadata"""
67
- return self.__metadata
67
+ return self._metadata
68
68
 
69
69
  @property
70
70
  def data_type(self) -> DataType:
@@ -97,5 +97,5 @@ class Conversion(Data, DuplicationSafeSendableBase):
97
97
  f"Conversion{{goal_id:{self.__goal_id},"
98
98
  f"revenue:{self.__revenue},"
99
99
  f"negative:{self.__negative},"
100
- f"metadata:{StringUtils.object_to_string(self.__metadata)}}}"
100
+ f"metadata:{StringUtils.object_to_string(self._metadata)}}}"
101
101
  )
@@ -11,6 +11,7 @@ class CustomData(Data, DuplicationUnsafeSendableBase):
11
11
  """Custom data"""
12
12
 
13
13
  EVENT_TYPE = "customData"
14
+ UNDEFINED_INDEX = -1
14
15
 
15
16
  def __init__(self, index_or_name: Union[int, str], *args: str, overwrite=True) -> None:
16
17
  """
@@ -29,7 +30,7 @@ class CustomData(Data, DuplicationUnsafeSendableBase):
29
30
  self.__index = index_or_name
30
31
  self._name = None
31
32
  else:
32
- self.__index = -1
33
+ self.__index = self.UNDEFINED_INDEX
33
34
  self._name = index_or_name
34
35
  self.__values = args
35
36
  self.__overwrite = overwrite
@@ -41,7 +42,7 @@ class CustomData(Data, DuplicationUnsafeSendableBase):
41
42
  return custom_data
42
43
 
43
44
  @property
44
- def id(self) -> int: # pylint: disable=C0103
45
+ def id(self) -> int:
45
46
  """
46
47
  Deprecated. Please use `index` instead.
47
48
 
@@ -0,0 +1,11 @@
1
+ """Legal Consent"""
2
+
3
+ from enum import Enum
4
+
5
+
6
+ class LegalConsent(Enum):
7
+ """Possible Legal Consent states"""
8
+
9
+ UNKNOWN = 0
10
+ GIVEN = 1
11
+ NOT_GIVEN = 2
@@ -24,6 +24,7 @@ from kameleoon.data.user_agent import UserAgent
24
24
  from kameleoon.data.manager.assigned_variation import AssignedVariation
25
25
  from kameleoon.data.manager.forced_experiment_variation import ForcedExperimentVariation
26
26
  from kameleoon.data.manager.forced_feature_variation import ForcedFeatureVariation
27
+ from kameleoon.data.manager.legal_consent import LegalConsent
27
28
  from kameleoon.data.manager.page_view_visit import PageViewVisit
28
29
  from kameleoon.logging.kameleoon_logger import KameleoonLogger
29
30
  from kameleoon.network.sendable import Sendable
@@ -246,7 +247,7 @@ class Visitor: # pylint: disable=R0904
246
247
  return mapping_identifier
247
248
 
248
249
  @mapping_identifier.setter
249
- def mapping_identifier(self, value: str):
250
+ def mapping_identifier(self, value: str) -> None:
250
251
  """Sets the mapping identifier for this Visitor."""
251
252
  if self._data.mapping_identifier:
252
253
  return
@@ -257,14 +258,14 @@ class Visitor: # pylint: disable=R0904
257
258
  KameleoonLogger.debug("CALL/RETURN: Visitor.mapping_identifier <- (mapping_identifier: %s)", value)
258
259
 
259
260
  @property
260
- def legal_consent(self) -> bool:
261
+ def legal_consent(self) -> LegalConsent:
261
262
  """Returns the legal consent status for this Visitor."""
262
263
  legal_consent = self._data.legal_consent
263
264
  KameleoonLogger.debug('CALL/RETURN: Visitor.legal_consent -> (legal_consent: %s)', legal_consent)
264
265
  return legal_consent
265
266
 
266
267
  @legal_consent.setter
267
- def legal_consent(self, value: bool):
268
+ def legal_consent(self, value: LegalConsent) -> None:
268
269
  """Sets the legal consent status for this Visitor."""
269
270
  self._data.legal_consent = value
270
271
  KameleoonLogger.debug("CALL/RETURN: Visitor.legal_consent <- (legal_consent: %s)", value)
@@ -300,7 +301,7 @@ class Visitor: # pylint: disable=R0904
300
301
  self.cbscores: Optional[CBScores] = None
301
302
  self.visitor_visits: Optional[VisitorVisits] = None
302
303
  self.mapping_identifier: Optional[str] = None
303
- self.legal_consent = False
304
+ self.legal_consent = LegalConsent.UNKNOWN
304
305
 
305
306
  def enumerate_sendable_data(self) -> Iterator[Sendable]:
306
307
  """Iterates over all sendable data associated with the visitor."""
@@ -3,7 +3,7 @@ import collections
3
3
  import time
4
4
  from typing import Any, Dict, Iterator, List, Optional
5
5
  from kameleoon.configuration.custom_data_info import CustomDataInfo
6
- from kameleoon.data import CustomData
6
+ from kameleoon.data import Conversion, CustomData
7
7
  from kameleoon.data.mapping_identifier import MappingIdentifier
8
8
  from kameleoon.data.manager.visitor import Visitor
9
9
  from kameleoon.data.manager.visitor_slot import VisitorSlot
@@ -77,9 +77,10 @@ class VisitorManager:
77
77
  data_to_add: List[Any] = [None] * len(args)
78
78
  for i, data in enumerate(args):
79
79
  if isinstance(data, CustomData):
80
- data_to_add[i] = self.__process_custom_data(visitor_code, visitor, custom_data_info, data)
81
- else:
82
- data_to_add[i] = data
80
+ data = self.__process_custom_data(visitor_code, visitor, custom_data_info, data)
81
+ elif isinstance(data, Conversion):
82
+ data = self.__process_conversion(data, custom_data_info)
83
+ data_to_add[i] = data
83
84
  visitor.add_data(*data_to_add)
84
85
  KameleoonLogger.debug("RETURN: VisitorManager.add_data(visitor_code: %s, args: %s) -> (visitor)",
85
86
  visitor_code, args)
@@ -89,11 +90,11 @@ class VisitorManager:
89
90
  self, visitor_code: str, visitor: Visitor, custom_data_info: CustomDataInfo, custom_data: CustomData
90
91
  ) -> Optional[CustomData]:
91
92
  """Processes custom data, potentially modifying or mapping it based on certain conditions."""
92
- if custom_data.name is not None:
93
- cd_index = custom_data_info.get_custom_data_index_by_name(custom_data.name)
94
- if cd_index is None:
95
- return None
96
- custom_data = custom_data._named_to_indexed(cd_index)
93
+ if mapped_cd := self.__try_map_custom_data_index_by_name(custom_data, custom_data_info):
94
+ custom_data = mapped_cd
95
+ else:
96
+ KameleoonLogger.error("%s is invalid and will be ignored", custom_data)
97
+ return None
97
98
  # We shouldn't send custom data with local only type
98
99
  if custom_data_info.is_local_only(custom_data.index):
99
100
  custom_data.mark_as_sent()
@@ -113,6 +114,28 @@ class VisitorManager:
113
114
  return MappingIdentifier(custom_data)
114
115
  return custom_data
115
116
 
117
+ @staticmethod
118
+ def __process_conversion(conversion: Conversion, cdi: CustomDataInfo) -> Conversion:
119
+ if conversion.metadata:
120
+ metadata = []
121
+ for cd in conversion.metadata:
122
+ mapped_cd = VisitorManager.__try_map_custom_data_index_by_name(cd, cdi)
123
+ if mapped_cd:
124
+ metadata.append(mapped_cd)
125
+ else:
126
+ KameleoonLogger.warning("Conversion metadata %s is invalid", cd)
127
+ conversion._metadata = metadata
128
+ return conversion
129
+
130
+ @staticmethod
131
+ def __try_map_custom_data_index_by_name(custom_data: CustomData, cdi: CustomDataInfo) -> Optional[CustomData]:
132
+ if custom_data.index != CustomData.UNDEFINED_INDEX:
133
+ return custom_data
134
+ if custom_data.name is None:
135
+ return None
136
+ cd_index = cdi.get_custom_data_index_by_name(custom_data.name)
137
+ return custom_data._named_to_indexed(cd_index) if cd_index is not None else None
138
+
116
139
  def __purge(self) -> None:
117
140
  KameleoonLogger.debug("CALL: VisitorManager.__purge()")
118
141
  expired_time = time.time() - self.__expiration_period
@@ -13,7 +13,7 @@ class Personalization(BaseData):
13
13
  self.__variation_id = variation_id
14
14
 
15
15
  @property
16
- def id(self) -> int: # pylint: disable=C0103
16
+ def id(self) -> int:
17
17
  """Returns personalization ID"""
18
18
  return self.__id
19
19
 
@@ -13,7 +13,7 @@ class TargetedSegment(BaseData, DuplicationUnsafeSendableBase):
13
13
  self.__id = id_
14
14
 
15
15
  @property
16
- def id(self) -> int: # pylint: disable=C0103
16
+ def id(self) -> int:
17
17
  """Returns the segment ID."""
18
18
  return self.__id
19
19
 
@@ -1,7 +1,5 @@
1
1
  """Kameleoon exceptions"""
2
2
 
3
- from typing import Optional
4
-
5
3
 
6
4
  class KameleoonError(Exception):
7
5
  """Base Kameleoon error"""
@@ -53,11 +51,6 @@ class FeatureVariationNotFound(NotFoundError):
53
51
  class FeatureEnvironmentDisabled(FeatureError):
54
52
  """Exception indicating that feature flag is disabled for the visitor's current environment."""
55
53
 
56
- def __init__(self, feature_key: str, environment: Optional[str] = None) -> None:
57
- env = "default" if environment is None else f"'{environment}'"
58
- message = f"Feature '{feature_key}' is disabled for {env} environment"
59
- super().__init__(message)
60
-
61
54
 
62
55
  class FeatureNotFound(NotFoundError):
63
56
  """Exception indicating that the requested feature ID
@@ -16,7 +16,7 @@ def get_size(obj) -> float:
16
16
  return sum([sys.getsizeof(v) + sys.getsizeof(k) for k, v in obj.items()])
17
17
 
18
18
 
19
- E = TypeVar('E', bound=Enum) # pylint: disable=C0103
19
+ E = TypeVar('E', bound=Enum)
20
20
 
21
21
 
22
22
  def enum_from_literal(literal: str, enum_type: Type[E], default_value: E) -> E:
@@ -7,6 +7,7 @@ from kameleoon.client_readiness.async_readiness import AsyncClientReadiness
7
7
  from kameleoon.client_readiness.threading_readiness import ThreadingClientReadiness
8
8
 
9
9
  from kameleoon import configuration
10
+ from kameleoon.configuration.consent_blocking_behaviour import ConsentBlockingBehaviour
10
11
  from kameleoon.configuration.data_file import DataFile
11
12
  from kameleoon.configuration.feature_flag import FeatureFlag
12
13
  from kameleoon.configuration.rule import Rule
@@ -15,6 +16,7 @@ from kameleoon.configuration.rule_type import RuleType
15
16
  from kameleoon.data import Conversion, CustomData, Data, UniqueIdentifier
16
17
  from kameleoon.data.manager.assigned_variation import AssignedVariation
17
18
  from kameleoon.data.manager.forced_experiment_variation import ForcedExperimentVariation
19
+ from kameleoon.data.manager.legal_consent import LegalConsent
18
20
  from kameleoon.data.manager.visitor import Visitor
19
21
  from kameleoon.data.manager.visitor_manager import VisitorManager
20
22
  from kameleoon.data.targeted_segment import TargetedSegment
@@ -312,7 +314,7 @@ class KameleoonClient:
312
314
  )
313
315
  validate_visitor_code(visitor_code)
314
316
  visitor = self._visitor_manager.get_or_create_visitor(visitor_code)
315
- visitor.legal_consent = consent
317
+ visitor.legal_consent = LegalConsent.GIVEN if consent else LegalConsent.NOT_GIVEN
316
318
  if cookies is not None:
317
319
  self._cookie_manager.update(visitor_code, consent, cookies)
318
320
  KameleoonLogger.info(
@@ -356,8 +358,13 @@ class KameleoonClient:
356
358
  KameleoonLogger.info("RETURN: KameleoonClient.add_data(visitor_code: %s, args: %s)", visitor_code, args)
357
359
 
358
360
  def track_conversion(
359
- self, visitor_code: str, goal_id: int, revenue: float = 0.0, is_unique_identifier: Optional[bool] = None,
360
- negative=False, metadata: Optional[Iterable[CustomData]] = None,
361
+ self,
362
+ visitor_code: str,
363
+ goal_id: int,
364
+ revenue: float = 0.0,
365
+ is_unique_identifier: Optional[bool] = None,
366
+ negative=False,
367
+ metadata: Optional[Iterable[CustomData]] = None,
361
368
  ) -> None:
362
369
  """
363
370
  To track conversion, use the track_conversion() method. This method requires visitor_code and goal_id to track
@@ -383,7 +390,12 @@ class KameleoonClient:
383
390
  KameleoonLogger.info(
384
391
  "CALL: KameleoonClient.track_conversion(visitor_code: %s, goal_id: %s, revenue: %s, "
385
392
  "is_unique_identifier: %s, negative: %s, metadata: %s)",
386
- visitor_code, goal_id, revenue, is_unique_identifier, negative, metadata
393
+ visitor_code,
394
+ goal_id,
395
+ revenue,
396
+ is_unique_identifier,
397
+ negative,
398
+ metadata,
387
399
  )
388
400
  validate_visitor_code(visitor_code)
389
401
  if is_unique_identifier is not None:
@@ -393,7 +405,12 @@ class KameleoonClient:
393
405
  KameleoonLogger.info(
394
406
  "RETURN: KameleoonClient.track_conversion(visitor_code: %s, goal_id: %s, revenue: %s, "
395
407
  "is_unique_identifier: %s, negative: %s, metadata: %s)",
396
- visitor_code, goal_id, revenue, is_unique_identifier, negative, metadata
408
+ visitor_code,
409
+ goal_id,
410
+ revenue,
411
+ is_unique_identifier,
412
+ negative,
413
+ metadata,
397
414
  )
398
415
 
399
416
  def flush(
@@ -619,7 +636,10 @@ class KameleoonClient:
619
636
  for feature_flag in self._data_manager.data_file.feature_flags.values():
620
637
  if not feature_flag.environment_enabled:
621
638
  continue
622
- variation_key, eval_exp = self.__get_variation_info(visitor_code, feature_flag, track)
639
+ try:
640
+ variation_key, eval_exp = self.__get_variation_info(visitor_code, feature_flag, track)
641
+ except FeatureEnvironmentDisabled:
642
+ continue
623
643
  if only_active and (variation_key == configuration.Variation.Type.OFF.value):
624
644
  continue
625
645
  variations[feature_flag.feature_key] = self.__create_external_variation(
@@ -731,7 +751,11 @@ class KameleoonClient:
731
751
  in_holdout_variation_key = "in-holdout"
732
752
  KameleoonLogger.debug(
733
753
  "CALL: KameleoonClient.__is_visitor_not_in_holdout(visitor, visitor_code: %s, track: %s, save: %s, "
734
- "bucketing_cd_index: %s)", visitor_code, track, save, bucketing_cd_index
754
+ "bucketing_cd_index: %s)",
755
+ visitor_code,
756
+ track,
757
+ save,
758
+ bucketing_cd_index,
735
759
  )
736
760
  is_not_in_holdout = True
737
761
  code_for_hash = self.__get_code_for_hash(visitor, visitor_code, bucketing_cd_index)
@@ -746,7 +770,11 @@ class KameleoonClient:
746
770
  KameleoonLogger.debug(
747
771
  "RETURN: KameleoonClient.__is_visitor_not_in_holdout(visitor, visitor_code: %s, track: %s, save: %s, "
748
772
  "bucketing_cd_index: %s) -> (is_not_in_holdout: %s)",
749
- visitor_code, track, save, bucketing_cd_index, is_not_in_holdout
773
+ visitor_code,
774
+ track,
775
+ save,
776
+ bucketing_cd_index,
777
+ is_not_in_holdout,
750
778
  )
751
779
  return is_not_in_holdout
752
780
 
@@ -1163,7 +1191,10 @@ class KameleoonClient:
1163
1191
  def filter_conditions(feature_flag: FeatureFlag) -> bool:
1164
1192
  if not feature_flag.environment_enabled:
1165
1193
  return False
1166
- eval_exp = self.__evaluate(visitor, visitor_code, feature_flag, False, False)
1194
+ try:
1195
+ eval_exp = self.__evaluate(visitor, visitor_code, feature_flag, False, False)
1196
+ except FeatureEnvironmentDisabled:
1197
+ return False
1167
1198
  variation_key = self.__calculate_variation_key(eval_exp, feature_flag.default_variation_key)
1168
1199
  return variation_key != configuration.Variation.Type.OFF.value
1169
1200
 
@@ -1211,7 +1242,10 @@ class KameleoonClient:
1211
1242
  for feature_flag in self._data_manager.data_file.feature_flags.values():
1212
1243
  if not feature_flag.environment_enabled:
1213
1244
  continue
1214
- eval_exp = self.__evaluate(visitor, visitor_code, feature_flag, False, False)
1245
+ try:
1246
+ eval_exp = self.__evaluate(visitor, visitor_code, feature_flag, False, False)
1247
+ except FeatureEnvironmentDisabled:
1248
+ continue
1215
1249
  variation_key = self.__calculate_variation_key(eval_exp, feature_flag.default_variation_key)
1216
1250
  if variation_key == configuration.Variation.Type.OFF.value:
1217
1251
  continue
@@ -1437,7 +1471,7 @@ class KameleoonClient:
1437
1471
  data_file = DataFile.from_json(
1438
1472
  self._config.environment,
1439
1473
  fetched_configuration.last_modified,
1440
- fetched_configuration.configuration
1474
+ fetched_configuration.configuration,
1441
1475
  )
1442
1476
  self._data_manager.data_file = data_file
1443
1477
  self._network_manager.url_provider.apply_data_api_domain(data_file.settings.data_api_domain)
@@ -1547,7 +1581,8 @@ class KameleoonClient:
1547
1581
  fetched_configuration = await service.fetch_configuration(self._config.environment, time_stamp, last_modified)
1548
1582
  KameleoonLogger.debug(
1549
1583
  "RETURN: KameleoonClient._obtain_configuration(time_stamp: %s) -> (fetched_configuration: %s)",
1550
- time_stamp, fetched_configuration
1584
+ time_stamp,
1585
+ fetched_configuration,
1551
1586
  )
1552
1587
  return fetched_configuration
1553
1588
 
@@ -1615,7 +1650,9 @@ class KameleoonClient:
1615
1650
  return None
1616
1651
  KameleoonLogger.debug(
1617
1652
  "CALL: KameleoonClient.__evaluate_cbscores(visitor, visitor_code: %s, rule: %s, bucketing_cd_index: %s)",
1618
- visitor_code, rule, bucketing_cd_index
1653
+ visitor_code,
1654
+ rule,
1655
+ bucketing_cd_index,
1619
1656
  )
1620
1657
  eval_exp = None
1621
1658
  var_id_group_by_scores = visitor.cbscores.values.get(rule.experiment.id_)
@@ -1640,11 +1677,15 @@ class KameleoonClient:
1640
1677
  eval_exp = EvaluatedExperiment.from_var_by_exp_rule(var_by_exp_in_cbs[idx], rule)
1641
1678
  KameleoonLogger.debug(
1642
1679
  "RETURN: KameleoonClient.__evaluate_cbscores(visitor, visitor_code: %s, rule: %s, bucketing_cd_index: %s)"
1643
- " -> (eval_exp: %s)", visitor_code, rule, bucketing_cd_index, eval_exp
1680
+ " -> (eval_exp: %s)",
1681
+ visitor_code,
1682
+ rule,
1683
+ bucketing_cd_index,
1684
+ eval_exp,
1644
1685
  )
1645
1686
  return eval_exp
1646
1687
 
1647
- def __calculate_variation_rule_for_feature(
1688
+ def __calculate_variation_rule_for_feature( # noqa: C901, pylint: disable=R0912
1648
1689
  self, visitor_code: str, feature_flag: FeatureFlag
1649
1690
  ) -> Optional[EvaluatedExperiment]:
1650
1691
  """helper method for calculate variation key for feature flag"""
@@ -1654,6 +1695,11 @@ class KameleoonClient:
1654
1695
  feature_flag,
1655
1696
  )
1656
1697
  visitor = self._visitor_manager.get_visitor(visitor_code)
1698
+ datafile = self._data_manager.data_file
1699
+ if datafile.settings.is_consent_required:
1700
+ consent = visitor.legal_consent if visitor else LegalConsent.UNKNOWN
1701
+ else:
1702
+ consent = LegalConsent.GIVEN
1657
1703
  code_for_hash = self.__get_code_for_hash(visitor, visitor_code, feature_flag.bucketing_custom_data_index)
1658
1704
  eval_exp = None
1659
1705
  for rule in feature_flag.rules:
@@ -1669,11 +1715,20 @@ class KameleoonClient:
1669
1715
  # Forcing experiment variation in targeting-only mode
1670
1716
  eval_exp = EvaluatedExperiment.from_var_by_exp_rule(forced_variation.var_by_exp, rule)
1671
1717
  break
1672
- # uses for rule exposition
1718
+ # used for rule exposition
1673
1719
  hash_rule = Hasher.obtain(code_for_hash, rule.id_, rule.respool_time)
1674
1720
  KameleoonLogger.debug("Calculated rule hash %s for code %s", hash_rule, code_for_hash)
1675
1721
  # check main expostion for rule with hashRule
1676
1722
  if hash_rule <= rule.exposition:
1723
+ # Checking if the evaluation is blocked due to the consent policy
1724
+ if (consent == LegalConsent.NOT_GIVEN) and rule.is_experimentation:
1725
+ blocking_behaviour = datafile.settings.blocking_behaviour_if_consent_not_given
1726
+ if blocking_behaviour == ConsentBlockingBehaviour.PARTIALLY_BLOCKED:
1727
+ break
1728
+ raise FeatureEnvironmentDisabled(
1729
+ f"Evaluation of {rule} is blocked because consent is not provided for visitor '{visitor_code}'"
1730
+ )
1731
+ # Checking cbs
1677
1732
  eval_exp = self.__evaluate_cbscores(
1678
1733
  visitor, visitor_code, rule, feature_flag.bucketing_custom_data_index
1679
1734
  )
@@ -1683,8 +1738,7 @@ class KameleoonClient:
1683
1738
  if rule.experiment.first_variation:
1684
1739
  eval_exp = EvaluatedExperiment.from_var_by_exp_rule(rule.experiment.first_variation, rule)
1685
1740
  break
1686
-
1687
- # uses for variation's expositions
1741
+ # used for variation's expositions
1688
1742
  hash_variation = Hasher.obtain(code_for_hash, rule.experiment.id_, rule.respool_time)
1689
1743
  KameleoonLogger.debug("Calculated variation hash %s for code %s", hash_variation, code_for_hash)
1690
1744
  # get variation with hash_variation
@@ -1727,7 +1781,7 @@ class KameleoonClient:
1727
1781
  return (
1728
1782
  not self._data_manager.data_file.settings.is_consent_required
1729
1783
  or ((visitor := self._visitor_manager.get_visitor(visitor_code)) is not None)
1730
- and visitor.legal_consent
1784
+ and (visitor.legal_consent == LegalConsent.GIVEN)
1731
1785
  )
1732
1786
 
1733
1787
  def set_forced_variation(
@@ -3,6 +3,7 @@ from typing import Iterable, List, Optional, Tuple
3
3
  from kameleoon.configuration.data_file import DataFile
4
4
  from kameleoon.configuration.rule_type import RuleType
5
5
  from kameleoon.data.custom_data import CustomData
6
+ from kameleoon.data.manager.legal_consent import LegalConsent
6
7
  from kameleoon.data.manager.visitor import Visitor
7
8
  from kameleoon.data.manager.visitor_manager import VisitorManager
8
9
  from kameleoon.logging.kameleoon_logger import KameleoonLogger
@@ -86,7 +87,9 @@ class TrackingBuilder:
86
87
  visitor_code, is_consent_given)
87
88
 
88
89
  def __is_consent_given(self, visitor: Optional[Visitor]) -> bool:
89
- return not self.__data_file.settings.is_consent_required or ((visitor is not None) and visitor.legal_consent)
90
+ return not self.__data_file.settings.is_consent_required or (
91
+ (visitor is not None) and (visitor.legal_consent == LegalConsent.GIVEN)
92
+ )
90
93
 
91
94
  def __collect_tracking_data(
92
95
  self, visitor_code: str, visitor: Optional[Visitor], is_consent_given: bool
@@ -74,13 +74,13 @@ class CookieManager:
74
74
  if default_visitor_code is None:
75
75
  visitor_code = generate_visitor_code()
76
76
  KameleoonLogger.debug("Generated new visitor code %s", visitor_code)
77
- if not self._data_manager.is_visitor_code_managed and cookies is not None:
77
+ if not self._data_manager.is_visitor_code_managed and (cookies is not None):
78
78
  self._add(visitor_code, cookies)
79
79
  return visitor_code
80
80
  validate_visitor_code(default_visitor_code)
81
81
  visitor_code = default_visitor_code
82
82
  KameleoonLogger.debug("Used default visitor code '%s'", default_visitor_code)
83
- if cookies is not None:
83
+ if not self._data_manager.is_visitor_code_managed and (cookies is not None):
84
84
  self._add(visitor_code, cookies)
85
85
  return visitor_code
86
86
 
@@ -90,8 +90,6 @@ class CookieManager:
90
90
  visitor_code, consent, cookies)
91
91
  if consent:
92
92
  self._add(visitor_code, cookies)
93
- else:
94
- self._remove(cookies)
95
93
  KameleoonLogger.debug("RETURN: CookieManager.update(visitor_code: %s, consent: %s, cookies: %s)",
96
94
  visitor_code, consent, cookies)
97
95
 
@@ -107,15 +105,6 @@ class CookieManager:
107
105
  cookies[VISITOR_CODE_COOKIE] = morsel
108
106
  KameleoonLogger.debug("RETURN: CookieManager._add(visitor_code: %s, cookies: %s)", visitor_code, cookies)
109
107
 
110
- def _remove(self, cookies: Dict[str, Morsel[str]]) -> None:
111
- KameleoonLogger.debug("CALL: CookieManager._remove(cookies: %s)", cookies)
112
- if self._data_manager.is_visitor_code_managed:
113
- if morsel := cookies.get(VISITOR_CODE_COOKIE):
114
- morsel["domain"] = self._top_level_domain
115
- morsel["path"] = "/"
116
- morsel["max-age"] = "0"
117
- KameleoonLogger.debug("RETURN: CookieManager._remove(cookies: %s)", cookies)
118
-
119
108
  def _process_simulated_variations(
120
109
  self, cookies_readonly: Optional[Dict[str, str]], cookies: Optional[Dict[str, Morsel[str]]], visitor_code: str
121
110
  ) -> None:
@@ -7,7 +7,7 @@ from kameleoon.network.service_initialize_context import ServiceInitializeContex
7
7
  from kameleoon.network.services.service import Service
8
8
 
9
9
 
10
- S = TypeVar("S", bound=Service) # pylint: disable=C0103
10
+ S = TypeVar("S", bound=Service)
11
11
 
12
12
 
13
13
  class NetworkManager:
@@ -4,7 +4,7 @@ from typing import Optional, Tuple
4
4
 
5
5
  from kameleoon.logging.kameleoon_logger import KameleoonLogger
6
6
 
7
- version_info = (3, 16, 2)
7
+ version_info = (3, 17, 0)
8
8
  __version__ = ".".join(str(v) for v in version_info) # uses in scripts
9
9
 
10
10