kameleoon-client-python 3.19.0__tar.gz → 3.20.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 (196) hide show
  1. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/PKG-INFO +17 -17
  2. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/conversion.py +25 -1
  3. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/manager/assigned_variation.py +7 -4
  4. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/manager/page_view_visit.py +3 -3
  5. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/manager/visitor.py +46 -44
  6. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/manager/visitor_manager.py +10 -7
  7. kameleoon_client_python-3.20.0/kameleoon/data/personalization.py +44 -0
  8. kameleoon_client_python-3.20.0/kameleoon/helpers/time.py +24 -0
  9. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/hybrid/hybrid_manager_impl.py +22 -13
  10. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/kameleoon_client.py +1 -1
  11. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/kameleoon_client_config.py +12 -11
  12. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/managers/remote_data/remote_visitor_data.py +13 -6
  13. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/sdk_version.py +1 -1
  14. kameleoon_client_python-3.20.0/kameleoon/targeting/conditions/conversion_condition.py +37 -0
  15. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/exclusive_experiment_condition.py +23 -12
  16. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/target_experiment_condition.py +11 -5
  17. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/target_feature_flag_condition.py +30 -20
  18. kameleoon_client_python-3.20.0/kameleoon/targeting/conditions/target_personalization_condition.py +30 -0
  19. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/time_elapsed_since_visit_condition.py +2 -2
  20. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/visit_number_today_condition.py +2 -3
  21. kameleoon_client_python-3.20.0/kameleoon/targeting/conditions/visitor_scope_condition.py +56 -0
  22. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/targeting_manager.py +31 -9
  23. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon_client_python.egg-info/PKG-INFO +17 -17
  24. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon_client_python.egg-info/SOURCES.txt +2 -0
  25. kameleoon_client_python-3.19.0/kameleoon/data/personalization.py +0 -30
  26. kameleoon_client_python-3.19.0/kameleoon/targeting/conditions/conversion_condition.py +0 -24
  27. kameleoon_client_python-3.19.0/kameleoon/targeting/conditions/target_personalization_condition.py +0 -23
  28. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/MANIFEST.in +0 -0
  29. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/README.md +0 -0
  30. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/__init__.py +0 -0
  31. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/client_readiness/__init__.py +0 -0
  32. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/client_readiness/async_readiness.py +0 -0
  33. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/client_readiness/threading_readiness.py +0 -0
  34. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/configuration/__init__.py +0 -0
  35. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/configuration/consent_blocking_behaviour.py +0 -0
  36. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/configuration/custom_data_info.py +0 -0
  37. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/configuration/data_file.py +0 -0
  38. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/configuration/experiment.py +0 -0
  39. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/configuration/feature_flag.py +0 -0
  40. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/configuration/me_group.py +0 -0
  41. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/configuration/rule.py +0 -0
  42. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/configuration/rule_type.py +0 -0
  43. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/configuration/settings.py +0 -0
  44. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/configuration/variable.py +0 -0
  45. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/configuration/variation.py +0 -0
  46. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/configuration/variation_by_exposition.py +0 -0
  47. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/__init__.py +0 -0
  48. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/application_version.py +0 -0
  49. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/browser.py +0 -0
  50. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/cbscores.py +0 -0
  51. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/cookie.py +0 -0
  52. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/custom_data.py +0 -0
  53. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/data.py +0 -0
  54. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/device.py +0 -0
  55. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/geolocation.py +0 -0
  56. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/kcs_heat.py +0 -0
  57. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/manager/__init__.py +0 -0
  58. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/manager/forced_experiment_variation.py +0 -0
  59. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/manager/forced_feature_variation.py +0 -0
  60. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/manager/forced_variation.py +0 -0
  61. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/manager/legal_consent.py +0 -0
  62. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/manager/visitor_slot.py +0 -0
  63. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/mapping_identifier.py +0 -0
  64. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/operating_system.py +0 -0
  65. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/page_view.py +0 -0
  66. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/targeted_segment.py +0 -0
  67. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/unique_identifier.py +0 -0
  68. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/user_agent.py +0 -0
  69. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/data/visitor_visits.py +0 -0
  70. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/defaults.py +0 -0
  71. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/exceptions.py +0 -0
  72. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/helpers/__init__.py +0 -0
  73. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/helpers/domain.py +0 -0
  74. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/helpers/functions.py +0 -0
  75. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/helpers/hasher.py +0 -0
  76. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/helpers/logger.py +0 -0
  77. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/helpers/multi_threading.py +0 -0
  78. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/helpers/nonce.py +0 -0
  79. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/helpers/repeat_timer.py +0 -0
  80. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/helpers/scheduler.py +0 -0
  81. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/helpers/sem_version.py +0 -0
  82. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/helpers/string_utils.py +0 -0
  83. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/helpers/visitor_code.py +0 -0
  84. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/hybrid/__init__.py +0 -0
  85. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/hybrid/hybrid_manager.py +0 -0
  86. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/kameleoon_client_factory.py +0 -0
  87. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/logging/__init__.py +0 -0
  88. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/logging/kameleoon_logger.py +0 -0
  89. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/logging/log_level.py +0 -0
  90. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/logging/logger.py +0 -0
  91. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/managers/__init__.py +0 -0
  92. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/managers/asyncexec/__init__.py +0 -0
  93. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/managers/asyncexec/async_executor.py +0 -0
  94. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/managers/data/__init__.py +0 -0
  95. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/managers/data/data_manager.py +0 -0
  96. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/managers/evaluation/__init__.py +0 -0
  97. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/managers/evaluation/evaluated_experiment.py +0 -0
  98. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/managers/remote_data/__init__.py +0 -0
  99. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/managers/remote_data/remote_data_manager.py +0 -0
  100. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/managers/tracking/__init__.py +0 -0
  101. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/managers/tracking/tracking_builder.py +0 -0
  102. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/managers/tracking/tracking_manager.py +0 -0
  103. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/managers/tracking/visitor_tracking_registry.py +0 -0
  104. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/managers/warehouse/__init__.py +0 -0
  105. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/managers/warehouse/warehouse_manager.py +0 -0
  106. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/middleware.py +0 -0
  107. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/__init__.py +0 -0
  108. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/access_token_source.py +0 -0
  109. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/access_token_source_factory.py +0 -0
  110. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/activity_event.py +0 -0
  111. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/cookie/__init__.py +0 -0
  112. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/cookie/cookie_manager.py +0 -0
  113. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/net_provider.py +0 -0
  114. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/net_provider_impl.py +0 -0
  115. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/network_manager.py +0 -0
  116. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/network_manager_factory.py +0 -0
  117. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/network_manager_factory_impl.py +0 -0
  118. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/network_manager_impl.py +0 -0
  119. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/query_builder.py +0 -0
  120. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/query_encodable.py +0 -0
  121. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/sendable.py +0 -0
  122. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/service_initialize_context.py +0 -0
  123. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/service_initialize_context_impl.py +0 -0
  124. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/services/__init__.py +0 -0
  125. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/services/automation_service.py +0 -0
  126. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/services/automation_service_impl.py +0 -0
  127. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/services/configuration_service.py +0 -0
  128. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/services/configuration_service_impl.py +0 -0
  129. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/services/data_service.py +0 -0
  130. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/services/data_service_impl.py +0 -0
  131. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/services/service.py +0 -0
  132. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/services/service_impl.py +0 -0
  133. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/uri_helper.py +0 -0
  134. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/network/url_provider.py +0 -0
  135. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/real_time/__init__.py +0 -0
  136. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/real_time/real_time_configuration_service.py +0 -0
  137. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/real_time/real_time_event.py +0 -0
  138. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/storage/__init__.py +0 -0
  139. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/storage/cache.py +0 -0
  140. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/storage/cache_factory.py +0 -0
  141. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/storage/cache_factory_impl.py +0 -0
  142. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/storage/cache_impl.py +0 -0
  143. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/__init__.py +0 -0
  144. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/__init__.py +0 -0
  145. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/browser_condition.py +0 -0
  146. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/constants.py +0 -0
  147. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/cookie_condition.py +0 -0
  148. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/custom_datum.py +0 -0
  149. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/device_condition.py +0 -0
  150. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/geolocation_condition.py +0 -0
  151. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/kcs_heat_range_condition.py +0 -0
  152. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/number_condition.py +0 -0
  153. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/operating_system_condition.py +0 -0
  154. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/page_title_condition.py +0 -0
  155. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/page_url_condition.py +0 -0
  156. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/page_view_number_condition.py +0 -0
  157. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/previous_page_condition.py +0 -0
  158. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/sdk_language_condition.py +0 -0
  159. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/segment_condition.py +0 -0
  160. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/string_value_condition.py +0 -0
  161. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/targeting_condition.py +0 -0
  162. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/unknown_condition.py +0 -0
  163. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/version_condition.py +0 -0
  164. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/visit_number_total_condition.py +0 -0
  165. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/visitor_code_condition.py +0 -0
  166. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/conditions/visitor_new_return_condition.py +0 -0
  167. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/models.py +0 -0
  168. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/tree_builder.py +0 -0
  169. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/targeting/tree_condition_factory.py +0 -0
  170. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/types/__init__.py +0 -0
  171. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/types/data_file.py +0 -0
  172. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/types/feature_flag.py +0 -0
  173. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/types/remote_visitor_data_filter.py +0 -0
  174. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/types/rule.py +0 -0
  175. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/types/variable.py +0 -0
  176. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon/types/variation.py +0 -0
  177. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon_client_python.egg-info/dependency_links.txt +0 -0
  178. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon_client_python.egg-info/requires.txt +16 -16
  179. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/kameleoon_client_python.egg-info/top_level.txt +0 -0
  180. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/setup.cfg +0 -0
  181. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/setup.py +0 -0
  182. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/tests/integration/proj/__init__.py +0 -0
  183. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/tests/integration/proj/kameleoon_app/__init__.py +0 -0
  184. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/tests/integration/proj/kameleoon_app/admin.py +0 -0
  185. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/tests/integration/proj/kameleoon_app/apps.py +0 -0
  186. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/tests/integration/proj/kameleoon_app/migrations/__init__.py +0 -0
  187. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/tests/integration/proj/kameleoon_app/models.py +0 -0
  188. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/tests/integration/proj/kameleoon_app/tests.py +0 -0
  189. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/tests/integration/proj/kameleoon_app/views.py +0 -0
  190. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/tests/integration/proj/manage.py +0 -0
  191. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/tests/integration/proj/proj/__init__.py +0 -0
  192. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/tests/integration/proj/proj/asgi.py +0 -0
  193. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/tests/integration/proj/proj/settings.py +0 -0
  194. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/tests/integration/proj/proj/urls.py +0 -0
  195. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.0}/tests/integration/proj/proj/wsgi.py +0 -0
  196. {kameleoon_client_python-3.19.0 → kameleoon_client_python-3.20.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.19.0
3
+ Version: 3.20.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: twine==3.4.1; extra == "test"
24
+ Requires-Dist: pytest-django==4.4.0; extra == "test"
25
+ Requires-Dist: pytest-pythonpath==0.7.3; extra == "test"
26
+ Requires-Dist: flake8==4.0.1; extra == "test"
23
27
  Requires-Dist: wheel==0.36.2; extra == "test"
24
- Requires-Dist: Werkzeug==2.0.1; extra == "test"
25
- Requires-Dist: aiohttp<4.0.0,>=3.8.0; extra == "test"
26
- Requires-Dist: pylint==2.12.*; extra == "test"
27
- Requires-Dist: types-requests==2.25.0; extra == "test"
28
28
  Requires-Dist: pytest-asyncio==0.21.*; extra == "test"
29
- Requires-Dist: sseclient-py<1.9.0,>=1.7.0; extra == "test"
30
- Requires-Dist: pytest-cov==2.12.1; extra == "test"
31
- Requires-Dist: types-python-dateutil==2.8.2; extra == "test"
32
- Requires-Dist: freezegun==1.1.0; extra == "test"
29
+ Requires-Dist: aioresponses==0.7.*; extra == "test"
30
+ Requires-Dist: requests<3.0.0,>=2.25; extra == "test"
33
31
  Requires-Dist: pyyaml<6.1.0,>=5.4.0; extra == "test"
34
- Requires-Dist: pytest-django==4.4.0; extra == "test"
35
- Requires-Dist: pytest-ordering==0.6; extra == "test"
32
+ Requires-Dist: mypy==0.991; extra == "test"
33
+ Requires-Dist: Werkzeug==2.0.1; extra == "test"
34
+ Requires-Dist: freezegun==1.1.0; extra == "test"
36
35
  Requires-Dist: Django==3.2.4; extra == "test"
36
+ Requires-Dist: types-requests==2.25.0; extra == "test"
37
+ Requires-Dist: pytest-cov==2.12.1; extra == "test"
38
+ Requires-Dist: pylint==2.12.*; extra == "test"
37
39
  Requires-Dist: types-PyYAML==5.4.3; extra == "test"
38
- Requires-Dist: flake8==4.0.1; extra == "test"
39
- Requires-Dist: pytest-pythonpath==0.7.3; extra == "test"
40
- Requires-Dist: mypy==0.991; extra == "test"
41
- Requires-Dist: requests<3.0.0,>=2.25; extra == "test"
42
- Requires-Dist: twine==3.4.1; extra == "test"
43
- Requires-Dist: aioresponses==0.7.*; extra == "test"
40
+ Requires-Dist: pytest-ordering==0.6; extra == "test"
41
+ Requires-Dist: aiohttp<4.0.0,>=3.8.0; extra == "test"
42
+ Requires-Dist: types-python-dateutil==2.8.2; extra == "test"
43
+ Requires-Dist: sseclient-py<1.9.0,>=1.7.0; extra == "test"
44
44
  Dynamic: author
45
45
  Dynamic: author-email
46
46
  Dynamic: classifier
@@ -6,6 +6,7 @@ from typing import Optional, Iterable
6
6
  from kameleoon.data.custom_data import CustomData
7
7
  from kameleoon.data.data import Data, DataType
8
8
  from kameleoon.helpers.string_utils import StringUtils
9
+ from kameleoon.helpers.time import time_ms
9
10
  from kameleoon.network.sendable import DuplicationSafeSendableBase
10
11
  from kameleoon.network.query_builder import QueryBuilder, QueryParam, QueryParams
11
12
 
@@ -45,6 +46,23 @@ class Conversion(Data, DuplicationSafeSendableBase):
45
46
  self.__revenue = revenue
46
47
  self.__negative = negative
47
48
  self._metadata = metadata
49
+ self._assignment_time_ms = time_ms()
50
+
51
+ # pylint: disable=too-many-arguments
52
+ @classmethod
53
+ def _build_internal(
54
+ cls,
55
+ goal_id: int,
56
+ revenue: float = 0.0,
57
+ negative: bool = False,
58
+ metadata: Optional[Iterable[CustomData]] = None,
59
+ assignment_time: Optional[int] = None,
60
+ ) -> "Conversion":
61
+ """Create a conversion with SDK-managed internal state."""
62
+ conversion = cls(goal_id, revenue, negative, metadata)
63
+ if assignment_time:
64
+ conversion._assignment_time_ms = assignment_time
65
+ return conversion
48
66
 
49
67
  @property
50
68
  def goal_id(self) -> int:
@@ -66,6 +84,11 @@ class Conversion(Data, DuplicationSafeSendableBase):
66
84
  """Returns metadata"""
67
85
  return self._metadata
68
86
 
87
+ @property
88
+ def _assignment_time(self) -> float:
89
+ """Returns the internal time when the conversion was added."""
90
+ return self._assignment_time_ms
91
+
69
92
  @property
70
93
  def data_type(self) -> DataType:
71
94
  return DataType.CONVERSION
@@ -97,5 +120,6 @@ class Conversion(Data, DuplicationSafeSendableBase):
97
120
  f"Conversion{{goal_id:{self.__goal_id},"
98
121
  f"revenue:{self.__revenue},"
99
122
  f"negative:{self.__negative},"
100
- f"metadata:{StringUtils.object_to_string(self._metadata)}}}"
123
+ f"metadata:{StringUtils.object_to_string(self._metadata)},"
124
+ f"assignment_time:{self._assignment_time_ms}}}"
101
125
  )
