Source code for recap.utils.text

import json
import re
from typing import Tuple, Optional, Any

JSON_FENCE = re.compile(r"```(?:json)?\s*(\{.*?\})\s*```", re.DOTALL)
JSON_INLINE = re.compile(r"\{.*\}", re.DOTALL)
_TRAILING_COMMAS = re.compile(r",\s*([}\]])")


def _clean_json(blob: str) -> str:
    """
    Given a JSON blob remove any invalid trailing commans

    Args:
      blob: string with json object

    Return:
      Corrected string with no trailing commas
    """
    return _TRAILING_COMMAS.sub(r"\1", blob)


[docs] def parse_json_body(text: str) -> Tuple[Optional[dict], str]: if not text: return None, text last_fence = None for last_fence in JSON_FENCE.finditer(text): pass if last_fence: blob = last_fence.group(1) try: obj: dict = json.loads(_clean_json(blob)) obj = strip_keys(obj) m = last_fence remainder = text[: m.start()] + text[m.end() :] return obj, remainder.strip() except Exception: pass last_inline = None for last_inline in JSON_INLINE.finditer(text): pass if last_inline: blob = last_inline.group(0) try: obj: dict = json.loads(_clean_json(blob)) obj = strip_keys(obj) start, end = last_inline.start(), last_inline.end() remainder = text[:start] + text[end:] return obj, remainder.strip() except Exception: pass return None, text
[docs] def strip_keys(obj) -> Any: """ Recursively remove leading and trailing whitespace from dictionary keys. Args: obj (dict): The dictionary object to process. Returns: object with all dictionary keys stripped of surrounding whitespace. """ if isinstance(obj, dict): new_dict = {} for key, value in obj.items(): # Strip whitespace from string keys only new_key = key.strip() if isinstance(key, str) else key new_dict[new_key] = strip_keys(value) return new_dict elif isinstance(obj, list): # Apply recursively to elements inside lists return [strip_keys(item) for item in obj] else: return obj