diff --git a/bentoml/__init__.py b/bentoml/__init__.py index 339a10e55ec..19ddac9bad3 100644 --- a/bentoml/__init__.py +++ b/bentoml/__init__.py @@ -17,6 +17,7 @@ from __future__ import print_function from ._version import get_versions + __version__ = get_versions()['version'] del get_versions diff --git a/bentoml/cli/config.py b/bentoml/cli/config.py index 8009da67462..37e07a3a686 100644 --- a/bentoml/cli/config.py +++ b/bentoml/cli/config.py @@ -30,6 +30,7 @@ DEFAULT_CONFIG_FILE, ) from bentoml.cli.click_utils import _echo, CLI_COLOR_ERROR +from bentoml.utils.usage_stats import track_cli # pylint: disable=unused-variable @@ -59,6 +60,7 @@ def config(): @config.command(help="View BentoML configurations") def view(): + track_cli('config-view') local_config = ConfigParser() with open(LOCAL_CONFIG_FILE, 'rb') as config_file: local_config.read_string(config_file.read().decode('utf-8')) @@ -68,6 +70,7 @@ def view(): @config.command() def view_effective(): + track_cli('config-view-effective') bentoml_config.write(sys.stdout) return @@ -77,6 +80,7 @@ def view_effective(): ) @click.argument("updates", nargs=-1) def set(updates): + track_cli('config-set') local_config = ConfigParser() with open(LOCAL_CONFIG_FILE, 'rb') as config_file: local_config.read_string(config_file.read().decode('utf-8')) @@ -106,6 +110,7 @@ def set(updates): ) @click.argument("updates", nargs=-1) def unset(updates): + track_cli('config-unset') local_config = ConfigParser() with open(LOCAL_CONFIG_FILE, 'rb') as config_file: local_config.read_string(config_file.read().decode('utf-8')) @@ -130,6 +135,7 @@ def unset(updates): @config.command(help="Reset BentoML configuration to default") def reset(): + track_cli('config-reset') if os.path.isfile(LOCAL_CONFIG_FILE): LOG.info("Removing existing BentoML config file: %s", LOCAL_CONFIG_FILE) os.remove(LOCAL_CONFIG_FILE) diff --git a/bentoml/utils/usage_stats.py b/bentoml/utils/usage_stats.py index 1d30b5c2e7e..ec093c01380 100644 --- a/bentoml/utils/usage_stats.py +++ b/bentoml/utils/usage_stats.py @@ -25,27 +25,36 @@ import uuid import requests -import bentoml +from bentoml import config, __version__ as BENTOML_VERSION, _version as version_mod logger = logging.getLogger(__name__) AMPLITUDE_URL = "https://api.amplitude.com/httpapi" -API_KEY = '7f65f2446427226eb86f6adfacbbf47a' - -bentoml_version = bentoml.__version__ -platform_info = platform.platform() -py_version = "{major}.{minor}.{micro}".format( +PLATFORM = platform.platform() +PY_VERSION = "{major}.{minor}.{micro}".format( major=sys.version_info.major, minor=sys.version_info.minor, micro=sys.version_info.micro, ) +SESSION_ID = str(uuid.uuid4()) # uuid that marks current python session -def get_bento_service_info(bento_service): - if not isinstance(bento_service, bentoml.BentoService): - return {} +def is_pypi_release(): + is_installed_package = hasattr(version_mod, 'version_json') + is_tagged = not BENTOML_VERSION.startswith('0+untagged') + is_clean = not version_mod.get_versions()['dirty'] + return is_installed_package and is_tagged and is_clean + +# Use dev amplitude key +API_KEY = '7f65f2446427226eb86f6adfacbbf47a' +if is_pypi_release(): + # Use prod amplitude key + API_KEY = '1ad6ee0e81b9666761aebd55955bbd3a' + + +def get_bento_service_info(bento_service): artifact_types = [] handler_types = [] @@ -64,47 +73,48 @@ def get_bento_service_info(bento_service): def track(event_type, info): - info['py_version'] = py_version - info["bento_version"] = bentoml_version - info["platform_info"] = platform_info + info['py_version'] = PY_VERSION + info["bento_version"] = BENTOML_VERSION + info["platform_info"] = PLATFORM return send_amplitude_event(event_type, info) def track_save(bento_service): - if bentoml.config['core'].getboolean("usage_tracking"): + if config['core'].getboolean("usage_tracking"): info = get_bento_service_info(bento_service) return track("save", info) def track_loading(bento_service): - if bentoml.config['core'].getboolean("usage_tracking"): + if config['core'].getboolean("usage_tracking"): info = get_bento_service_info(bento_service) return track("load", info) def track_cli(command, deploy_platform=None): - if bentoml.config['core'].getboolean("usage_tracking"): + if config['core'].getboolean("usage_tracking"): info = {} if deploy_platform is not None: info['platform'] = deploy_platform return track('cli-' + command, info) -def send_amplitude_event(event, info): +def send_amplitude_event(event, event_properties): """Send event to amplitude https://developers.amplitude.com/?java#keys-for-the-event-argument """ - event_info = [ - {"event_type": event, "user_id": str(uuid.uuid4()), "event_properties": info} + { + "event_type": event, + "user_id": SESSION_ID, + "event_properties": event_properties, + } ] event_data = {"api_key": API_KEY, "event": json.dumps(event_info)} try: - requests.post(AMPLITUDE_URL, data=event_data, timeout=1) - return - except Exception as error: # pylint:disable=broad-except - # silently fail - logger.info(str(error)) - return + return requests.post(AMPLITUDE_URL, data=event_data, timeout=1) + except Exception as err: # pylint:disable=broad-except + # silently fail since this error is not important for BentoML user + logger.info(str(err))