Source code for json2xml.utils

"""Utility methods for reading JSON data from various sources."""
from __future__ import annotations

import json
from typing import Any

__lazy_modules__ = ["urllib3"]

from .types import JSONValue

DEFAULT_URL_TIMEOUT: Any | None = None
_HTTP: Any | None = None


def _get_http_client() -> tuple[Any, Any, Any]:
    """Import and initialize urllib3 only for URL reads."""
    import urllib3

    global DEFAULT_URL_TIMEOUT, _HTTP
    if DEFAULT_URL_TIMEOUT is None:
        DEFAULT_URL_TIMEOUT = urllib3.Timeout(connect=5.0, read=30.0)
    if _HTTP is None:
        _HTTP = urllib3.PoolManager()
    return urllib3, _HTTP, DEFAULT_URL_TIMEOUT


[docs] class JSONReadError(Exception): """Raised when there is an error reading JSON data.""" pass
[docs] class InvalidDataError(Exception): """Raised when the data is invalid.""" pass
[docs] class URLReadError(Exception): """Raised when there is an error reading from a URL.""" pass
[docs] class StringReadError(Exception): """Raised when there is an error reading from a string.""" pass
# @lat: [[behavior#Input readers]]
[docs] def readfromjson(filename: str) -> JSONValue: """Read JSON data from a file.""" try: with open(filename, encoding="utf-8") as jsondata: return json.load(jsondata) except (ValueError, OSError) as error: raise JSONReadError("Invalid JSON File") from error
[docs] def readfromurl(url: str, params: dict[str, str] | None = None) -> JSONValue: """Load JSON data from a URL.""" urllib3, http, timeout = _get_http_client() try: response = http.request( "GET", url, fields=params, timeout=timeout, retries=False, ) except urllib3.exceptions.HTTPError as error: raise URLReadError("URL could not be read") from error if response.status != 200: raise URLReadError("URL is not returning correct response") try: return json.loads(response.data.decode("utf-8")) except (UnicodeDecodeError, json.JSONDecodeError) as error: raise URLReadError("URL did not return valid JSON") from error
[docs] def readfromstring(jsondata: object) -> JSONValue: """Load JSON data from a string.""" if not isinstance(jsondata, str): raise StringReadError("Input is not a proper JSON string") try: return json.loads(jsondata) except ValueError as error: raise StringReadError("Input is not a proper JSON string") from error