@@ -1,14 +1,17 @@
1
+ # pylint: disable=duplicate-code
1
2
  """Assigned Variation"""
2
- import time
3
+
3
4
  from typing import Optional
4
5
  from kameleoon.configuration.rule_type import RuleType
5
6
  from kameleoon.data.data import BaseData, DataType
7
+ from kameleoon.helpers.time import time_ms
6
8
  from kameleoon.network.sendable import DuplicationUnsafeSendableBase
7
9
  from kameleoon.network.query_builder import QueryBuilder, QueryParam, QueryParams
8
10
 
9
11
 
10
12
  class AssignedVariation(BaseData, DuplicationUnsafeSendableBase):
11
13
  """Assigned variation"""
14
+
12
15
  EVENT_TYPE = "experiment"
13
16
 
14
17
  def __init__(
@@ -22,7 +25,7 @@ class AssignedVariation(BaseData, DuplicationUnsafeSendableBase):
22
25
  self.__experiment_id = experiment_id
23
26
  self.__variation_id = variation_id
24
27
  self.__rule_type = rule_type
25
- self.__assignment_time = assignment_time or time.time()
28
+ self.__assignment_time_ms = assignment_time or time_ms()
26
29
 
27
30
  @property
28
31
  def experiment_id(self) -> int:
@@ -42,7 +45,7 @@ class AssignedVariation(BaseData, DuplicationUnsafeSendableBase):
42
45
  @property
43
46
  def assignment_time(self) -> float:
44
47
  """Returns the time when the assignment occurred."""
45
- return self.__assignment_time
48
+ return self.__assignment_time_ms
46
49
 
47
50
  @property
48
51
  def data_type(self) -> DataType:
@@ -66,6 +69,6 @@ class AssignedVariation(BaseData, DuplicationUnsafeSendableBase):
66
69
  return (
67
70
  f"AssignedVariation{{experiment_id:{self.__experiment_id},"
68
71
  f"variation_id:{self.__variation_id},"
69
- f"assignment_time:{self.__assignment_time},"
72
+ f"assignment_time:{self.__assignment_time_ms},"
70
73
  f"rule_type:{self.__rule_type}}}"
71
74
  )
@@ -1,10 +1,10 @@
1
1
  """Page view visit"""
2
2
 
3
- import time
4
3
  from typing import Optional
5
4
  from kameleoon.data import DataType
6
5
  from kameleoon.data.data import BaseData
7
6
  from kameleoon.data.page_view import PageView
7
+ from kameleoon.helpers.time import time_ms
8
8
 
9
9
 
10
10
  class PageViewVisit(BaseData):
@@ -14,13 +14,13 @@ class PageViewVisit(BaseData):
14
14
  super().__init__()
15
15
  self.page_view = page_view
16
16
  self.count = count
17
- self.last_timestamp = last_timestamp or int(time.time() * 1000)
17
+ self.last_timestamp = last_timestamp or time_ms()
18
18
 
19
19
  def overwrite(self, new_page_view: PageView) -> None:
20
20
  """Overwrites the current PageView with a new PageView and increments the visit count."""
21
21
  self.page_view = new_page_view
22
22
  self.count += 1
23
- self.last_timestamp = int(time.time() * 1000)
23
+ self.last_timestamp = time_ms()
24
24
 
25
25
  def merge(self, page_view_visit) -> None:
26
26
  """Merges the visit data from another PageViewVisit instance into this one."""
@@ -1,5 +1,4 @@
1
1
  """Visitor"""
2
- import time
3
2
 
4
3
  from threading import Lock
5
4
  from typing import Any, Callable, Optional, Dict, List, Iterator, Iterable, cast
@@ -27,6 +26,7 @@ from kameleoon.data.manager.forced_experiment_variation import ForcedExperimentV
27
26
  from kameleoon.data.manager.forced_feature_variation import ForcedFeatureVariation
28
27
  from kameleoon.data.manager.legal_consent import LegalConsent
29
28
  from kameleoon.data.manager.page_view_visit import PageViewVisit
29
+ from kameleoon.helpers.time import time_ms
30
30
  from kameleoon.logging.kameleoon_logger import KameleoonLogger
31
31
  from kameleoon.network.sendable import Sendable
32
32
 
@@ -37,6 +37,7 @@ EMPTY_LIST: List[Any] = []
37
37
 
38
38
  class Visitor: # pylint: disable=R0904
39
39
  """Visitor"""
40
+
40
41
  def __init__(self, source: Optional["Visitor"] = None) -> None:
41
42
  if source is None:
42
43
  self._data = Visitor.VisitorData()
@@ -56,108 +57,109 @@ class Visitor: # pylint: disable=R0904
56
57
 
57
58
  def enumerate_sendable_data(self) -> Iterator[Sendable]:
58
59
  """Enumerates all sendable data associated with this Visitor."""
59
- KameleoonLogger.debug('CALL: Visitor.enumerate_sendable_data()')
60
+ KameleoonLogger.debug("CALL: Visitor.enumerate_sendable_data()")
60
61
  sendable_data = self._data.enumerate_sendable_data()
61
- KameleoonLogger.debug('RETURN: Visitor.enumerate_sendable_data() -> (sendable_data)')
62
+ KameleoonLogger.debug("RETURN: Visitor.enumerate_sendable_data() -> (sendable_data)")
62
63
  return sendable_data
63
64
 
64
65
  def count_sendable_data(self) -> int:
65
66
  """Counts the number of sendable data items associated with this Visitor."""
66
- KameleoonLogger.debug('CALL: Visitor.count_sendable_data()')
67
+ KameleoonLogger.debug("CALL: Visitor.count_sendable_data()")
67
68
  count_sendable_data = self._data.count_sendable_data()
68
- KameleoonLogger.debug('RETURN: Visitor.count_sendable_data() -> (count: %s)', count_sendable_data)
69
+ KameleoonLogger.debug("RETURN: Visitor.count_sendable_data() -> (count: %s)", count_sendable_data)
69
70
  return count_sendable_data
70
71
 
71
72
  @property
72
73
  def user_agent(self) -> Optional[str]:
73
74
  """Returns the user agent string associated with this Visitor."""
74
75
  user_agent = self._data.user_agent
75
- KameleoonLogger.debug('CALL/RETURN: Visitor.user_agent -> (user_agent: %s)', user_agent)
76
+ KameleoonLogger.debug("CALL/RETURN: Visitor.user_agent -> (user_agent: %s)", user_agent)
76
77
  return user_agent
77
78
 
78
79
  @property
79
80
  def device(self) -> Optional[Device]:
80
81
  """Returns the device information associated with this Visitor."""
81
82
  device = self._data.device
82
- KameleoonLogger.debug('CALL/RETURN: Visitor.device -> (device: %s)', device)
83
+ KameleoonLogger.debug("CALL/RETURN: Visitor.device -> (device: %s)", device)
83
84
  return device
84
85
 
85
86
  @property
86
87
  def browser(self) -> Optional[Browser]:
87
88
  """Returns the browser information associated with this Visitor."""
88
89
  browser = self._data.browser
89
- KameleoonLogger.debug('CALL/RETURN: Visitor.browser -> (browser: %s)', browser)
90
+ KameleoonLogger.debug("CALL/RETURN: Visitor.browser -> (browser: %s)", browser)
90
91
  return browser
91
92
 
92
93
  @property
93
94
  def geolocation(self) -> Optional[Geolocation]:
94
95
  """Returns the geolocation information associated with this Visitor."""
95
96
  geolocation = self._data.geolocation
96
- KameleoonLogger.debug('CALL/RETURN: Visitor.geolocation -> (geolocation: %s)', geolocation)
97
+ KameleoonLogger.debug("CALL/RETURN: Visitor.geolocation -> (geolocation: %s)", geolocation)
97
98
  return geolocation
98
99
 
99
100
  @property
100
101
  def operating_system(self) -> Optional[OperatingSystem]:
101
102
  """Returns the operating system information associated with this Visitor."""
102
103
  operating_system = self._data.operating_system
103
- KameleoonLogger.debug('CALL/RETURN: Visitor.operating_system -> (operating_system: %s)', operating_system)
104
+ KameleoonLogger.debug("CALL/RETURN: Visitor.operating_system -> (operating_system: %s)", operating_system)
104
105
  return operating_system
105
106
 
106
107
  @property
107
108
  def application_version(self) -> Optional[ApplicationVersion]:
108
109
  """Returns the application version information associated with this Visitor."""
109
110
  application_version = self._data.application_version
110
- KameleoonLogger.debug('CALL/RETURN: Visitor.application_version -> (application_version: %s)',
111
- application_version)
111
+ KameleoonLogger.debug(
112
+ "CALL/RETURN: Visitor.application_version -> (application_version: %s)", application_version
113
+ )
112
114
  return application_version
113
115
 
114
116
  @property
115
117
  def cookie(self) -> Optional[Cookie]:
116
118
  """Returns the cookie information associated with this Visitor."""
117
119
  cookie = self._data.cookie
118
- KameleoonLogger.debug('CALL/RETURN: Visitor.cookie -> (cookie: %s)', cookie)
120
+ KameleoonLogger.debug("CALL/RETURN: Visitor.cookie -> (cookie: %s)", cookie)
119
121
  return cookie
120
122
 
121
123
  @property
122
124
  def custom_data(self) -> Dict[int, CustomData]:
123
125
  """Returns the custom data associated with this Visitor."""
124
126
  custom_data = EMPTY_DICT if self._data.custom_data_dict is None else self._data.custom_data_dict.copy()
125
- KameleoonLogger.debug('CALL/RETURN: Visitor.custom_data -> (custom_data: %s)', custom_data)
127
+ KameleoonLogger.debug("CALL/RETURN: Visitor.custom_data -> (custom_data: %s)", custom_data)
126
128
  return custom_data
127
129
 
128
130
  @property
129
131
  def page_view_visits(self) -> Dict[str, PageViewVisit]:
130
132
  """Returns the page view visits associated with this Visitor."""
131
133
  page_view_visits = EMPTY_DICT if self._data.page_view_visits is None else self._data.page_view_visits.copy()
132
- KameleoonLogger.debug('CALL/RETURN: Visitor.page_view_visits -> (page_view_visits: %s)', page_view_visits)
134
+ KameleoonLogger.debug("CALL/RETURN: Visitor.page_view_visits -> (page_view_visits: %s)", page_view_visits)
133
135
  return page_view_visits
134
136
 
135
137
  @property
136
138
  def conversions(self) -> List[Conversion]:
137
139
  """Returns the conversions associated with this Visitor."""
138
140
  conversions = EMPTY_LIST if self._data.conversions is None else self._data.conversions.copy()
139
- KameleoonLogger.debug('CALL/RETURN: Visitor.conversions -> (conversions: %s)', conversions)
141
+ KameleoonLogger.debug("CALL/RETURN: Visitor.conversions -> (conversions: %s)", conversions)
140
142
  return conversions
141
143
 
142
144
  @property
143
145
  def variations(self) -> Dict[int, AssignedVariation]:
144
146
  """Returns the variations associated with this Visitor."""
145
147
  variations = EMPTY_DICT if self._data.variations is None else self._data.variations.copy()
146
- KameleoonLogger.debug('CALL/RETURN: Visitor.variations -> (variations: %s)', variations)
148
+ KameleoonLogger.debug("CALL/RETURN: Visitor.variations -> (variations: %s)", variations)
147
149
  return variations
148
150
 
149
151
  @property
150
152
  def personalizations(self) -> Dict[int, Personalization]:
151
153
  """Returns the personalizations associated with this Visitor."""
152
154
  personalizations = EMPTY_DICT if self._data.personalizations is None else self._data.personalizations.copy()
153
- KameleoonLogger.debug('CALL/RETURN: Visitor.personalizations -> (personalizations: %s)', personalizations)
155
+ KameleoonLogger.debug("CALL/RETURN: Visitor.personalizations -> (personalizations: %s)", personalizations)
154
156
  return personalizations
155
157
 
156
158
  @property
157
159
  def targeted_segments(self) -> Dict[int, TargetedSegment]:
158
160
  """Returns the personalizations associated with this Visitor."""
159
161
  targeted_segments = EMPTY_DICT if self._data.targeted_segments is None else self._data.targeted_segments.copy()
160
- KameleoonLogger.debug('CALL/RETURN: Visitor.targeted_segments -> (targeted_segments: %s)', targeted_segments)
162
+ KameleoonLogger.debug("CALL/RETURN: Visitor.targeted_segments -> (targeted_segments: %s)", targeted_segments)
161
163
  return targeted_segments
162
164
 
163
165
  def get_forced_feature_variation(self, feature_key: str) -> Optional[ForcedFeatureVariation]:
@@ -165,10 +167,10 @@ class Visitor: # pylint: disable=R0904
165
167
  Returns an associated forced feature variation by its feature key if it is present.
166
168
  Otherwise returns `None`.
167
169
  """
168
- KameleoonLogger.debug('CALL: Visitor.get_forced_feature_variation(feature_key: %s)', feature_key)
170
+ KameleoonLogger.debug("CALL: Visitor.get_forced_feature_variation(feature_key: %s)", feature_key)
169
171
  ffv = self._data.simulated_variations.get(feature_key) if self._data.simulated_variations else None
170
172
  KameleoonLogger.debug(
171
- 'RETURN: Visitor.get_forced_feature_variation(feature_key: %s) -> (variation: %s)', feature_key, ffv
173
+ "RETURN: Visitor.get_forced_feature_variation(feature_key: %s) -> (variation: %s)", feature_key, ffv
172
174
  )
173
175
  return ffv
174
176
 
@@ -177,64 +179,64 @@ class Visitor: # pylint: disable=R0904
177
179
  Returns an associated forced experiment variation by its experiment id if it is present.
178
180
  Otherwise returns `None`.
179
181
  """
180
- KameleoonLogger.debug('CALL: Visitor.get_forced_experiment_variation(experiment_id: %s)', experiment_id)
182
+ KameleoonLogger.debug("CALL: Visitor.get_forced_experiment_variation(experiment_id: %s)", experiment_id)
181
183
  fev = self._data.forced_variations.get(experiment_id) if self._data.forced_variations else None
182
184
  KameleoonLogger.debug(
183
- 'RETURN: Visitor.get_forced_experiment_variation(experiment_id: %s) -> (variation: %s)', experiment_id, fev
185
+ "RETURN: Visitor.get_forced_experiment_variation(experiment_id: %s) -> (variation: %s)", experiment_id, fev
184
186
  )
185
187
  return fev
186
188
 
187
189
  def reset_forced_experiment_variation(self, experiment_id: int) -> None:
188
190
  """Resets an associated forced experiment variation for some experiment id"""
189
- KameleoonLogger.debug('CALL: Visitor.reset_forced_experiment_variation(experiment_id: %s)', experiment_id)
191
+ KameleoonLogger.debug("CALL: Visitor.reset_forced_experiment_variation(experiment_id: %s)", experiment_id)
190
192
  if self._data.forced_variations:
191
193
  self._data.forced_variations.pop(experiment_id, None)
192
- KameleoonLogger.debug('RETURN: Visitor.reset_forced_experiment_variation(experiment_id: %s)', experiment_id)
194
+ KameleoonLogger.debug("RETURN: Visitor.reset_forced_experiment_variation(experiment_id: %s)", experiment_id)
193
195
 
194
196
  def update_simulated_variations(self, variations: Iterable[ForcedFeatureVariation]) -> None:
195
197
  """Updates the associated simulated variations"""
196
198
  if not (self._data.simulated_variations or variations):
197
199
  return
198
- KameleoonLogger.debug('CALL: Visitor.update_simulated_variations(variations: %s)', variations)
200
+ KameleoonLogger.debug("CALL: Visitor.update_simulated_variations(variations: %s)", variations)
199
201
  self._data.simulated_variations = {sv.feature_key: sv for sv in variations}
200
- KameleoonLogger.debug('RETURN: Visitor.update_simulated_variations(variations: %s)', variations)
202
+ KameleoonLogger.debug("RETURN: Visitor.update_simulated_variations(variations: %s)", variations)
201
203
 
202
204
  @property
203
205
  def kcs_heat(self) -> Optional[KcsHeat]:
204
206
  """Returns the KCS heat data associated with this Visitor."""
205
207
  kcs_heat = self._data.kcs_heat
206
- KameleoonLogger.debug('CALL/RETURN: Visitor.kcs_heat -> (kcs_heat: %s)', kcs_heat)
208
+ KameleoonLogger.debug("CALL/RETURN: Visitor.kcs_heat -> (kcs_heat: %s)", kcs_heat)
207
209
  return kcs_heat
208
210
 
209
211
  @property
210
212
  def cbscores(self) -> Optional[CBScores]:
211
213
  """Returns the CBS data associated with this Visitor."""
212
214
  cbs = self._data.cbscores
213
- KameleoonLogger.debug('CALL/RETURN: Visitor.cbscores -> (cbs: %s)', cbs)
215
+ KameleoonLogger.debug("CALL/RETURN: Visitor.cbscores -> (cbs: %s)", cbs)
214
216
  return cbs
215
217
 
216
218
  @property
217
219
  def visitor_visits(self) -> Optional[VisitorVisits]:
218
220
  """Returns the visitor visits data associated with this Visitor."""
219
221
  visitor_visits = self._data.visitor_visits
220
- KameleoonLogger.debug('CALL/RETURN: Visitor.visitor_visits -> (visitor_visits: %s)', visitor_visits)
222
+ KameleoonLogger.debug("CALL/RETURN: Visitor.visitor_visits -> (visitor_visits: %s)", visitor_visits)
221
223
  return visitor_visits
222
224
 
223
225
  def assign_variation(self, variation: AssignedVariation) -> None:
224
226
  """Assigns a variation to the Visitor."""
225
- KameleoonLogger.debug('CALL: Visitor.assign_variation(variation: %s)', variation)
227
+ KameleoonLogger.debug("CALL: Visitor.assign_variation(variation: %s)", variation)
226
228
  if self._data.variations is None:
227
229
  with self._data.lock:
228
230
  if self._data.variations is None:
229
231
  self._data.variations = {variation.experiment_id: variation}
230
- KameleoonLogger.debug('RETURN: Visitor.assign_variation(variation: %s)', variation)
232
+ KameleoonLogger.debug("RETURN: Visitor.assign_variation(variation: %s)", variation)
231
233
  return
232
234
  self._data.variations[variation.experiment_id] = variation
233
- KameleoonLogger.debug('RETURN: Visitor.assign_variation(variation: %s)', variation)
235
+ KameleoonLogger.debug("RETURN: Visitor.assign_variation(variation: %s)", variation)
234
236
 
235
237
  def add_data(self, *args, overwrite: bool = True, track: bool = True) -> None:
236
238
  """Adds data to the Visitor."""
237
- KameleoonLogger.debug('CALL: Visitor.add_data(args: %s, overwrite: %s, track: %s)', args, overwrite, track)
239
+ KameleoonLogger.debug("CALL: Visitor.add_data(args: %s, overwrite: %s, track: %s)", args, overwrite, track)
238
240
  with self._data.lock:
239
241
  for data in args:
240
242
  if data is None:
@@ -247,14 +249,13 @@ class Visitor: # pylint: disable=R0904
247
249
  data_adder(self, self.DataAddingContext(data, overwrite))
248
250
  else:
249
251
  KameleoonLogger.warning("Data has unsupported type %s", data_type)
250
- KameleoonLogger.debug('RETURN: Visitor.add_data(args: %s, overwrite: %s, track: %s)', args, overwrite, track)
252
+ KameleoonLogger.debug("RETURN: Visitor.add_data(args: %s, overwrite: %s, track: %s)", args, overwrite, track)
251
253
 
252
254
  @property
253
255
  def mapping_identifier(self) -> Optional[str]:
254
256
  """Returns the mapping identifier associated with this Visitor."""
255
257
  mapping_identifier = self._data.mapping_identifier
256
- KameleoonLogger.debug('CALL/RETURN: Visitor.mapping_identifier -> (mapping_identifier: %s)',
257
- mapping_identifier)
258
+ KameleoonLogger.debug("CALL/RETURN: Visitor.mapping_identifier -> (mapping_identifier: %s)", mapping_identifier)
258
259
  return mapping_identifier
259
260
 
260
261
  @mapping_identifier.setter
@@ -272,7 +273,7 @@ class Visitor: # pylint: disable=R0904
272
273
  def legal_consent(self) -> LegalConsent:
273
274
  """Returns the legal consent status for this Visitor."""
274
275
  legal_consent = self._data.legal_consent
275
- KameleoonLogger.debug('CALL/RETURN: Visitor.legal_consent -> (legal_consent: %s)', legal_consent)
276
+ KameleoonLogger.debug("CALL/RETURN: Visitor.legal_consent -> (legal_consent: %s)", legal_consent)
276
277
  return legal_consent
277
278
 
278
279
  @legal_consent.setter
@@ -285,14 +286,16 @@ class Visitor: # pylint: disable=R0904
285
286
  def is_unique_identifier(self) -> bool:
286
287
  """Returns the unique identifier status for this Visitor."""
287
288
  is_unique_identifier = self._is_unique_identifier
288
- KameleoonLogger.debug('CALL/RETURN: Visitor.is_unique_identifier -> (is_unique_identifier: %s)',
289
- is_unique_identifier)
289
+ KameleoonLogger.debug(
290
+ "CALL/RETURN: Visitor.is_unique_identifier -> (is_unique_identifier: %s)", is_unique_identifier
291
+ )
290
292
  return is_unique_identifier
291
293
 
292
294
  class VisitorData:
293
295
  """Visitor Data"""
296
+
294
297
  def __init__(self) -> None:
295
- self.time_started = int(time.time() * 1000)
298
+ self.time_started = time_ms()
296
299
  self.lock = Lock()
297
300
  self.user_agent: Optional[str] = None
298
301
  self.device: Optional[Device] = None
@@ -365,9 +368,8 @@ class Visitor: # pylint: disable=R0904
365
368
 
366
369
  class DataAddingContext:
367
370
  """Data adding context"""
368
- def __init__(
369
- self, data: Data, overwrite: bool = True
370
- ) -> None:
371
+
372
+ def __init__(self, data: Data, overwrite: bool = True) -> None:
371
373
  self._data = data
372
374
  self._overwrite = overwrite
373
375
 
@@ -17,14 +17,16 @@ from kameleoon.managers.data.data_manager import DataManager
17
17
  class VisitorManager:
18
18
  """Visitor manager"""
19
19
 
20
- def __init__(self, data_manager: DataManager, expiration_period: float, scheduler: Scheduler) -> None:
21
- KameleoonLogger.debug("CALL: VisitorManager(data_manager, expiration_period: %s, scheduler)", expiration_period)
20
+ def __init__(self, data_manager: DataManager, expiration_period_sec: float, scheduler: Scheduler) -> None:
21
+ KameleoonLogger.debug(
22
+ "CALL: VisitorManager(data_manager, expiration_period: %s, scheduler)", expiration_period_sec
23
+ )
22
24
  self._data_manager = data_manager
23
- self.__expiration_period = expiration_period
25
+ self.__expiration_period_sec = expiration_period_sec
24
26
  self._slots: Dict[str, VisitorSlot] = collections.defaultdict(VisitorSlot)
25
- scheduler.schedule_job("VisitorManager.purge", expiration_period, self.__purge)
27
+ scheduler.schedule_job("VisitorManager.purge", expiration_period_sec, self.__purge)
26
28
  KameleoonLogger.debug(
27
- "RETURN: VisitorManager(data_manager, expiration_period: %s, scheduler)", expiration_period
29
+ "RETURN: VisitorManager(data_manager, expiration_period: %s, scheduler)", expiration_period_sec
28
30
  )
29
31
 
30
32
  def __iter__(self) -> Iterator[str]:
@@ -75,7 +77,8 @@ class VisitorManager:
75
77
  finally:
76
78
  slot.lock.release()
77
79
  KameleoonLogger.debug(
78
- f"RETURN: VisitorManager.peekVisitor(visitor_code: {visitor_code}) -> "f"(visitor: {visitor})")
80
+ f"RETURN: VisitorManager.peekVisitor(visitor_code: {visitor_code}) -> " f"(visitor: {visitor})"
81
+ )
79
82
  return visitor
