Source code for supervisely.io.json

# coding: utf-8
import os
import json
from typing import Dict, Optional


class JsonSerializable:
    def to_json(self):
        """Serialize to JSON-compatible dict.
        :return: dict
        """
        raise NotImplementedError()

    @classmethod
    def from_json(cls, data):
        """
        Deserialize from a JSON-compatible dict
        :param data: JSON-compatible dict
        :return: Parsed object
        """
        raise NotImplementedError()


[docs]def load_json_file(filename: str) -> Dict: """ Decoding data from json file with given filename. :param filename: Target file path. :type filename: str :raises IsADirectoryError: If given filename is a directory, not a file. :raises FileNotFoundError: If file with given filename was not found. :raises RuntimeError: If can not decode json file. :returns: Json format as a dict :rtype: :class:`dict` :Usage example: .. code-block:: python from supervisely.io.json import load_json_file json_example = load_json_file('/home/admin/work/projects/examples/ann.json') print(json_example) # Output: { # "description": "", # "tags": [], # "size": { # "height": 800, # "width": 1067 # }, # "objects": [ # { # "id": 619053179, # "classId": 2791451, # "description": "", # "geometryType": "bitmap", # "labelerLogin": "alexxx", # "createdAt": "2021-02-10T08:36:33.898Z", # "updatedAt": "2021-02-10T08:39:24.828Z", # "tags": [], # "classTitle": "lemon", # "bitmap": { # "data": "eJwBZgOZ/IlQTkcNChoKAAAADUlIR...AiRp9+EwAAAABJRU5ErkJgggn2cM0=", # "origin": [ # 531, # 120 # ] # } # }, # { # "id": 619053347, # "classId": 2791453, # "description": "", # "geometryType": "rectangle", # "labelerLogin": "alexxx", # "createdAt": "2021-02-10T08:39:08.369Z", # "updatedAt": "2021-02-10T08:39:24.828Z", # "tags": [], # "classTitle": "kiwi", # "points": { # "exterior": [ # [ # 764, # 387 # ], # [ # 967, # 608 # ] # ], # "interior": [] # } # }, # { # "id": 619053355, # "classId": 2791453, # "description": "", # "geometryType": "rectangle", # "labelerLogin": "alexxx", # "createdAt": "2021-02-10T08:39:16.938Z", # "updatedAt": "2021-02-10T08:39:24.828Z", # "tags": [], # "classTitle": "kiwi", # "points": { # "exterior": [ # [ # 477, # 543 # ], # [ # 647, # 713 # ] # ], # "interior": [] # } # } # ] # } """ if os.path.isdir(filename): raise IsADirectoryError(f"The path {filename} is a directory, not a file.") elif not os.path.isfile(filename): raise FileNotFoundError(f"File with path {filename} was not found.") try: with open(filename, encoding="utf-8") as fin: return json.load(fin) except json.decoder.JSONDecodeError as e: raise RuntimeError( f"Can not decode json file with path {filename}: {e.msg} at " f"line number: {e.lineno}, column: {e.colno}, position: {e.pos}. " f"Document: {e.doc}" )
[docs]def dump_json_file(data: Dict, filename: str, indent: Optional[int] = 4) -> None: """ Write given data in json format in file with given name. :param data: Data in json format as a dict. :type data: dict :param filename: Target file path to write data. :type filename: str :param indent: Json array elements and object members will be pretty-printed with that indent level. :type indent: int, optional :returns: None :rtype: :class:`NoneType` :Usage example: .. code-block:: python from supervisely.io.json import dump_json_file data = {1: 'example'} dump_json_file(data, '/home/admin/work/projects/examples/1.json') """ with open(filename, "w") as fout: json.dump(data, fout, indent=indent)
[docs]def flatten_json(data: Dict, sep: Optional[str] = ".") -> Dict: """ Normalize semi-structured JSON data into a flat table. :param data: Data in json format as a dict. :type data: dict :param sep: Nested records will generate names separated by sep. :type sep: str, optional :returns: Dict :rtype: :class:`dict` """ import pandas as pd df = pd.json_normalize(data, sep=sep) return df.to_dict(orient="records")[0]
[docs]def modify_keys( data: Dict, prefix: Optional[str] = None, suffix: Optional[str] = None ) -> Dict[str, str]: """ Add prefix and suffix to keys of given dict. :param data: Data in json format as a dict. :type data: dict :param prefix: Prefix which will be added to dict. :type prefix: str, optional :param suffix: Suffix which will be added to dict. :type suffix: str, optional :returns: New dict with prefix and suffix in keys :rtype: :class:`dict` :Usage example: .. code-block:: python from supervisely.io.json import modify_keys data = {'1': 'example', '3': 4} new_data = modify_keys(data, prefix='pr_', suffix='_su') print(new_data) # Output: {'pr_1_su': 'example', 'pr_3_su': 4} """ def _modify(k): res = k if prefix is not None: res = prefix + res if suffix is not None: res += suffix return res return {_modify(k): v for k, v in data.items()}