prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Json file exploration/profiling
  Unstructured data as JSON can not be explored as regular tabular data. I have been exploring using tree depth and count to highlight the user in which nodes could have important data.
  
  Some work in progress, here. https://github.com/ironmussa/Optimus/blob/develop-3.0/optimus/engines/pandas/io/json.py
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `optimus/engines/pandas/io/json.py`
  Content:
  ```
  1 import glob
  2 
  3 import pandas as pd
  4 import ujson
  5 from glom import glom
  6 
  7 from optimus.infer import is_dict, is_list, is_str, is_int
  8 
  9 META = "_meta"
  10 PROPERTIES = "_properties"
  11 ITEMS = "_items"
  12 
  13 COL_DEPTH = "depth"
  14 
  15 
  16 class JSON:
  17     def __init__(self):
  18         self.data = None
  19 
  20     def load(self, path):
  21         """
  22         Load a file in JSON  format
  23         :param path:
  24         :return:
  25         """
  26         all_json = glob.glob(path, recursive=True)
  27         # pd.read_json("data/corona.json")
  28         with open(all_json[0]) as f:
  29             self.data = ujson.load(f)
  30 
  31     def schema(self):
  32         """
  33         Return a JSON with the count, dtype and nested structure
  34         :return:
  35         """
  36 
  37         def _schema(_data, _keys):
  38             if isinstance(_data, dict):
  39                 for x, y in _data.items():
  40                     if is_dict(y):
  41                         _keys[x] = {META: {"count": len(y), "dtype": type(y)}}
  42                         if len(y) > 0:
  43                             _keys[x][PROPERTIES] = {}
  44                             _schema(y, _keys[x][PROPERTIES])
  45                     elif is_list(y):
  46                         _keys[x] = {META: {"count": len(y), "dtype": type(y)}}
  47                         if len(y) > 0:
  48                             _keys[x] = {ITEMS: {PROPERTIES: {}, META: {"count": len(y), "dtype": type(y)}}}
  49                             _schema(y, _keys[x][ITEMS][PROPERTIES])
  50                     elif is_str(y):
  51                         _keys[x] = {META: {"count": len(y), "dtype": type(y)}}
  52                         _schema(y, _keys[x])
  53                     elif is_int(y):
  54                         _keys[x] = {META: {"dtype": type(y)}}
  55                         _schema(y, _keys[x])
  56 
  57             elif is_list(_data):
  58                 for x in _data:
  59                     _schema(x, _keys)
  60 
  61         keys = {}
  62         _schema(self.data, keys)
  63         return keys
  64 
  65     def freq(self, n=100):
  66         """
  67         Calculate the count on every dict or list in the json
  68         :param n:
  69         :return:
  70         """
  71 
  72         def _profile(keys, parent, result=None):
  73             for key, values in keys.items():
  74                 if values.get(PROPERTIES):
  75                     _meta = values.get(META)
  76                     _properties = values.get(PROPERTIES)
  77                 elif values.get(ITEMS):
  78                     _meta = values.get(ITEMS).get(META)
  79                     _properties = values.get(ITEMS).get(PROPERTIES)
  80 
  81                 if values.get(PROPERTIES) or values.get(ITEMS):
  82                     result.append([key, _meta["count"], _meta["dtype"], parent, len(parent)])
  83                     _profile(_properties, parent + [key], result=result)
  84 
  85         data = []
  86         _profile(self.schema(), [], data)
  87         df = pd.DataFrame(data, columns=['key', 'count', 'dtype', 'path', COL_DEPTH])
  88         df = df.sort_values(by=["count", COL_DEPTH], ascending=[False, True]).head(n).to_dict(orient='row')
  89         return df
  90 
  91     def flatten(self, path):
  92         """
  93         Flatten a JSON from a json path
  94         :param path:
  95         :return:
  96         """
  97 
  98         def _flatten_json(_values):
  99             out = {}
  100 
  101             def flatten(x, name=''):
  102                 if type(x) is dict:
  103                     for a in x:
  104                         flatten(x[a], name + a + '_')
  105                 elif type(x) is list:
  106                     # i = 0
  107                     for a in x:
  108                         # flatten(a, name + str(i) + '_')
  109                         flatten(a, name + '_')
  110                         # i += 1
  111                 else:
  112                     out[name[:-1]] = x
  113 
  114             flatten(_values)
  115             return out
  116 
  117         result = []
  118         value = glom(self.data, path, skip_exc=KeyError)
  119         if is_list(value):
  120             for i in value:
  121                 result.append((_flatten_json(i)))
  122         elif is_dict(value):
  123             for i, j in value.items():
  124                 a = {"col": i}
  125                 a.update(_flatten_json(j))
  126                 result.append(a)
  127         return result
  128 
  129     def to_pandas(self, path):
  130         result = self.flatten(path)
  131         return pd.DataFrame(data=result)
  132
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/optimus/engines/pandas/io/json.py b/optimus/engines/pandas/io/json.py
  --- a/optimus/engines/pandas/io/json.py
  +++ b/optimus/engines/pandas/io/json.py
  @@ -121,7 +121,7 @@
                   result.append((_flatten_json(i)))
           elif is_dict(value):
               for i, j in value.items():
  -                a = {"col": i}
  +                a = {path: i}
                   a.update(_flatten_json(j))
                   result.append(a)
           return result
  
verification_info: {"golden_diff": "diff --git a/optimus/engines/pandas/io/json.py b/optimus/engines/pandas/io/json.py\n--- a/optimus/engines/pandas/io/json.py\n+++ b/optimus/engines/pandas/io/json.py\n@@ -121,7 +121,7 @@\n                 result.append((_flatten_json(i)))\n         elif is_dict(value):\n             for i, j in value.items():\n-                a = {\"col\": i}\n+                a = {path: i}\n                 a.update(_flatten_json(j))\n                 result.append(a)\n         return result\n", "issue": "Json file exploration/profiling\nUnstructured data as JSON can not be explored as regular tabular data. I have been exploring using tree depth and count to highlight the user in which nodes could have important data.\r\n\r\nSome work in progress, here. https://github.com/ironmussa/Optimus/blob/develop-3.0/optimus/engines/pandas/io/json.py\n", "before_files": [{"content": "import glob\n\nimport pandas as pd\nimport ujson\nfrom glom import glom\n\nfrom optimus.infer import is_dict, is_list, is_str, is_int\n\nMETA = \"_meta\"\nPROPERTIES = \"_properties\"\nITEMS = \"_items\"\n\nCOL_DEPTH = \"depth\"\n\n\nclass JSON:\n    def __init__(self):\n        self.data = None\n\n    def load(self, path):\n        \"\"\"\n        Load a file in JSON  format\n        :param path:\n        :return:\n        \"\"\"\n        all_json = glob.glob(path, recursive=True)\n        # pd.read_json(\"data/corona.json\")\n        with open(all_json[0]) as f:\n            self.data = ujson.load(f)\n\n    def schema(self):\n        \"\"\"\n        Return a JSON with the count, dtype and nested structure\n        :return:\n        \"\"\"\n\n        def _schema(_data, _keys):\n            if isinstance(_data, dict):\n                for x, y in _data.items():\n                    if is_dict(y):\n                        _keys[x] = {META: {\"count\": len(y), \"dtype\": type(y)}}\n                        if len(y) > 0:\n                            _keys[x][PROPERTIES] = {}\n                            _schema(y, _keys[x][PROPERTIES])\n                    elif is_list(y):\n                        _keys[x] = {META: {\"count\": len(y), \"dtype\": type(y)}}\n                        if len(y) > 0:\n                            _keys[x] = {ITEMS: {PROPERTIES: {}, META: {\"count\": len(y), \"dtype\": type(y)}}}\n                            _schema(y, _keys[x][ITEMS][PROPERTIES])\n                    elif is_str(y):\n                        _keys[x] = {META: {\"count\": len(y), \"dtype\": type(y)}}\n                        _schema(y, _keys[x])\n                    elif is_int(y):\n                        _keys[x] = {META: {\"dtype\": type(y)}}\n                        _schema(y, _keys[x])\n\n            elif is_list(_data):\n                for x in _data:\n                    _schema(x, _keys)\n\n        keys = {}\n        _schema(self.data, keys)\n        return keys\n\n    def freq(self, n=100):\n        \"\"\"\n        Calculate the count on every dict or list in the json\n        :param n:\n        :return:\n        \"\"\"\n\n        def _profile(keys, parent, result=None):\n            for key, values in keys.items():\n                if values.get(PROPERTIES):\n                    _meta = values.get(META)\n                    _properties = values.get(PROPERTIES)\n                elif values.get(ITEMS):\n                    _meta = values.get(ITEMS).get(META)\n                    _properties = values.get(ITEMS).get(PROPERTIES)\n\n                if values.get(PROPERTIES) or values.get(ITEMS):\n                    result.append([key, _meta[\"count\"], _meta[\"dtype\"], parent, len(parent)])\n                    _profile(_properties, parent + [key], result=result)\n\n        data = []\n        _profile(self.schema(), [], data)\n        df = pd.DataFrame(data, columns=['key', 'count', 'dtype', 'path', COL_DEPTH])\n        df = df.sort_values(by=[\"count\", COL_DEPTH], ascending=[False, True]).head(n).to_dict(orient='row')\n        return df\n\n    def flatten(self, path):\n        \"\"\"\n        Flatten a JSON from a json path\n        :param path:\n        :return:\n        \"\"\"\n\n        def _flatten_json(_values):\n            out = {}\n\n            def flatten(x, name=''):\n                if type(x) is dict:\n                    for a in x:\n                        flatten(x[a], name + a + '_')\n                elif type(x) is list:\n                    # i = 0\n                    for a in x:\n                        # flatten(a, name + str(i) + '_')\n                        flatten(a, name + '_')\n                        # i += 1\n                else:\n                    out[name[:-1]] = x\n\n            flatten(_values)\n            return out\n\n        result = []\n        value = glom(self.data, path, skip_exc=KeyError)\n        if is_list(value):\n            for i in value:\n                result.append((_flatten_json(i)))\n        elif is_dict(value):\n            for i, j in value.items():\n                a = {\"col\": i}\n                a.update(_flatten_json(j))\n                result.append(a)\n        return result\n\n    def to_pandas(self, path):\n        result = self.flatten(path)\n        return pd.DataFrame(data=result)\n", "path": "optimus/engines/pandas/io/json.py"}], "after_files": [{"content": "import glob\n\nimport pandas as pd\nimport ujson\nfrom glom import glom\n\nfrom optimus.infer import is_dict, is_list, is_str, is_int\n\nMETA = \"_meta\"\nPROPERTIES = \"_properties\"\nITEMS = \"_items\"\n\nCOL_DEPTH = \"depth\"\n\n\nclass JSON:\n    def __init__(self):\n        self.data = None\n\n    def load(self, path):\n        \"\"\"\n        Load a file in JSON  format\n        :param path:\n        :return:\n        \"\"\"\n        all_json = glob.glob(path, recursive=True)\n        # pd.read_json(\"data/corona.json\")\n        with open(all_json[0]) as f:\n            self.data = ujson.load(f)\n\n    def schema(self):\n        \"\"\"\n        Return a JSON with the count, dtype and nested structure\n        :return:\n        \"\"\"\n\n        def _schema(_data, _keys):\n            if isinstance(_data, dict):\n                for x, y in _data.items():\n                    if is_dict(y):\n                        _keys[x] = {META: {\"count\": len(y), \"dtype\": type(y)}}\n                        if len(y) > 0:\n                            _keys[x][PROPERTIES] = {}\n                            _schema(y, _keys[x][PROPERTIES])\n                    elif is_list(y):\n                        _keys[x] = {META: {\"count\": len(y), \"dtype\": type(y)}}\n                        if len(y) > 0:\n                            _keys[x] = {ITEMS: {PROPERTIES: {}, META: {\"count\": len(y), \"dtype\": type(y)}}}\n                            _schema(y, _keys[x][ITEMS][PROPERTIES])\n                    elif is_str(y):\n                        _keys[x] = {META: {\"count\": len(y), \"dtype\": type(y)}}\n                        _schema(y, _keys[x])\n                    elif is_int(y):\n                        _keys[x] = {META: {\"dtype\": type(y)}}\n                        _schema(y, _keys[x])\n\n            elif is_list(_data):\n                for x in _data:\n                    _schema(x, _keys)\n\n        keys = {}\n        _schema(self.data, keys)\n        return keys\n\n    def freq(self, n=100):\n        \"\"\"\n        Calculate the count on every dict or list in the json\n        :param n:\n        :return:\n        \"\"\"\n\n        def _profile(keys, parent, result=None):\n            for key, values in keys.items():\n                if values.get(PROPERTIES):\n                    _meta = values.get(META)\n                    _properties = values.get(PROPERTIES)\n                elif values.get(ITEMS):\n                    _meta = values.get(ITEMS).get(META)\n                    _properties = values.get(ITEMS).get(PROPERTIES)\n\n                if values.get(PROPERTIES) or values.get(ITEMS):\n                    result.append([key, _meta[\"count\"], _meta[\"dtype\"], parent, len(parent)])\n                    _profile(_properties, parent + [key], result=result)\n\n        data = []\n        _profile(self.schema(), [], data)\n        df = pd.DataFrame(data, columns=['key', 'count', 'dtype', 'path', COL_DEPTH])\n        df = df.sort_values(by=[\"count\", COL_DEPTH], ascending=[False, True]).head(n).to_dict(orient='row')\n        return df\n\n    def flatten(self, path):\n        \"\"\"\n        Flatten a JSON from a json path\n        :param path:\n        :return:\n        \"\"\"\n\n        def _flatten_json(_values):\n            out = {}\n\n            def flatten(x, name=''):\n                if type(x) is dict:\n                    for a in x:\n                        flatten(x[a], name + a + '_')\n                elif type(x) is list:\n                    # i = 0\n                    for a in x:\n                        # flatten(a, name + str(i) + '_')\n                        flatten(a, name + '_')\n                        # i += 1\n                else:\n                    out[name[:-1]] = x\n\n            flatten(_values)\n            return out\n\n        result = []\n        value = glom(self.data, path, skip_exc=KeyError)\n        if is_list(value):\n            for i in value:\n                result.append((_flatten_json(i)))\n        elif is_dict(value):\n            for i, j in value.items():\n                a = {path: i}\n                a.update(_flatten_json(j))\n                result.append(a)\n        return result\n\n    def to_pandas(self, path):\n        result = self.flatten(path)\n        return pd.DataFrame(data=result)\n", "path": "optimus/engines/pandas/io/json.py"}]}