80
83
 
81
84
  def add_data(self, visitor_code: str, *args, track: bool = True) -> Visitor:
@@ -163,7 +166,7 @@ class VisitorManager:
163
166
 
164
167
  def __purge(self) -> None:
165
168
  KameleoonLogger.debug("CALL: VisitorManager.__purge()")
166
- expired_time = time.time() - self.__expiration_period
169
+ expired_time = time.time() - self.__expiration_period_sec
167
170
  for visitor_code in list(self._slots):
168
171
  if slot := self.__try_acquire_slot_once(visitor_code):
169
172
  try:
@@ -0,0 +1,44 @@
1
+ # pylint: disable=duplicate-code
2
+ """Personalization"""
3
+
4
+ from typing import Optional
5
+
6
+ from kameleoon.data import DataType
7
+ from kameleoon.data.data import BaseData
8
+ from kameleoon.helpers.time import time_ms
9
+
10
+
11
+ class Personalization(BaseData):
12
+ """Personalization"""
13
+
14
+ def __init__(self, id_: int, variation_id: int, assignment_time: Optional[int] = None) -> None:
15
+ super().__init__()
16
+ self.__id = id_
17
+ self.__variation_id = variation_id
18
+ self.__assignment_time_ms = assignment_time or time_ms()
19
+
20
+ @property
21
+ def id(self) -> int:
22
+ """Returns personalization ID"""
23
+ return self.__id
24
+
25
+ @property
26
+ def variation_id(self) -> int:
27
+ """Returns variation ID"""
28
+ return self.__variation_id
29
+
30
+ @property
31
+ def data_type(self) -> DataType:
32
+ return DataType.PERSONALIZATION
33
+
34
+ @property
35
+ def assignment_time(self) -> float:
36
+ """Returns the time when the personalization was assigned."""
37
+ return self.__assignment_time_ms
38
+
39
+ def __str__(self):
40
+ return (
41
+ f"Personalization{{id:{self.__id},"
42
+ f"variation_id:{self.__variation_id},"
43
+ f"assignment_time:{self.__assignment_time_ms}}}"
44
+ )
@@ -0,0 +1,24 @@
1
+ """Time conversion helpers."""
2
+
3
+ from __future__ import annotations
4
+ import time
5
+
6
+
7
+ def ns_to_ms(ns: int) -> int:
8
+ """Convert nanoseconds to milliseconds."""
9
+ return ns // 1_000_000
10
+
11
+
12
+ def time_ms() -> int:
13
+ """Return current time in milliseconds."""
14
+ return time.time_ns() // 1_000_000
15
+
16
+
17
+ def m_to_s(m: int) -> int:
18
+ """Convert minutes to seconds."""
19
+ return m * 60
20
+
21
+
22
+ def s_to_ms(s: int | float) -> int:
23
+ """Convert seconds to milliseconds."""
24
+ return int(s * 1000)
@@ -1,8 +1,10 @@
1
+ # pylint: disable=duplicate-code
1
2
  """Hybrid"""
