notebooks/util/postproc/deser.py [11:72]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def pascal_to_snake_case(s: str) -> str:
    """Convert a string from PascalCase to snake_case"""
    if not s:
        return s
    # Interpret sequences of 2+ uppercase chars as acronyms to be wordified. e.g. HTML -> Html
    result = re.sub(r"([A-Z])([A-Z]+)", lambda m: m.group(1) + m.group(2).lower(), s)
    # Find any uppercase character(s) following a lowercase character, insert an underscore and
    # convert. E.g. aA -> a_a, MyHtmlThing -> my_html_thing
    # Replace any aA combo with a_a:
    result = re.sub(
        r"([^A-Z])([A-Z]+)",
        lambda m: "_".join((m.group(1), m.group(2).lower())),
        result,
    )
    # Force lowercase first char:
    return result[0].lower() + result[1:]


def snake_to_pascal_case(s: str) -> str:
    """Convert a string from snake_case to PascalCase"""
    if not s:
        return s
    return "".join(
        map(
            lambda segment: (segment[0].upper() + segment[1:]) if segment else segment,
            s.split("_"),
        ),
    )


class PascalJsonableDataClass:
    """Mixin to make a class with snake_case attrs interop with JSON/dicts with PascalCase attrs

    from_dict maps dict keys to constructor args { "MyProp": 1 } -> __init__(my_prop=1)

    to_dict maps data properties (as enumerated by __dict__) to dict keys

    from_json/to_json methods simply wrap the above with json.loads() / json.dumps()
    """

    @classmethod
    def from_dict(cls, d: dict):
        kwargs = {pascal_to_snake_case(k): v for k, v in d.items()}
        return cls(**kwargs)

    @classmethod
    def from_json(cls, s: str):
        return cls.from_dict(json.loads(s))

    def to_dict(self, omit: Optional[Iterable[str]] = None):
        if not omit:
            omit = []
        return {
            snake_to_pascal_case(attr): value.to_dict() if hasattr(value, "to_dict") else value
            for attr, value in filter(
                lambda kv: not (kv[1] is None or kv[0].startswith("_") or kv[0] in omit),
                self.__dict__.items(),
            )
        }

    def to_json(self, omit: Optional[Iterable[str]] = None):
        return json.dumps(self.to_dict(omit=omit))
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



pipeline/postprocessing/fn-postprocess/util/deser.py [11:72]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def pascal_to_snake_case(s: str) -> str:
    """Convert a string from PascalCase to snake_case"""
    if not s:
        return s
    # Interpret sequences of 2+ uppercase chars as acronyms to be wordified. e.g. HTML -> Html
    result = re.sub(r"([A-Z])([A-Z]+)", lambda m: m.group(1) + m.group(2).lower(), s)
    # Find any uppercase character(s) following a lowercase character, insert an underscore and
    # convert. E.g. aA -> a_a, MyHtmlThing -> my_html_thing
    # Replace any aA combo with a_a:
    result = re.sub(
        r"([^A-Z])([A-Z]+)",
        lambda m: "_".join((m.group(1), m.group(2).lower())),
        result,
    )
    # Force lowercase first char:
    return result[0].lower() + result[1:]


def snake_to_pascal_case(s: str) -> str:
    """Convert a string from snake_case to PascalCase"""
    if not s:
        return s
    return "".join(
        map(
            lambda segment: (segment[0].upper() + segment[1:]) if segment else segment,
            s.split("_"),
        ),
    )


class PascalJsonableDataClass:
    """Mixin to make a class with snake_case attrs interop with JSON/dicts with PascalCase attrs

    from_dict maps dict keys to constructor args { "MyProp": 1 } -> __init__(my_prop=1)

    to_dict maps data properties (as enumerated by __dict__) to dict keys

    from_json/to_json methods simply wrap the above with json.loads() / json.dumps()
    """

    @classmethod
    def from_dict(cls, d: dict):
        kwargs = {pascal_to_snake_case(k): v for k, v in d.items()}
        return cls(**kwargs)

    @classmethod
    def from_json(cls, s: str):
        return cls.from_dict(json.loads(s))

    def to_dict(self, omit: Optional[Iterable[str]] = None):
        if not omit:
            omit = []
        return {
            snake_to_pascal_case(attr): value.to_dict() if hasattr(value, "to_dict") else value
            for attr, value in filter(
                lambda kv: not (kv[1] is None or kv[0].startswith("_") or kv[0] in omit),
                self.__dict__.items(),
            )
        }

    def to_json(self, omit: Optional[Iterable[str]] = None):
        return json.dumps(self.to_dict(omit=omit))
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



