Skip to content

Utilities

griddy / nfl / utils**


Module Contents

Functions

get_discriminator

get_discriminator(
    model: Any, fieldname: str, key: str
) -> str

Recursively search for the discriminator attribute in a model.

PARAMETER DESCRIPTION
model

The model to search within.

TYPE: Any

fieldname

The name of the field to search for.

TYPE: str

key

The key to search for in dictionaries.

TYPE: str

RETURNS DESCRIPTION
str

The name of the discriminator attribute.

TYPE: str

RAISES DESCRIPTION
ValueError

If the discriminator attribute is not found.

Source code in griddy/nfl/utils/annotations.py
def get_discriminator(model: Any, fieldname: str, key: str) -> str:
    """
    Recursively search for the discriminator attribute in a model.

    Args:
        model (Any): The model to search within.
        fieldname (str): The name of the field to search for.
        key (str): The key to search for in dictionaries.

    Returns:
        str: The name of the discriminator attribute.

    Raises:
        ValueError: If the discriminator attribute is not found.
    """
    upper_fieldname = fieldname.upper()

    def get_field_discriminator(field: Any) -> Optional[str]:
        """Search for the discriminator attribute in a given field."""

        if isinstance(field, dict):
            if key in field:
                return f"{field[key]}"

        if hasattr(field, fieldname):
            attr = getattr(field, fieldname)
            if isinstance(attr, Enum):
                return f"{attr.value}"
            return f"{attr}"

        if hasattr(field, upper_fieldname):
            attr = getattr(field, upper_fieldname)
            if isinstance(attr, Enum):
                return f"{attr.value}"
            return f"{attr}"

        return None

    def search_nested_discriminator(obj: Any) -> Optional[str]:
        """Recursively search for discriminator in nested structures."""
        # First try direct field lookup
        discriminator = get_field_discriminator(obj)
        if discriminator is not None:
            return discriminator

        # If it's a dict, search in nested values
        if isinstance(obj, dict):
            for value in obj.values():
                if isinstance(value, list):
                    # Search in list items
                    for item in value:
                        nested_discriminator = search_nested_discriminator(item)
                        if nested_discriminator is not None:
                            return nested_discriminator
                elif isinstance(value, dict):
                    # Search in nested dict
                    nested_discriminator = search_nested_discriminator(value)
                    if nested_discriminator is not None:
                        return nested_discriminator

        return None

    if isinstance(model, list):
        for field in model:
            discriminator = search_nested_discriminator(field)
            if discriminator is not None:
                return discriminator

    discriminator = search_nested_discriminator(model)
    if discriminator is not None:
        return discriminator

    raise ValueError(f"Could not find discriminator field {fieldname} in {model}")

parse_datetime

parse_datetime(datetime_string: str) -> datetime

Convert a RFC 3339 / ISO 8601 formatted string into a datetime object. Python versions 3.11 and later support parsing RFC 3339 directly with datetime.fromisoformat(), but for earlier versions, this function encapsulates the necessary extra logic.

Source code in griddy/nfl/utils/datetimes.py
def parse_datetime(datetime_string: str) -> datetime:
    """
    Convert a RFC 3339 / ISO 8601 formatted string into a datetime object.
    Python versions 3.11 and later support parsing RFC 3339 directly with
    datetime.fromisoformat(), but for earlier versions, this function
    encapsulates the necessary extra logic.
    """
    # Python 3.11 and later can parse RFC 3339 directly
    if sys.version_info >= (3, 11):
        return datetime.fromisoformat(datetime_string)

    # For Python 3.10 and earlier, a common ValueError is trailing 'Z' suffix,
    # so fix that upfront.
    if datetime_string.endswith("Z"):
        datetime_string = datetime_string[:-1] + "+00:00"

    return datetime.fromisoformat(datetime_string)