kameleoon-client-python 3.17.1__tar.gz → 3.18.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.17.1 → kameleoon_client_python-3.18.0}/PKG-INFO +13 -13
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/__init__.py +2 -0
- kameleoon_client_python-3.18.0/kameleoon/data/application_version.py +39 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/data.py +1 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/manager/visitor.py +20 -3
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/manager/visitor_manager.py +24 -14
- kameleoon_client_python-3.18.0/kameleoon/helpers/sem_version.py +60 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/kameleoon_client.py +17 -11
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/kameleoon_client_config.py +2 -2
- kameleoon_client_python-3.18.0/kameleoon/sdk_version.py +12 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/browser_condition.py +4 -2
- kameleoon_client_python-3.18.0/kameleoon/targeting/conditions/sdk_language_condition.py +38 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/targeting_condition.py +1 -0
- kameleoon_client_python-3.18.0/kameleoon/targeting/conditions/version_condition.py +61 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/targeting_manager.py +3 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/tree_condition_factory.py +4 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon_client_python.egg-info/PKG-INFO +13 -13
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon_client_python.egg-info/SOURCES.txt +3 -0
- kameleoon_client_python-3.17.1/kameleoon/sdk_version.py +0 -40
- kameleoon_client_python-3.17.1/kameleoon/targeting/conditions/sdk_language_condition.py +0 -79
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/MANIFEST.in +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/README.md +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/client_readiness/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/client_readiness/async_readiness.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/client_readiness/threading_readiness.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/configuration/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/configuration/consent_blocking_behaviour.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/configuration/custom_data_info.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/configuration/data_file.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/configuration/experiment.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/configuration/feature_flag.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/configuration/me_group.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/configuration/rule.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/configuration/rule_type.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/configuration/settings.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/configuration/variable.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/configuration/variation.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/configuration/variation_by_exposition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/browser.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/cbscores.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/conversion.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/cookie.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/custom_data.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/device.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/geolocation.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/kcs_heat.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/manager/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/manager/assigned_variation.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/manager/forced_experiment_variation.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/manager/forced_feature_variation.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/manager/forced_variation.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/manager/legal_consent.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/manager/page_view_visit.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/manager/visitor_slot.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/mapping_identifier.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/operating_system.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/page_view.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/personalization.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/targeted_segment.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/unique_identifier.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/user_agent.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/visitor_visits.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/defaults.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/exceptions.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/helpers/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/helpers/domain.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/helpers/functions.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/helpers/hasher.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/helpers/logger.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/helpers/multi_threading.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/helpers/nonce.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/helpers/repeat_timer.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/helpers/scheduler.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/helpers/string_utils.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/helpers/visitor_code.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/hybrid/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/hybrid/hybrid_manager.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/hybrid/hybrid_manager_impl.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/kameleoon_client_factory.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/logging/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/logging/kameleoon_logger.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/logging/log_level.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/logging/logger.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/managers/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/managers/asyncexec/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/managers/asyncexec/async_executor.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/managers/data/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/managers/data/data_manager.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/managers/evaluation/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/managers/evaluation/evaluated_experiment.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/managers/remote_data/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/managers/remote_data/remote_data_manager.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/managers/remote_data/remote_visitor_data.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/managers/tracking/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/managers/tracking/tracking_builder.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/managers/tracking/tracking_manager.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/managers/tracking/visitor_tracking_registry.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/managers/warehouse/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/managers/warehouse/warehouse_manager.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/middleware.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/access_token_source.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/access_token_source_factory.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/activity_event.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/cookie/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/cookie/cookie_manager.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/net_provider.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/net_provider_impl.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/network_manager.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/network_manager_factory.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/network_manager_factory_impl.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/network_manager_impl.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/query_builder.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/query_encodable.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/sendable.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/service_initialize_context.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/service_initialize_context_impl.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/services/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/services/automation_service.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/services/automation_service_impl.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/services/configuration_service.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/services/configuration_service_impl.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/services/data_service.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/services/data_service_impl.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/services/service.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/services/service_impl.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/uri_helper.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/network/url_provider.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/real_time/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/real_time/real_time_configuration_service.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/real_time/real_time_event.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/storage/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/storage/cache.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/storage/cache_factory.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/storage/cache_factory_impl.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/storage/cache_impl.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/constants.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/conversion_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/cookie_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/custom_datum.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/device_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/exclusive_experiment_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/geolocation_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/kcs_heat_range_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/number_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/operating_system_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/page_title_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/page_url_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/page_view_number_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/previous_page_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/segment_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/string_value_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/target_experiment_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/target_feature_flag_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/target_personalization_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/time_elapsed_since_visit_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/unknown_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/visit_number_today_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/visit_number_total_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/visitor_code_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/conditions/visitor_new_return_condition.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/models.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/targeting/tree_builder.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/types/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/types/remote_visitor_data_filter.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/types/variable.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/types/variation.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon_client_python.egg-info/dependency_links.txt +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon_client_python.egg-info/requires.txt +12 -12
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon_client_python.egg-info/top_level.txt +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/setup.cfg +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/setup.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/tests/integration/proj/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/tests/integration/proj/kameleoon_app/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/tests/integration/proj/kameleoon_app/admin.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/tests/integration/proj/kameleoon_app/apps.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/tests/integration/proj/kameleoon_app/migrations/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/tests/integration/proj/kameleoon_app/models.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/tests/integration/proj/kameleoon_app/tests.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/tests/integration/proj/kameleoon_app/views.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/tests/integration/proj/manage.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/tests/integration/proj/proj/__init__.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/tests/integration/proj/proj/asgi.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/tests/integration/proj/proj/settings.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/tests/integration/proj/proj/urls.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/tests/integration/proj/proj/wsgi.py +0 -0
- {kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.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.18.0
|
|
4
4
|
Summary: Kameleoon Client Python Software Development Kit.
|
|
5
5
|
Home-page: https://developers.kameleoon.com/python-sdk.html
|
|
6
6
|
Author: Kameleoon
|
|
@@ -20,27 +20,27 @@ Requires-Dist: requests<3.0.0,>=2.25
|
|
|
20
20
|
Requires-Dist: sseclient-py<1.9.0,>=1.7.0
|
|
21
21
|
Requires-Dist: aiohttp<4.0.0,>=3.8.0
|
|
22
22
|
Provides-Extra: test
|
|
23
|
+
Requires-Dist: mypy==0.991; extra == "test"
|
|
23
24
|
Requires-Dist: flake8==4.0.1; extra == "test"
|
|
24
|
-
Requires-Dist: freezegun==1.1.0; extra == "test"
|
|
25
25
|
Requires-Dist: types-requests==2.25.0; extra == "test"
|
|
26
|
-
Requires-Dist: pytest-asyncio==0.21.*; extra == "test"
|
|
27
|
-
Requires-Dist: types-python-dateutil==2.8.2; extra == "test"
|
|
28
26
|
Requires-Dist: pytest-pythonpath==0.7.3; extra == "test"
|
|
29
27
|
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
28
|
Requires-Dist: twine==3.4.1; extra == "test"
|
|
33
29
|
Requires-Dist: pytest-django==4.4.0; extra == "test"
|
|
34
|
-
Requires-Dist:
|
|
35
|
-
Requires-Dist: pyyaml<6.1.0,>=5.4.0; extra == "test"
|
|
30
|
+
Requires-Dist: Django==3.2.4; extra == "test"
|
|
36
31
|
Requires-Dist: pytest-cov==2.12.1; extra == "test"
|
|
37
|
-
Requires-Dist:
|
|
38
|
-
Requires-Dist: sseclient-py<1.9.0,>=1.7.0; extra == "test"
|
|
39
|
-
Requires-Dist: Werkzeug==2.0.1; extra == "test"
|
|
32
|
+
Requires-Dist: types-python-dateutil==2.8.2; extra == "test"
|
|
40
33
|
Requires-Dist: pylint==2.12.*; extra == "test"
|
|
41
|
-
Requires-Dist: Django==3.2.4; extra == "test"
|
|
42
|
-
Requires-Dist: mypy==0.991; extra == "test"
|
|
43
34
|
Requires-Dist: aiohttp<4.0.0,>=3.8.0; extra == "test"
|
|
35
|
+
Requires-Dist: Werkzeug==2.0.1; extra == "test"
|
|
36
|
+
Requires-Dist: pytest-asyncio==0.21.*; extra == "test"
|
|
37
|
+
Requires-Dist: sseclient-py<1.9.0,>=1.7.0; extra == "test"
|
|
38
|
+
Requires-Dist: wheel==0.36.2; extra == "test"
|
|
39
|
+
Requires-Dist: types-PyYAML==5.4.3; extra == "test"
|
|
40
|
+
Requires-Dist: pyyaml<6.1.0,>=5.4.0; extra == "test"
|
|
41
|
+
Requires-Dist: pytest-ordering==0.6; extra == "test"
|
|
42
|
+
Requires-Dist: freezegun==1.1.0; extra == "test"
|
|
43
|
+
Requires-Dist: requests<3.0.0,>=2.25; extra == "test"
|
|
44
44
|
Dynamic: author
|
|
45
45
|
Dynamic: author-email
|
|
46
46
|
Dynamic: classifier
|
{kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/__init__.py
RENAMED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
""" Imports all kameleoon data objects """
|
|
2
2
|
|
|
3
|
+
from .application_version import ApplicationVersion
|
|
3
4
|
from .browser import Browser, BrowserType
|
|
4
5
|
from .conversion import Conversion
|
|
5
6
|
from .cookie import Cookie
|
|
@@ -13,6 +14,7 @@ from .user_agent import UserAgent
|
|
|
13
14
|
from .unique_identifier import UniqueIdentifier
|
|
14
15
|
|
|
15
16
|
__all__ = [
|
|
17
|
+
"ApplicationVersion",
|
|
16
18
|
"Browser",
|
|
17
19
|
"BrowserType",
|
|
18
20
|
"Conversion",
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Application version data"""
|
|
2
|
+
|
|
3
|
+
from kameleoon.data.data import Data, DataType
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ApplicationVersion(Data):
|
|
7
|
+
"""Application version data for targeting by application version.
|
|
8
|
+
|
|
9
|
+
The ApplicationVersion class represents the version of a user's application
|
|
10
|
+
and is used for targeting users based on semantic versioning (major, major.minor,
|
|
11
|
+
or major.minor.patch).
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def __init__(self, version: str) -> None:
|
|
15
|
+
"""
|
|
16
|
+
Creates a new ApplicationVersion.
|
|
17
|
+
|
|
18
|
+
:param version: The application version string (semantic versioning: major, major.minor, or
|
|
19
|
+
major.minor.patch). Examples: "1", "1.2", "1.2.3"
|
|
20
|
+
|
|
21
|
+
Example:
|
|
22
|
+
|
|
23
|
+
.. code-block:: python3
|
|
24
|
+
|
|
25
|
+
kameleoon_client.add_data(visitor_code, ApplicationVersion("1.2.3"))
|
|
26
|
+
"""
|
|
27
|
+
self.__version = version
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
def version(self) -> str:
|
|
31
|
+
"""Returns the application version string."""
|
|
32
|
+
return self.__version
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def data_type(self) -> DataType:
|
|
36
|
+
return DataType.APPLICATION_VERSION
|
|
37
|
+
|
|
38
|
+
def __str__(self):
|
|
39
|
+
return f"ApplicationVersion{{version:{self.__version}}}"
|
{kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/data/manager/visitor.py
RENAMED
|
@@ -6,6 +6,7 @@ from typing import Any, Callable, Optional, Dict, List, Iterator, Iterable, cast
|
|
|
6
6
|
|
|
7
7
|
from kameleoon.data.visitor_visits import VisitorVisits
|
|
8
8
|
from kameleoon.data.data import Data
|
|
9
|
+
from kameleoon.data.application_version import ApplicationVersion
|
|
9
10
|
from kameleoon.data.browser import Browser
|
|
10
11
|
from kameleoon.data.cbscores import CBScores
|
|
11
12
|
from kameleoon.data.conversion import Conversion
|
|
@@ -102,6 +103,14 @@ class Visitor: # pylint: disable=R0904
|
|
|
102
103
|
KameleoonLogger.debug('CALL/RETURN: Visitor.operating_system -> (operating_system: %s)', operating_system)
|
|
103
104
|
return operating_system
|
|
104
105
|
|
|
106
|
+
@property
|
|
107
|
+
def application_version(self) -> Optional[ApplicationVersion]:
|
|
108
|
+
"""Returns the application version information associated with this Visitor."""
|
|
109
|
+
application_version = self._data.application_version
|
|
110
|
+
KameleoonLogger.debug('CALL/RETURN: Visitor.application_version -> (application_version: %s)',
|
|
111
|
+
application_version)
|
|
112
|
+
return application_version
|
|
113
|
+
|
|
105
114
|
@property
|
|
106
115
|
def cookie(self) -> Optional[Cookie]:
|
|
107
116
|
"""Returns the cookie information associated with this Visitor."""
|
|
@@ -223,20 +232,22 @@ class Visitor: # pylint: disable=R0904
|
|
|
223
232
|
self._data.variations[variation.experiment_id] = variation
|
|
224
233
|
KameleoonLogger.debug('RETURN: Visitor.assign_variation(variation: %s)', variation)
|
|
225
234
|
|
|
226
|
-
def add_data(self, *args, overwrite: bool = True) -> None:
|
|
235
|
+
def add_data(self, *args, overwrite: bool = True, track: bool = True) -> None:
|
|
227
236
|
"""Adds data to the Visitor."""
|
|
228
|
-
KameleoonLogger.debug('CALL: Visitor.add_data(args: %s, overwrite: %s)', args, overwrite)
|
|
237
|
+
KameleoonLogger.debug('CALL: Visitor.add_data(args: %s, overwrite: %s, track: %s)', args, overwrite, track)
|
|
229
238
|
with self._data.lock:
|
|
230
239
|
for data in args:
|
|
231
240
|
if data is None:
|
|
232
241
|
continue
|
|
242
|
+
if not track and isinstance(data, Sendable):
|
|
243
|
+
data.mark_as_sent()
|
|
233
244
|
data_type = type(data)
|
|
234
245
|
data_adder = self.DATA_ADDERS.get(data_type)
|
|
235
246
|
if data_adder:
|
|
236
247
|
data_adder(self, self.DataAddingContext(data, overwrite))
|
|
237
248
|
else:
|
|
238
249
|
KameleoonLogger.warning("Data has unsupported type %s", data_type)
|
|
239
|
-
KameleoonLogger.debug('RETURN: Visitor.add_data(args: %s, overwrite: %s)', args, overwrite)
|
|
250
|
+
KameleoonLogger.debug('RETURN: Visitor.add_data(args: %s, overwrite: %s, track: %s)', args, overwrite, track)
|
|
240
251
|
|
|
241
252
|
@property
|
|
242
253
|
def mapping_identifier(self) -> Optional[str]:
|
|
@@ -302,6 +313,7 @@ class Visitor: # pylint: disable=R0904
|
|
|
302
313
|
self.visitor_visits: Optional[VisitorVisits] = None
|
|
303
314
|
self.mapping_identifier: Optional[str] = None
|
|
304
315
|
self.legal_consent = LegalConsent.UNKNOWN
|
|
316
|
+
self.application_version: Optional[ApplicationVersion] = None
|
|
305
317
|
|
|
306
318
|
def enumerate_sendable_data(self) -> Iterator[Sendable]:
|
|
307
319
|
"""Iterates over all sendable data associated with the visitor."""
|
|
@@ -420,6 +432,10 @@ class Visitor: # pylint: disable=R0904
|
|
|
420
432
|
if context.overwrite or self._data.operating_system is None:
|
|
421
433
|
self._data.operating_system = cast(OperatingSystem, context.data)
|
|
422
434
|
|
|
435
|
+
def _set_application_version(self, context: DataAddingContext) -> None:
|
|
436
|
+
if context.overwrite or self._data.application_version is None:
|
|
437
|
+
self._data.application_version = cast(ApplicationVersion, context.data)
|
|
438
|
+
|
|
423
439
|
def _set_cookie(self, context: DataAddingContext) -> None:
|
|
424
440
|
self._data.cookie = cast(Cookie, context.data)
|
|
425
441
|
|
|
@@ -482,6 +498,7 @@ class Visitor: # pylint: disable=R0904
|
|
|
482
498
|
Browser: _set_browser,
|
|
483
499
|
Geolocation: _set_geolocation,
|
|
484
500
|
OperatingSystem: _set_operating_system,
|
|
501
|
+
ApplicationVersion: _set_application_version,
|
|
485
502
|
Cookie: _set_cookie,
|
|
486
503
|
CustomData: _add_custom_data,
|
|
487
504
|
MappingIdentifier: _add_custom_data,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Visitor Manager"""
|
|
2
|
+
|
|
2
3
|
import collections
|
|
3
4
|
import time
|
|
4
5
|
from typing import Any, Dict, Iterator, List, Optional
|
|
@@ -14,17 +15,16 @@ from kameleoon.managers.data.data_manager import DataManager
|
|
|
14
15
|
|
|
15
16
|
class VisitorManager:
|
|
16
17
|
"""Visitor manager"""
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
KameleoonLogger.debug("CALL: VisitorManager(data_manager, expiration_period: %s, scheduler)",
|
|
21
|
-
expiration_period)
|
|
18
|
+
|
|
19
|
+
def __init__(self, data_manager: DataManager, expiration_period: float, scheduler: Scheduler) -> None:
|
|
20
|
+
KameleoonLogger.debug("CALL: VisitorManager(data_manager, expiration_period: %s, scheduler)", expiration_period)
|
|
22
21
|
self._data_manager = data_manager
|
|
23
22
|
self.__expiration_period = expiration_period
|
|
24
23
|
self._slots: Dict[str, VisitorSlot] = collections.defaultdict(VisitorSlot)
|
|
25
24
|
scheduler.schedule_job("VisitorManager.purge", expiration_period, self.__purge)
|
|
26
|
-
KameleoonLogger.debug(
|
|
27
|
-
|
|
25
|
+
KameleoonLogger.debug(
|
|
26
|
+
"RETURN: VisitorManager(data_manager, expiration_period: %s, scheduler)", expiration_period
|
|
27
|
+
)
|
|
28
28
|
|
|
29
29
|
def __iter__(self) -> Iterator[str]:
|
|
30
30
|
yield from list(self._slots)
|
|
@@ -44,8 +44,9 @@ class VisitorManager:
|
|
|
44
44
|
visitor = slot.visitor
|
|
45
45
|
finally:
|
|
46
46
|
slot.lock.release()
|
|
47
|
-
KameleoonLogger.debug(
|
|
48
|
-
|
|
47
|
+
KameleoonLogger.debug(
|
|
48
|
+
"RETURN: VisitorManager.get_visitor(visitor_code: %s) -> (visitor: %s)", visitor_code, visitor
|
|
49
|
+
)
|
|
49
50
|
return visitor
|
|
50
51
|
|
|
51
52
|
def get_or_create_visitor(self, visitor_code: str) -> Visitor:
|
|
@@ -62,7 +63,7 @@ class VisitorManager:
|
|
|
62
63
|
slot.lock.release()
|
|
63
64
|
KameleoonLogger.debug("RETURN: VisitorManager.get_or_create_visitor(visitor_code: %s)", visitor_code)
|
|
64
65
|
|
|
65
|
-
def add_data(self, visitor_code: str, *args) -> Visitor:
|
|
66
|
+
def add_data(self, visitor_code: str, *args, track: bool = True) -> Visitor:
|
|
66
67
|
"""
|
|
67
68
|
Adds data to a visitor.
|
|
68
69
|
|
|
@@ -70,8 +71,13 @@ class VisitorManager:
|
|
|
70
71
|
* marks custom data of the local scope as unsent
|
|
71
72
|
* converts custom data with the mapping identifier index to the mapping identifier
|
|
72
73
|
* maps a visitor by its mapping identifier
|
|
74
|
+
|
|
75
|
+
:param track: A boolean indicating whether the data should be tracked (sent to server).
|
|
76
|
+
If False, sendable data will be marked as sent immediately. Default is True.
|
|
73
77
|
"""
|
|
74
|
-
KameleoonLogger.debug(
|
|
78
|
+
KameleoonLogger.debug(
|
|
79
|
+
"CALL: VisitorManager.add_data(visitor_code: %s, args: %s, track: %s)", visitor_code, args, track
|
|
80
|
+
)
|
|
75
81
|
visitor = self.get_or_create_visitor(visitor_code)
|
|
76
82
|
custom_data_info = self._data_manager.data_file.custom_data_info
|
|
77
83
|
data_to_add: List[Any] = [None] * len(args)
|
|
@@ -81,9 +87,13 @@ class VisitorManager:
|
|
|
81
87
|
elif isinstance(data, Conversion):
|
|
82
88
|
data = self.__process_conversion(data, custom_data_info)
|
|
83
89
|
data_to_add[i] = data
|
|
84
|
-
visitor.add_data(*data_to_add)
|
|
85
|
-
KameleoonLogger.debug(
|
|
86
|
-
|
|
90
|
+
visitor.add_data(*data_to_add, track=track)
|
|
91
|
+
KameleoonLogger.debug(
|
|
92
|
+
"RETURN: VisitorManager.add_data(visitor_code: %s, args: %s, track: %s) -> (visitor)",
|
|
93
|
+
visitor_code,
|
|
94
|
+
args,
|
|
95
|
+
track,
|
|
96
|
+
)
|
|
87
97
|
return visitor
|
|
88
98
|
|
|
89
99
|
def __process_custom_data(
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""Version utility for parsing and comparing semantic versions"""
|
|
2
|
+
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from kameleoon.logging.kameleoon_logger import KameleoonLogger
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SemVersion:
|
|
9
|
+
"""SemVersion (Semantic versions) is a utility class for parsing and comparing semantic versions.
|
|
10
|
+
|
|
11
|
+
Supports semantic versioning with major, minor, and patch components.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
@staticmethod
|
|
15
|
+
def from_string(version_string: str) -> Optional["SemVersion"]:
|
|
16
|
+
"""
|
|
17
|
+
Parses a version string into a Version object.
|
|
18
|
+
|
|
19
|
+
:param version_string: The version string to parse (e.g., "1", "1.2", "1.2.3")
|
|
20
|
+
:return: Version object or None if parsing failed
|
|
21
|
+
"""
|
|
22
|
+
versions = [0, 0, 0]
|
|
23
|
+
version_parts = version_string.split(".")
|
|
24
|
+
|
|
25
|
+
for i in range(min(len(versions), len(version_parts))):
|
|
26
|
+
try:
|
|
27
|
+
versions[i] = int(version_parts[i])
|
|
28
|
+
except ValueError:
|
|
29
|
+
KameleoonLogger.error("Invalid version component, index: %s, value: %s", i, version_parts[i])
|
|
30
|
+
return None
|
|
31
|
+
|
|
32
|
+
return SemVersion(versions[0], versions[1], versions[2])
|
|
33
|
+
|
|
34
|
+
def __init__(self, major: int = 0, minor: int = 0, patch: int = 0) -> None:
|
|
35
|
+
"""
|
|
36
|
+
Creates a new Version.
|
|
37
|
+
|
|
38
|
+
:param major: Major version number
|
|
39
|
+
:param minor: Minor version number
|
|
40
|
+
:param patch: Patch version number
|
|
41
|
+
"""
|
|
42
|
+
self.major = major
|
|
43
|
+
self.minor = minor
|
|
44
|
+
self.patch = patch
|
|
45
|
+
|
|
46
|
+
def compare_to(self, other: "SemVersion") -> int:
|
|
47
|
+
"""
|
|
48
|
+
Compares SemVersion instances
|
|
49
|
+
"""
|
|
50
|
+
a = (self.major, self.minor, self.patch)
|
|
51
|
+
b = (other.major, other.minor, other.patch)
|
|
52
|
+
return (a > b) - (a < b)
|
|
53
|
+
|
|
54
|
+
def to_float(self) -> float:
|
|
55
|
+
"""
|
|
56
|
+
Converts the version to a float (only major and minor are considered).
|
|
57
|
+
|
|
58
|
+
:return: Float representation of the version (e.g., 1.2)
|
|
59
|
+
"""
|
|
60
|
+
return float(f"{self.major}.{self.minor}")
|
{kameleoon_client_python-3.17.1 → kameleoon_client_python-3.18.0}/kameleoon/kameleoon_client.py
RENAMED
|
@@ -324,7 +324,7 @@ class KameleoonClient:
|
|
|
324
324
|
cookies,
|
|
325
325
|
)
|
|
326
326
|
|
|
327
|
-
def add_data(self, visitor_code: str, *args) -> None:
|
|
327
|
+
def add_data(self, visitor_code: str, *args, track: bool = True) -> None:
|
|
328
328
|
"""
|
|
329
329
|
To associate various data with the current user, we can use the add_data() method.
|
|
330
330
|
This method requires the visitor_code as a first parameter, and then accepts several additional parameters.
|
|
@@ -337,7 +337,9 @@ class KameleoonClient:
|
|
|
337
337
|
|
|
338
338
|
:param visitor_code: Unique identifier of the user. This field is mandatory.
|
|
339
339
|
:type visitor_code: str
|
|
340
|
-
:param args:
|
|
340
|
+
:param args: One or more Kameleoon Data objects to associate with the visitor.
|
|
341
|
+
:param track: A boolean indicating whether the data should be tracked (sent to server). Default is True.
|
|
342
|
+
:type track: bool
|
|
341
343
|
:return: None
|
|
342
344
|
|
|
343
345
|
Examples:
|
|
@@ -349,13 +351,17 @@ class KameleoonClient:
|
|
|
349
351
|
visitor_code = kameleoon_client.get_visitor_code(request.COOKIES)
|
|
350
352
|
kameleoon_client.add_data(visitor_code, CustomData("test-id", "test-value"))
|
|
351
353
|
kameleoon_client.add_data(visitor_code, Browser(BrowserType.CHROME))
|
|
352
|
-
kameleoon_client.add_data(visitor_code, PageView("www.test.com", "test-title"))
|
|
353
|
-
kameleoon_client.add_data(visitor_code, Conversion(1, 100.0))
|
|
354
|
+
kameleoon_client.add_data(visitor_code, PageView("www.test.com", "test-title"), track=True)
|
|
355
|
+
kameleoon_client.add_data(visitor_code, Conversion(1, 100.0), track=False)
|
|
354
356
|
"""
|
|
355
|
-
KameleoonLogger.info(
|
|
357
|
+
KameleoonLogger.info(
|
|
358
|
+
"CALL: KameleoonClient.add_data(visitor_code: %s, args: %s, track: %s)", visitor_code, args, track
|
|
359
|
+
)
|
|
356
360
|
validate_visitor_code(visitor_code)
|
|
357
|
-
self._visitor_manager.add_data(visitor_code, *args)
|
|
358
|
-
KameleoonLogger.info(
|
|
361
|
+
self._visitor_manager.add_data(visitor_code, *args, track=track)
|
|
362
|
+
KameleoonLogger.info(
|
|
363
|
+
"RETURN: KameleoonClient.add_data(visitor_code: %s, args: %s, track: %s)", visitor_code, args, track
|
|
364
|
+
)
|
|
359
365
|
|
|
360
366
|
def track_conversion(
|
|
361
367
|
self,
|
|
@@ -481,7 +487,7 @@ class KameleoonClient:
|
|
|
481
487
|
)
|
|
482
488
|
|
|
483
489
|
def is_feature_active(
|
|
484
|
-
self, visitor_code: str, feature_key: str, is_unique_identifier: Optional[bool] = None, track=True
|
|
490
|
+
self, visitor_code: str, feature_key: str, is_unique_identifier: Optional[bool] = None, track: bool = True
|
|
485
491
|
) -> bool:
|
|
486
492
|
"""
|
|
487
493
|
Check if feature is active for a given visitor code
|
|
@@ -561,7 +567,7 @@ class KameleoonClient:
|
|
|
561
567
|
)
|
|
562
568
|
return feature_active
|
|
563
569
|
|
|
564
|
-
def get_variation(self, visitor_code: str, feature_key: str, track=True) -> Variation:
|
|
570
|
+
def get_variation(self, visitor_code: str, feature_key: str, track: bool = True) -> Variation:
|
|
565
571
|
"""
|
|
566
572
|
Retrieves the variation assigned to the given visitor for a specific feature flag.
|
|
567
573
|
|
|
@@ -605,7 +611,7 @@ class KameleoonClient:
|
|
|
605
611
|
)
|
|
606
612
|
return external_variation
|
|
607
613
|
|
|
608
|
-
def get_variations(self, visitor_code: str, only_active=False, track=True) -> Dict[str, Variation]:
|
|
614
|
+
def get_variations(self, visitor_code: str, only_active=False, track: bool = True) -> Dict[str, Variation]:
|
|
609
615
|
"""
|
|
610
616
|
Forms a dictionary of variations assigned to a given visitor across all feature flags.
|
|
611
617
|
This method iterates over all available feature flags and returns the assigned variation for each flag
|
|
@@ -1615,7 +1621,7 @@ class KameleoonClient:
|
|
|
1615
1621
|
)
|
|
1616
1622
|
return (feature_flag, variation_key)
|
|
1617
1623
|
|
|
1618
|
-
def __save_variation(self, visitor_code: str, eval_exp: Optional[EvaluatedExperiment], track=True) -> None:
|
|
1624
|
+
def __save_variation(self, visitor_code: str, eval_exp: Optional[EvaluatedExperiment], track: bool = True) -> None:
|
|
1619
1625
|
if (eval_exp is None) or (eval_exp.experiment.id_ is None) or (eval_exp.var_by_exp.variation_id is None):
|
|
1620
1626
|
return
|
|
1621
1627
|
KameleoonLogger.debug(
|
|
@@ -15,8 +15,8 @@ DEFAULT_REFRESH_INTERVAL_MINUTES = 60
|
|
|
15
15
|
DEFAULT_SESSION_DURATION_MINUTES = 30
|
|
16
16
|
DEFAULT_DEFAULT_TIMEOUT_MILLISECONDS = 10_000
|
|
17
17
|
DEFAULT_TRACKING_INTERVAL_MILLISECONDS = 1000
|
|
18
|
-
MIN_TRACKING_INTERVAL_MILLISECONDS =
|
|
19
|
-
MAX_TRACKING_INTERVAL_MILLISECONDS =
|
|
18
|
+
MIN_TRACKING_INTERVAL_MILLISECONDS = 1_000
|
|
19
|
+
MAX_TRACKING_INTERVAL_MILLISECONDS = 5_000
|
|
20
20
|
DEFAULT_CONFIGURATION_PATH = "/etc/kameleoon/client-python.yaml"
|
|
21
21
|
|
|
22
22
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""Kameleoon SDK version"""
|
|
2
|
+
|
|
3
|
+
version_info = (3, 18, 0)
|
|
4
|
+
__version__ = ".".join(str(v) for v in version_info) # uses in scripts
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# pylint: disable=R0903
|
|
8
|
+
class SdkVersion:
|
|
9
|
+
"""SdkVersion is a helper class for get name and version of sdk"""
|
|
10
|
+
|
|
11
|
+
NAME = "PYTHON"
|
|
12
|
+
VERSION = __version__
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"""Browser condition"""
|
|
2
|
+
|
|
2
3
|
from typing import Any, Dict, Union
|
|
3
4
|
from kameleoon.data import Browser, BrowserType
|
|
5
|
+
from kameleoon.helpers.sem_version import SemVersion
|
|
4
6
|
from kameleoon.logging.kameleoon_logger import KameleoonLogger
|
|
5
|
-
from kameleoon.sdk_version import SdkVersion
|
|
6
7
|
from kameleoon.targeting.conditions.constants import TargetingOperator
|
|
7
8
|
from kameleoon.targeting.conditions.targeting_condition import TargetingCondition
|
|
8
9
|
|
|
@@ -40,7 +41,8 @@ class BrowserCondition(TargetingCondition):
|
|
|
40
41
|
return True
|
|
41
42
|
|
|
42
43
|
# If browser types are equal and browser version is defined in condition, then need to compare versions
|
|
43
|
-
|
|
44
|
+
version = SemVersion.from_string(str(self.__version))
|
|
45
|
+
version_number = version.to_float() if version else None
|
|
44
46
|
if version_number is None:
|
|
45
47
|
return False
|
|
46
48
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""Sdk language condition"""
|
|
2
|
+
from typing import Any, Dict, Union
|
|
3
|
+
|
|
4
|
+
from kameleoon.logging.kameleoon_logger import KameleoonLogger
|
|
5
|
+
from kameleoon.targeting.conditions.version_condition import VersionCondition
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SdkLanguageCondition(VersionCondition):
|
|
9
|
+
"""SdkLanguage uses in case if you need to target by sdk type and version"""
|
|
10
|
+
|
|
11
|
+
class SdkInfo:
|
|
12
|
+
"""SdkInfo is a helper class to pass sdk name and version as parameters"""
|
|
13
|
+
|
|
14
|
+
def __init__(self, sdk_language: str, version: str) -> None:
|
|
15
|
+
self.__sdk_language = sdk_language
|
|
16
|
+
self.__version = version
|
|
17
|
+
|
|
18
|
+
@property
|
|
19
|
+
def sdk_language(self):
|
|
20
|
+
"""Return sdk language (type)"""
|
|
21
|
+
return self.__sdk_language
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def version(self):
|
|
25
|
+
"""Return sdk version"""
|
|
26
|
+
return self.__version
|
|
27
|
+
|
|
28
|
+
def __init__(self, json_condition: Dict[str, Union[str, int, Any]]):
|
|
29
|
+
super().__init__(json_condition)
|
|
30
|
+
try:
|
|
31
|
+
self.__sdk_language = json_condition.get("sdkLanguage", "")
|
|
32
|
+
except KeyError as ex:
|
|
33
|
+
KameleoonLogger.error("%s has wrong JSON structure: %s", self.__class__, ex)
|
|
34
|
+
|
|
35
|
+
def check(self, data: Any) -> bool:
|
|
36
|
+
return isinstance(data, SdkLanguageCondition.SdkInfo) and \
|
|
37
|
+
self.__sdk_language == data.sdk_language and \
|
|
38
|
+
(self._condition_version is None or self.check_targeting(data.version))
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""Version condition for targeting by application version"""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, Optional, Union
|
|
4
|
+
|
|
5
|
+
from kameleoon.data.application_version import ApplicationVersion
|
|
6
|
+
from kameleoon.helpers.sem_version import SemVersion
|
|
7
|
+
from kameleoon.logging.kameleoon_logger import KameleoonLogger
|
|
8
|
+
from kameleoon.targeting.conditions.constants import TargetingOperator
|
|
9
|
+
from kameleoon.targeting.conditions.targeting_condition import TargetingCondition
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class VersionCondition(TargetingCondition):
|
|
13
|
+
"""VersionCondition is used for targeting by application version.
|
|
14
|
+
|
|
15
|
+
Compares the visitor's application version against a configured version
|
|
16
|
+
using semantic versioning comparison (EQUAL, GREATER, LOWER).
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(self, json_condition: Dict[str, Union[str, int, Any]]):
|
|
20
|
+
super().__init__(json_condition)
|
|
21
|
+
self._condition_version = json_condition.get("version", None)
|
|
22
|
+
try:
|
|
23
|
+
self.__operator = TargetingOperator[str(json_condition.get("versionMatchType", None))]
|
|
24
|
+
except KeyError as ex:
|
|
25
|
+
KameleoonLogger.error("%s has wrong JSON structure: %s", self.__class__, ex)
|
|
26
|
+
self.__operator = TargetingOperator.UNDEFINED
|
|
27
|
+
self.__cached_sem_version: Optional[SemVersion] = None
|
|
28
|
+
|
|
29
|
+
def check(self, data: Any) -> bool:
|
|
30
|
+
return self.check_targeting(data.version) if isinstance(data, ApplicationVersion) else False
|
|
31
|
+
|
|
32
|
+
def check_targeting(self, version: str) -> bool:
|
|
33
|
+
"""Compare the provided version with the condition version.
|
|
34
|
+
|
|
35
|
+
:param version: The version string to compare
|
|
36
|
+
:return: True if the comparison matches, False otherwise
|
|
37
|
+
"""
|
|
38
|
+
if self.__cached_sem_version is None and self._condition_version:
|
|
39
|
+
self.__cached_sem_version = SemVersion.from_string(str(self._condition_version))
|
|
40
|
+
|
|
41
|
+
version_compare = SemVersion.from_string(version)
|
|
42
|
+
|
|
43
|
+
if self.__cached_sem_version is None or version_compare is None:
|
|
44
|
+
KameleoonLogger.error(
|
|
45
|
+
"VersionCondition has unexpected values to compare, condition version: '%s', provided version: '%s'",
|
|
46
|
+
self._condition_version,
|
|
47
|
+
version,
|
|
48
|
+
)
|
|
49
|
+
return False
|
|
50
|
+
|
|
51
|
+
if self.__operator == TargetingOperator.EQUAL:
|
|
52
|
+
return self.__cached_sem_version.compare_to(version_compare) == 0
|
|
53
|
+
|
|
54
|
+
if self.__operator == TargetingOperator.GREATER:
|
|
55
|
+
return self.__cached_sem_version.compare_to(version_compare) < 0
|
|
56
|
+
|
|
57
|
+
if self.__operator == TargetingOperator.LOWER:
|
|
58
|
+
return self.__cached_sem_version.compare_to(version_compare) > 0
|
|
59
|
+
|
|
60
|
+
KameleoonLogger.error("Unexpected comparing operation for VersionCondition: %s", self.__operator)
|
|
61
|
+
return False
|
|
@@ -96,6 +96,7 @@ class TargetingManager:
|
|
|
96
96
|
)
|
|
97
97
|
return condition_data
|
|
98
98
|
|
|
99
|
+
# pylint: disable=R0912
|
|
99
100
|
def __get_condition_data_by_type(self, visitor: Visitor, condition_type: TargetingConditionType): # noqa: C901
|
|
100
101
|
if condition_type == TargetingConditionType.BROWSER:
|
|
101
102
|
return visitor.browser
|
|
@@ -107,6 +108,8 @@ class TargetingManager:
|
|
|
107
108
|
return visitor.geolocation
|
|
108
109
|
if condition_type == TargetingConditionType.OPERATING_SYSTEM:
|
|
109
110
|
return visitor.operating_system
|
|
111
|
+
if condition_type == TargetingConditionType.APPLICATION_VERSION:
|
|
112
|
+
return visitor.application_version
|
|
110
113
|
if condition_type == TargetingConditionType.CUSTOM_DATUM:
|
|
111
114
|
return visitor.custom_data
|
|
112
115
|
if condition_type == TargetingConditionType.CONVERSIONS:
|
|
@@ -25,6 +25,7 @@ from kameleoon.targeting.conditions.visit_number_today_condition import VisitNum
|
|
|
25
25
|
from kameleoon.targeting.conditions.visit_number_total_condition import VisitNumberTotalCondition
|
|
26
26
|
from kameleoon.targeting.conditions.visitor_new_return_condition import VisitorNewReturnCondition
|
|
27
27
|
from kameleoon.targeting.conditions.time_elapsed_since_visit_condition import TimeElapsedSinceVisitCondition
|
|
28
|
+
from kameleoon.targeting.conditions.version_condition import VersionCondition
|
|
28
29
|
|
|
29
30
|
|
|
30
31
|
class TreeConditionFactory:
|
|
@@ -87,6 +88,9 @@ class TreeConditionFactory:
|
|
|
87
88
|
if condition_type == TargetingConditionType.OPERATING_SYSTEM:
|
|
88
89
|
return OperatingSystemCondition(condition_json)
|
|
89
90
|
|
|
91
|
+
if condition_type == TargetingConditionType.APPLICATION_VERSION:
|
|
92
|
+
return VersionCondition(condition_json)
|
|
93
|
+
|
|
90
94
|
if condition_type == TargetingConditionType.SEGMENT:
|
|
91
95
|
return SegmentCondition(condition_json)
|
|
92
96
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kameleoon-client-python
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.18.0
|
|
4
4
|
Summary: Kameleoon Client Python Software Development Kit.
|
|
5
5
|
Home-page: https://developers.kameleoon.com/python-sdk.html
|
|
6
6
|
Author: Kameleoon
|
|
@@ -20,27 +20,27 @@ Requires-Dist: requests<3.0.0,>=2.25
|
|
|
20
20
|
Requires-Dist: sseclient-py<1.9.0,>=1.7.0
|
|
21
21
|
Requires-Dist: aiohttp<4.0.0,>=3.8.0
|
|
22
22
|
Provides-Extra: test
|
|
23
|
+
Requires-Dist: mypy==0.991; extra == "test"
|
|
23
24
|
Requires-Dist: flake8==4.0.1; extra == "test"
|
|
24
|
-
Requires-Dist: freezegun==1.1.0; extra == "test"
|
|
25
25
|
Requires-Dist: types-requests==2.25.0; extra == "test"
|
|
26
|
-
Requires-Dist: pytest-asyncio==0.21.*; extra == "test"
|
|
27
|
-
Requires-Dist: types-python-dateutil==2.8.2; extra == "test"
|
|
28
26
|
Requires-Dist: pytest-pythonpath==0.7.3; extra == "test"
|
|
29
27
|
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
28
|
Requires-Dist: twine==3.4.1; extra == "test"
|
|
33
29
|
Requires-Dist: pytest-django==4.4.0; extra == "test"
|
|
34
|
-
Requires-Dist:
|
|
35
|
-
Requires-Dist: pyyaml<6.1.0,>=5.4.0; extra == "test"
|
|
30
|
+
Requires-Dist: Django==3.2.4; extra == "test"
|
|
36
31
|
Requires-Dist: pytest-cov==2.12.1; extra == "test"
|
|
37
|
-
Requires-Dist:
|
|
38
|
-
Requires-Dist: sseclient-py<1.9.0,>=1.7.0; extra == "test"
|
|
39
|
-
Requires-Dist: Werkzeug==2.0.1; extra == "test"
|
|
32
|
+
Requires-Dist: types-python-dateutil==2.8.2; extra == "test"
|
|
40
33
|
Requires-Dist: pylint==2.12.*; extra == "test"
|
|
41
|
-
Requires-Dist: Django==3.2.4; extra == "test"
|
|
42
|
-
Requires-Dist: mypy==0.991; extra == "test"
|
|
43
34
|
Requires-Dist: aiohttp<4.0.0,>=3.8.0; extra == "test"
|
|
35
|
+
Requires-Dist: Werkzeug==2.0.1; extra == "test"
|
|
36
|
+
Requires-Dist: pytest-asyncio==0.21.*; extra == "test"
|
|
37
|
+
Requires-Dist: sseclient-py<1.9.0,>=1.7.0; extra == "test"
|
|
38
|
+
Requires-Dist: wheel==0.36.2; extra == "test"
|
|
39
|
+
Requires-Dist: types-PyYAML==5.4.3; extra == "test"
|
|
40
|
+
Requires-Dist: pyyaml<6.1.0,>=5.4.0; extra == "test"
|
|
41
|
+
Requires-Dist: pytest-ordering==0.6; extra == "test"
|
|
42
|
+
Requires-Dist: freezegun==1.1.0; extra == "test"
|
|
43
|
+
Requires-Dist: requests<3.0.0,>=2.25; extra == "test"
|
|
44
44
|
Dynamic: author
|
|
45
45
|
Dynamic: author-email
|
|
46
46
|
Dynamic: classifier
|