2
- import time
3
+
3
4
  from typing import Dict, Optional
4
5
  from kameleoon.data.manager.assigned_variation import AssignedVariation
5
6
  from kameleoon.helpers.string_utils import StringUtils
7
+ from kameleoon.helpers.time import time_ms
6
8
  from kameleoon.hybrid.hybrid_manager import HybridManager
7
9
  from kameleoon.logging.kameleoon_logger import KameleoonLogger
8
10
  from kameleoon.managers.data.data_manager import DataManager
@@ -10,34 +12,41 @@ from kameleoon.managers.data.data_manager import DataManager
10
12
 
11
13
  class HybridManagerImpl(HybridManager):
12
14
  """Implementation of HybridManager that generates tracking code for engine integration."""
15
+
13
16
  TC_INIT = "window.kameleoonQueue=window.kameleoonQueue||[];"
14
17
  TC_ASSIGN_VARIATION_F = "window.kameleoonQueue.push(['Experiments.assignVariation',{0},{1},true]);"
15
18
  TC_TRIGGER_F = "window.kameleoonQueue.push(['Experiments.trigger',{0},{2}]);"
16
19
  TC_ASSIGN_VARIATION_TRIGGER_F = TC_ASSIGN_VARIATION_F + TC_TRIGGER_F
17
20
 
