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