kameleoon-client-python 3.18.0__tar.gz → 3.19.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 (192) hide show
  1. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/PKG-INFO +16 -16
  2. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/configuration/data_file.py +42 -15
  3. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/configuration/variation.py +2 -0
  4. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/manager/visitor_manager.py +16 -1
  5. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/kameleoon_client.py +31 -43
  6. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/managers/data/data_manager.py +7 -0
  7. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/managers/tracking/tracking_builder.py +1 -1
  8. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/access_token_source.py +9 -1
  9. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/net_provider.py +8 -2
  10. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/services/automation_service.py +1 -1
  11. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/services/automation_service_impl.py +7 -8
  12. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/url_provider.py +10 -6
  13. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/sdk_version.py +1 -1
  14. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/unknown_condition.py +3 -0
  15. kameleoon_client_python-3.19.0/kameleoon/types/data_file.py +38 -0
  16. kameleoon_client_python-3.19.0/kameleoon/types/feature_flag.py +69 -0
  17. kameleoon_client_python-3.19.0/kameleoon/types/rule.py +40 -0
  18. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/types/variable.py +7 -3
  19. kameleoon_client_python-3.19.0/kameleoon/types/variation.py +89 -0
  20. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon_client_python.egg-info/PKG-INFO +16 -16
  21. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon_client_python.egg-info/SOURCES.txt +3 -0
  22. kameleoon_client_python-3.18.0/kameleoon/types/variation.py +0 -46
  23. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/MANIFEST.in +0 -0
  24. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/README.md +0 -0
  25. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/__init__.py +0 -0
  26. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/client_readiness/__init__.py +0 -0
  27. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/client_readiness/async_readiness.py +0 -0
  28. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/client_readiness/threading_readiness.py +0 -0
  29. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/configuration/__init__.py +0 -0
  30. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/configuration/consent_blocking_behaviour.py +0 -0
  31. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/configuration/custom_data_info.py +0 -0
  32. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/configuration/experiment.py +0 -0
  33. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/configuration/feature_flag.py +0 -0
  34. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/configuration/me_group.py +0 -0
  35. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/configuration/rule.py +0 -0
  36. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/configuration/rule_type.py +0 -0
  37. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/configuration/settings.py +0 -0
  38. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/configuration/variable.py +0 -0
  39. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/configuration/variation_by_exposition.py +0 -0
  40. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/__init__.py +0 -0
  41. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/application_version.py +0 -0
  42. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/browser.py +0 -0
  43. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/cbscores.py +0 -0
  44. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/conversion.py +0 -0
  45. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/cookie.py +0 -0
  46. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/custom_data.py +0 -0
  47. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/data.py +0 -0
  48. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/device.py +0 -0
  49. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/geolocation.py +0 -0
  50. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/kcs_heat.py +0 -0
  51. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/manager/__init__.py +0 -0
  52. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/manager/assigned_variation.py +0 -0
  53. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/manager/forced_experiment_variation.py +0 -0
  54. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/manager/forced_feature_variation.py +0 -0
  55. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/manager/forced_variation.py +0 -0
  56. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/manager/legal_consent.py +0 -0
  57. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/manager/page_view_visit.py +0 -0
  58. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/manager/visitor.py +0 -0
  59. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/manager/visitor_slot.py +0 -0
  60. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/mapping_identifier.py +0 -0
  61. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/operating_system.py +0 -0
  62. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/page_view.py +0 -0
  63. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/personalization.py +0 -0
  64. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/targeted_segment.py +0 -0
  65. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/unique_identifier.py +0 -0
  66. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/user_agent.py +0 -0
  67. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/data/visitor_visits.py +0 -0
  68. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/defaults.py +0 -0
  69. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/exceptions.py +0 -0
  70. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/helpers/__init__.py +0 -0
  71. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/helpers/domain.py +0 -0
  72. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/helpers/functions.py +0 -0
  73. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/helpers/hasher.py +0 -0
  74. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/helpers/logger.py +0 -0
  75. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/helpers/multi_threading.py +0 -0
  76. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/helpers/nonce.py +0 -0
  77. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/helpers/repeat_timer.py +0 -0
  78. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/helpers/scheduler.py +0 -0
  79. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/helpers/sem_version.py +0 -0
  80. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/helpers/string_utils.py +0 -0
  81. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/helpers/visitor_code.py +0 -0
  82. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/hybrid/__init__.py +0 -0
  83. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/hybrid/hybrid_manager.py +0 -0
  84. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/hybrid/hybrid_manager_impl.py +0 -0
  85. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/kameleoon_client_config.py +0 -0
  86. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/kameleoon_client_factory.py +0 -0
  87. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/logging/__init__.py +0 -0
  88. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/logging/kameleoon_logger.py +0 -0
  89. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/logging/log_level.py +0 -0
  90. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/logging/logger.py +0 -0
  91. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/managers/__init__.py +0 -0
  92. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/managers/asyncexec/__init__.py +0 -0
  93. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/managers/asyncexec/async_executor.py +0 -0
  94. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/managers/data/__init__.py +0 -0
  95. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/managers/evaluation/__init__.py +0 -0
  96. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/managers/evaluation/evaluated_experiment.py +0 -0
  97. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/managers/remote_data/__init__.py +0 -0
  98. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/managers/remote_data/remote_data_manager.py +0 -0
  99. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/managers/remote_data/remote_visitor_data.py +0 -0
  100. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/managers/tracking/__init__.py +0 -0
  101. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/managers/tracking/tracking_manager.py +0 -0
  102. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/managers/tracking/visitor_tracking_registry.py +0 -0
  103. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/managers/warehouse/__init__.py +0 -0
  104. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/managers/warehouse/warehouse_manager.py +0 -0
  105. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/middleware.py +0 -0
  106. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/__init__.py +0 -0
  107. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/access_token_source_factory.py +0 -0
  108. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/activity_event.py +0 -0
  109. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/cookie/__init__.py +0 -0
  110. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/cookie/cookie_manager.py +0 -0
  111. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/net_provider_impl.py +0 -0
  112. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/network_manager.py +0 -0
  113. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/network_manager_factory.py +0 -0
  114. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/network_manager_factory_impl.py +0 -0
  115. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/network_manager_impl.py +0 -0
  116. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/query_builder.py +0 -0
  117. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/query_encodable.py +0 -0
  118. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/sendable.py +0 -0
  119. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/service_initialize_context.py +0 -0
  120. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/service_initialize_context_impl.py +0 -0
  121. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/services/__init__.py +0 -0
  122. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/services/configuration_service.py +0 -0
  123. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/services/configuration_service_impl.py +0 -0
  124. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/services/data_service.py +0 -0
  125. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/services/data_service_impl.py +0 -0
  126. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/services/service.py +0 -0
  127. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/services/service_impl.py +0 -0
  128. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/network/uri_helper.py +0 -0
  129. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/real_time/__init__.py +0 -0
  130. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/real_time/real_time_configuration_service.py +0 -0
  131. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/real_time/real_time_event.py +0 -0
  132. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/storage/__init__.py +0 -0
  133. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/storage/cache.py +0 -0
  134. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/storage/cache_factory.py +0 -0
  135. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/storage/cache_factory_impl.py +0 -0
  136. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/storage/cache_impl.py +0 -0
  137. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/__init__.py +0 -0
  138. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/__init__.py +0 -0
  139. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/browser_condition.py +0 -0
  140. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/constants.py +0 -0
  141. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/conversion_condition.py +0 -0
  142. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/cookie_condition.py +0 -0
  143. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/custom_datum.py +0 -0
  144. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/device_condition.py +0 -0
  145. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/exclusive_experiment_condition.py +0 -0
  146. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/geolocation_condition.py +0 -0
  147. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/kcs_heat_range_condition.py +0 -0
  148. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/number_condition.py +0 -0
  149. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/operating_system_condition.py +0 -0
  150. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/page_title_condition.py +0 -0
  151. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/page_url_condition.py +0 -0
  152. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/page_view_number_condition.py +0 -0
  153. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/previous_page_condition.py +0 -0
  154. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/sdk_language_condition.py +0 -0
  155. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/segment_condition.py +0 -0
  156. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/string_value_condition.py +0 -0
  157. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/target_experiment_condition.py +0 -0
  158. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/target_feature_flag_condition.py +0 -0
  159. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/target_personalization_condition.py +0 -0
  160. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/targeting_condition.py +0 -0
  161. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/time_elapsed_since_visit_condition.py +0 -0
  162. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/version_condition.py +0 -0
  163. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/visit_number_today_condition.py +0 -0
  164. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/visit_number_total_condition.py +0 -0
  165. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/visitor_code_condition.py +0 -0
  166. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/conditions/visitor_new_return_condition.py +0 -0
  167. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/models.py +0 -0
  168. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/targeting_manager.py +0 -0
  169. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/tree_builder.py +0 -0
  170. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/targeting/tree_condition_factory.py +0 -0
  171. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/types/__init__.py +0 -0
  172. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon/types/remote_visitor_data_filter.py +0 -0
  173. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon_client_python.egg-info/dependency_links.txt +0 -0
  174. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon_client_python.egg-info/requires.txt +15 -15
  175. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/kameleoon_client_python.egg-info/top_level.txt +0 -0
  176. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/setup.cfg +0 -0
  177. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/setup.py +0 -0
  178. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/tests/integration/proj/__init__.py +0 -0
  179. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/tests/integration/proj/kameleoon_app/__init__.py +0 -0
  180. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/tests/integration/proj/kameleoon_app/admin.py +0 -0
  181. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/tests/integration/proj/kameleoon_app/apps.py +0 -0
  182. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/tests/integration/proj/kameleoon_app/migrations/__init__.py +0 -0
  183. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/tests/integration/proj/kameleoon_app/models.py +0 -0
  184. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/tests/integration/proj/kameleoon_app/tests.py +0 -0
  185. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/tests/integration/proj/kameleoon_app/views.py +0 -0
  186. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/tests/integration/proj/manage.py +0 -0
  187. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/tests/integration/proj/proj/__init__.py +0 -0
  188. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/tests/integration/proj/proj/asgi.py +0 -0
  189. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/tests/integration/proj/proj/settings.py +0 -0
  190. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/tests/integration/proj/proj/urls.py +0 -0
  191. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.0}/tests/integration/proj/proj/wsgi.py +0 -0
  192. {kameleoon_client_python-3.18.0 → kameleoon_client_python-3.19.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.18.0
3
+ Version: 3.19.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: mypy==0.991; extra == "test"
24
- Requires-Dist: flake8==4.0.1; extra == "test"
25
- Requires-Dist: types-requests==2.25.0; extra == "test"
26
- Requires-Dist: pytest-pythonpath==0.7.3; extra == "test"
27
- Requires-Dist: aioresponses==0.7.*; extra == "test"
28
- Requires-Dist: twine==3.4.1; extra == "test"
29
- Requires-Dist: pytest-django==4.4.0; extra == "test"
30
- Requires-Dist: Django==3.2.4; extra == "test"
31
- Requires-Dist: pytest-cov==2.12.1; extra == "test"
32
- Requires-Dist: types-python-dateutil==2.8.2; extra == "test"
33
- Requires-Dist: pylint==2.12.*; extra == "test"
34
- Requires-Dist: aiohttp<4.0.0,>=3.8.0; extra == "test"
23
+ Requires-Dist: wheel==0.36.2; extra == "test"
35
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"
36
28
  Requires-Dist: pytest-asyncio==0.21.*; extra == "test"
37
29
  Requires-Dist: sseclient-py<1.9.0,>=1.7.0; extra == "test"
38
- Requires-Dist: wheel==0.36.2; extra == "test"
39
- Requires-Dist: types-PyYAML==5.4.3; 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"
40
33
  Requires-Dist: pyyaml<6.1.0,>=5.4.0; extra == "test"
34
+ Requires-Dist: pytest-django==4.4.0; extra == "test"
41
35
  Requires-Dist: pytest-ordering==0.6; extra == "test"
42
- Requires-Dist: freezegun==1.1.0; extra == "test"
36
+ Requires-Dist: Django==3.2.4; extra == "test"
37
+ 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"
43
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"
44
44
  Dynamic: author
45
45
  Dynamic: author-email
46
46
  Dynamic: classifier
@@ -1,6 +1,7 @@
1
1
  """Kameleoon Configuration"""
2
2
 
3
3
  from typing import Any, Dict, Iterable, List, Optional, Set
4
+
4
5
  from kameleoon.configuration import Variable
5
6
  from kameleoon.configuration.custom_data_info import CustomDataInfo
6
7
  from kameleoon.configuration.experiment import Experiment
@@ -20,7 +21,7 @@ class DataFile:
20
21
  @staticmethod
21
22
  def default(environment: Optional[str]) -> "DataFile":
22
23
  """Creates new instance of `DataFile` initialized with default values"""
23
- data_file = DataFile(environment, None, Settings(), {}, {}, CustomDataInfo(None))
24
+ data_file = DataFile(environment, None, Settings(), {}, {}, CustomDataInfo(None), None, 0)
24
25
  return data_file
25
26
 
26
27
  @staticmethod
@@ -33,23 +34,29 @@ class DataFile:
33
34
  custom_data_info = CustomDataInfo(configuration.get("customData"))
34
35
  feature_flags = DataFile.__parse_feature_flags(configuration, segments, custom_data_info)
35
36
  holdout = Experiment.from_json(configuration["holdout"]) if "holdout" in configuration else None
36
- data_file = DataFile(environment, last_modified, settings, segments, feature_flags, custom_data_info, holdout)
37
+ date_modified = int(configuration.get("dateModified", 0))
38
+ data_file = DataFile(
39
+ environment,
40
+ last_modified,
41
+ settings,
42
+ segments,
43
+ feature_flags,
44
+ custom_data_info,
45
+ holdout,
46
+ date_modified,
47
+ )
37
48
  return data_file
38
49
 
39
50
  @staticmethod
40
51
  def __parse_segments(configuration: Dict[str, Any]) -> Dict[int, Segment]:
41
- return {
42
- (seg := Segment.from_json(jobj)).id_: seg
43
- for jobj in configuration.get("segments") or []
44
- }
52
+ return {(seg := Segment.from_json(jobj)).id_: seg for jobj in configuration.get("segments") or []}
45
53
 
46
54
  @staticmethod
47
55
  def __parse_feature_flags(
48
56
  configuration: Dict[str, Any], segments: Dict[int, Segment], cdi: CustomDataInfo
49
57
  ) -> Dict[str, FeatureFlag]:
50
58
  return {
51
- (ff := FeatureFlag(jobj, segments, cdi)).feature_key: ff
52
- for jobj in configuration.get("featureFlags") or []
59
+ (ff := FeatureFlag(jobj, segments, cdi)).feature_key: ff for jobj in configuration.get("featureFlags") or []
53
60
  }
54
61
 
55
62
  # pylint: disable=R0913
@@ -61,15 +68,22 @@ class DataFile:
61
68
  segments: Dict[int, Segment],
62
69
  feature_flags: Dict[str, FeatureFlag],
63
70
  custom_data_info: CustomDataInfo,
64
- holdout: Optional[Experiment] = None,
71
+ holdout: Optional[Experiment],
72
+ date_modified: int,
65
73
  ) -> None:
