Source code for app_utils.helpers
"""General purpose helpers."""
import hashlib
import os
import random
import string
from typing import Any, Callable, Optional
from django.core.cache import cache
[docs]
def chunks(lst, size):
"""Yield successive sized chunks from lst."""
for i in range(0, len(lst), size):
yield lst[i : i + size]
[docs]
def default_if_none(value, default):
"""Return default if value is None."""
if value is None:
return default
return value
# old: get_swagger_spec_path
[docs]
def swagger_spec_path() -> str:
"""returns the path to the current esi swagger spec file"""
return os.path.join(os.path.dirname(os.path.abspath(__file__)), "swagger.json")
[docs]
def random_string(char_count: int) -> str:
"""returns a random string of given length"""
return "".join(
random.choice(string.ascii_uppercase + string.digits) for _ in range(char_count)
)
[docs]
class AttrDict(dict):
"""Enhanced dict that allows property access to its keys.
Example:
.. code-block:: python
>> my_dict = AttrDict({"color": "red", "size": "medium"})
>> my_dict["color"]
"red"
>> my_dict.color
"red"
"""
[docs]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.__dict__ = self
[docs]
def humanize_number(value, magnitude: Optional[str] = None, precision: int = 1) -> str:
"""Return the value in humanized format, e.g. `1234` becomes `1.2k`
Args:
magnitude: fix the magnitude to format the number, e.g. `"b"`
precision: number of digits to round for
"""
value = float(value)
power_map = {"t": 12, "b": 9, "m": 6, "k": 3, "": 0}
if magnitude not in power_map:
if value >= 10**12:
magnitude = "t"
elif value >= 10**9:
magnitude = "b"
elif value >= 10**6:
magnitude = "m"
elif value >= 10**3:
magnitude = "k"
else:
magnitude = ""
return f"{value / 10 ** power_map[magnitude]:,.{precision}f}{magnitude}"
[docs]
def throttle(func: Callable, context_id: str, timeout: Optional[int]) -> Any:
"""Call a function, but limit repeated calls with a timeout, e.g. once per day.
When a repeated call falls within the timeout the call will simply be ignored.
Args:
func: the function to be called
context_id: a string representing the context for applying the throttle,\
e.g. a combination of feature name and user ID
timeout: timeout in seconds between each repeated call of the function
Returns:
Return cached value of called function func
"""
hashed_id = hashlib.md5(str(context_id).encode("utf-8")).hexdigest()
key = f"APP_UTILS_THROTTLED_{hashed_id}"
return cache.get_or_set(key, func, timeout)