# AUTOGENERATED! DO NOT EDIT! File to edit: notebooks/API_Helper.ipynb (unless otherwise specified).

__all__ = [
    "ensure_is_instance",
    "get_base_url",
    "post_data",
    "get_data",
    "delete_data",
    "add_ready_column",
    "generate_df",
    "get_tag_str",
]

# Cell

from typing import *

# Internal Cell

import os
import requests

import pandas as pd

# Cell


def ensure_is_instance(o: Any, cls: Type):
    """A function to check if the object argument is an instance of the class argument.

    Args:
        o: A python object for which the instance needs to be checked.
        cls: The expected instance of the object argument.

    Raises:
        A TypeError if the object is not an instance of the class type.
    """
    if not isinstance(o, cls):
        raise TypeError(
            f"The parameter must be a {cls} type, but got `{type(o).__name__}`"
        )


# Internal Cell


def _get_json(response: requests.Response) -> Any:
    """A function to validate the status of the response object.

    Args:
        response: The response object that encapsulates the server's response.

    Returns:
        A dictionary of the response body.

    Raises:
        ValueError: If the response code is not in range of 200 - 399.
    """
    if response:
        return response.json()
    else:
        raise ValueError(response.json()["detail"])


# Cell


def get_base_url(server: Optional[str]) -> str:
    """Return the base URL for the airt server.

    If the server value is `None`, retrive the value from the environment variable `AIRT_SERVER_URL`.
    If the variable is not set as well, then the default public server will be used.
    """

    env_airt_service_url = "AIRT_SERVER_URL"
    airt_prod_server_url = "https://api.airt.ai"

    return (
        server
        if server is not None
        else os.environ.get(env_airt_service_url, airt_prod_server_url)
    )


# Cell


def post_data(
    url: str,
    data: Optional[Dict[str, Any]],
    token: Optional[str],
) -> Dict[str, Any]:
    """A function to send a POST request.

    Args:
        url: The URL of the server to which the request needs to be sent.
        data: A Dictionary object to send in the body of the POST request.
        token: The unique auth token for the client, obtained via calling the `Client.get_token()` method.
            Set it to `None` in `Client.get_token()` to obtain the token.

    Returns:
        A dictionary that encapsulates the response body.

    Raises:
        ConnectionError: If the server is not reachable.
        ValueError: If the response code is not in range of 200 - 399.
    """
    if token is not None:
        headers = {"Authorization": f"Bearer {token}"}
        response = requests.post(url, json=data, headers=headers)
    else:
        response = requests.post(url, data=data)
    return _get_json(response)


# Cell


def get_data(url: str, token: Optional[str]) -> Any:
    """Send a GET request.

    Args:
        url: The URL of the server to which the request needs to be sent.
        token: The unique auth token for the client, obtained via calling the `Client.get_token()` method.

    Returns:
        A dictionary that encapsulates the response body.

    Raises:
        ConnectionError: If the server is not reachable.
        ValueError: If the response code is not in range of 200 - 399.
    """
    headers = {"Authorization": f"Bearer {token}"}
    response = requests.get(url, headers=headers)
    return _get_json(response)


# Cell


def delete_data(url: str, token: Optional[str]) -> Dict[str, Any]:
    """Send a DELETE request.

    Args:
        url: The URL of the server to which the request needs to be sent.
        token: The unique auth token for the client, obtained via calling the `Client.get_token()` method.

    Returns:
        A dictionary that encapsulates the response body.

    Raises:
        ConnectionError: If the server is not reachable.
        ValueError: If the response code is not in range of 200 - 399.
    """
    headers = {"Authorization": f"Bearer {token}"}
    response = requests.delete(url, headers=headers)
    return _get_json(response)


# Cell


def add_ready_column(df: pd.DataFrame) -> pd.DataFrame:
    """Add ready column to the DataFrame

    Args:
        df: A pandas DataFrame with completed_steps and total_steps columns

    Returns:
        A pandas DataFrame with ready column
    """

    df["ready"] = df["completed_steps"] == df["total_steps"]
    return df.drop(columns=["completed_steps", "total_steps"])


# Cell


def generate_df(items: Dict[str, Any], columns: list) -> pd.DataFrame:
    """Generate a DataFrame based on the items length

    Args:
        items: A list encapsulating the response from an API endpoint that needs to be converted into a DataFrame.
        columns: A list of columns names to be included in the DataFrame.

    Returns:
        A DataFrame with a shape of (items, columns), if the length of the items is > 0, otherwise an empty DataFrame with only columns names.
    """

    if len(items) > 0:
        df = pd.DataFrame(items)[columns]
    else:
        df = pd.DataFrame({c: [] for c in columns})

    return df


# Cell


def get_tag_str(tags: list) -> str:
    """Get tag names as string seperated by comma from the response

    Args:
        tags: The tags list from the response

    Returns:
        The tag names as string seperated by comma. If the tags list is empty, <none> will be returned.
    """

    if len(tags) == 0:
        return "<none>"

    return ", ".join([t["name"] for t in tags])