18
- def __init__(self, expiration_period: float, data_manager: DataManager) -> None:
19
- KameleoonLogger.debug("CALL: HybridManagerImpl(expiration_period: %s)", expiration_period)
21
+ def __init__(self, expiration_period_ms: int, data_manager: DataManager) -> None:
22
+ KameleoonLogger.debug("CALL: HybridManagerImpl(expiration_period: %s)", expiration_period_ms)
20
23
  super().__init__()
21
- self._expiration_period = expiration_period
24
+ self._expiration_period_ms = expiration_period_ms
22
25
  self._data_manager = data_manager
23
- KameleoonLogger.debug("RETURN: HybridManagerImpl(expiration_period: %s)", expiration_period)
26
+ KameleoonLogger.debug("RETURN: HybridManagerImpl(expiration_period: %s)", expiration_period_ms)
24
27
 
25
28
  def get_engine_tracking_code(self, visitor_variations: Optional[Dict[int, AssignedVariation]]) -> str:
26
- KameleoonLogger.debug("CALL: HybridManagerImpl.get_engine_tracking_code(visitor_variations: %s)",
27
- visitor_variations)
29
+ KameleoonLogger.debug(
30
+ "CALL: HybridManagerImpl.get_engine_tracking_code(visitor_variations: %s)", visitor_variations
31
+ )
28
32
  lines = [self.TC_INIT]