66
74
  KameleoonLogger.debug(
67
75
  "CALL: DataFile(environment: %s, last_modified: %s, settings: %s, segments, feature_flags,"
68
- " custom_data_info: %s, holdout: %s)",
69
- environment, last_modified, settings, custom_data_info, holdout
76
+ " custom_data_info: %s, holdout: %s, date_modified: %s)",
77
+ environment,
78
+ last_modified,
79
+ settings,
80
+ custom_data_info,
81
+ holdout,
82
+ date_modified,
70
83
  )
71
84
  self.__environment = environment # pylint: disable=W0238
72
85
  self.__last_modified = last_modified
86
+ self.__date_modified = date_modified
73
87
  self.__settings = settings
74
88
  self.__segments = segments
75
89
  self.__audience_tracking_segments = [seg for seg in segments.values() if seg.audience_tracking]
@@ -90,8 +104,13 @@ class DataFile:
90
104
  self.__holdout = holdout
91
105
  KameleoonLogger.debug(
92
106
  "RETURN: DataFile(environment: %s, last_modified: %s, settings: %s, segments, feature_flags,"
93
- " custom_data_info: %s, holdout: %s)",
94
- environment, last_modified, settings, custom_data_info, holdout
107
+ " custom_data_info: %s, holdout: %s, date_modified: %s)",
108
+ environment,
109
+ last_modified,
110
+ settings,
111
+ custom_data_info,
112
+ holdout,
113
+ date_modified,
95
114
  )
