mirror of https://github.com/nicolargo/glances.git
Create a Glances API in order to use Glances as a Python lib #3237
This commit is contained in:
parent
365a670c12
commit
3d263bc7d4
3
Makefile
3
Makefile
|
|
@ -211,8 +211,9 @@ trivy: ## Run Trivy to find vulnerabilities in container images
|
|||
# ===================================================================
|
||||
|
||||
docs: ## Create the documentation
|
||||
$(PYTHON) -m glances -C $(CONF) --api-doc > ./docs/api/python.rst
|
||||
$(PYTHON) ./generate_openapi.py
|
||||
$(PYTHON) -m glances -C $(CONF) --api-doc > ./docs/api.rst
|
||||
$(PYTHON) -m glances -C $(CONF) --api-restful-doc > ./docs/api/restful.rst
|
||||
cd docs && ./build.sh && cd ..
|
||||
|
||||
docs-server: docs ## Start a Web server to serve the documentation
|
||||
|
|
|
|||
16
NEWS.rst
16
NEWS.rst
|
|
@ -424,7 +424,7 @@ See release note in Wiki format: https://github.com/nicolargo/glances/wiki/Glanc
|
|||
**BREAKING CHANGES:**
|
||||
|
||||
* The minimal Python version is 3.8
|
||||
* The Glances API version 3 is replaced by the version 4. So Restfull API URL is now /api/4/ #2610
|
||||
* The Glances API version 3 is replaced by the version 4. So Restful API URL is now /api/4/ #2610
|
||||
* Alias definition change in the configuration file #1735
|
||||
|
||||
Glances version 3.x and lower:
|
||||
|
|
@ -449,9 +449,9 @@ Minimal requirements for Glances version 4 are:
|
|||
* packaging
|
||||
* ujson
|
||||
* pydantic
|
||||
* fastapi (for WebUI / RestFull API)
|
||||
* uvicorn (for WebUI / RestFull API)
|
||||
* jinja2 (for WebUI / RestFull API)
|
||||
* fastapi (for WebUI / RestFul API)
|
||||
* uvicorn (for WebUI / RestFul API)
|
||||
* jinja2 (for WebUI / RestFul API)
|
||||
|
||||
Majors changes between Glances version 3 and version 4:
|
||||
|
||||
|
|
@ -511,7 +511,7 @@ Bug corrected:
|
|||
CI and documentation:
|
||||
|
||||
* New logo for Glances version 4.0 #2713
|
||||
* Update api.rst documentation #2496
|
||||
* Update api-restful.rst documentation #2496
|
||||
* Change Renovate config #2729
|
||||
* Docker compose password unrecognized arguments when applying docs #2698
|
||||
* Docker includes OS Release Volume mount info #2473
|
||||
|
|
@ -889,7 +889,7 @@ Bugs corrected:
|
|||
* Threading.Event.isSet is deprecated in Python 3.10 #2017
|
||||
* Fix code scanning alert - Clear-text logging of sensitive information security #2006
|
||||
* The gpu temperature unit are displayed incorrectly in web ui bug #2002
|
||||
* Doc for 'alert' Restfull/JSON API response documentation #1994
|
||||
* Doc for 'alert' Restful/JSON API response documentation #1994
|
||||
* Show the spinning state of a disk documentation #1993
|
||||
* Web server status check endpoint enhancement #1988
|
||||
* --time parameter being ignored for client/server mode bug #1978
|
||||
|
|
@ -984,7 +984,7 @@ Bugs corrected:
|
|||
* [3.2.0/3.2.1] keybinding not working anymore #1904
|
||||
* InfluxDB/InfluxDB2 Export object has no attribute hostname #1899
|
||||
|
||||
Documentation: The "make docs" generate RestFull/API documentation file.
|
||||
Documentation: The "make docs" generate RestFul/API documentation file.
|
||||
|
||||
===============
|
||||
Version 3.2.1
|
||||
|
|
@ -2011,7 +2011,7 @@ Version 2.1
|
|||
* Add Glances log message (in the /tmp/glances.log file)
|
||||
The default log level is INFO, you can switch to the DEBUG mode using the -d option on the command line.
|
||||
* Add RESTful API to the Web server mode
|
||||
RESTful API doc: https://github.com/nicolargo/glances/wiki/The-Glances-RESTFULL-JSON-API
|
||||
RESTful API doc: https://github.com/nicolargo/glances/wiki/The-Glances-RESTFUL-JSON-API
|
||||
* Improve SNMP fallback mode for Cisco IOS, VMware ESXi
|
||||
* Add --theme-white feature to optimize display for white background
|
||||
* Experimental history feature (--enable-history option on the command line)
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ history_size=1200
|
|||
# You can download it in a specific folder
|
||||
# thanks to https://github.com/nicolargo/glances/issues/2021
|
||||
# then configure this folder with the webui_root_path key
|
||||
# Default is folder where glances_restfull_api.py is hosted
|
||||
# Default is folder where glances_restful_api.py is hosted
|
||||
#webui_root_path=
|
||||
# CORS options
|
||||
# Comma separated list of origins that should be permitted to make cross-origin requests.
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ max_processes_display=25
|
|||
# You can download it in a specific folder
|
||||
# thanks to https://github.com/nicolargo/glances/issues/2021
|
||||
# then configure this folder with the webui_root_path key
|
||||
# Default is folder where glances_restfull_api.py is hosted
|
||||
# Default is folder where glances_restful_api.py is hosted
|
||||
#webui_root_path=
|
||||
# CORS options
|
||||
# Comma separated list of origins that should be permitted to make cross-origin requests.
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ Within ``/etc/glances/actions.d/fs-critical.py``:
|
|||
.. note::
|
||||
|
||||
You can use all the stats for the current plugin. See
|
||||
https://github.com/nicolargo/glances/wiki/The-Glances-RESTFULL-JSON-API
|
||||
https://github.com/nicolargo/glances/wiki/The-Glances-RESTFUL-JSON-API
|
||||
for the stats list.
|
||||
|
||||
It is also possible to repeat action until the end of the alert.
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -80,7 +80,7 @@ than a second one concerning the user interface:
|
|||
# You can download it in a specific folder
|
||||
# thanks to https://github.com/nicolargo/glances/issues/2021
|
||||
# then configure this folder with the webui_root_path key
|
||||
# Default is folder where glances_restfull_api.py is hosted
|
||||
# Default is folder where glances_restful_api.py is hosted
|
||||
#webui_root_path=
|
||||
# CORS options
|
||||
# Comma separated list of origins that should be permitted to make cross-origin requests.
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ Table of Contents
|
|||
config
|
||||
aoa/index
|
||||
gw/index
|
||||
api
|
||||
api/python
|
||||
api/restful
|
||||
docker
|
||||
faq
|
||||
support
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "GLANCES" "1" "Jul 09, 2025" "4.3.3" "Glances"
|
||||
.TH "GLANCES" "1" "Jul 12, 2025" "4.4.0_dev1" "Glances"
|
||||
.SH NAME
|
||||
glances \- An eye on your system
|
||||
.SH SYNOPSIS
|
||||
|
|
@ -666,7 +666,7 @@ max_processes_display=25
|
|||
# You can download it in a specific folder
|
||||
# thanks to https://github.com/nicolargo/glances/issues/2021
|
||||
# then configure this folder with the webui_root_path key
|
||||
# Default is folder where glances_restfull_api.py is hosted
|
||||
# Default is folder where glances_restful_api.py is hosted
|
||||
#webui_root_path=
|
||||
# CORS options
|
||||
# Comma separated list of origins that should be permitted to make cross\-origin requests.
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ test_args = core.get_args()
|
|||
|
||||
app = GlancesRestfulApi(config=test_config, args=test_args)._app
|
||||
|
||||
with open('./docs/openapi.json', 'w') as f:
|
||||
with open('./docs/api/openapi.json', 'w') as f:
|
||||
json.dump(
|
||||
get_openapi(
|
||||
title=app.title,
|
||||
|
|
|
|||
|
|
@ -95,8 +95,8 @@ def check_memleak(args, mode):
|
|||
|
||||
|
||||
def setup_server_mode(args, mode):
|
||||
if args.stdout_issue or args.stdout_apidoc:
|
||||
# Serve once for issue/test mode
|
||||
if args.stdout_issue or args.stdout_api_restful_doc or args.stdout_api_doc:
|
||||
# Serve once for issue and API documentation modes
|
||||
mode.serve_issue()
|
||||
else:
|
||||
# Serve forever
|
||||
|
|
|
|||
|
|
@ -7,18 +7,45 @@
|
|||
#
|
||||
|
||||
from glances import __version__ as glances_version
|
||||
from glances.globals import weak_lru_cache
|
||||
from glances.main import GlancesMain
|
||||
from glances.stats import GlancesStats
|
||||
|
||||
plugin_dependencies_tree = {
|
||||
'processlist': ['processcount'],
|
||||
}
|
||||
|
||||
|
||||
class GlancesAPI:
|
||||
def __init__(self):
|
||||
ttl = 2.0 # Default cache TTL in seconds
|
||||
|
||||
def __init__(self, config=None, args=None, args_begin_at=1):
|
||||
self.__version__ = glances_version.split('.')[0] # Get the major version
|
||||
|
||||
core = GlancesMain(args_begin_at=2)
|
||||
self._stats = GlancesStats(config=core.get_config(), args=core.get_args())
|
||||
core = GlancesMain(args_begin_at)
|
||||
self.args = args if args is not None else core.get_args()
|
||||
self.config = config if config is not None else core.get_config()
|
||||
self._stats = GlancesStats(config=self.config, args=self.args)
|
||||
|
||||
for p in self._stats.getPluginsList():
|
||||
plugin = self._stats.get_plugin(p)
|
||||
if plugin is not None:
|
||||
setattr(self, p, plugin)
|
||||
# Set the cache TTL for the API
|
||||
self.ttl = self.args.time if self.args.time is not None else self.ttl
|
||||
|
||||
# Init the stats of all plugins in order to ensure that rate are computed
|
||||
self._stats.update()
|
||||
|
||||
@weak_lru_cache(maxsize=1, ttl=ttl)
|
||||
def __getattr__(self, item):
|
||||
"""Fallback to the stats object for any missing attributes."""
|
||||
if item in self._stats.getPluginsList():
|
||||
if item in plugin_dependencies_tree:
|
||||
# Ensure dependencies are updated before accessing the plugin
|
||||
for dependency in plugin_dependencies_tree[item]:
|
||||
self._stats.get_plugin(dependency).update()
|
||||
# Update the plugin stats
|
||||
self._stats.get_plugin(item).update()
|
||||
return self._stats.get_plugin(item)
|
||||
raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{item}'")
|
||||
|
||||
def plugins(self):
|
||||
"""Return the list of available plugins."""
|
||||
return self._stats.getPluginsList()
|
||||
|
|
|
|||
|
|
@ -550,7 +550,18 @@ Examples of use:
|
|||
help='test memory leak (python 3.4 or higher needed)',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--api-doc', default=None, action='store_true', dest='stdout_apidoc', help='display fields descriptions'
|
||||
'--api-doc',
|
||||
default=None,
|
||||
action='store_true',
|
||||
dest='stdout_api_doc',
|
||||
help='display Python API documentation',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--api-restful-doc',
|
||||
default=None,
|
||||
action='store_true',
|
||||
dest='stdout_api_restful_doc',
|
||||
help='display Restful API documentation',
|
||||
)
|
||||
if not WINDOWS:
|
||||
parser.add_argument(
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
# SPDX-License-Identifier: LGPL-3.0-only
|
||||
#
|
||||
|
||||
"""RestFull API interface class."""
|
||||
"""RestFul API interface class."""
|
||||
|
||||
import os
|
||||
import socket
|
||||
|
|
|
|||
|
|
@ -0,0 +1,175 @@
|
|||
#
|
||||
# This file is part of Glances.
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2025 Nicolas Hennion <nicolas@nicolargo.com>
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-3.0-only
|
||||
#
|
||||
|
||||
"""Generate Glances Python API documentation."""
|
||||
|
||||
from pprint import pformat
|
||||
|
||||
from glances import api
|
||||
|
||||
APIDOC_HEADER = """\
|
||||
.. _api:
|
||||
|
||||
Python API documentation
|
||||
========================
|
||||
|
||||
This documentation describes the Glances Python API.
|
||||
|
||||
Note: This API is only available in Glances 4.4.0 or higher.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
def printtab(s, indent=' '):
|
||||
print(indent + s.replace('\n', '\n' + indent))
|
||||
|
||||
|
||||
def print_tldr(gl):
|
||||
"""Print the TL;DR section of the API documentation."""
|
||||
sub_title = 'TL;DR'
|
||||
print(sub_title)
|
||||
print('-' * len(sub_title))
|
||||
print('')
|
||||
print('You can access the Glances API by importing the `glances.api` module and creating an')
|
||||
print('instance of the `GlancesAPI` class. This instance provides access to all Glances plugins')
|
||||
print('and their fields. For example, to access the CPU plugin and its total field, you can')
|
||||
print('use the following code:')
|
||||
print('')
|
||||
print('.. code-block:: python')
|
||||
print('')
|
||||
printtab('>>> from glances import api')
|
||||
printtab('>>> gl = api.GlancesAPI()')
|
||||
printtab('>>> gl.cpu')
|
||||
printtab(f'{pformat(gl.cpu.stats)}')
|
||||
printtab('>>> gl.cpu["total"]')
|
||||
printtab(f'{gl.cpu["total"]}')
|
||||
print('')
|
||||
print('If the stats return a list of items (like network interfaces or processes), you can')
|
||||
print('access them by their name:')
|
||||
print('')
|
||||
print('.. code-block:: python')
|
||||
print('')
|
||||
printtab(f'{gl.network.keys()}')
|
||||
printtab(f'>>> gl.network["{gl.network.keys()[0]}"]')
|
||||
printtab(f'{pformat(gl.network[gl.network.keys()[0]])}')
|
||||
print('')
|
||||
|
||||
|
||||
def print_init_api(gl):
|
||||
sub_title = 'Init Glances Python API'
|
||||
print(sub_title)
|
||||
print('-' * len(sub_title))
|
||||
print('')
|
||||
print('Init the Glances API:')
|
||||
print('')
|
||||
print('.. code-block:: python')
|
||||
print('')
|
||||
printtab('>>> from glances import api')
|
||||
printtab('>>> gl = api.GlancesAPI()')
|
||||
print('')
|
||||
|
||||
|
||||
def print_plugins_list(gl):
|
||||
sub_title = 'Get Glances plugins list'
|
||||
print(sub_title)
|
||||
print('-' * len(sub_title))
|
||||
print('')
|
||||
print('Get the plugins list:')
|
||||
print('')
|
||||
print('.. code-block:: python')
|
||||
print('')
|
||||
printtab('>>> gl.plugins()')
|
||||
printtab(f'{gl.plugins()}')
|
||||
print('```')
|
||||
print('')
|
||||
|
||||
|
||||
def print_plugin(gl, plugin):
|
||||
"""Print the details of a single plugin."""
|
||||
sub_title = f'Glances {plugin}'
|
||||
print(sub_title)
|
||||
print('-' * len(sub_title))
|
||||
print('')
|
||||
|
||||
stats_obj = gl.__getattr__(plugin)
|
||||
|
||||
print(f'{plugin.capitalize()} stats:')
|
||||
print('')
|
||||
print('.. code-block:: python')
|
||||
print('')
|
||||
printtab(f'>>> gl.{plugin}')
|
||||
printtab(f'Return a {type(stats_obj)} object')
|
||||
if len(stats_obj.keys()) > 0 and isinstance(stats_obj[stats_obj.keys()[0]], dict):
|
||||
printtab(f'>>> gl.{plugin}')
|
||||
printtab(f'Return a dict of dict with key=<{stats_obj[stats_obj.keys()[0]]["key"]}>')
|
||||
printtab(f'>>> gl.{plugin}.keys()')
|
||||
printtab(f'{stats_obj.keys()}')
|
||||
printtab(f'>>> gl.{plugin}["{stats_obj.keys()[0]}"]')
|
||||
printtab(f'{pformat(stats_obj[stats_obj.keys()[0]])}')
|
||||
else:
|
||||
printtab(f'>>> gl.{plugin}')
|
||||
printtab(f'{pformat(stats_obj.stats)}')
|
||||
if len(stats_obj.keys()) > 0:
|
||||
printtab(f'>>> gl.{plugin}.keys()')
|
||||
printtab(f'{stats_obj.keys()}')
|
||||
printtab(f'>>> gl.{plugin}["{stats_obj.keys()[0]}"]')
|
||||
printtab(f'{pformat(stats_obj[stats_obj.keys()[0]])}')
|
||||
print('')
|
||||
|
||||
if stats_obj.fields_description is not None:
|
||||
print(f'{plugin.capitalize()} fields description:')
|
||||
print('')
|
||||
for field, description in stats_obj.fields_description.items():
|
||||
print(f'* {field}: {description["description"]}')
|
||||
print('')
|
||||
|
||||
print(f'{plugin.capitalize()} limits:')
|
||||
print('')
|
||||
print('.. code-block:: python')
|
||||
print('')
|
||||
printtab(f'>>> gl.{plugin}.limits')
|
||||
printtab(f'{pformat(gl.__getattr__(plugin).limits)}')
|
||||
print('')
|
||||
|
||||
|
||||
def print_plugins(gl):
|
||||
"""Print the details of all plugins."""
|
||||
for plugin in gl.plugins():
|
||||
print_plugin(gl, plugin)
|
||||
|
||||
|
||||
class GlancesStdoutApiDoc:
|
||||
"""This class manages the fields description display."""
|
||||
|
||||
def __init__(self, config=None, args=None):
|
||||
# Init
|
||||
self.gl = api.GlancesAPI()
|
||||
|
||||
def end(self):
|
||||
pass
|
||||
|
||||
def update(self, stats, duration=1):
|
||||
"""Display issue"""
|
||||
|
||||
# Display header
|
||||
print(APIDOC_HEADER)
|
||||
|
||||
# Display TL;DR section
|
||||
print_tldr(self.gl)
|
||||
|
||||
# Init the API
|
||||
print_init_api(self.gl)
|
||||
|
||||
# Display plugins list
|
||||
print_plugins_list(self.gl)
|
||||
|
||||
# Loop over plugins
|
||||
print_plugins(self.gl)
|
||||
|
||||
# Return True to exit directly (no refresh)
|
||||
return True
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
# SPDX-License-Identifier: LGPL-3.0-only
|
||||
#
|
||||
|
||||
"""Fields description interface class."""
|
||||
"""Generate Glances Restful API documentation."""
|
||||
|
||||
import json
|
||||
import time
|
||||
|
|
@ -19,20 +19,20 @@ from glances.logger import logger
|
|||
API_URL = f"http://localhost:61208/api/{__apiversion__}"
|
||||
|
||||
APIDOC_HEADER = f"""\
|
||||
.. _api:
|
||||
.. _api_restful:
|
||||
|
||||
API (Restfull/JSON) documentation
|
||||
=================================
|
||||
Restful/JSON API documentation
|
||||
==============================
|
||||
|
||||
This documentation describes the Glances API version {__apiversion__} (Restfull/JSON) interface.
|
||||
This documentation describes the Glances API version {__apiversion__} (Restful/JSON) interface.
|
||||
|
||||
An OpenAPI specification file is available at:
|
||||
``https://raw.githubusercontent.com/nicolargo/glances/refs/heads/develop/docs/openapi.json``
|
||||
``https://raw.githubusercontent.com/nicolargo/glances/refs/heads/develop/docs/api/openapi.json``
|
||||
|
||||
Run the Glances API server
|
||||
--------------------------
|
||||
|
||||
The Glances Restfull/API server could be ran using the following command line:
|
||||
The Glances Restful/API server could be ran using the following command line:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
|
|
@ -354,7 +354,7 @@ def print_plugin_post_events():
|
|||
print('')
|
||||
|
||||
|
||||
class GlancesStdoutApiDoc:
|
||||
class GlancesStdoutApiRestfulDoc:
|
||||
"""This class manages the fields description display."""
|
||||
|
||||
def __init__(self, config=None, args=None):
|
||||
|
|
@ -150,14 +150,13 @@ class GlancesPluginModel:
|
|||
|
||||
def __getitem__(self, item):
|
||||
"""Return the stats item."""
|
||||
if self.stats is not None:
|
||||
# Stats is a dict try, to return the item
|
||||
if isinstance(self.stats, dict) and item in self.stats:
|
||||
return self.stats[item]
|
||||
if isinstance(self.stats, list):
|
||||
ltd = list_to_dict(self.stats)
|
||||
if item in ltd:
|
||||
return ltd[item]
|
||||
if isinstance(self.stats, dict) and item in self.stats:
|
||||
return self.stats[item]
|
||||
|
||||
if isinstance(self.stats, list):
|
||||
ltd = list_to_dict(self.stats)
|
||||
if item in ltd:
|
||||
return ltd[item]
|
||||
|
||||
raise KeyError(f"'{self.__class__.__name__}' object has no key '{item}'")
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ from glances.logger import logger
|
|||
from glances.outdated import Outdated
|
||||
from glances.outputs.glances_curses import GlancesCursesStandalone
|
||||
from glances.outputs.glances_stdout import GlancesStdout
|
||||
from glances.outputs.glances_stdout_apidoc import GlancesStdoutApiDoc
|
||||
from glances.outputs.glances_stdout_api_doc import GlancesStdoutApiDoc
|
||||
from glances.outputs.glances_stdout_api_restful_doc import GlancesStdoutApiRestfulDoc
|
||||
from glances.outputs.glances_stdout_csv import GlancesStdoutCsv
|
||||
from glances.outputs.glances_stdout_issue import GlancesStdoutIssue
|
||||
from glances.outputs.glances_stdout_json import GlancesStdoutJson
|
||||
|
|
@ -85,10 +86,14 @@ class GlancesStandalone:
|
|||
logger.info("Issue mode is ON")
|
||||
# Init screen
|
||||
self.screen = GlancesStdoutIssue(config=config, args=args)
|
||||
elif args.stdout_apidoc:
|
||||
logger.info("Fields descriptions mode is ON")
|
||||
elif args.stdout_api_doc:
|
||||
logger.info("Restful Python documentation mode is ON")
|
||||
# Init screen
|
||||
self.screen = GlancesStdoutApiDoc(config=config, args=args)
|
||||
elif args.stdout_api_restful_doc:
|
||||
logger.info("Restful API documentation mode is ON")
|
||||
# Init screen
|
||||
self.screen = GlancesStdoutApiRestfulDoc(config=config, args=args)
|
||||
elif args.stdout:
|
||||
logger.info(f"Stdout mode is ON, following stats will be displayed: {args.stdout}")
|
||||
# Init screen
|
||||
|
|
|
|||
|
|
@ -266,8 +266,10 @@ please rename it to "{plugin_path.capitalize()}Plugin"'
|
|||
for p in self.getPluginsList(enable=False):
|
||||
self._plugins[p].load_limits(config)
|
||||
|
||||
# It's a weak cache to avoid updating the same plugin too often
|
||||
# Note: the function always return None
|
||||
@weak_lru_cache(maxsize=1, ttl=1)
|
||||
def __update_plugin(self, p):
|
||||
def update_plugin(self, p):
|
||||
"""Update stats, history and views for the given plugin name p"""
|
||||
self._plugins[p].update()
|
||||
self._plugins[p].update_views()
|
||||
|
|
@ -280,7 +282,7 @@ please rename it to "{plugin_path.capitalize()}Plugin"'
|
|||
"""
|
||||
# Start update of all enable plugins
|
||||
for p in self.getPluginsList(enable=True):
|
||||
self.__update_plugin(p)
|
||||
self.update_plugin(p)
|
||||
|
||||
def export(self, input_stats=None):
|
||||
"""Export all the stats.
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ from glances import __version__, api
|
|||
# Init Glances API
|
||||
# test_config = core.get_config()
|
||||
# test_args = core.get_args()
|
||||
gl = api.GlancesAPI()
|
||||
gl = api.GlancesAPI(args_begin_at=2)
|
||||
|
||||
|
||||
# Pytest functions to test the Glances API version
|
||||
|
|
@ -25,11 +25,22 @@ def test_glances_api_version():
|
|||
assert gl.__version__ == __version__.split('.')[0]
|
||||
|
||||
|
||||
def test_glances_api_plugins():
|
||||
# Check that the plugins list is not empty
|
||||
assert len(gl.plugins()) > 0
|
||||
# Check that the cpu plugin is in the list of plugins
|
||||
assert 'cpu' in gl.plugins()
|
||||
# Check that the network plugin is in the list of plugins
|
||||
assert 'network' in gl.plugins()
|
||||
# Check that the processcount plugin is in the list of plugins
|
||||
assert 'processcount' in gl.plugins()
|
||||
# Check that the processlist plugin is in the list of plugins
|
||||
assert 'processlist' in gl.plugins()
|
||||
|
||||
|
||||
def test_glances_api_plugin_cpu():
|
||||
# Check that the cpu plugin is available
|
||||
assert gl.cpu is not None
|
||||
# Update stats
|
||||
gl.cpu.update()
|
||||
# Get list of keys (cpu stat fields)
|
||||
keys = gl.cpu.keys()
|
||||
# Check that the keys are not empty
|
||||
|
|
@ -45,8 +56,6 @@ def test_glances_api_plugin_cpu():
|
|||
def test_glances_api_plugin_network():
|
||||
# Check that the network plugin is available
|
||||
assert gl.network is not None
|
||||
# Update stats
|
||||
gl.network.update()
|
||||
# Get list of keys (interfaces)
|
||||
keys = gl.network.keys()
|
||||
# Check that the keys are not empty
|
||||
|
|
@ -56,7 +65,6 @@ def test_glances_api_plugin_network():
|
|||
|
||||
|
||||
def test_glances_api_plugin_process():
|
||||
gl.processcount.update()
|
||||
# Get list of keys (processes)
|
||||
keys = gl.processcount.keys()
|
||||
# Check that the keys are not empty
|
||||
|
|
@ -64,11 +72,13 @@ def test_glances_api_plugin_process():
|
|||
# Check that processcount total is > 0
|
||||
assert gl.processcount['total'] > 0
|
||||
|
||||
# Note should be done after processcount update
|
||||
gl.processlist.update()
|
||||
# Get list of keys (processes)
|
||||
keys = gl.processlist.keys()
|
||||
# Check that first key is an integer (PID)
|
||||
assert isinstance(keys[0], int)
|
||||
# Check that the first item is a dictionary
|
||||
assert isinstance(gl.processlist[keys[0]], dict)
|
||||
|
||||
|
||||
def test_glances_api_limits():
|
||||
assert isinstance(gl.cpu.limits, dict)
|
||||
|
|
|
|||
Loading…
Reference in New Issue