kameleoon-client-python 3.16.3__tar.gz → 3.17.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/PKG-INFO +15 -15
- kameleoon_client_python-3.17.1/kameleoon/configuration/consent_blocking_behaviour.py +16 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/data_file.py +2 -1
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/settings.py +9 -0
- kameleoon_client_python-3.17.1/kameleoon/data/manager/legal_consent.py +11 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/manager/visitor.py +5 -4
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/exceptions.py +0 -7
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/kameleoon_client.py +86 -19
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/remote_data/remote_visitor_data.py +8 -10
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/tracking/tracking_builder.py +4 -1
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/cookie/cookie_manager.py +2 -13
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/sdk_version.py +1 -1
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon_client_python.egg-info/PKG-INFO +15 -15
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon_client_python.egg-info/SOURCES.txt +2 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/MANIFEST.in +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/README.md +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/client_readiness/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/client_readiness/async_readiness.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/client_readiness/threading_readiness.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/custom_data_info.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/experiment.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/feature_flag.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/me_group.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/rule.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/rule_type.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/variable.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/variation.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/configuration/variation_by_exposition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/browser.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/cbscores.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/conversion.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/cookie.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/custom_data.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/data.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/device.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/geolocation.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/kcs_heat.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/manager/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/manager/assigned_variation.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/manager/forced_experiment_variation.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/manager/forced_feature_variation.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/manager/forced_variation.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/manager/page_view_visit.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/manager/visitor_manager.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/manager/visitor_slot.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/mapping_identifier.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/operating_system.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/page_view.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/personalization.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/targeted_segment.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/unique_identifier.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/user_agent.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/data/visitor_visits.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/defaults.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/helpers/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/helpers/domain.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/helpers/functions.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/helpers/hasher.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/helpers/logger.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/helpers/multi_threading.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/helpers/nonce.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/helpers/repeat_timer.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/helpers/scheduler.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/helpers/string_utils.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/helpers/visitor_code.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/hybrid/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/hybrid/hybrid_manager.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/hybrid/hybrid_manager_impl.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/kameleoon_client_config.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/kameleoon_client_factory.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/logging/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/logging/kameleoon_logger.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/logging/log_level.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/logging/logger.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/asyncexec/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/asyncexec/async_executor.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/data/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/data/data_manager.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/evaluation/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/evaluation/evaluated_experiment.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/remote_data/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/remote_data/remote_data_manager.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/tracking/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/tracking/tracking_manager.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/tracking/visitor_tracking_registry.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/warehouse/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/managers/warehouse/warehouse_manager.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/middleware.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/access_token_source.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/access_token_source_factory.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/activity_event.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/cookie/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/net_provider.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/net_provider_impl.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/network_manager.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/network_manager_factory.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/network_manager_factory_impl.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/network_manager_impl.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/query_builder.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/query_encodable.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/sendable.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/service_initialize_context.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/service_initialize_context_impl.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/services/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/services/automation_service.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/services/automation_service_impl.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/services/configuration_service.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/services/configuration_service_impl.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/services/data_service.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/services/data_service_impl.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/services/service.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/services/service_impl.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/uri_helper.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/network/url_provider.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/real_time/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/real_time/real_time_configuration_service.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/real_time/real_time_event.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/storage/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/storage/cache.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/storage/cache_factory.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/storage/cache_factory_impl.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/storage/cache_impl.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/browser_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/constants.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/conversion_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/cookie_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/custom_datum.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/device_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/exclusive_experiment_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/geolocation_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/kcs_heat_range_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/number_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/operating_system_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/page_title_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/page_url_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/page_view_number_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/previous_page_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/sdk_language_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/segment_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/string_value_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/target_experiment_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/target_feature_flag_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/target_personalization_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/targeting_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/time_elapsed_since_visit_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/unknown_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/visit_number_today_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/visit_number_total_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/visitor_code_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/conditions/visitor_new_return_condition.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/models.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/targeting_manager.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/tree_builder.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/targeting/tree_condition_factory.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/types/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/types/remote_visitor_data_filter.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/types/variable.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon/types/variation.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon_client_python.egg-info/dependency_links.txt +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon_client_python.egg-info/requires.txt +14 -14
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/kameleoon_client_python.egg-info/top_level.txt +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/setup.cfg +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/setup.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/kameleoon_app/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/kameleoon_app/admin.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/kameleoon_app/apps.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/kameleoon_app/migrations/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/kameleoon_app/models.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/kameleoon_app/tests.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/kameleoon_app/views.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/manage.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/proj/__init__.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/proj/asgi.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/proj/settings.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/proj/urls.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/integration/proj/proj/wsgi.py +0 -0
- {kameleoon_client_python-3.16.3 → kameleoon_client_python-3.17.1}/tests/resources/config.yml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kameleoon-client-python
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.17.1
|
|
4
4
|
Summary: Kameleoon Client Python Software Development Kit.
|
|
5
5
|
Home-page: https://developers.kameleoon.com/python-sdk.html
|
|
6
6
|
Author: Kameleoon
|
|
@@ -20,27 +20,27 @@ Requires-Dist: requests<3.0.0,>=2.25
|
|
|
20
20
|
Requires-Dist: sseclient-py<1.9.0,>=1.7.0
|
|
21
21
|
Requires-Dist: aiohttp<4.0.0,>=3.8.0
|
|
22
22
|
Provides-Extra: test
|
|
23
|
-
Requires-Dist:
|
|
23
|
+
Requires-Dist: flake8==4.0.1; extra == "test"
|
|
24
|
+
Requires-Dist: freezegun==1.1.0; extra == "test"
|
|
25
|
+
Requires-Dist: types-requests==2.25.0; extra == "test"
|
|
26
|
+
Requires-Dist: pytest-asyncio==0.21.*; extra == "test"
|
|
24
27
|
Requires-Dist: types-python-dateutil==2.8.2; extra == "test"
|
|
28
|
+
Requires-Dist: pytest-pythonpath==0.7.3; extra == "test"
|
|
29
|
+
Requires-Dist: aioresponses==0.7.*; extra == "test"
|
|
30
|
+
Requires-Dist: wheel==0.36.2; extra == "test"
|
|
31
|
+
Requires-Dist: requests<3.0.0,>=2.25; extra == "test"
|
|
32
|
+
Requires-Dist: twine==3.4.1; extra == "test"
|
|
33
|
+
Requires-Dist: pytest-django==4.4.0; extra == "test"
|
|
25
34
|
Requires-Dist: types-PyYAML==5.4.3; extra == "test"
|
|
35
|
+
Requires-Dist: pyyaml<6.1.0,>=5.4.0; extra == "test"
|
|
36
|
+
Requires-Dist: pytest-cov==2.12.1; extra == "test"
|
|
26
37
|
Requires-Dist: pytest-ordering==0.6; extra == "test"
|
|
27
|
-
Requires-Dist: pylint==2.12.*; extra == "test"
|
|
28
38
|
Requires-Dist: sseclient-py<1.9.0,>=1.7.0; extra == "test"
|
|
29
39
|
Requires-Dist: Werkzeug==2.0.1; extra == "test"
|
|
40
|
+
Requires-Dist: pylint==2.12.*; extra == "test"
|
|
30
41
|
Requires-Dist: Django==3.2.4; extra == "test"
|
|
31
|
-
Requires-Dist: types-requests==2.25.0; extra == "test"
|
|
32
|
-
Requires-Dist: pytest-cov==2.12.1; extra == "test"
|
|
33
|
-
Requires-Dist: aioresponses==0.7.*; extra == "test"
|
|
34
|
-
Requires-Dist: pytest-asyncio==0.21.*; extra == "test"
|
|
35
|
-
Requires-Dist: twine==3.4.1; extra == "test"
|
|
36
|
-
Requires-Dist: aiohttp<4.0.0,>=3.8.0; extra == "test"
|
|
37
|
-
Requires-Dist: requests<3.0.0,>=2.25; extra == "test"
|
|
38
|
-
Requires-Dist: flake8==4.0.1; extra == "test"
|
|
39
|
-
Requires-Dist: pytest-pythonpath==0.7.3; extra == "test"
|
|
40
42
|
Requires-Dist: mypy==0.991; extra == "test"
|
|
41
|
-
Requires-Dist:
|
|
42
|
-
Requires-Dist: freezegun==1.1.0; extra == "test"
|
|
43
|
-
Requires-Dist: pyyaml<6.1.0,>=5.4.0; extra == "test"
|
|
43
|
+
Requires-Dist: aiohttp<4.0.0,>=3.8.0; extra == "test"
|
|
44
44
|
Dynamic: author
|
|
45
45
|
Dynamic: author-email
|
|
46
46
|
Dynamic: classifier
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Kameleoon Configuration"""
|
|
2
|
+
|
|
3
|
+
from enum import Enum
|
|
4
|
+
from kameleoon.helpers.functions import enum_from_literal
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ConsentBlockingBehaviour(Enum):
|
|
8
|
+
"""Possible Consent Blocking Behaviour types"""
|
|
9
|
+
|
|
10
|
+
PARTIALLY_BLOCKED = "PARTIALLY_BLOCK"
|
|
11
|
+
COMPLETELY_BLOCKED = "FULLY_BLOCK"
|
|
12
|
+
|
|
13
|
+
@staticmethod
|
|
14
|
+
def from_str(s: str) -> "ConsentBlockingBehaviour":
|
|
15
|
+
"""Makes ConsentBlockingBehaviour from string"""
|
|
16
|
+
return enum_from_literal(s, ConsentBlockingBehaviour, ConsentBlockingBehaviour.PARTIALLY_BLOCKED)
|
|
@@ -153,7 +153,8 @@ class DataFile:
|
|
|
153
153
|
if feature_flag is None:
|
|
154
154
|
raise FeatureNotFound(feature_key)
|
|
155
155
|
if not feature_flag.environment_enabled:
|
|
156
|
-
|
|
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.3 → kameleoon_client_python-3.17.1}/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."""
|
|
@@ -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.3 → kameleoon_client_python-3.17.1}/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,8 +751,17 @@ class KameleoonClient:
|
|
|
731
751
|
in_holdout_variation_key = "in-holdout"
|
|
732
752
|
KameleoonLogger.debug(
|
|
733
753
|
"CALL: KameleoonClient.__is_visitor_not_in_holdout(visitor, visitor_code: %s, track: %s, save: %s, "
|
|
734
|
-
"bucketing_cd_index: %s)",
|
|
754
|
+
"bucketing_cd_index: %s)",
|
|
755
|
+
visitor_code,
|
|
756
|
+
track,
|
|
757
|
+
save,
|
|
758
|
+
bucketing_cd_index,
|
|
735
759
|
)
|
|
760
|
+
consent, blocking_behaviour = self.__get_consent_and_blocking_behaviour(visitor)
|
|
761
|
+
if consent == LegalConsent.NOT_GIVEN and blocking_behaviour == ConsentBlockingBehaviour.COMPLETELY_BLOCKED:
|
|
762
|
+
raise FeatureEnvironmentDisabled(
|
|
763
|
+
"Evaluation for a holdout is blocked because visitor's consent was not provided."
|
|
764
|
+
)
|
|
736
765
|
is_not_in_holdout = True
|
|
737
766
|
code_for_hash = self.__get_code_for_hash(visitor, visitor_code, bucketing_cd_index)
|
|
738
767
|
variation_hash = Hasher.obtain(code_for_hash, holdout.id_)
|
|
@@ -746,7 +775,11 @@ class KameleoonClient:
|
|
|
746
775
|
KameleoonLogger.debug(
|
|
747
776
|
"RETURN: KameleoonClient.__is_visitor_not_in_holdout(visitor, visitor_code: %s, track: %s, save: %s, "
|
|
748
777
|
"bucketing_cd_index: %s) -> (is_not_in_holdout: %s)",
|
|
749
|
-
visitor_code,
|
|
778
|
+
visitor_code,
|
|
779
|
+
track,
|
|
780
|
+
save,
|
|
781
|
+
bucketing_cd_index,
|
|
782
|
+
is_not_in_holdout,
|
|
750
783
|
)
|
|
751
784
|
return is_not_in_holdout
|
|
752
785
|
|
|
@@ -1163,7 +1196,10 @@ class KameleoonClient:
|
|
|
1163
1196
|
def filter_conditions(feature_flag: FeatureFlag) -> bool:
|
|
1164
1197
|
if not feature_flag.environment_enabled:
|
|
1165
1198
|
return False
|
|
1166
|
-
|
|
1199
|
+
try:
|
|
1200
|
+
eval_exp = self.__evaluate(visitor, visitor_code, feature_flag, False, False)
|
|
1201
|
+
except FeatureEnvironmentDisabled:
|
|
1202
|
+
return False
|
|
1167
1203
|
variation_key = self.__calculate_variation_key(eval_exp, feature_flag.default_variation_key)
|
|
1168
1204
|
return variation_key != configuration.Variation.Type.OFF.value
|
|
1169
1205
|
|
|
@@ -1211,7 +1247,10 @@ class KameleoonClient:
|
|
|
1211
1247
|
for feature_flag in self._data_manager.data_file.feature_flags.values():
|
|
1212
1248
|
if not feature_flag.environment_enabled:
|
|
1213
1249
|
continue
|
|
1214
|
-
|
|
1250
|
+
try:
|
|
1251
|
+
eval_exp = self.__evaluate(visitor, visitor_code, feature_flag, False, False)
|
|
1252
|
+
except FeatureEnvironmentDisabled:
|
|
1253
|
+
continue
|
|
1215
1254
|
variation_key = self.__calculate_variation_key(eval_exp, feature_flag.default_variation_key)
|
|
1216
1255
|
if variation_key == configuration.Variation.Type.OFF.value:
|
|
1217
1256
|
continue
|
|
@@ -1437,7 +1476,7 @@ class KameleoonClient:
|
|
|
1437
1476
|
data_file = DataFile.from_json(
|
|
1438
1477
|
self._config.environment,
|
|
1439
1478
|
fetched_configuration.last_modified,
|
|
1440
|
-
fetched_configuration.configuration
|
|
1479
|
+
fetched_configuration.configuration,
|
|
1441
1480
|
)
|
|
1442
1481
|
self._data_manager.data_file = data_file
|
|
1443
1482
|
self._network_manager.url_provider.apply_data_api_domain(data_file.settings.data_api_domain)
|
|
@@ -1547,7 +1586,8 @@ class KameleoonClient:
|
|
|
1547
1586
|
fetched_configuration = await service.fetch_configuration(self._config.environment, time_stamp, last_modified)
|
|
1548
1587
|
KameleoonLogger.debug(
|
|
1549
1588
|
"RETURN: KameleoonClient._obtain_configuration(time_stamp: %s) -> (fetched_configuration: %s)",
|
|
1550
|
-
time_stamp,
|
|
1589
|
+
time_stamp,
|
|
1590
|
+
fetched_configuration,
|
|
1551
1591
|
)
|
|
1552
1592
|
return fetched_configuration
|
|
1553
1593
|
|
|
@@ -1615,7 +1655,9 @@ class KameleoonClient:
|
|
|
1615
1655
|
return None
|
|
1616
1656
|
KameleoonLogger.debug(
|
|
1617
1657
|
"CALL: KameleoonClient.__evaluate_cbscores(visitor, visitor_code: %s, rule: %s, bucketing_cd_index: %s)",
|
|
1618
|
-
visitor_code,
|
|
1658
|
+
visitor_code,
|
|
1659
|
+
rule,
|
|
1660
|
+
bucketing_cd_index,
|
|
1619
1661
|
)
|
|
1620
1662
|
eval_exp = None
|
|
1621
1663
|
var_id_group_by_scores = visitor.cbscores.values.get(rule.experiment.id_)
|
|
@@ -1640,11 +1682,15 @@ class KameleoonClient:
|
|
|
1640
1682
|
eval_exp = EvaluatedExperiment.from_var_by_exp_rule(var_by_exp_in_cbs[idx], rule)
|
|
1641
1683
|
KameleoonLogger.debug(
|
|
1642
1684
|
"RETURN: KameleoonClient.__evaluate_cbscores(visitor, visitor_code: %s, rule: %s, bucketing_cd_index: %s)"
|
|
1643
|
-
" -> (eval_exp: %s)",
|
|
1685
|
+
" -> (eval_exp: %s)",
|
|
1686
|
+
visitor_code,
|
|
1687
|
+
rule,
|
|
1688
|
+
bucketing_cd_index,
|
|
1689
|
+
eval_exp,
|
|
1644
1690
|
)
|
|
1645
1691
|
return eval_exp
|
|
1646
1692
|
|
|
1647
|
-
def __calculate_variation_rule_for_feature(
|
|
1693
|
+
def __calculate_variation_rule_for_feature( # noqa: C901, pylint: disable=R0912
|
|
1648
1694
|
self, visitor_code: str, feature_flag: FeatureFlag
|
|
1649
1695
|
) -> Optional[EvaluatedExperiment]:
|
|
1650
1696
|
"""helper method for calculate variation key for feature flag"""
|
|
@@ -1654,6 +1700,7 @@ class KameleoonClient:
|
|
|
1654
1700
|
feature_flag,
|
|
1655
1701
|
)
|
|
1656
1702
|
visitor = self._visitor_manager.get_visitor(visitor_code)
|
|
1703
|
+
consent, blocking_behaviour = self.__get_consent_and_blocking_behaviour(visitor)
|
|
1657
1704
|
code_for_hash = self.__get_code_for_hash(visitor, visitor_code, feature_flag.bucketing_custom_data_index)
|
|
1658
1705
|
eval_exp = None
|
|
1659
1706
|
for rule in feature_flag.rules:
|
|
@@ -1669,11 +1716,19 @@ class KameleoonClient:
|
|
|
1669
1716
|
# Forcing experiment variation in targeting-only mode
|
|
1670
1717
|
eval_exp = EvaluatedExperiment.from_var_by_exp_rule(forced_variation.var_by_exp, rule)
|
|
1671
1718
|
break
|
|
1672
|
-
#
|
|
1719
|
+
# used for rule exposition
|
|
1673
1720
|
hash_rule = Hasher.obtain(code_for_hash, rule.id_, rule.respool_time)
|
|
1674
1721
|
KameleoonLogger.debug("Calculated rule hash %s for code %s", hash_rule, code_for_hash)
|
|
1675
1722
|
# check main expostion for rule with hashRule
|
|
1676
1723
|
if hash_rule <= rule.exposition:
|
|
1724
|
+
# Checking if the evaluation is blocked due to the consent policy
|
|
1725
|
+
if (consent == LegalConsent.NOT_GIVEN) and rule.is_experimentation:
|
|
1726
|
+
if blocking_behaviour == ConsentBlockingBehaviour.PARTIALLY_BLOCKED:
|
|
1727
|
+
break
|
|
1728
|
+
raise FeatureEnvironmentDisabled(
|
|
1729
|
+
f"Evaluation of {rule} is blocked because consent is not provided for visitor '{visitor_code}'"
|
|
1730
|
+
)
|
|
1731
|
+
# Checking cbs
|
|
1677
1732
|
eval_exp = self.__evaluate_cbscores(
|
|
1678
1733
|
visitor, visitor_code, rule, feature_flag.bucketing_custom_data_index
|
|
1679
1734
|
)
|
|
@@ -1683,8 +1738,7 @@ class KameleoonClient:
|
|
|
1683
1738
|
if rule.experiment.first_variation:
|
|
1684
1739
|
eval_exp = EvaluatedExperiment.from_var_by_exp_rule(rule.experiment.first_variation, rule)
|
|
1685
1740
|
break
|
|
1686
|
-
|
|
1687
|
-
# uses for variation's expositions
|
|
1741
|
+
# used for variation's expositions
|
|
1688
1742
|
hash_variation = Hasher.obtain(code_for_hash, rule.experiment.id_, rule.respool_time)
|
|
1689
1743
|
KameleoonLogger.debug("Calculated variation hash %s for code %s", hash_variation, code_for_hash)
|
|
1690
1744
|
# get variation with hash_variation
|
|
@@ -1703,6 +1757,19 @@ class KameleoonClient:
|
|
|
1703
1757
|
)
|
|
1704
1758
|
return eval_exp
|
|
1705
1759
|
|
|
1760
|
+
def __get_consent_and_blocking_behaviour(
|
|
1761
|
+
self,
|
|
1762
|
+
visitor: Optional[Visitor],
|
|
1763
|
+
) -> Tuple[LegalConsent, ConsentBlockingBehaviour]:
|
|
1764
|
+
datafile = self._data_manager.data_file
|
|
1765
|
+
if datafile.settings.is_consent_required:
|
|
1766
|
+
consent = visitor.legal_consent if visitor else LegalConsent.UNKNOWN
|
|
1767
|
+
else:
|
|
1768
|
+
consent = LegalConsent.GIVEN
|
|
1769
|
+
behaviour = datafile.settings.blocking_behaviour_if_consent_not_given
|
|
1770
|
+
|
|
1771
|
+
return consent, behaviour
|
|
1772
|
+
|
|
1706
1773
|
@staticmethod
|
|
1707
1774
|
def __calculate_variation_key(eval_exp: Optional[EvaluatedExperiment], default_value: str) -> str:
|
|
1708
1775
|
KameleoonLogger.debug(
|
|
@@ -1727,7 +1794,7 @@ class KameleoonClient:
|
|
|
1727
1794
|
return (
|
|
1728
1795
|
not self._data_manager.data_file.settings.is_consent_required
|
|
1729
1796
|
or ((visitor := self._visitor_manager.get_visitor(visitor_code)) is not None)
|
|
1730
|
-
and visitor.legal_consent
|
|
1797
|
+
and (visitor.legal_consent == LegalConsent.GIVEN)
|
|
1731
1798
|
)
|
|
1732
1799
|
|
|
1733
1800
|
def set_forced_variation(
|
|
@@ -50,15 +50,15 @@ class RemoteVisitorData:
|
|
|
50
50
|
self.__visitor_code: Optional[str] = None
|
|
51
51
|
current_visit = json.get("currentVisit")
|
|
52
52
|
if current_visit is not None:
|
|
53
|
-
self.__parse_visit(current_visit,
|
|
53
|
+
self.__parse_visit(current_visit, 0)
|
|
54
54
|
previous_visits = json.get("previousVisits")
|
|
55
55
|
if previous_visits:
|
|
56
56
|
prev_visits = []
|
|
57
|
-
for visit in previous_visits:
|
|
57
|
+
for i, visit in enumerate(previous_visits):
|
|
58
58
|
time_started = visit.get("timeStarted", 0)
|
|
59
59
|
time_last_event = visit.get("timeLastEvent", time_started)
|
|
60
60
|
prev_visits.append(VisitorVisits.Visit(time_started, time_last_event))
|
|
61
|
-
self.__parse_visit(visit,
|
|
61
|
+
self.__parse_visit(visit, i + 1)
|
|
62
62
|
if len(prev_visits) > 0:
|
|
63
63
|
self.__visitor_visits = VisitorVisits(prev_visits, self.__visit_number)
|
|
64
64
|
self.__kcs_heat = self.__parse_kcs_heat(json.get("kcs"))
|
|
@@ -123,7 +123,7 @@ class RemoteVisitorData:
|
|
|
123
123
|
"""Returns the `visitorCode` from the most recent visit"""
|
|
124
124
|
return self.__visitor_code
|
|
125
125
|
|
|
126
|
-
def __parse_visit(self, json_visit: Dict[str, Any],
|
|
126
|
+
def __parse_visit(self, json_visit: Dict[str, Any], visit_offset: int) -> None:
|
|
127
127
|
if (self.__visitor_code is None) and isinstance(visitor_code := json_visit.get("visitorCode"), str):
|
|
128
128
|
self.__visitor_code = visitor_code
|
|
129
129
|
custom_data_events = json_visit.get("customDataEvents")
|
|
@@ -143,7 +143,7 @@ class RemoteVisitorData:
|
|
|
143
143
|
self.__parse_geolocation(geolocation_events[-1])
|
|
144
144
|
static_data_event = json_visit.get("staticDataEvent")
|
|
145
145
|
if static_data_event:
|
|
146
|
-
self.__parse_static_data(static_data_event,
|
|
146
|
+
self.__parse_static_data(static_data_event, visit_offset)
|
|
147
147
|
personalization_events = json_visit.get("personalizationEvents")
|
|
148
148
|
if personalization_events:
|
|
149
149
|
self.__parse_personalizations(personalization_events)
|
|
@@ -209,15 +209,13 @@ class RemoteVisitorData:
|
|
|
209
209
|
if country is not None:
|
|
210
210
|
self.__geolocation = Geolocation(country, data.get("region"), data.get("city"))
|
|
211
211
|
|
|
212
|
-
def __parse_static_data(self, static_data_event: Dict[str, Any],
|
|
212
|
+
def __parse_static_data(self, static_data_event: Dict[str, Any], visit_offset: int) -> None:
|
|
213
213
|
if self.__device and self.__browser and self.__operating_system:
|
|
214
214
|
return
|
|
215
215
|
data = static_data_event.get("data")
|
|
216
216
|
if data is not None:
|
|
217
|
-
if self.__visit_number == 0:
|
|
218
|
-
self.__visit_number =
|
|
219
|
-
if is_prev_visit and (self.__visit_number > 0):
|
|
220
|
-
self.__visit_number += 1
|
|
217
|
+
if (self.__visit_number == 0) and (remote_visit_number := data.get("visitNumber")):
|
|
218
|
+
self.__visit_number = remote_visit_number + visit_offset
|
|
221
219
|
if self.__filter.device and (self.__device is None):
|
|
222
220
|
device_type = enum_from_name_literal(data.get("deviceType"), DeviceType, None)
|
|
223
221
|
if device_type is not None:
|
|
@@ -3,6 +3,7 @@ from typing import Iterable, List, Optional, Tuple
|
|
|
3
3
|
from kameleoon.configuration.data_file import DataFile
|
|
4
4
|
from kameleoon.configuration.rule_type import RuleType
|
|
5
5
|
from kameleoon.data.custom_data import CustomData
|
|
6
|
+
from kameleoon.data.manager.legal_consent import LegalConsent
|
|
6
7
|
from kameleoon.data.manager.visitor import Visitor
|
|
7
8
|
from kameleoon.data.manager.visitor_manager import VisitorManager
|
|
8
9
|
from kameleoon.logging.kameleoon_logger import KameleoonLogger
|
|
@@ -86,7 +87,9 @@ class TrackingBuilder:
|
|
|
86
87
|
visitor_code, is_consent_given)
|
|
87
88
|
|
|
88
89
|
def __is_consent_given(self, visitor: Optional[Visitor]) -> bool:
|
|
89
|
-
return not self.__data_file.settings.is_consent_required or (
|
|
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:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kameleoon-client-python
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.17.1
|
|
4
4
|
Summary: Kameleoon Client Python Software Development Kit.
|
|
5
5
|
Home-page: https://developers.kameleoon.com/python-sdk.html
|
|
6
6
|
Author: Kameleoon
|
|
@@ -20,27 +20,27 @@ Requires-Dist: requests<3.0.0,>=2.25
|
|
|
20
20
|
Requires-Dist: sseclient-py<1.9.0,>=1.7.0
|
|
21
21
|
Requires-Dist: aiohttp<4.0.0,>=3.8.0
|
|
22
22
|
Provides-Extra: test
|
|
23
|
-
Requires-Dist:
|
|
23
|
+
Requires-Dist: flake8==4.0.1; extra == "test"
|
|
24
|
+
Requires-Dist: freezegun==1.1.0; extra == "test"
|
|
25
|
+
Requires-Dist: types-requests==2.25.0; extra == "test"
|
|
26
|
+
Requires-Dist: pytest-asyncio==0.21.*; extra == "test"
|
|
24
27
|
Requires-Dist: types-python-dateutil==2.8.2; extra == "test"
|
|
28
|
+
Requires-Dist: pytest-pythonpath==0.7.3; extra == "test"
|
|
29
|
+
Requires-Dist: aioresponses==0.7.*; extra == "test"
|
|
30
|
+
Requires-Dist: wheel==0.36.2; extra == "test"
|
|
31
|
+
Requires-Dist: requests<3.0.0,>=2.25; extra == "test"
|
|
32
|
+
Requires-Dist: twine==3.4.1; extra == "test"
|
|
33
|
+
Requires-Dist: pytest-django==4.4.0; extra == "test"
|
|
25
34
|
Requires-Dist: types-PyYAML==5.4.3; extra == "test"
|
|
35
|
+
Requires-Dist: pyyaml<6.1.0,>=5.4.0; extra == "test"
|
|
36
|
+
Requires-Dist: pytest-cov==2.12.1; extra == "test"
|
|
26
37
|
Requires-Dist: pytest-ordering==0.6; extra == "test"
|
|
27
|
-
Requires-Dist: pylint==2.12.*; extra == "test"
|
|
28
38
|
Requires-Dist: sseclient-py<1.9.0,>=1.7.0; extra == "test"
|
|
29
39
|
Requires-Dist: Werkzeug==2.0.1; extra == "test"
|
|
40
|
+
Requires-Dist: pylint==2.12.*; extra == "test"
|
|
30
41
|
Requires-Dist: Django==3.2.4; extra == "test"
|
|
31
|
-
Requires-Dist: types-requests==2.25.0; extra == "test"
|
|
32
|
-
Requires-Dist: pytest-cov==2.12.1; extra == "test"
|
|
33
|
-
Requires-Dist: aioresponses==0.7.*; extra == "test"
|
|
34
|
-
Requires-Dist: pytest-asyncio==0.21.*; extra == "test"
|
|
35
|
-
Requires-Dist: twine==3.4.1; extra == "test"
|
|
36
|
-
Requires-Dist: aiohttp<4.0.0,>=3.8.0; extra == "test"
|
|
37
|
-
Requires-Dist: requests<3.0.0,>=2.25; extra == "test"
|
|
38
|
-
Requires-Dist: flake8==4.0.1; extra == "test"
|
|
39
|
-
Requires-Dist: pytest-pythonpath==0.7.3; extra == "test"
|
|
40
42
|
Requires-Dist: mypy==0.991; extra == "test"
|
|
41
|
-
Requires-Dist:
|
|
42
|
-
Requires-Dist: freezegun==1.1.0; extra == "test"
|
|
43
|
-
Requires-Dist: pyyaml<6.1.0,>=5.4.0; extra == "test"
|
|
43
|
+
Requires-Dist: aiohttp<4.0.0,>=3.8.0; extra == "test"
|
|
44
44
|
Dynamic: author
|
|
45
45
|
Dynamic: author-email
|
|
46
46
|
Dynamic: classifier
|
|
@@ -14,6 +14,7 @@ kameleoon/client_readiness/__init__.py
|
|
|
14
14
|
kameleoon/client_readiness/async_readiness.py
|
|
15
15
|
kameleoon/client_readiness/threading_readiness.py
|
|
16
16
|
kameleoon/configuration/__init__.py
|
|
17
|
+
kameleoon/configuration/consent_blocking_behaviour.py
|
|
17
18
|
kameleoon/configuration/custom_data_info.py
|
|
18
19
|
kameleoon/configuration/data_file.py
|
|
19
20
|
kameleoon/configuration/experiment.py
|
|
@@ -48,6 +49,7 @@ kameleoon/data/manager/assigned_variation.py
|
|
|
48
49
|
kameleoon/data/manager/forced_experiment_variation.py
|
|
49
50
|
kameleoon/data/manager/forced_feature_variation.py
|
|
50
51
|
kameleoon/data/manager/forced_variation.py
|
|
52
|
+
kameleoon/data/manager/legal_consent.py
|
|
51
53
|
kameleoon/data/manager/page_view_visit.py
|
|
52
54
|
kameleoon/data/manager/visitor.py
|
|
53
55
|
kameleoon/data/manager/visitor_manager.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|