96
115
 
97
116
  @property
@@ -99,6 +118,11 @@ class DataFile:
99
118
  """Returns last modified string"""
100
119
  return self.__last_modified
101
120
 
121
+ @property
122
+ def date_modified(self) -> int:
123
+ """Returns the last data-file update timestamp from the configuration."""
124
+ return self.__date_modified
125
+
102
126
  @property
103
127
  def settings(self) -> Settings:
104
128
  """Returns settings"""
@@ -152,10 +176,12 @@ class DataFile:
152
176
  feature_flag = self.__feature_flags.get(feature_key)
153
177
  if feature_flag is None:
154
178
  raise FeatureNotFound(feature_key)
179
+ return feature_flag
180
+
181
+ def _ensure_environment_enabled(self, feature_flag: FeatureFlag):
155
182
  if not feature_flag.environment_enabled:
156
183
  env = "default" if self.__environment is None else f"'{self.__environment}'"
157
- raise FeatureEnvironmentDisabled(f"Feature '{feature_key}' is disabled for {env} environment")
158
- return feature_flag
184
+ raise FeatureEnvironmentDisabled(f"Feature '{feature_flag.feature_key}' is disabled for {env} environment")
159
185
 
160
186
  @property
161
187
  def custom_data_info(self) -> CustomDataInfo:
