Skip to content

Commit

Permalink
chg: make orjson optional
Browse files Browse the repository at this point in the history
  • Loading branch information
RazCrimson committed Aug 27, 2024
1 parent 92de3be commit 1e278fa
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 28 deletions.
8 changes: 3 additions & 5 deletions glances/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -118,7 +116,7 @@ def _login_glances(self):
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(
Expand Down Expand Up @@ -195,7 +193,7 @@ def update_glances(self):
"""
# 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"
Expand Down
18 changes: 8 additions & 10 deletions glances/client_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -97,13 +95,13 @@ def __update_stats(self, server):
# 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})")
Expand All @@ -124,8 +122,8 @@ def __update_stats(self, server):
# 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})")

Expand Down
22 changes: 16 additions & 6 deletions glances/globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,22 @@
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()

##############
Expand Down Expand Up @@ -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)

This comment has been minimized.

Copy link
@nicolargo

nicolargo Sep 1, 2024

Owner

This peace of code (including the previous version) is not relevant for orjson.

orjson.dumps('été', ensure_ascii=True)
Traceback (most recent call last):
File "", line 1, in
TypeError: dumps() got an unexpected keyword argument

json.dumps('été', ensure_ascii=True)
'"\u00e9t\u00e9"'

This comment has been minimized.

Copy link
@nicolargo

nicolargo Sep 1, 2024

Owner

Perhaps ensure_ascii option is not needed anymore for Python 3...

This comment has been minimized.

Copy link
@nicolargo

nicolargo Sep 1, 2024

Owner

In fact the json_dumps function is not used in Glances. The only file that uses JSON dumps is server.py and it directly import json and not orjson.

This comment has been minimized.

Copy link
@RazCrimson

RazCrimson Sep 1, 2024

Author Collaborator

@nicolargo
Any reason to avoid using orjson or other faster serialization libs and stick to native json instead for dumps?

If there is none, then wont it be better to just have a centralized json_dumps method which internally can use a faster lib if its available, otherwise fallback to native json lib?



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):
Expand Down
13 changes: 6 additions & 7 deletions glances/plugins/vms/engines/multipass.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -40,8 +39,8 @@ def update_version(self):
# }
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)
Expand Down Expand Up @@ -84,8 +83,8 @@ def update_info(self):
# }
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', {})
Expand Down

0 comments on commit 1e278fa

Please sign in to comment.