29
33
  if visitor_variations:
30
- expiration_time = time.time() - self._expiration_period
34
+ expiration_time = time_ms() - self._expiration_period_ms
31
35
  for variation in visitor_variations.values():
32
36
  if variation.assignment_time > expiration_time:
33
- tracking_only = not (self._data_manager.data_file.
34
- has_experiment_js_css_variable(variation.experiment_id))
37
+ tracking_only = not (
38
+ self._data_manager.data_file.has_experiment_js_css_variable(variation.experiment_id)
39
+ )
35
40
  line = self.TC_ASSIGN_VARIATION_TRIGGER_F.format(
36
- variation.experiment_id, variation.variation_id,
37
- StringUtils.bool_to_string_lower_case(tracking_only))
41
+ variation.experiment_id,
42
+ variation.variation_id,
43
+ StringUtils.bool_to_string_lower_case(tracking_only),
44
+ )
38
45
  lines.append(line)
39
46
  tracking_code = "".join(lines)
40
47
  KameleoonLogger.debug(
41
48
  "RETURN: HybridManagerImpl.get_engine_tracking_code(visitor_variations: %s) -> (tracking_code: %s)",
42
- visitor_variations, tracking_code)
49
+ visitor_variations,
50
+ tracking_code,
51
+ )
43
52
  return tracking_code