@@ -211,6 +237,7 @@ class DataFile:
211
237
  "DataFile{"
212
238
  f"environment:'{self.__environment}',"
213
239
  f"last_modified:'{self.__last_modified}',"
240
+ f"date_modified:{self.__date_modified},"
214
241
  f"feature_flags:{len(self.__feature_flags)},"
215
242
  f"settings:{self.__settings}"
216
243
  "}"
@@ -23,6 +23,7 @@ class Variation:
23
23
 
24
24
  def __init__(self, dict_json: Dict[str, Any]):
25
25
  self.key: str = dict_json.get("key", "")
26
+ self.name: str = dict_json.get("name", "")
26
27
  self.variables: List[Variable] = Variable.from_array(
27
28
  dict_json.get("variables", [])
28
29
  )
@@ -33,4 +34,5 @@ class Variation:
33
34
 
34
35
  def __str__(self):
35
36
  return (f"Variation{{key:'{self.key}',"
37
+ f"name:'{self.name}',"
36
38
  f"variables:{StringUtils.object_to_string(self.variables)}}}")
@@ -3,11 +3,12 @@
3
3
  import collections
4
4
  import time
5
5
  from typing import Any, Dict, Iterator, List, Optional
6
+
6
7
  from kameleoon.configuration.custom_data_info import CustomDataInfo
7
8
  from kameleoon.data import Conversion, CustomData
8
- from kameleoon.data.mapping_identifier import MappingIdentifier
9
9
  from kameleoon.data.manager.visitor import Visitor
10
10
  from kameleoon.data.manager.visitor_slot import VisitorSlot
11
+ from kameleoon.data.mapping_identifier import MappingIdentifier
11
12
  from kameleoon.helpers.scheduler import Scheduler
12
13
  from kameleoon.logging.kameleoon_logger import KameleoonLogger
13
14
  from kameleoon.managers.data.data_manager import DataManager
@@ -63,6 +64,20 @@ class VisitorManager:
63
64
  slot.lock.release()
64
65
  KameleoonLogger.debug("RETURN: VisitorManager.get_or_create_visitor(visitor_code: %s)", visitor_code)
65
66
 
67
+ def peek_visitor(self, visitor_code: str) -> Optional[Visitor]:
68
+ """Retrieves a visitor by their code if it exists, otherwise returns `None`."""
69
+ KameleoonLogger.debug(f"CALL: VisitorManager.peekVisitor(visitor_code: {visitor_code})")
70
+ if (slot := self.__try_acquire_slot(visitor_code)) is None:
71
+ visitor = None
72
+ else:
73
+ try:
74
+ visitor = slot.visitor
75
+ finally:
76
+ slot.lock.release()
77
+ KameleoonLogger.debug(
78
+ f"RETURN: VisitorManager.peekVisitor(visitor_code: {visitor_code}) -> "f"(visitor: {visitor})")
79
+ return visitor
80
+
66
81
  def add_data(self, visitor_code: str, *args, track: bool = True) -> Visitor:
