-
Notifications
You must be signed in to change notification settings - Fork 131
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This adds a few things to enable one to more easily customize what is captured via the SDK, and adds docs. 1. Should you capture any data statistics at all? 2. Max lengths of dicts and lists -> so they don't get too big. You can configure this via three means: 1. python constants 2. config file variables 3. environment variables There is a precedence order. So there are default values in the module. You can then override them via config file variables. Which then can in turn be overridden by environment variables. Lastly the user can always modify the constants by directly changing the module variables. Note: we also skip logging metadata from datasavers and loaders if the CAPTURE_DATA_STATISTICS = False. We can fix this by special casing it, but for now I don't think people would complain with the current functionality. We use globals and modify state of the constants to help ensure a great developer experience / static analysis is able to find where people are using the constants easily. Squashed commits: Tweaks docs on sdk constants (+4 squashed commits) Squashed commits: [ff484f5] Adds some docs on the SDK configurability [80c24fa] minor refactor of constants function [69d12f3] Adds function to convert config types Config parser types are by default strings. They aren't converted. This adds a function to do that for ints, floats, and booleans. [0a4949e] Adds configurable capture for SDK This adds a few things to enable one to more easily customize what is captured via the SDK. 1. Should you capture any data statistics at all? 2. Max lengths of dicts and lists -> so they don't get too big. You can configure this via three means: 1. python constants 2. config file variables 3. environment variables There is a prescedence order. So there are default values in the module. You can then override them via config file variables. Which then can in turn be overriden by environment variables. Lastly the user can always modify the constants by directly changing the module variables. Note: we also skip logging metadata from datasavers and loaders if the CAPTURE_DATA_STATISTICS = False. We can fix this by special casing it, but for now I don't think people would complain with the current functionality.
- Loading branch information
Showing
7 changed files
with
303 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
"""This module contains constants for tracking. | ||
We then override these by: | ||
1. Looking for a configuration file and taking the section under `SDK_CONSTANTS`. | ||
2. Via environment variables. They should be prefixed with `HAMILTON_`. | ||
3. Lastly folks can manually adjust these values directly by importing the module and changing the value. | ||
Note: This module cannot import other Hamilton modules. | ||
""" | ||
|
||
import configparser | ||
import logging | ||
import os | ||
from typing import Any | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
# The following are the default values for the tracking client | ||
CAPTURE_DATA_STATISTICS = True | ||
MAX_LIST_LENGTH_CAPTURE = 50 | ||
MAX_DICT_LENGTH_CAPTURE = 100 | ||
|
||
# Check for configuration file | ||
# TODO -- add configuration file support | ||
DEFAULT_CONFIG_URI = os.environ.get("HAMILTON_CONFIG_URI", "~/.hamilton.conf") | ||
DEFAULT_CONFIG_LOCATION = os.path.expanduser(DEFAULT_CONFIG_URI) | ||
|
||
|
||
def _load_config(config_location: str) -> configparser.ConfigParser: | ||
"""Pulls config if it exists. | ||
:param config_location: location of the config file. | ||
""" | ||
config = configparser.ConfigParser() | ||
try: | ||
with open(config_location) as f: | ||
config.read_file(f) | ||
except Exception: | ||
pass | ||
|
||
return config | ||
|
||
|
||
_constant_values = globals() | ||
file_config = _load_config(DEFAULT_CONFIG_LOCATION) | ||
|
||
|
||
def _convert_to_type(val_: str) -> Any: | ||
if not isinstance(val_, str): # guard | ||
return val_ | ||
if val_.isdigit(): | ||
# convert to int | ||
val_ = int(val_) | ||
elif val_.lower() in {"true", "false"}: | ||
# convert to bool | ||
val_ = val_.lower() == "true" | ||
else: | ||
try: # check if float | ||
val_ = float(val_) | ||
except ValueError: | ||
pass | ||
return val_ | ||
|
||
|
||
# loads from config file and overwrites | ||
if "SDK_CONSTANTS" in file_config: | ||
for key, val in file_config["SDK_CONSTANTS"].items(): | ||
upper_key = key.upper() | ||
if upper_key not in _constant_values: | ||
continue | ||
# convert from string to appropriate type | ||
val = _convert_to_type(val) | ||
# overwrite value | ||
_constant_values[upper_key] = val | ||
|
||
# Check for environment variables & overwrites | ||
# TODO automate this by pulling anything in with a prefix and checking | ||
# globals here and updating them. | ||
CAPTURE_DATA_STATISTICS = os.getenv("HAMILTON_CAPTURE_DATA_STATISTICS", CAPTURE_DATA_STATISTICS) | ||
if isinstance(CAPTURE_DATA_STATISTICS, str): | ||
CAPTURE_DATA_STATISTICS = CAPTURE_DATA_STATISTICS.lower() == "true" | ||
MAX_LIST_LENGTH_CAPTURE = int( | ||
os.getenv("HAMILTON_MAX_LIST_LENGTH_CAPTURE", MAX_LIST_LENGTH_CAPTURE) | ||
) | ||
MAX_DICT_LENGTH_CAPTURE = int( | ||
os.getenv("HAMILTON_MAX_DICT_LENGTH_CAPTURE", MAX_DICT_LENGTH_CAPTURE) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import configparser | ||
from hamilton_sdk.tracking import constants | ||
|
||
|
||
def test__convert_to_type(): | ||
# using configparser to make it more realistic | ||
config = configparser.ConfigParser() | ||
config["SDK_CONSTANTS"] = { | ||
"CAPTURE_DATA_STATISTICS": "true", | ||
"MAX_LIST_LENGTH_CAPTURE": "5", | ||
"MAX_DICT_LENGTH_CAPTURE": "10", | ||
"SOMETHING_ELSE": "11.0", | ||
"Another_thing": "1asdfasdf", | ||
} | ||
assert constants._convert_to_type(config["SDK_CONSTANTS"]["CAPTURE_DATA_STATISTICS"]) is True | ||
assert constants._convert_to_type(config["SDK_CONSTANTS"]["MAX_LIST_LENGTH_CAPTURE"]) == 5 | ||
assert constants._convert_to_type(config["SDK_CONSTANTS"]["MAX_DICT_LENGTH_CAPTURE"]) == 10 | ||
assert constants._convert_to_type(config["SDK_CONSTANTS"]["SOMETHING_ELSE"]) == 11.0 | ||
assert constants._convert_to_type(config["SDK_CONSTANTS"]["Another_thing"]) == "1asdfasdf" | ||
o = object() | ||
assert constants._convert_to_type(o) == o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters