Test Failed
Push — develop ( 0abc39...ef45c6 )
by Nicolas
02:52
created

print_auto_unit()   A

Complexity

Conditions 1

Size

Total Lines 16
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 16
nop 1
dl 0
loc 16
rs 9.6
c 0
b 0
f 0
1
#
2
# This file is part of Glances.
3
#
4
# SPDX-FileCopyrightText: 2025 Nicolas Hennion <[email protected]>
5
#
6
# SPDX-License-Identifier: LGPL-3.0-only
7
#
8
9
"""Generate Glances Python API documentation."""
10
11
from pprint import pformat
12
13
from glances import api
14
15
APIDOC_HEADER = """\
16
.. _api:
17
18
Python API documentation
19
========================
20
21
This documentation describes the Glances Python API.
22
23
Note: This API is only available in Glances 4.4.0 or higher.
24
25
"""
26
27
28
def printtab(s, indent='    '):
29
    print(indent + s.replace('\n', '\n' + indent))
30
31
32
def print_tldr(gl):
33
    """Print the TL;DR section of the API documentation."""
34
    sub_title = 'TL;DR'
35
    print(sub_title)
36
    print('-' * len(sub_title))
37
    print('')
38
    print('You can access the Glances API by importing the `glances.api` module and creating an')
39
    print('instance of the `GlancesAPI` class. This instance provides access to all Glances plugins')
40
    print('and their fields. For example, to access the CPU plugin and its total field, you can')
41
    print('use the following code:')
42
    print('')
43
    print('.. code-block:: python')
44
    print('')
45
    printtab('>>> from glances import api')
46
    printtab('>>> gl = api.GlancesAPI()')
47
    printtab('>>> gl.cpu')
48
    printtab(f'{pformat(gl.cpu.stats)}')
49
    printtab('>>> gl.cpu["total"]')
50
    printtab(f'{gl.cpu["total"]}')
51
    printtab('>>> gl.mem["used"]')
52
    printtab(f'{gl.mem["used"]}')
53
    printtab('>>> gl.auto_unit(gl.mem["used"])')
54
    printtab(f'{gl.auto_unit(gl.mem["used"])}')
55
    print('')
56
    print('If the stats return a list of items (like network interfaces or processes), you can')
57
    print('access them by their name:')
58
    print('')
59
    print('.. code-block:: python')
60
    print('')
61
    printtab('>>> gl.network.keys()')
62
    printtab(f'{gl.network.keys()}')
63
    printtab(f'>>> gl.network["{gl.network.keys()[0]}"]')
64
    printtab(f'{pformat(gl.network[gl.network.keys()[0]])}')
65
    print('')
66
67
68
def print_init_api(gl):
69
    sub_title = 'Init Glances Python API'
70
    print(sub_title)
71
    print('-' * len(sub_title))
72
    print('')
73
    print('Init the Glances API:')
74
    print('')
75
    print('.. code-block:: python')
76
    print('')
77
    printtab('>>> from glances import api')
78
    printtab('>>> gl = api.GlancesAPI()')
79
    print('')
80
81
82
def print_plugins_list(gl):
83
    sub_title = 'Get Glances plugins list'
84
    print(sub_title)
85
    print('-' * len(sub_title))
86
    print('')
87
    print('Get the plugins list:')
88
    print('')
89
    print('.. code-block:: python')
90
    print('')
91
    printtab('>>> gl.plugins()')
92
    printtab(f'{gl.plugins()}')
93
    print('')
94
95
96
def print_plugin(gl, plugin):
97
    """Print the details of a single plugin."""
98
    sub_title = f'Glances {plugin}'
99
    print(sub_title)
100
    print('-' * len(sub_title))
101
    print('')
102
103
    stats_obj = gl.__getattr__(plugin)
104
105
    print(f'{plugin.capitalize()} stats:')
106
    print('')
107
    print('.. code-block:: python')
108
    print('')
109
    printtab(f'>>> type(gl.{plugin})')
110
    printtab(f'{type(stats_obj)}')
111
    if len(stats_obj.keys()) > 0 and isinstance(stats_obj[stats_obj.keys()[0]], dict):
112
        printtab(f'>>> gl.{plugin}')
113
        printtab(f'Return a dict of dict with key=<{stats_obj[stats_obj.keys()[0]]["key"]}>')
114
        printtab(f'>>> gl.{plugin}.keys()')
115
        printtab(f'{stats_obj.keys()}')
116
        printtab(f'>>> gl.{plugin}["{stats_obj.keys()[0]}"]')
117
        printtab(f'{pformat(stats_obj[stats_obj.keys()[0]])}')
118
    else:
119
        printtab(f'>>> gl.{plugin}')
120
        printtab(f'{pformat(stats_obj.stats)}')
121
        if len(stats_obj.keys()) > 0:
122
            printtab(f'>>> gl.{plugin}.keys()')
123
            printtab(f'{stats_obj.keys()}')
124
            printtab(f'>>> gl.{plugin}["{stats_obj.keys()[0]}"]')
125
            printtab(f'{pformat(stats_obj[stats_obj.keys()[0]])}')
126
    print('')