67
82
  """
68
83
  Adds data to a visitor.
@@ -3,16 +3,14 @@
3
3
  from http.cookies import Morsel
4
4
  from typing import cast, Callable, Coroutine, Optional, Tuple, Union, Any, List, Dict, Iterable
5
5
 
6
+ from kameleoon import configuration
6
7
  from kameleoon.client_readiness.async_readiness import AsyncClientReadiness
7
8
  from kameleoon.client_readiness.threading_readiness import ThreadingClientReadiness
8
-
9
- from kameleoon import configuration
10
9
  from kameleoon.configuration.consent_blocking_behaviour import ConsentBlockingBehaviour
11
10
  from kameleoon.configuration.data_file import DataFile
12
11
  from kameleoon.configuration.feature_flag import FeatureFlag
13
12
  from kameleoon.configuration.rule import Rule
14
13
  from kameleoon.configuration.rule_type import RuleType
15
-
16
14
  from kameleoon.data import Conversion, CustomData, Data, UniqueIdentifier
17
15
  from kameleoon.data.manager.assigned_variation import AssignedVariation
18
16
  from kameleoon.data.manager.forced_experiment_variation import ForcedExperimentVariation
@@ -20,7 +18,6 @@ from kameleoon.data.manager.legal_consent import LegalConsent
20
18
  from kameleoon.data.manager.visitor import Visitor
21
19
  from kameleoon.data.manager.visitor_manager import VisitorManager
22
20
  from kameleoon.data.targeted_segment import TargetedSegment
23
-
24
21
  from kameleoon.exceptions import (
25
22
  FeatureVariationNotFound,
26
23
  FeatureExperimentNotFound,
@@ -28,37 +25,28 @@ from kameleoon.exceptions import (
28
25
  FeatureEnvironmentDisabled,
29
26
  SiteCodeIsEmpty,
30
27
  )
31
-
32
28
  from kameleoon.helpers.hasher import Hasher
33
29
  from kameleoon.helpers.visitor_code import validate_visitor_code
34
-
35
30
  from kameleoon.hybrid.hybrid_manager_impl import HybridManagerImpl
36
-
37
31
  from kameleoon.kameleoon_client_config import KameleoonClientConfig
38
32
  from kameleoon.logging.kameleoon_logger import KameleoonLogger
39
33
  from kameleoon.logging.logger import DefaultLogger
40
-
41
34
  from kameleoon.managers.asyncexec.async_executor import AsyncExecutor
42
35
  from kameleoon.managers.data.data_manager import DataManager
43
36
  from kameleoon.managers.evaluation.evaluated_experiment import EvaluatedExperiment
44
37
  from kameleoon.managers.remote_data.remote_data_manager import RemoteDataManager
45
38
  from kameleoon.managers.tracking.tracking_manager import TrackingManager
46
39
  from kameleoon.managers.warehouse.warehouse_manager import WarehouseManager
47
-
48
40
  from kameleoon.network.access_token_source_factory import AccessTokenSourceFactory
41
+ from kameleoon.network.cookie.cookie_manager import CookieManager
49
42
  from kameleoon.network.net_provider_impl import NetProviderImpl
50
43
  from kameleoon.network.network_manager_factory import NetworkManagerFactory
51
44
  from kameleoon.network.network_manager_factory_impl import NetworkManagerFactoryImpl
52
45
  from kameleoon.network.sendable import Sendable
53
46
  from kameleoon.network.services.configuration_service import ConfigurationService, FetchedConfiguration
54
- from kameleoon.network.cookie.cookie_manager import CookieManager
55
-
56
47
  from kameleoon.real_time.real_time_configuration_service import RealTimeConfigurationService
57
-
58
48
  from kameleoon.targeting.targeting_manager import TargetingManager
59
-
60
49
  from kameleoon.types.remote_visitor_data_filter import RemoteVisitorDataFilter
61
- from kameleoon.types.variable import Variable
62
50
  from kameleoon.types.variation import Variation
63
51
 
64
52
  __all__ = [
@@ -596,9 +584,7 @@ class KameleoonClient:
596
584
  validate_visitor_code(visitor_code)
597
585
  feature_flag = self._data_manager.data_file.get_feature_flag(feature_key)
598
586
  variation_key, eval_exp = self.__get_variation_info(visitor_code, feature_flag, track)
599
- external_variation = self.__create_external_variation(
600
- variation_key, feature_flag.get_variation(variation_key), eval_exp
601
- )
587
+ external_variation = self.__create_external_variation(feature_flag.get_variation(variation_key), eval_exp)
602
588
  if track:
603
589
  self._tracking_manager.add_visitor_code(visitor_code)
604
590
  KameleoonLogger.info(
@@ -611,6 +597,14 @@ class KameleoonClient:
611
597
  )
612
598
  return external_variation
613
599
 
600
+ def get_data_file(self):
601
+ """Retrieves the information about the data file"""
602
+
603
+ KameleoonLogger.info("CALL: KameleoonClient.get_data_file()")
604
+ data_file = self._data_manager.external_datafile
605
+ KameleoonLogger.info("RETURN: KameleoonClient.get_data_file() -> (data_file: %s)", data_file)
606
+ return data_file
607
+
614
608
  def get_variations(self, visitor_code: str, only_active=False, track: bool = True) -> Dict[str, Variation]:
615
609
  """
616
610
  Forms a dictionary of variations assigned to a given visitor across all feature flags.
@@ -640,8 +634,6 @@ class KameleoonClient:
640
634
  validate_visitor_code(visitor_code)
641
635
  variations: Dict[str, Variation] = {}
642
636
  for feature_flag in self._data_manager.data_file.feature_flags.values():
643
- if not feature_flag.environment_enabled:
644
- continue
645
637
  try:
646
638
  variation_key, eval_exp = self.__get_variation_info(visitor_code, feature_flag, track)
647
639
  except FeatureEnvironmentDisabled:
@@ -649,7 +641,7 @@ class KameleoonClient:
649
641
  if only_active and (variation_key == configuration.Variation.Type.OFF.value):
650
642
  continue
651
643
  variations[feature_flag.feature_key] = self.__create_external_variation(
652
- variation_key, feature_flag.get_variation(variation_key), eval_exp
644
+ feature_flag.get_variation(variation_key), eval_exp
653
645
  )
654
646
  if track:
655
647
  self._tracking_manager.add_visitor_code(visitor_code)
@@ -698,6 +690,10 @@ class KameleoonClient:
698
690
  )
699
691
  eval_exp = None
700
692
  forced_variation = visitor.get_forced_feature_variation(feature_flag.feature_key) if visitor else None
693
+
694
+ if not (forced_variation and forced_variation.simulated):
695
+ self._data_manager.data_file._ensure_environment_enabled(feature_flag)
696
+
701
697
  if forced_variation:
702
698
  eval_exp = EvaluatedExperiment.from_forced_variation(forced_variation)
