Skip to content

utils

Various utiles used from the projects.

deprecation_warning(message, skip=3)

Log a deprecation warning with caller's information. "skip" is the number of stack levels to go back to the caller info.

Source code in cat/utils.py
def deprecation_warning(message: str, skip=3):
    """Log a deprecation warning with caller's information.
        "skip" is the number of stack levels to go back to the caller info."""

    caller = get_caller_info(skip, return_short=False)

    # Format and log the warning message
    log.warning(
        f"{caller} Deprecation Warning: {message})"
    )

get_base_path()

Allows exposing the base path.

Source code in cat/utils.py
def get_base_path():
    """Allows exposing the base path."""
    return "cat/"

get_base_url()

Allows exposing the base url.

Source code in cat/utils.py
def get_base_url():
    """Allows exposing the base url."""
    secure = "s" if get_env("CCAT_CORE_USE_SECURE_PROTOCOLS") in ("true", "1") else ""
    cat_host = get_env("CCAT_CORE_HOST")
    cat_port = get_env("CCAT_CORE_PORT")
    return f"http{secure}://{cat_host}:{cat_port}/"

get_caller_info(skip=2, return_short=True, return_string=True)

Get the name of a caller in the format module.class.method.

Adapted from: https://gist.github.com/techtonik/2151727

Parameters:

Name Type Description Default
skip int

Specifies how many levels of stack to skip while getting caller name.

2
return_string bool

If True, returns the caller info as a string, otherwise as a tuple.

True

Returns:

Name Type Description
package str

Caller package.

module str

Caller module.

klass str

Caller classname if one otherwise None.

caller str

Caller function or method (if a class exist).

line int

The line of the call.

Notes

skip=1 means "who calls me", skip=2 "who calls my caller" etc.

None is returned if skipped levels exceed stack height.

Source code in cat/utils.py
def get_caller_info(skip=2, return_short=True, return_string=True):
    """Get the name of a caller in the format module.class.method.

    Adapted from: https://gist.github.com/techtonik/2151727

    Parameters
    ----------
    skip :  int
        Specifies how many levels of stack to skip while getting caller name.
    return_string : bool
        If True, returns the caller info as a string, otherwise as a tuple.

    Returns
    -------
    package : str
        Caller package.
    module : str
        Caller module.
    klass : str
        Caller classname if one otherwise None.
    caller : str
        Caller function or method (if a class exist).
    line : int
        The line of the call.


    Notes
    -----
    skip=1 means "who calls me",
    skip=2 "who calls my caller" etc.

    None is returned if skipped levels exceed stack height.
    """

    stack = inspect.stack()
    start = 0 + skip
    if len(stack) < start + 1:
        return None

    parentframe = stack[start][0]

    # module and packagename.
    module_info = inspect.getmodule(parentframe)
    if module_info:
        mod = module_info.__name__.split(".")
        package = mod[0]
        module = ".".join(mod[1:])

    # class name.
    klass = ""
    if "self" in parentframe.f_locals:
        klass = parentframe.f_locals["self"].__class__.__name__

    # method or function name.
    caller = None
    if parentframe.f_code.co_name != "<module>":  # top level usually
        caller = parentframe.f_code.co_name

    # call line.
    line = parentframe.f_lineno

    # Remove reference to frame
    # See: https://docs.python.org/3/library/inspect.html#the-interpreter-stack
    del parentframe

    if return_string:
        if return_short:
            return f"{klass}.{caller}"
        else:
            return f"{package}.{module}.{klass}.{caller}::{line}"
    return package, module, klass, caller, line

get_plugins_path()

Allows exposing the plugins' path.

Source code in cat/utils.py
def get_plugins_path():
    """Allows exposing the plugins' path."""
    return os.path.join(get_base_path(), "plugins/")

get_static_path()

Allows exposing the static files' path.

Source code in cat/utils.py
def get_static_path():
    """Allows exposing the static files' path."""
    return os.path.join(get_base_path(), "static/")

get_static_url()

Allows exposing the static server url.

Source code in cat/utils.py
def get_static_url():
    """Allows exposing the static server url."""
    return get_base_url() + "static/"

match_prompt_variables(prompt_variables, prompt_template)

Ensure prompt variables and prompt placeholders map, so there are no issues on mismatches

Source code in cat/utils.py
def match_prompt_variables(
        prompt_variables: Dict,
        prompt_template: str
    ) -> Tuple[Dict, str]:
    """Ensure prompt variables and prompt placeholders map, so there are no issues on mismatches"""

    tmp_prompt = PromptTemplate.from_template(
        template=prompt_template
    )

    # outer set difference
    prompt_mismatches = set(prompt_variables.keys()) ^ set(tmp_prompt.input_variables)

    # clean up
    for m in prompt_mismatches:
        if m in prompt_variables.keys():
            log.debug(f"Prompt variable '{m}' not found in prompt template, removed")
            del prompt_variables[m]
        if m in tmp_prompt.input_variables:
            prompt_template = \
                prompt_template.replace("{" + m + "}", "")
            log.debug(f"Placeholder '{m}' not found in prompt variables, removed")

    return prompt_variables, prompt_template

to_camel_case(text)

Format string to camel case.

Takes a string of words separated by either hyphens or underscores and returns a string of words in camel case.

Parameters:

Name Type Description Default
text str

String of hyphens or underscores separated words.

required

Returns:

Type Description
str

Camel case formatted string.

Source code in cat/utils.py
def to_camel_case(text: str) -> str:
    """Format string to camel case.

    Takes a string of words separated by either hyphens or underscores and returns a string of words in camel case.

    Parameters
    ----------
    text : str
        String of hyphens or underscores separated words.

    Returns
    -------
    str
        Camel case formatted string.
    """
    s = text.replace("-", " ").replace("_", " ").capitalize()
    s = s.split()
    if len(text) == 0:
        return text
    return s[0] + "".join(i.capitalize() for i in s[1:])

verbal_timedelta(td)

Convert a timedelta in human form.

The function takes a timedelta and converts it to a human-readable string format.

Parameters:

Name Type Description Default
td timedelta

Difference between two dates.

required

Returns:

Type Description
str

Human-readable string of time difference.

Notes

This method is used to give the Language Model information time information about the memories retrieved from the vector database.

Examples:

>>> print(verbal_timedelta(timedelta(days=2, weeks=1))
'One week and two days ago'
Source code in cat/utils.py
def verbal_timedelta(td: timedelta) -> str:
    """Convert a timedelta in human form.

    The function takes a timedelta and converts it to a human-readable string format.

    Parameters
    ----------
    td : timedelta
        Difference between two dates.

    Returns
    -------
    str
        Human-readable string of time difference.

    Notes
    -----
    This method is used to give the Language Model information time information about the memories retrieved from
    the vector database.

    Examples
    --------
    >>> print(verbal_timedelta(timedelta(days=2, weeks=1))
    'One week and two days ago'
    """

    if td.days != 0:
        abs_days = abs(td.days)
        if abs_days > 7:
            abs_delta = "{} weeks".format(td.days // 7)
        else:
            abs_delta = "{} days".format(td.days)
    else:
        abs_minutes = abs(td.seconds) // 60
        if abs_minutes > 60:
            abs_delta = "{} hours".format(abs_minutes // 60)
        else:
            abs_delta = "{} minutes".format(abs_minutes)
    if td < timedelta(0):
        return "{} ago".format(abs_delta)
    else:
        return "{} ago".format(abs_delta)