kameleoon-client-python 3.16.3__tar.gz → 3.17.1__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.3 → kameleoon_client_python-3.17.1}/PKG-INFO +15 -15
  2. kameleoon_client_python-3.17.1/kameleoon/configuration/consent_blocking_behaviour.py +16 -0
  3. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/data_file.py +2 -1
  4. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/settings.py +9 -0
  5. kameleoon_client_python-3.17.1/kameleoon/data/manager/legal_consent.py +11 -0
  6. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/manager/visitor.py +5 -4
  7. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/exceptions.py +0 -7
  8. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/kameleoon_client.py +86 -19
  9. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/remote_data/remote_visitor_data.py +8 -10
  10. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/tracking/tracking_builder.py +4 -1
  11. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/cookie/cookie_manager.py +2 -13
  12. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/sdk_version.py +1 -1
  13. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon_client_python.egg-info/PKG-INFO +15 -15
  14. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon_client_python.egg-info/SOURCES.txt +2 -0
  15. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/MANIFEST.in +0 -0
  16. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/README.md +0 -0
  17. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/__init__.py +0 -0
  18. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/client_readiness/__init__.py +0 -0
  19. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/client_readiness/async_readiness.py +0 -0
  20. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/client_readiness/threading_readiness.py +0 -0
  21. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/__init__.py +0 -0
  22. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/custom_data_info.py +0 -0
  23. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/experiment.py +0 -0
  24. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/feature_flag.py +0 -0
  25. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/me_group.py +0 -0
  26. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/rule.py +0 -0
  27. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/rule_type.py +0 -0
  28. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/variable.py +0 -0
  29. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/variation.py +0 -0
  30. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/variation_by_exposition.py +0 -0
  31. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/__init__.py +0 -0
  32. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/browser.py +0 -0
  33. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/cbscores.py +0 -0
  34. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/conversion.py +0 -0
  35. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/cookie.py +0 -0
  36. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/custom_data.py +0 -0
  37. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/data.py +0 -0
  38. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/device.py +0 -0
  39. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/geolocation.py +0 -0
  40. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/kcs_heat.py +0 -0
  41. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/manager/__init__.py +0 -0
  42. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/manager/assigned_variation.py +0 -0
  43. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/manager/forced_experiment_variation.py +0 -0
  44. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/manager/forced_feature_variation.py +0 -0
  45. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/manager/forced_variation.py +0 -0
  46. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/manager/page_view_visit.py +0 -0
  47. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/manager/visitor_manager.py +0 -0
  48. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/manager/visitor_slot.py +0 -0
  49. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/mapping_identifier.py +0 -0
  50. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/operating_system.py +0 -0
  51. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/page_view.py +0 -0
  52. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/personalization.py +0 -0
  53. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/targeted_segment.py +0 -0
  54. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/unique_identifier.py +0 -0
  55. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/user_agent.py +0 -0
  56. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/visitor_visits.py +0 -0
  57. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/defaults.py +0 -0
  58. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/helpers/__init__.py +0 -0
  59. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/helpers/domain.py +0 -0
  60. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/helpers/functions.py +0 -0
  61. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/helpers/hasher.py +0 -0
  62. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/helpers/logger.py +0 -0
  63. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/helpers/multi_threading.py +0 -0
  64. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/helpers/nonce.py +0 -0
  65. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/helpers/repeat_timer.py +0 -0
  66. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/helpers/scheduler.py +0 -0
  67. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/helpers/string_utils.py +0 -0
  68. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/helpers/visitor_code.py +0 -0
  69. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/hybrid/__init__.py +0 -0
  70. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/hybrid/hybrid_manager.py +0 -0
  71. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/hybrid/hybrid_manager_impl.py +0 -0
  72. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/kameleoon_client_config.py +0 -0
  73. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/kameleoon_client_factory.py +0 -0
  74. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/logging/__init__.py +0 -0
  75. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/logging/kameleoon_logger.py +0 -0
  76. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/logging/log_level.py +0 -0
  77. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/logging/logger.py +0 -0
  78. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/__init__.py +0 -0
  79. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/asyncexec/__init__.py +0 -0
  80. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/asyncexec/async_executor.py +0 -0
  81. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/data/__init__.py +0 -0
  82. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/data/data_manager.py +0 -0
  83. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/evaluation/__init__.py +0 -0
  84. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/evaluation/evaluated_experiment.py +0 -0
  85. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/remote_data/__init__.py +0 -0
  86. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/remote_data/remote_data_manager.py +0 -0
  87. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/tracking/__init__.py +0 -0
  88. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/tracking/tracking_manager.py +0 -0
  89. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/tracking/visitor_tracking_registry.py +0 -0
  90. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/warehouse/__init__.py +0 -0
  91. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/warehouse/warehouse_manager.py +0 -0
  92. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/middleware.py +0 -0
  93. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/__init__.py +0 -0
  94. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/access_token_source.py +0 -0
  95. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/access_token_source_factory.py +0 -0
  96. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/activity_event.py +0 -0
  97. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/cookie/__init__.py +0 -0
  98. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/net_provider.py +0 -0
  99. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/net_provider_impl.py +0 -0
  100. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/network_manager.py +0 -0
  101. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/network_manager_factory.py +0 -0
  102. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/network_manager_factory_impl.py +0 -0
  103. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/network_manager_impl.py +0 -0
  104. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/query_builder.py +0 -0
  105. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/query_encodable.py +0 -0
  106. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/sendable.py +0 -0
  107. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/service_initialize_context.py +0 -0
  108. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/service_initialize_context_impl.py +0 -0
  109. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/services/__init__.py +0 -0
  110. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/services/automation_service.py +0 -0
  111. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/services/automation_service_impl.py +0 -0
  112. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/services/configuration_service.py +0 -0
  113. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/services/configuration_service_impl.py +0 -0
  114. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/services/data_service.py +0 -0
  115. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/services/data_service_impl.py +0 -0
  116. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/services/service.py +0 -0
  117. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/services/service_impl.py +0 -0
  118. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/uri_helper.py +0 -0
  119. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/url_provider.py +0 -0
  120. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/real_time/__init__.py +0 -0
  121. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/real_time/real_time_configuration_service.py +0 -0
  122. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/real_time/real_time_event.py +0 -0
  123. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/storage/__init__.py +0 -0
  124. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/storage/cache.py +0 -0
  125. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/storage/cache_factory.py +0 -0
  126. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/storage/cache_factory_impl.py +0 -0
  127. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/storage/cache_impl.py +0 -0
  128. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/__init__.py +0 -0
  129. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/__init__.py +0 -0
  130. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/browser_condition.py +0 -0
  131. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/constants.py +0 -0
  132. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/conversion_condition.py +0 -0
  133. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/cookie_condition.py +0 -0
  134. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/custom_datum.py +0 -0
  135. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/device_condition.py +0 -0
  136. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/exclusive_experiment_condition.py +0 -0
  137. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/geolocation_condition.py +0 -0
  138. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/kcs_heat_range_condition.py +0 -0
  139. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/number_condition.py +0 -0
  140. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/operating_system_condition.py +0 -0
  141. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/page_title_condition.py +0 -0
  142. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/page_url_condition.py +0 -0
  143. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/page_view_number_condition.py +0 -0
  144. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/previous_page_condition.py +0 -0
  145. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/sdk_language_condition.py +0 -0
  146. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/segment_condition.py +0 -0
  147. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/string_value_condition.py +0 -0
  148. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/target_experiment_condition.py +0 -0
  149. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/target_feature_flag_condition.py +0 -0
  150. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/target_personalization_condition.py +0 -0
  151. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/targeting_condition.py +0 -0
  152. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/time_elapsed_since_visit_condition.py +0 -0
  153. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/unknown_condition.py +0 -0
  154. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/visit_number_today_condition.py +0 -0
  155. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/visit_number_total_condition.py +0 -0
  156. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/visitor_code_condition.py +0 -0
  157. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/visitor_new_return_condition.py +0 -0
  158. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/models.py +0 -0
  159. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/targeting_manager.py +0 -0
  160. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/tree_builder.py +0 -0
  161. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/tree_condition_factory.py +0 -0
  162. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/types/__init__.py +0 -0
  163. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/types/remote_visitor_data_filter.py +0 -0
  164. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/types/variable.py +0 -0
  165. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/types/variation.py +0 -0
  166. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon_client_python.egg-info/dependency_links.txt +0 -0
  167. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon_client_python.egg-info/requires.txt +14 -14
  168. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon_client_python.egg-info/top_level.txt +0 -0
  169. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/setup.cfg +0 -0
  170. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/setup.py +0 -0
  171. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/__init__.py +0 -0
  172. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/kameleoon_app/__init__.py +0 -0
  173. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/kameleoon_app/admin.py +0 -0
  174. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/kameleoon_app/apps.py +0 -0
  175. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/kameleoon_app/migrations/__init__.py +0 -0
  176. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/kameleoon_app/models.py +0 -0
  177. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/kameleoon_app/tests.py +0 -0
  178. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/kameleoon_app/views.py +0 -0
  179. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/manage.py +0 -0
  180. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/proj/__init__.py +0 -0
  181. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/proj/asgi.py +0 -0
  182. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/proj/settings.py +0 -0
  183. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/proj/urls.py +0 -0
  184. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/proj/wsgi.py +0 -0
  185. {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/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.3
3
+ Version: 3.17.1
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: wheel==0.36.2; extra == "test"
23
+ Requires-Dist: flake8==4.0.1; extra == "test"
24
+ Requires-Dist: freezegun==1.1.0; extra == "test"
25
+ Requires-Dist: types-requests==2.25.0; extra == "test"
26
+ Requires-Dist: pytest-asyncio==0.21.*; extra == "test"
24
27
  Requires-Dist: types-python-dateutil==2.8.2; extra == "test"
28
+ Requires-Dist: pytest-pythonpath==0.7.3; extra == "test"
29
+ Requires-Dist: aioresponses==0.7.*; 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: twine==3.4.1; extra == "test"
33
+ Requires-Dist: pytest-django==4.4.0; extra == "test"
25
34
  Requires-Dist: types-PyYAML==5.4.3; extra == "test"
35
+ Requires-Dist: pyyaml<6.1.0,>=5.4.0; extra == "test"
36
+ Requires-Dist: pytest-cov==2.12.1; extra == "test"
26
37
  Requires-Dist: pytest-ordering==0.6; extra == "test"
27
- Requires-Dist: pylint==2.12.*; extra == "test"
28
38
  Requires-Dist: sseclient-py<1.9.0,>=1.7.0; extra == "test"
29
39
  Requires-Dist: Werkzeug==2.0.1; extra == "test"
40
+ Requires-Dist: pylint==2.12.*; extra == "test"
30
41
  Requires-Dist: Django==3.2.4; extra == "test"
31
- Requires-Dist: types-requests==2.25.0; extra == "test"
32
- Requires-Dist: pytest-cov==2.12.1; extra == "test"
33
- Requires-Dist: aioresponses==0.7.*; extra == "test"
34
- Requires-Dist: pytest-asyncio==0.21.*; extra == "test"
35
- Requires-Dist: twine==3.4.1; extra == "test"
36
- Requires-Dist: aiohttp<4.0.0,>=3.8.0; extra == "test"
37
- Requires-Dist: requests<3.0.0,>=2.25; extra == "test"
38
- Requires-Dist: flake8==4.0.1; extra == "test"
39
- Requires-Dist: pytest-pythonpath==0.7.3; extra == "test"
40
42
  Requires-Dist: mypy==0.991; extra == "test"
41
- Requires-Dist: pytest-django==4.4.0; extra == "test"
42
- Requires-Dist: freezegun==1.1.0; extra == "test"
43
- Requires-Dist: pyyaml<6.1.0,>=5.4.0; extra == "test"
43
+ Requires-Dist: aiohttp<4.0.0,>=3.8.0; 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)
@@ -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
  )