703
699
  elif self.__is_visitor_not_in_holdout(
@@ -791,31 +787,20 @@ class KameleoonClient:
791
787
 
792
788
  @staticmethod
793
789
  def __create_external_variation(
794
- variation_key: str,
795
790
  variation: Optional[configuration.Variation],
796
791
  eval_exp: Optional[EvaluatedExperiment],
797
792
  ) -> Variation:
798
793
  KameleoonLogger.debug(
799
- "CALL: KameleoonClient.__create_external_variation(variation_key: %s, internal_variation: %s, "
800
- "eval_exp: %s)",
801
- variation_key,
794
+ "CALL: KameleoonClient.__create_external_variation(variation: %s, eval_exp: %s)",
802
795
  variation,
803
796
  eval_exp,
804
797
  )
805
- ext_variables: Dict[str, Variable] = {}
806
- if variation:
807
- for variable in variation.variables:
808
- ext_variables[variable.key] = Variable(variable.key, variable.get_type(), variable.get_value())
809
- variation_id = None
810
- experiment_id = None
811
- if eval_exp:
812
- variation_id = eval_exp.var_by_exp.variation_id
813
- experiment_id = eval_exp.experiment.id_
814
- ext_variation = Variation(variation_key, variation_id, experiment_id, ext_variables)
798
+ variation_id, experiment_id = (
799
+ (eval_exp.var_by_exp.variation_id, eval_exp.experiment.id_) if eval_exp else (None, None)
800
+ )
801
+ ext_variation = Variation._build_from_internal(variation, variation_id, experiment_id)
815
802
  KameleoonLogger.debug(
816
- "RETURN: KameleoonClient.__create_external_variation(variation_key: %s, internal_variation: %s, "
817
- "eval_exp: %s) -> (ext_variation: %s)",
818
- variation_key,
803
+ "RETURN: KameleoonClient.__create_external_variation(variation: %s, eval_exp: %s) -> (ext_variation: %s)",
819
804
  variation,
820
805
  eval_exp,
821
806
  ext_variation,
@@ -863,6 +848,9 @@ class KameleoonClient:
863
848
  variation_key,
864
849
  )
865
850
  feature_flag = self._data_manager.data_file.get_feature_flag(feature_key)
851
+
852
+ self._data_manager.data_file._ensure_environment_enabled(feature_flag)
853
+
866
854
  variation = feature_flag.get_variation(variation_key)
867
855
  if not variation:
868
856
  raise FeatureVariationNotFound(variation_key)
@@ -1164,14 +1152,18 @@ class KameleoonClient:
1164
1152
  )
1165
1153
  return custom_data
1166
1154
 
1155
+ # Deprecated methods
1167
1156
  def get_feature_list(self) -> List[str]:
1168
1157
  """
1158
+ Deprecated function. Please use `get_data_file` instead.
1159
+
1169
1160
  The get_feature_list method uses for obtaining a list of feature flag IDs:
1170
1161
  - currently available for the SDK
1171
1162
 
1172
1163
  :return: List of all feature flag IDs
1173
- :rtype: List[int]
1164
+ :rtype: List[str]
1174
1165
  """
1166
+ KameleoonLogger.info("Call to deprecated function `get_feature_list`. Please use `get_data_file` instead.")
1175
1167
  KameleoonLogger.info("CALL: KameleoonClient.get_feature_list()")
1176
1168
  features = list(self._data_manager.data_file.feature_flags)
1177
1169
  KameleoonLogger.info("RETURN: KameleoonClient.get_feature_list() -> (features: %s)", features)
@@ -1200,8 +1192,6 @@ class KameleoonClient:
1200
1192
  visitor = self._visitor_manager.get_visitor(visitor_code)
1201
1193
 
1202
1194
  def filter_conditions(feature_flag: FeatureFlag) -> bool:
1203
- if not feature_flag.environment_enabled:
1204
- return False
1205
1195
  try:
1206
1196
  eval_exp = self.__evaluate(visitor, visitor_code, feature_flag, False, False)
1207
1197
  except FeatureEnvironmentDisabled:
@@ -1251,8 +1241,6 @@ class KameleoonClient:
1251
1241
  visitor = self._visitor_manager.get_visitor(visitor_code)
1252
1242
  map_active_features: Dict[str, Variation] = {}
1253
1243
  for feature_flag in self._data_manager.data_file.feature_flags.values():
1254
- if not feature_flag.environment_enabled:
1255
- continue
1256
1244
  try:
1257
1245
  eval_exp = self.__evaluate(visitor, visitor_code, feature_flag, False, False)
1258
1246
  except FeatureEnvironmentDisabled:
@@ -1261,7 +1249,7 @@ class KameleoonClient:
1261
1249
  if variation_key == configuration.Variation.Type.OFF.value:
1262
1250
  continue
1263
1251
  map_active_features[feature_flag.feature_key] = self.__create_external_variation(
1264
- variation_key, feature_flag.get_variation(variation_key), eval_exp
1252
+ feature_flag.get_variation(variation_key), eval_exp
1265
1253
  )
