From 1e278fa2cbc039412abca9ec75c07c20bcc3beec Mon Sep 17 00:00:00 2001 From: Bharath Vignesh J K <52282402+RazCrimson@users.noreply.github.com> Date: Wed, 28 Aug 2024 00:04:22 +0530 Subject: [PATCH] chg: make orjson optional --- glances/client.py | 8 +++----- glances/client_browser.py | 18 ++++++++---------- glances/globals.py | 22 ++++++++++++++++------ glances/plugins/vms/engines/multipass.py | 13 ++++++------- 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/glances/client.py b/glances/client.py index 308f2061..a8f659bd 100644 --- a/glances/client.py +++ b/glances/client.py @@ -11,10 +11,8 @@ import sys import time -import orjson - from glances import __version__ -from glances.globals import Fault, ProtocolError, ServerProxy, Transport +from glances.globals import Fault, ProtocolError, ServerProxy, Transport, json_loads from glances.logger import logger from glances.outputs.glances_curses import GlancesCursesClient from glances.stats_client import GlancesStatsClient @@ -118,7 +116,7 @@ class GlancesClient: if __version__.split('.')[0] == client_version.split('.')[0]: # Init stats self.stats = GlancesStatsClient(config=self.config, args=self.args) - self.stats.set_plugins(orjson.loads(self.client.getAllPlugins())) + self.stats.set_plugins(json_loads(self.client.getAllPlugins())) logger.debug(f"Client version: {__version__} / Server version: {client_version}") else: self.log_and_exit( @@ -195,7 +193,7 @@ class GlancesClient: """ # Update the stats try: - server_stats = orjson.loads(self.client.getAll()) + server_stats = json_loads(self.client.getAll()) except OSError: # Client cannot get server stats return "Disconnected" diff --git a/glances/client_browser.py b/glances/client_browser.py index 12a52680..d2a2f3ae 100644 --- a/glances/client_browser.py +++ b/glances/client_browser.py @@ -10,11 +10,9 @@ import threading -import orjson - from glances.autodiscover import GlancesAutoDiscoverServer from glances.client import GlancesClient, GlancesClientTransport -from glances.globals import Fault, ProtocolError, ServerProxy +from glances.globals import Fault, ProtocolError, ServerProxy, json_loads from glances.logger import LOG_FILENAME, logger from glances.outputs.glances_curses_browser import GlancesCursesBrowser from glances.password_list import GlancesPasswordList as GlancesPassword @@ -97,13 +95,13 @@ class GlancesClientBrowser: # CPU% # logger.info(f"CPU stats {s.getPlugin('cpu')}") # logger.info(f"CPU views {s.getPluginView('cpu')}") - server['cpu_percent'] = orjson.loads(s.getPlugin('cpu'))['total'] - server['cpu_percent_decoration'] = orjson.loads(s.getPluginView('cpu'))['total']['decoration'] + server['cpu_percent'] = json_loads(s.getPlugin('cpu'))['total'] + server['cpu_percent_decoration'] = json_loads(s.getPluginView('cpu'))['total']['decoration'] # MEM% - server['mem_percent'] = orjson.loads(s.getPlugin('mem'))['percent'] - server['mem_percent_decoration'] = orjson.loads(s.getPluginView('mem'))['percent']['decoration'] + server['mem_percent'] = json_loads(s.getPlugin('mem'))['percent'] + server['mem_percent_decoration'] = json_loads(s.getPluginView('mem'))['percent']['decoration'] # OS (Human Readable name) - server['hr_name'] = orjson.loads(s.getPlugin('system'))['hr_name'] + server['hr_name'] = json_loads(s.getPlugin('system'))['hr_name'] server['hr_name_decoration'] = 'DEFAULT' except (OSError, Fault, KeyError) as e: logger.debug(f"Error while grabbing stats form server ({e})") @@ -124,8 +122,8 @@ class GlancesClientBrowser: # Optional stats (load is not available on Windows OS) try: # LOAD - server['load_min5'] = round(orjson.loads(s.getPlugin('load'))['min5'], 1) - server['load_min5_decoration'] = orjson.loads(s.getPluginView('load'))['min5']['decoration'] + server['load_min5'] = round(json_loads(s.getPlugin('load'))['min5'], 1) + server['load_min5_decoration'] = json_loads(s.getPluginView('load'))['min5']['decoration'] except Exception as e: logger.warning(f"Error while grabbing stats form server ({e})") diff --git a/glances/globals.py b/glances/globals.py index 0060e3d1..e6c24ce0 100644 --- a/glances/globals.py +++ b/glances/globals.py @@ -27,17 +27,22 @@ from configparser import ConfigParser, NoOptionError, NoSectionError from datetime import datetime from operator import itemgetter, methodcaller from statistics import mean +from typing import Dict, List, Union from urllib.error import HTTPError, URLError from urllib.parse import urlparse from urllib.request import Request, urlopen from xmlrpc.client import Fault, ProtocolError, Server, ServerProxy, Transport from xmlrpc.server import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer -import orjson - -# Correct issue #1025 by monkey path the xmlrpc lib from defusedxml.xmlrpc import monkey_patch +# Optionally use orjson if available +try: + import orjson as json +except ImportError: + import json + +# Correct issue #1025 by monkey path the xmlrpc lib monkey_patch() ############## @@ -303,15 +308,20 @@ def urlopen_auth(url, username, password): ) -def json_dumps(data): +def json_dumps(data) -> str: """Return the object data in a JSON format. Manage the issue #815 for Windows OS with UnicodeDecodeError catching. """ try: - return orjson.dumps(data) + return json.dumps(data) except UnicodeDecodeError: - return orjson.dumps(data, ensure_ascii=False) + return json.dumps(data, ensure_ascii=False) + + +def json_loads(data: Union[str, bytes, bytearray]) -> Union[Dict, List]: + """Load a JSON buffer into memory as a Python object""" + return json.loads(data) def dictlist(data, item): diff --git a/glances/plugins/vms/engines/multipass.py b/glances/plugins/vms/engines/multipass.py index 2bd9725f..bb1b9eca 100644 --- a/glances/plugins/vms/engines/multipass.py +++ b/glances/plugins/vms/engines/multipass.py @@ -8,12 +8,11 @@ """Multipass Extension unit for Glances' Vms plugin.""" +import json import os from typing import Any, Dict, List, Tuple -import orjson - -from glances.globals import nativestr +from glances.globals import json_loads, nativestr from glances.secure import secure_popen # Check if multipass binary exist @@ -40,8 +39,8 @@ class VmExtension: # } ret_cmd = secure_popen(f'{MULTIPASS_PATH} {MULTIPASS_VERSION_OPTIONS}') try: - ret = orjson.loads(ret_cmd) - except orjson.JSONDecodeError: + ret = json_loads(ret_cmd) + except json.JSONDecodeError: return {} else: return ret.get('multipass', None) @@ -84,8 +83,8 @@ class VmExtension: # } ret_cmd = secure_popen(f'{MULTIPASS_PATH} {MULTIPASS_INFO_OPTIONS}') try: - ret = orjson.loads(ret_cmd) - except orjson.JSONDecodeError: + ret = json_loads(ret_cmd) + except json.JSONDecodeError: return {} else: return ret.get('info', {})