@@ -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."""
@@ -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
@@ -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,8 +751,17 @@ 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
  )
760
+ consent, blocking_behaviour = self.__get_consent_and_blocking_behaviour(visitor)
761
+ if consent == LegalConsent.NOT_GIVEN and blocking_behaviour == ConsentBlockingBehaviour.COMPLETELY_BLOCKED:
762
+ raise FeatureEnvironmentDisabled(
763
+ "Evaluation for a holdout is blocked because visitor's consent was not provided."
764
+ )
736
765
  is_not_in_holdout = True
737
766
  code_for_hash = self.__get_code_for_hash(visitor, visitor_code, bucketing_cd_index)
738
767
  variation_hash = Hasher.obtain(code_for_hash, holdout.id_)
@@ -746,7 +775,11 @@ class KameleoonClient:
746
775
  KameleoonLogger.debug(
747
776
  "RETURN: KameleoonClient.__is_visitor_not_in_holdout(visitor, visitor_code: %s, track: %s, save: %s, "
748
777
  "bucketing_cd_index: %s) -> (is_not_in_holdout: %s)",
749
- visitor_code, track, save, bucketing_cd_index, is_not_in_holdout
778
+ visitor_code,
779
+ track,
780
+ save,
781
+ bucketing_cd_index,
782
+ is_not_in_holdout,
750
783
  )
751
784
  return is_not_in_holdout
752
785
 
@@ -1163,7 +1196,10 @@ class KameleoonClient:
1163
1196
  def filter_conditions(feature_flag: FeatureFlag) -> bool:
1164
1197
  if not feature_flag.environment_enabled:
1165
1198
  return False
1166
- eval_exp = self.__evaluate(visitor, visitor_code, feature_flag, False, False)
1199
+ try:
1200
+ eval_exp = self.__evaluate(visitor, visitor_code, feature_flag, False, False)
1201
+ except FeatureEnvironmentDisabled:
1202
+ return False
1167
1203
  variation_key = self.__calculate_variation_key(eval_exp, feature_flag.default_variation_key)
1168
1204
  return variation_key != configuration.Variation.Type.OFF.value
1169
1205
 
@@ -1211,7 +1247,10 @@ class KameleoonClient:
1211
1247
  for feature_flag in self._data_manager.data_file.feature_flags.values():
1212
1248
  if not feature_flag.environment_enabled:
1213
1249
  continue
1214
- eval_exp = self.__evaluate(visitor, visitor_code, feature_flag, False, False)
1250
+ try:
1251
+ eval_exp = self.__evaluate(visitor, visitor_code, feature_flag, False, False)
1252
+ except FeatureEnvironmentDisabled:
1253
+ continue
1215
1254
  variation_key = self.__calculate_variation_key(eval_exp, feature_flag.default_variation_key)
1216
1255
  if variation_key == configuration.Variation.Type.OFF.value:
1217
1256
  continue
@@ -1437,7 +1476,7 @@ class KameleoonClient:
1437
1476
  data_file = DataFile.from_json(
1438
1477
  self._config.environment,
1439
1478
  fetched_configuration.last_modified,
1440
- fetched_configuration.configuration
1479
+ fetched_configuration.configuration,
1441
1480
  )
1442
1481
  self._data_manager.data_file = data_file
1443
1482
  self._network_manager.url_provider.apply_data_api_domain(data_file.settings.data_api_domain)
@@ -1547,7 +1586,8 @@ class KameleoonClient:
1547
1586
  fetched_configuration = await service.fetch_configuration(self._config.environment, time_stamp, last_modified)
1548
1587
  KameleoonLogger.debug(
1549
1588
  "RETURN: KameleoonClient._obtain_configuration(time_stamp: %s) -> (fetched_configuration: %s)",
1550
- time_stamp, fetched_configuration
1589
+ time_stamp,
1590
+ fetched_configuration,
1551
1591
  )
1552
1592
  return fetched_configuration
1553
1593
 
@@ -1615,7 +1655,9 @@ class KameleoonClient:
1615
1655
  return None
1616
1656
  KameleoonLogger.debug(
1617
1657
  "CALL: KameleoonClient.__evaluate_cbscores(visitor, visitor_code: %s, rule: %s, bucketing_cd_index: %s)",
1618
- visitor_code, rule, bucketing_cd_index
1658
+ visitor_code,
1659
+ rule,
1660
+ bucketing_cd_index,
1619
1661
  )
1620
1662
  eval_exp = None
1621
1663
  var_id_group_by_scores = visitor.cbscores.values.get(rule.experiment.id_)
@@ -1640,11 +1682,15 @@ class KameleoonClient:
1640
1682
  eval_exp = EvaluatedExperiment.from_var_by_exp_rule(var_by_exp_in_cbs[idx], rule)
1641
1683
  KameleoonLogger.debug(
1642
1684
  "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
1685
+ " -> (eval_exp: %s)",
1686
+ visitor_code,
1687
+ rule,
1688
+ bucketing_cd_index,
1689
+ eval_exp,
1644
1690
  )
1645
1691
  return eval_exp
1646
1692
 
1647
- def __calculate_variation_rule_for_feature(
1693
+ def __calculate_variation_rule_for_feature( # noqa: C901, pylint: disable=R0912
1648
1694
  self, visitor_code: str, feature_flag: FeatureFlag
1649
1695
  ) -> Optional[EvaluatedExperiment]:
1650
1696
  """helper method for calculate variation key for feature flag"""
@@ -1654,6 +1700,7 @@ class KameleoonClient:
1654
1700
  feature_flag,
1655
1701
  )
1656
1702
  visitor = self._visitor_manager.get_visitor(visitor_code)
1703
+ consent, blocking_behaviour = self.__get_consent_and_blocking_behaviour(visitor)
1657
1704
  code_for_hash = self.__get_code_for_hash(visitor, visitor_code, feature_flag.bucketing_custom_data_index)
1658
1705
  eval_exp = None
1659
1706
  for rule in feature_flag.rules:
@@ -1669,11 +1716,19 @@ class KameleoonClient:
1669
1716
  # Forcing experiment variation in targeting-only mode
1670
1717
  eval_exp = EvaluatedExperiment.from_var_by_exp_rule(forced_variation.var_by_exp, rule)
1671
1718
  break
1672
- # uses for rule exposition
1719
+ # used for rule exposition
1673
1720
  hash_rule = Hasher.obtain(code_for_hash, rule.id_, rule.respool_time)
1674
1721
  KameleoonLogger.debug("Calculated rule hash %s for code %s", hash_rule, code_for_hash)
1675
1722
  # check main expostion for rule with hashRule
1676
1723
  if hash_rule <= rule.exposition:
1724
+ # Checking if the evaluation is blocked due to the consent policy
1725
+ if (consent == LegalConsent.NOT_GIVEN) and rule.is_experimentation:
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
@@ -1703,6 +1757,19 @@ class KameleoonClient:
1703
1757
  )
1704
1758
  return eval_exp
1705
1759
 
1760
+ def __get_consent_and_blocking_behaviour(
1761
+ self,
1762
+ visitor: Optional[Visitor],
1763
+ ) -> Tuple[LegalConsent, ConsentBlockingBehaviour]:
1764
+ datafile = self._data_manager.data_file
1765
+ if datafile.settings.is_consent_required:
1766
+ consent = visitor.legal_consent if visitor else LegalConsent.UNKNOWN
1767
+ else:
1768
+ consent = LegalConsent.GIVEN
1769
+ behaviour = datafile.settings.blocking_behaviour_if_consent_not_given
1770
+
1771
+ return consent, behaviour
1772
+
1706
1773
  @staticmethod
1707
1774
  def __calculate_variation_key(eval_exp: Optional[EvaluatedExperiment], default_value: str) -> str:
1708
1775
  KameleoonLogger.debug(
@@ -1727,7 +1794,7 @@ class KameleoonClient:
1727
1794
  return (
1728
1795
  not self._data_manager.data_file.settings.is_consent_required
1729
1796
  or ((visitor := self._visitor_manager.get_visitor(visitor_code)) is not None)
1730
- and visitor.legal_consent
1797
+ and (visitor.legal_consent == LegalConsent.GIVEN)
1731
1798
  )
1732
1799
 
1733
1800
  def set_forced_variation(
@@ -50,15 +50,15 @@ class RemoteVisitorData:
50
50
  self.__visitor_code: Optional[str] = None
51
51
  current_visit = json.get("currentVisit")
52
52
  if current_visit is not None:
53
- self.__parse_visit(current_visit, False)
53
+ self.__parse_visit(current_visit, 0)
54
54
  previous_visits = json.get("previousVisits")
55
55
  if previous_visits:
56
56
  prev_visits = []
57
- for visit in previous_visits:
57
+ for i, visit in enumerate(previous_visits):
58
58
  time_started = visit.get("timeStarted", 0)
59
59
  time_last_event = visit.get("timeLastEvent", time_started)
60
60
  prev_visits.append(VisitorVisits.Visit(time_started, time_last_event))
61
- self.__parse_visit(visit, True)
61
+ self.__parse_visit(visit, i + 1)
62
62
  if len(prev_visits) > 0:
63
63
  self.__visitor_visits = VisitorVisits(prev_visits, self.__visit_number)
64
64
  self.__kcs_heat = self.__parse_kcs_heat(json.get("kcs"))
@@ -123,7 +123,7 @@ class RemoteVisitorData:
123
123
  """Returns the `visitorCode` from the most recent visit"""
124
124
  return self.__visitor_code
125
125
 
126
- def __parse_visit(self, json_visit: Dict[str, Any], is_prev_visit: bool) -> None:
126
+ def __parse_visit(self, json_visit: Dict[str, Any], visit_offset: int) -> None:
127
127
  if (self.__visitor_code is None) and isinstance(visitor_code := json_visit.get("visitorCode"), str):
128
128
  self.__visitor_code = visitor_code
129
129
  custom_data_events = json_visit.get("customDataEvents")
@@ -143,7 +143,7 @@ class RemoteVisitorData:
143
143
  self.__parse_geolocation(geolocation_events[-1])
144
144
  static_data_event = json_visit.get("staticDataEvent")
145
145
  if static_data_event:
146
- self.__parse_static_data(static_data_event, is_prev_visit)
146
+ self.__parse_static_data(static_data_event, visit_offset)
147
147
  personalization_events = json_visit.get("personalizationEvents")
148
148
  if personalization_events:
149
149
  self.__parse_personalizations(personalization_events)
@@ -209,15 +209,13 @@ class RemoteVisitorData:
209
209
  if country is not None:
210
210
  self.__geolocation = Geolocation(country, data.get("region"), data.get("city"))
211
211
 
212
- def __parse_static_data(self, static_data_event: Dict[str, Any], is_prev_visit: bool) -> None:
212
+ def __parse_static_data(self, static_data_event: Dict[str, Any], visit_offset: int) -> None:
213
213
  if self.__device and self.__browser and self.__operating_system:
214
214
  return
215
215
  data = static_data_event.get("data")
216
216
  if data is not None:
217
- if self.__visit_number == 0:
218
- self.__visit_number = data.get("visitNumber", 0)
219
- if is_prev_visit and (self.__visit_number > 0):
220
- self.__visit_number += 1
217
+ if (self.__visit_number == 0) and (remote_visit_number := data.get("visitNumber")):
218
+ self.__visit_number = remote_visit_number + visit_offset
221
219
  if self.__filter.device and (self.__device is None):
222
220
  device_type = enum_from_name_literal(data.get("deviceType"), DeviceType, None)
223
221
  if device_type is not None:
@@ -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:
@@ -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, 3)
7
+ version_info = (3, 17, 1)
8
8
  __version__ = ".".join(str(v) for v in version_info) # uses in scripts
9
9
 
10
10
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kameleoon-client-python
3
- Version: 3.16.3
3
+ Version: 3.17.1
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: wheel==0.36.2; extra == "test"
23
+ Requires-Dist: flake8==4.0.1; extra == "test"
24
+ Requires-Dist: freezegun==1.1.0; extra == "test"
25
+ Requires-Dist: types-requests==2.25.0; extra == "test"
26
+ Requires-Dist: pytest-asyncio==0.21.*; extra == "test"
24
27
  Requires-Dist: types-python-dateutil==2.8.2; extra == "test"
28
+ Requires-Dist: pytest-pythonpath==0.7.3; extra == "test"
29
+ Requires-Dist: aioresponses==0.7.*; 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: twine==3.4.1; extra == "test"
33
+ Requires-Dist: pytest-django==4.4.0; extra == "test"
25
34
  Requires-Dist: types-PyYAML==5.4.3; extra == "test"
35
+ Requires-Dist: pyyaml<6.1.0,>=5.4.0; extra == "test"
36
+ Requires-Dist: pytest-cov==2.12.1; extra == "test"
26
37
  Requires-Dist: pytest-ordering==0.6; extra == "test"
27
- Requires-Dist: pylint==2.12.*; extra == "test"
28
38
  Requires-Dist: sseclient-py<1.9.0,>=1.7.0; extra == "test"
29
39
  Requires-Dist: Werkzeug==2.0.1; extra == "test"
40
+ Requires-Dist: pylint==2.12.*; extra == "test"
30
41
  Requires-Dist: Django==3.2.4; extra == "test"
31
- Requires-Dist: types-requests==2.25.0; extra == "test"
32
- Requires-Dist: pytest-cov==2.12.1; extra == "test"
33
- Requires-Dist: aioresponses==0.7.*; extra == "test"
34
- Requires-Dist: pytest-asyncio==0.21.*; extra == "test"
35
- Requires-Dist: twine==3.4.1; extra == "test"
36
- Requires-Dist: aiohttp<4.0.0,>=3.8.0; extra == "test"
37
- Requires-Dist: requests<3.0.0,>=2.25; extra == "test"
38
- Requires-Dist: flake8==4.0.1; extra == "test"
39
- Requires-Dist: pytest-pythonpath==0.7.3; extra == "test"
40
42
  Requires-Dist: mypy==0.991; extra == "test"
41
- Requires-Dist: pytest-django==4.4.0; extra == "test"
42
- Requires-Dist: freezegun==1.1.0; extra == "test"
43
- Requires-Dist: pyyaml<6.1.0,>=5.4.0; extra == "test"
43
+ Requires-Dist: aiohttp<4.0.0,>=3.8.0; extra == "test"
44
44
  Dynamic: author
45
45
  Dynamic: author-email
46
46
  Dynamic: classifier
@@ -14,6 +14,7 @@ kameleoon/client_readiness/__init__.py
14
14
  kameleoon/client_readiness/async_readiness.py
15
15
  kameleoon/client_readiness/threading_readiness.py
16
16
  kameleoon/configuration/__init__.py
17
+ kameleoon/configuration/consent_blocking_behaviour.py
17
18
  kameleoon/configuration/custom_data_info.py
18
19
  kameleoon/configuration/data_file.py
19
20
  kameleoon/configuration/experiment.py
@@ -48,6 +49,7 @@ kameleoon/data/manager/assigned_variation.py
48
49
  kameleoon/data/manager/forced_experiment_variation.py
49
50
  kameleoon/data/manager/forced_feature_variation.py
50
51
  kameleoon/data/manager/forced_variation.py
52
+ kameleoon/data/manager/legal_consent.py
51
53
  kameleoon/data/manager/page_view_visit.py
52
54
  kameleoon/data/manager/visitor.py
53
55
  kameleoon/data/manager/visitor_manager.py