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