127
128
    if stats_obj.fields_description is not None:
129
        print(f'{plugin.capitalize()} fields description:')
130
        print('')
131
        for field, description in stats_obj.fields_description.items():
132
            print(f'* {field}: {description["description"]}')
133
        print('')
134
135
    print(f'{plugin.capitalize()} limits:')
136
    print('')
137
    print('.. code-block:: python')
138
    print('')
139
    printtab(f'>>> gl.{plugin}.limits')
140
    printtab(f'{pformat(gl.__getattr__(plugin).limits)}')
141
    print('')
142
143
144
def print_plugins(gl):
145
    """Print the details of all plugins."""
146
    for plugin in [p for p in gl.plugins() if p not in ['help', 'programlist']]:
147
        print_plugin(gl, plugin)
148
149
150
def print_auto_unit(gl):
151
    sub_title = 'Use auto_unit to display a human-readable string with the unit'
152
    print(sub_title)
153
    print('-' * len(sub_title))
154
    print('')
155
    print('Use auto_unit() function to generate a human-readable string with the unit:')
156
    print('')
157
    print('.. code-block:: python')
158
    print('')
159
    printtab('>>> gl.mem["used"]')
160
    printtab(f'{gl.mem["used"]}')
161
    print('')
162
    printtab('>>> gl.auto_unit(gl.mem["used"])')
163
    printtab(f'{gl.auto_unit(gl.mem["used"])}')
164
    print('')
165
    print("""
166
Args:
167
168
    number (float or int): The numeric value to be converted.
169
170
    low_precision (bool, optional): If True, use lower precision for the output. Defaults to False.
171
172
    min_symbol (str, optional): The minimum unit symbol to use (e.g., 'K' for kilo). Defaults to 'K'.
173
174
    none_symbol (str, optional): The symbol to display if the number is None. Defaults to '-'.
175
176
Returns:
177
178
    str: A human-readable string representation of the number with units.
179
180
""")
181
182
183
def print_bar(gl):
184
    sub_title = 'Use to display stat as a bar'
185
    print(sub_title)
186
    print('-' * len(sub_title))
187
    print('')
188
    print('Use bar() function to generate a bar:')
189
    print('')
190
    print('.. code-block:: python')
191
    print('')
192
    printtab('>>> gl.bar(gl.mem["percent"])')
193
    printtab(f'{gl.bar(gl.mem["percent"])}')
194
    print('')
195
    print("""
196
Args:
197
198
    value (float): The percentage value to represent in the bar (typically between 0 and 100).
199
200
    size (int, optional): The total length of the bar in characters. Defaults to 18.
201
202
    bar_char (str, optional): The character used to represent the filled portion of the bar. Defaults to '■'.
203
204
    empty_char (str, optional): The character used to represent the empty portion of the bar. Defaults to '□'.
205
206
    pre_char (str, optional): A string to prepend to the bar. Defaults to ''.
207
208
    post_char (str, optional): A string to append to the bar. Defaults to ''.
209
210
Returns:
211
212
    str: A string representing the progress bar.
213
214
""")
215
216
217
def print_top_process(gl):
218
    sub_title = 'Use to display top process list'
219
    print(sub_title)
220
    print('-' * len(sub_title))
221
    print('')
222
    print('Use top_process() function to generate a list of top processes sorted by CPU or MEM usage:')
223
    print('')
224
    print('.. code-block:: python')
225
    print('')
226
    printtab('>>> gl.top_process()')
227
    printtab(f'{gl.top_process()}')
228
    print('')
229
    print("""
230
Args:
231
232
    limit (int, optional): The maximum number of top processes to return. Defaults to 3.
233
234
    sorted_by (str, optional): The primary key to sort processes by (e.g., 'cpu_percent').
235
                                Defaults to 'cpu_percent'.
236
237
    sorted_by_secondary (str, optional): The secondary key to sort processes by if primary keys are equal
238
                                            (e.g., 'memory_percent'). Defaults to 'memory_percent'.
239
240
Returns:
241
242
    list: A list of dictionaries representing the top processes, excluding those with 'glances' in their
243
            command line.
244
245
Note:
246
247
    The 'glances' process is excluded from the returned list to avoid self-generated CPU load affecting
248
    the results.
249
250
""")
251
252
253
class GlancesStdoutApiDoc:
254
    """This class manages the fields description display."""
255
256
    def __init__(self, config=None, args=None):
257
        # Init
258
        self.gl = api.GlancesAPI()
259
260
    def end(self):
261
        pass
262
263
    def update(self, stats, duration=1):
264
        """Display issue"""
265
        # Display header
266
        print(APIDOC_HEADER)
267
268
        # Display TL;DR section
269
        print_tldr(self.gl)
270
271
        # Init the API
272
        print_init_api(self.gl)
273
274
        # Display plugins list
275
        print_plugins_list(self.gl)
276
277
        # Loop over plugins
278
        print_plugins(self.gl)
279
280
        # Others helpers
281
        print_auto_unit(self.gl)
282
        print_bar(self.gl)
283
        print_top_process(self.gl)
284
285
        # Return True to exit directly (no refresh)
286
        return True
287