1266
1254
  KameleoonLogger.info(
1267
1255
  "RETURN: KameleoonClient.get_active_features(visitor_code: %s) -> (active_features: %s)",
@@ -2,6 +2,7 @@
2
2
 
3
3
  from kameleoon.configuration.data_file import DataFile
4
4
  from kameleoon.logging.kameleoon_logger import KameleoonLogger
5
+ from kameleoon.types.data_file import DataFile as TypesDataFile
5
6
 
6
7
 
7
8
  class DataManager:
@@ -22,6 +23,11 @@ class DataManager:
22
23
  """Sets a new `DataFile` for this instance by updating the container."""
23
24
  self.__container = DataManager.Container(value)
24
25
 
26
+ @property
27
+ def external_datafile(self) -> TypesDataFile:
28
+ """Returns the external `DataFile` associated with this instance."""
29
+ return self.__container.external_datafile
30
+
25
31
  @property
26
32
  def is_visitor_code_managed(self) -> bool:
27
33
  """Returns `True` if consent is required, otherwise returns `False`."""
@@ -34,6 +40,7 @@ class DataManager:
34
40
  def __init__(self, data_file: DataFile) -> None:
35
41
  KameleoonLogger.debug("CALL: DataManager.Container(data_file: %s)", data_file)
36
42
  self.data_file = data_file
43
+ self.external_datafile = TypesDataFile._build_from_internal(data_file)
37
44
  # Regarding GDPR policy we should set visitorCode if legal consent isn't required or we have at
38
45
  # least one Targeted Delivery rule in datafile
39
46
  self.is_visitor_code_managed = (
@@ -61,7 +61,7 @@ class TrackingBuilder:
61
61
  return
62
62
  for visitor_code in self.__visitor_codes:
63
63
  if self.__total_size <= self.__request_size_limit:
64
- visitor = self.__visitor_manager.get_visitor(visitor_code)
64
+ visitor = self.__visitor_manager.peek_visitor(visitor_code)
65
65
  is_consent_given = self.__is_consent_given(visitor)
66
66
  data = self.__collect_tracking_data(visitor_code, visitor, is_consent_given)
67
67
  if len(data) > 0:
@@ -1,5 +1,6 @@
1
1
  """Network"""
2
2
  import asyncio
3
+ import base64
3
4
  import time
4
5
  from typing import Optional
5
6
 
@@ -25,11 +26,18 @@ class AccessTokenSource:
25
26
  self._client_secret = client_secret
26
27
  self._cached_token: Optional[AccessTokenSource.ExpiringToken] = None
27
28
  self._fetching = False
29
+ self._basic_authorization_token = AccessTokenSource.construct_basic_token(client_id, client_secret)
28
30
  KameleoonLogger.debug(
29
31
  lambda: f"RETURN: AccessTokenSource(network_manager, client_id: '{StringUtils.secret(client_id)}', "
30
32
  f"client_secret: '{StringUtils.secret(client_secret)}')"
31
33
  )
32
34
 
35
+ @staticmethod
36
+ def construct_basic_token(client_id: str, client_secret: str) -> str:
37
+ """Returns the basic token"""
38
+ basic_token_content = f"{client_id}:{client_secret}"
39
+ return "Basic " + base64.b64encode(basic_token_content.encode("utf-8")).decode("utf-8")
40
+
33
41
  async def get_token(self, timeout: Optional[float] = None) -> Optional[str]:
34
42
  """Returns the access token. Fetches a new token if the cached one is expired or obsolete."""
35
43
  KameleoonLogger.debug("CALL: AccessTokenSource.get_token(timeout: %s)", timeout)
@@ -73,7 +81,7 @@ class AccessTokenSource:
73
81
  KameleoonLogger.debug("CALL: AccessTokenSource._fetch_token(timeout: %s)", timeout)
74
82
  try:
75
83
  service: AutomationService = self._network_manager.get_service(AutomationService)
76
- response = await service.fetch_access_jwtoken(self._client_id, self._client_secret, timeout)
84
+ response = await service.fetch_access_jwtoken(self._basic_authorization_token, timeout)
77
85
  if not response.success:
78
86
  KameleoonLogger.error("Failed to fetch access JWT")
79
87
  return None
@@ -64,8 +64,14 @@ class Request:
64
64
  def __str__(self):
65
65
  body = "None"
66
66
  if self.body is not None:
67
- body = "'****'" if self.body.startswith('grant_type=client_credentials') else f"'{self.body}'"
68
- return f"HttpRequest{{Method:'{self.method}',Url:'{self.url}',Headers:{self.headers},Body:{body}}}"
67
+ body = self.body
68
+
69
+ headers = [
70
+ f"{name}:{'***' if name == 'Authorization' else value}"
71
+ for name, value in (self.headers or {}).items()
72
+ ]
73
+
74
+ return f"HttpRequest{{Method:'{self.method}',Url:'{self.url}',Headers:{headers},Body:{body}}}"
69
75
 
70
76
 
71
77
  class NetProvider:
@@ -7,7 +7,7 @@ from kameleoon.network.net_provider import Response
7
7
  class AutomationService(Service):
8
8
  """Abstract automation service"""
9
9
  def fetch_access_jwtoken(
10
- self, client_id: str, client_secret: str, timeout: Optional[float] = None
10
+ self, basic_authorization_token: str, timeout: Optional[float] = None
11
11
  ) -> Coroutine[Any, Any, Response]:
12
12
  """Fetches an access JWT token asynchronously."""
13
13
  raise NotImplementedError()
@@ -13,6 +13,7 @@ class AutomationServiceImpl(AutomationService, ServiceImpl):
13
13
  """Automation service implementation"""
14
14
  _ACCESS_TOKEN_GRANT_TYPE = "client_credentials"
15
15
  _H_CONTENT_TYPE_NAME = "Content-Type"
16
+ _H_AUTHORIZATION = "Authorization"
16
17
  _H_CONTENT_TYPE_VALUE = "application/x-www-form-urlencoded"
17
18
 
18
19
  def __init__(self, network_manager) -> None:
@@ -22,27 +23,25 @@ class AutomationServiceImpl(AutomationService, ServiceImpl):
22
23
  KameleoonLogger.debug("RETURN: AutomationServiceImpl(network_manager)")
23
24
 
24
25
  def fetch_access_jwtoken(
25
- self, client_id: str, client_secret: str, timeout: Optional[float] = None
26
+ self, basic_authorization_token: str, timeout: Optional[float] = None
26
27
  ) -> Coroutine[Any, Any, Response]:
27
28
  KameleoonLogger.debug(lambda: f"CALL: AutomationServiceImpl.fetch_access_jwtoken("
28
- f"client_id: '{StringUtils.secret(client_id)}', "
29
- f"client_secret: '{StringUtils.secret(client_secret)}', timeout: {timeout})")
29
+ f"basic_authorization_token: '{StringUtils.secret(basic_authorization_token)}', "
30
+ f"timeout: {timeout})")
30
31
  if timeout is None:
31
32
  timeout = self.network_manager.call_timeout
32
33
  url: str = self.network_manager.url_provider.make_access_token_url()
33
34
  body = QueryBuilder(
34
35
  QueryParam(QueryParams.GRANT_TYPE, self._ACCESS_TOKEN_GRANT_TYPE),
35
- QueryParam(QueryParams.CLIENT_ID, client_id),
36
- QueryParam(QueryParams.CLIENT_SECRET, client_secret),
37
36
  )
38
- headers = {self._H_CONTENT_TYPE_NAME: self._H_CONTENT_TYPE_VALUE}
37
+ headers = {self._H_CONTENT_TYPE_NAME: self._H_CONTENT_TYPE_VALUE,
38
+ self._H_AUTHORIZATION: basic_authorization_token}
39
39
  request = Request(
40
40
  HttpMethod.POST, url, timeout, headers=headers, body=str(body),
41
41
  response_content_type=ResponseContentType.JSON,
42
42
  )
43
43
  response = self._make_call(request, False)
44
44
  KameleoonLogger.debug(lambda: f"CALL: AutomationServiceImpl.fetch_access_jwtoken("
45
- f"client_id: '{StringUtils.secret(client_id)}', "
46
- f"client_secret: '{StringUtils.secret(client_secret)}', "
45
+ f"basic_authorization_token: '{StringUtils.secret(basic_authorization_token)}', "
47
46
  f"timeout: {timeout}) -> (response_coroutine)")
48
47
  return response
@@ -34,18 +34,22 @@ class UrlProvider:
34
34
  self.site_code = site_code
35
35
  self._data_api_domain = self.DEFAULT_DATA_API_DOMAIN # if remove W0201 error (pylint)
36
36
  self.__setup_domains(network_domain)
37
- self.__post_query_base = self.__make_post_query_base()
37
+ query_builder = self.__make_sdk_sitecode_query_builder()
38
+ self.__sdk_sitecode_query_base = str(query_builder)
39
+ query_builder.append(
40
+ QueryParam(QueryParams.BODY_UA, "true"),
41
+ )
42
+ self.__tracking_query_base = str(query_builder)
38
43
 
39
- def __make_post_query_base(self) -> str:
44
+ def __make_sdk_sitecode_query_builder(self) -> QueryBuilder:
40
45
  # fmt: off
41
46
  query_builder = QueryBuilder(
42
47
  QueryParam(QueryParams.SDK_NAME, SdkVersion.NAME),
43
48
  QueryParam(QueryParams.SDK_VERSION, SdkVersion.VERSION),
44
49
  QueryParam(QueryParams.SITE_CODE, self.site_code),
45
- QueryParam(QueryParams.BODY_UA, "true"),
46
50
  )
47
51
  # fmt: on
48
- return str(query_builder)
52
+ return query_builder
49
53
 
50
54
  def __setup_domains(self, network_domain: Optional[str]) -> None:
51
55
  """Updates the domains based on the provided network domain."""
@@ -73,7 +77,7 @@ class UrlProvider:
73
77
 
74
78
  def make_tracking_url(self) -> str:
75
79
  """Constructs the URL for tracking events."""
76
- return self._DATA_API_URL_FORMAT.format(self._data_api_domain, self._TRACKING_PATH, self.__post_query_base)
80
+ return self._DATA_API_URL_FORMAT.format(self._data_api_domain, self._TRACKING_PATH, self.__tracking_query_base)
77
81
 
78
82
  def make_visitor_data_get_url(
79
83
  self, visitor_code: str, data_filter: RemoteVisitorDataFilter, is_unique_identifier: bool = False
@@ -134,4 +138,4 @@ class UrlProvider:
134
138
 
135
139
  def make_access_token_url(self) -> str:
136
140
  """Constructs the URL for fetching access tokens."""
137
- return self._ACCESS_TOKEN_URL_FORMAT.format(self._access_token_domain)
141
+ return self._ACCESS_TOKEN_URL_FORMAT.format(self._access_token_domain) + "?" + self.__sdk_sitecode_query_base
@@ -1,6 +1,6 @@
1
1
  """Kameleoon SDK version"""
2
2
 
3
- version_info = (3, 18, 0)
3
+ version_info = (3, 19, 0)
4
4
  __version__ = ".".join(str(v) for v in version_info) # uses in scripts
5
5
 
6
6
 
@@ -1,5 +1,7 @@
1
1
  """Unknown condition"""
2
2
  from typing import Any
3
+
4
+ from kameleoon.logging.kameleoon_logger import KameleoonLogger
3
5
  from kameleoon.targeting.conditions.targeting_condition import TargetingCondition
4
6
 
5
7
 
@@ -11,4 +13,5 @@ class UnknownCondition(TargetingCondition):
11
13
  """
12
14
 
13
15
  def check(self, data: Any) -> bool:
16
+ KameleoonLogger.warning("Condition of unknown type '%s' evaluated as true", self.type)
14
17
  return True