From 5d175558179b1ef998c9a2e61615d214b10896d4 Mon Sep 17 00:00:00 2001 From: yogendrarau Date: Sat, 18 Jul 2026 15:03:25 -0400 Subject: [PATCH] Add a new /all/msgpack endpoint in the API #3593 Add a compact binary alternative to the /all endpoint, which returns a very large JSON payload. The new GET /api/4/all/msgpack endpoint returns the same dictionary of all plugin stats serialized to MessagePack using msgspec (~25% smaller than JSON on a typical payload). - GlancesMsgpackResponse mirrors GlancesJSONResponse; msgspec encodes datetime as ISO 8601 strings, so the decoded payload matches /all. - msgspec is optional: the endpoint returns HTTP 501 if it is missing, and it is added to the "web" optional-dependencies group. - Add a RESTful test, document the endpoint, and regenerate openapi.json. Co-Authored-By: Claude Opus 4.8 --- NEWS.rst | 1 + docs/api/openapi.json | 2 +- docs/api/restful.rst | 5 ++ glances/outputs/glances_restful_api.py | 51 ++++++++++++++++++- .../outputs/glances_stdout_api_restful_doc.py | 5 ++ pyproject.toml | 1 + tests/test_restful.py | 20 ++++++++ 7 files changed, 83 insertions(+), 2 deletions(-) diff --git a/NEWS.rst b/NEWS.rst index 84f3580447..ea53cf83bd 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -20,6 +20,7 @@ Bugs corrected: Enhancements: +* Add a new /all/msgpack endpoint in the API #3593 * Add meter for CPU and MEM of GPU in the Quicklook plugin #1711 * Add cpu limit to docker, podman and lxd containers #3557 * GPU Monitoring (ARM / RaspberryPi) #1048 diff --git a/docs/api/openapi.json b/docs/api/openapi.json index 21ebfb3e58..09577605e9 100644 --- a/docs/api/openapi.json +++ b/docs/api/openapi.json @@ -1 +1 @@ -{"openapi": "3.0.2", "info": {"title": "FastAPI", "version": "0.1.0"}, "paths": {"/api/4/status": {"get": {"summary": " Api Status", "description": "Glances API RESTful implementation.\n\nReturn a 200 status code.\nThis entry point should be used to check the API health.\n\nSee related issue: Web server health check endpoint #1988", "operationId": "_api_status_api_4_status_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}, "head": {"summary": " Api Status", "description": "Glances API RESTful implementation.\n\nReturn a 200 status code.\nThis entry point should be used to check the API health.\n\nSee related issue: Web server health check endpoint #1988", "operationId": "_api_status_api_4_status_head", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/events/clear/warning": {"post": {"summary": " Events Clear Warning", "description": "Glances API RESTful implementation.\n\nReturn a 200 status code.\n\nIt's a post message to clean warning events", "operationId": "_events_clear_warning_api_4_events_clear_warning_post", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/events/clear/all": {"post": {"summary": " Events Clear All", "description": "Glances API RESTful implementation.\n\nReturn a 200 status code.\n\nIt's a post message to clean all events", "operationId": "_events_clear_all_api_4_events_clear_all_post", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/processes/extended/disable": {"post": {"summary": " Api Disable Extended Processes", "description": "Glances API RESTful implementation.\n\nDisable extended process stats\nHTTP/200 if OK\nHTTP/400 if PID is not found\nHTTP/404 if others error", "operationId": "_api_disable_extended_processes_api_4_processes_extended_disable_post", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/processes/extended/{pid}": {"post": {"summary": " Api Set Extended Processes", "description": "Glances API RESTful implementation.\n\nSet the extended process stats for the given PID\nHTTP/200 if OK\nHTTP/400 if PID is not found\nHTTP/404 if others error", "operationId": "_api_set_extended_processes_api_4_processes_extended__pid__post", "parameters": [{"name": "pid", "in": "path", "required": true, "schema": {"type": "string", "title": "Pid"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/config": {"get": {"summary": " Api Config", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of the Glances configuration file\nHTTP/200 if OK\nHTTP/404 if others error", "operationId": "_api_config_api_4_config_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/config/{section}": {"get": {"summary": " Api Config Section", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of the Glances configuration section\nHTTP/200 if OK\nHTTP/400 if item is not found\nHTTP/404 if others error", "operationId": "_api_config_section_api_4_config__section__get", "parameters": [{"name": "section", "in": "path", "required": true, "schema": {"type": "string", "title": "Section"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/config/{section}/{item}": {"get": {"summary": " Api Config Section Item", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of the Glances configuration section/item\nHTTP/200 if OK\nHTTP/400 if item is not found\nHTTP/404 if others error", "operationId": "_api_config_section_item_api_4_config__section___item__get", "parameters": [{"name": "section", "in": "path", "required": true, "schema": {"type": "string", "title": "Section"}}, {"name": "item", "in": "path", "required": true, "schema": {"type": "string", "title": "Item"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/args": {"get": {"summary": " Api Args", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of the Glances command line arguments\nHTTP/200 if OK\nHTTP/404 if others error", "operationId": "_api_args_api_4_args_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/args/{item}": {"get": {"summary": " Api Args Item", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of the Glances command line arguments item\nHTTP/200 if OK\nHTTP/400 if item is not found\nHTTP/404 if others error", "operationId": "_api_args_item_api_4_args__item__get", "parameters": [{"name": "item", "in": "path", "required": true, "schema": {"type": "string", "title": "Item"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/help": {"get": {"summary": " Api Help", "description": "Glances API RESTful implementation.\n\nReturn the help data or 404 error.", "operationId": "_api_help_api_4_help_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/all": {"get": {"summary": " Api All", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of all the plugins\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_all_api_4_all_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/all/limits": {"get": {"summary": " Api All Limits", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of all the plugins limits\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_all_limits_api_4_all_limits_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/all/views": {"get": {"summary": " Api All Views", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of all the plugins views\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_all_views_api_4_all_views_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/pluginslist": {"get": {"summary": " Api Plugins", "description": "Glances API RESTFul implementation.\n\n@api {get} /api/%s/pluginslist Get plugins list\n@apiVersion 2.0\n@apiName pluginslist\n@apiGroup plugin\n\n@apiSuccess {String[]} Plugins list.\n\n@apiSuccessExample Success-Response:\n HTTP/1.1 200 OK\n [\n \"load\",\n \"help\",\n \"ip\",\n \"memswap\",\n \"processlist\",\n ...\n ]\n\n @apiError Cannot get plugin list.\n\n @apiErrorExample Error-Response:\n HTTP/1.1 404 Not Found", "operationId": "_api_plugins_api_4_pluginslist_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/serverslist": {"get": {"summary": " Api Servers List", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of the servers list (for browser mode)\nHTTP/200 if OK", "operationId": "_api_servers_list_api_4_serverslist_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/processes/extended": {"get": {"summary": " Api Get Extended Processes", "description": "Glances API RESTful implementation.\n\nGet the extended process stats (if set before)\nHTTP/200 if OK\nHTTP/400 if PID is not found\nHTTP/404 if others error", "operationId": "_api_get_extended_processes_api_4_processes_extended_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/processes/{pid}": {"get": {"summary": " Api Get Processes", "description": "Glances API RESTful implementation.\n\nGet the process stats for the given PID\nHTTP/200 if OK\nHTTP/400 if PID is not found\nHTTP/404 if others error", "operationId": "_api_get_processes_api_4_processes__pid__get", "parameters": [{"name": "pid", "in": "path", "required": true, "schema": {"type": "string", "title": "Pid"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}": {"get": {"summary": " Api", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of a given plugin\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_api_4__plugin__get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/history": {"get": {"summary": " Api History", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of a given plugin history\nLimit to the last nb items (all if nb=0)\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_history_api_4__plugin__history_get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "nb", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "title": "Nb"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/history/{nb}": {"get": {"summary": " Api History", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of a given plugin history\nLimit to the last nb items (all if nb=0)\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_history_api_4__plugin__history__nb__get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "nb", "in": "path", "required": true, "schema": {"type": "integer", "title": "Nb"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/top/{nb}": {"get": {"summary": " Api Top", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of a given plugin limited to the top nb items.\nIt is used to reduce the payload of the HTTP response (example: processlist).\n\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_top_api_4__plugin__top__nb__get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "nb", "in": "path", "required": true, "schema": {"type": "integer", "title": "Nb"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/limits": {"get": {"summary": " Api Limits", "description": "Glances API RESTful implementation.\n\nReturn the JSON limits of a given plugin\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_limits_api_4__plugin__limits_get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/views": {"get": {"summary": " Api Views", "description": "Glances API RESTful implementation.\n\nReturn the JSON views of a given plugin\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_views_api_4__plugin__views_get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/{item}": {"get": {"summary": " Api Item", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of the couple plugin/item\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_item_api_4__plugin___item__get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "item", "in": "path", "required": true, "schema": {"type": "string", "title": "Item"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/{item}/views": {"get": {"summary": " Api Item Views", "description": "Glances API RESTful implementation.\n\nReturn the JSON view representation of the couple plugin/item\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_item_views_api_4__plugin___item__views_get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "item", "in": "path", "required": true, "schema": {"type": "string", "title": "Item"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/{item}/history": {"get": {"summary": " Api Item History", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of the couple plugin/history of item\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_item_history_api_4__plugin___item__history_get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "item", "in": "path", "required": true, "schema": {"type": "string", "title": "Item"}}, {"name": "nb", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "title": "Nb"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/{item}/history/{nb}": {"get": {"summary": " Api Item History", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of the couple plugin/history of item\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_item_history_api_4__plugin___item__history__nb__get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "item", "in": "path", "required": true, "schema": {"type": "string", "title": "Item"}}, {"name": "nb", "in": "path", "required": true, "schema": {"type": "integer", "title": "Nb"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/{item}/description": {"get": {"summary": " Api Item Description", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of the couple plugin/item description\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_item_description_api_4__plugin___item__description_get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "item", "in": "path", "required": true, "schema": {"type": "string", "title": "Item"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/{item}/unit": {"get": {"summary": " Api Item Unit", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of the couple plugin/item unit\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_item_unit_api_4__plugin___item__unit_get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "item", "in": "path", "required": true, "schema": {"type": "string", "title": "Item"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/{item}/value/{value}": {"get": {"summary": " Api Value", "description": "Glances API RESTful implementation.\n\nReturn the process stats (dict) for the given item=value\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_value_api_4__plugin___item__value__value__get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "item", "in": "path", "required": true, "schema": {"type": "string", "title": "Item"}}, {"name": "value", "in": "path", "required": true, "schema": {"anyOf": [{"type": "string"}, {"type": "integer"}, {"type": "number"}], "title": "Value"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/{item}/{key}": {"get": {"summary": " Api Key", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of plugin/item/key\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_key_api_4__plugin___item___key__get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "item", "in": "path", "required": true, "schema": {"type": "string", "title": "Item"}}, {"name": "key", "in": "path", "required": true, "schema": {"type": "string", "title": "Key"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/{item}/{key}/views": {"get": {"summary": " Api Key Views", "description": "Glances API RESTful implementation.\n\nReturn the JSON view representation of plugin/item/key\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_key_views_api_4__plugin___item___key__views_get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "item", "in": "path", "required": true, "schema": {"type": "string", "title": "Item"}}, {"name": "key", "in": "path", "required": true, "schema": {"type": "string", "title": "Key"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/": {"get": {"summary": " Index", "description": "Return main index.html (/) file.\n\nParameters are available through the request object.\nExample: http://localhost:61208/?refresh=5\n\nNote: This function is only called the first time the page is loaded.", "operationId": "_index__get", "responses": {"200": {"description": "Successful Response", "content": {"text/html": {"schema": {"type": "string"}}}}}}}}, "components": {"schemas": {"HTTPValidationError": {"properties": {"detail": {"items": {"$ref": "#/components/schemas/ValidationError"}, "type": "array", "title": "Detail"}}, "type": "object", "title": "HTTPValidationError"}, "ValidationError": {"properties": {"loc": {"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]}, "type": "array", "title": "Location"}, "msg": {"type": "string", "title": "Message"}, "type": {"type": "string", "title": "Error Type"}, "input": {"title": "Input"}, "ctx": {"type": "object", "title": "Context"}}, "type": "object", "required": ["loc", "msg", "type"], "title": "ValidationError"}}}} \ No newline at end of file +{"openapi": "3.0.2", "info": {"title": "FastAPI", "version": "0.1.0"}, "paths": {"/api/4/status": {"get": {"summary": " Api Status", "description": "Glances API RESTful implementation.\n\nReturn a 200 status code.\nThis entry point should be used to check the API health.\n\nSee related issue: Web server health check endpoint #1988", "operationId": "_api_status_api_4_status_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}, "head": {"summary": " Api Status", "description": "Glances API RESTful implementation.\n\nReturn a 200 status code.\nThis entry point should be used to check the API health.\n\nSee related issue: Web server health check endpoint #1988", "operationId": "_api_status_api_4_status_head", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/events/clear/warning": {"post": {"summary": " Events Clear Warning", "description": "Glances API RESTful implementation.\n\nReturn a 200 status code.\n\nIt's a post message to clean warning events", "operationId": "_events_clear_warning_api_4_events_clear_warning_post", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/events/clear/all": {"post": {"summary": " Events Clear All", "description": "Glances API RESTful implementation.\n\nReturn a 200 status code.\n\nIt's a post message to clean all events", "operationId": "_events_clear_all_api_4_events_clear_all_post", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/processes/extended/disable": {"post": {"summary": " Api Disable Extended Processes", "description": "Glances API RESTful implementation.\n\nDisable extended process stats\nHTTP/200 if OK\nHTTP/400 if PID is not found\nHTTP/404 if others error", "operationId": "_api_disable_extended_processes_api_4_processes_extended_disable_post", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/processes/extended/{pid}": {"post": {"summary": " Api Set Extended Processes", "description": "Glances API RESTful implementation.\n\nSet the extended process stats for the given PID\nHTTP/200 if OK\nHTTP/400 if PID is not found\nHTTP/404 if others error", "operationId": "_api_set_extended_processes_api_4_processes_extended__pid__post", "parameters": [{"name": "pid", "in": "path", "required": true, "schema": {"type": "string", "title": "Pid"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/config": {"get": {"summary": " Api Config", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of the Glances configuration file\nHTTP/200 if OK\nHTTP/404 if others error", "operationId": "_api_config_api_4_config_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/config/{section}": {"get": {"summary": " Api Config Section", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of the Glances configuration section\nHTTP/200 if OK\nHTTP/400 if item is not found\nHTTP/404 if others error", "operationId": "_api_config_section_api_4_config__section__get", "parameters": [{"name": "section", "in": "path", "required": true, "schema": {"type": "string", "title": "Section"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/config/{section}/{item}": {"get": {"summary": " Api Config Section Item", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of the Glances configuration section/item\nHTTP/200 if OK\nHTTP/400 if item is not found\nHTTP/404 if others error", "operationId": "_api_config_section_item_api_4_config__section___item__get", "parameters": [{"name": "section", "in": "path", "required": true, "schema": {"type": "string", "title": "Section"}}, {"name": "item", "in": "path", "required": true, "schema": {"type": "string", "title": "Item"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/args": {"get": {"summary": " Api Args", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of the Glances command line arguments\nHTTP/200 if OK\nHTTP/404 if others error", "operationId": "_api_args_api_4_args_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/args/{item}": {"get": {"summary": " Api Args Item", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of the Glances command line arguments item\nHTTP/200 if OK\nHTTP/400 if item is not found\nHTTP/404 if others error", "operationId": "_api_args_item_api_4_args__item__get", "parameters": [{"name": "item", "in": "path", "required": true, "schema": {"type": "string", "title": "Item"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/help": {"get": {"summary": " Api Help", "description": "Glances API RESTful implementation.\n\nReturn the help data or 404 error.", "operationId": "_api_help_api_4_help_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/all": {"get": {"summary": " Api All", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of all the plugins\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_all_api_4_all_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/all/msgpack": {"get": {"summary": " Api All Msgpack", "description": "Glances API RESTful implementation.\n\nReturn a msgpack (binary) representation of all the plugins.\nThis is a compact alternative to the (potentially huge) /all JSON endpoint.\nHTTP/200 if OK\nHTTP/404 if stats cannot be retrieved\nHTTP/501 if the msgspec library is not installed", "operationId": "_api_all_msgpack_api_4_all_msgpack_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/all/limits": {"get": {"summary": " Api All Limits", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of all the plugins limits\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_all_limits_api_4_all_limits_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/all/views": {"get": {"summary": " Api All Views", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of all the plugins views\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_all_views_api_4_all_views_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/pluginslist": {"get": {"summary": " Api Plugins", "description": "Glances API RESTFul implementation.\n\n@api {get} /api/%s/pluginslist Get plugins list\n@apiVersion 2.0\n@apiName pluginslist\n@apiGroup plugin\n\n@apiSuccess {String[]} Plugins list.\n\n@apiSuccessExample Success-Response:\n HTTP/1.1 200 OK\n [\n \"load\",\n \"help\",\n \"ip\",\n \"memswap\",\n \"processlist\",\n ...\n ]\n\n @apiError Cannot get plugin list.\n\n @apiErrorExample Error-Response:\n HTTP/1.1 404 Not Found", "operationId": "_api_plugins_api_4_pluginslist_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/serverslist": {"get": {"summary": " Api Servers List", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of the servers list (for browser mode)\nHTTP/200 if OK", "operationId": "_api_servers_list_api_4_serverslist_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/processes/extended": {"get": {"summary": " Api Get Extended Processes", "description": "Glances API RESTful implementation.\n\nGet the extended process stats (if set before)\nHTTP/200 if OK\nHTTP/400 if PID is not found\nHTTP/404 if others error", "operationId": "_api_get_extended_processes_api_4_processes_extended_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/api/4/processes/{pid}": {"get": {"summary": " Api Get Processes", "description": "Glances API RESTful implementation.\n\nGet the process stats for the given PID\nHTTP/200 if OK\nHTTP/400 if PID is not found\nHTTP/404 if others error", "operationId": "_api_get_processes_api_4_processes__pid__get", "parameters": [{"name": "pid", "in": "path", "required": true, "schema": {"type": "string", "title": "Pid"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}": {"get": {"summary": " Api", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of a given plugin\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_api_4__plugin__get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/history": {"get": {"summary": " Api History", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of a given plugin history\nLimit to the last nb items (all if nb=0)\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_history_api_4__plugin__history_get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "nb", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "title": "Nb"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/history/{nb}": {"get": {"summary": " Api History", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of a given plugin history\nLimit to the last nb items (all if nb=0)\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_history_api_4__plugin__history__nb__get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "nb", "in": "path", "required": true, "schema": {"type": "integer", "title": "Nb"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/top/{nb}": {"get": {"summary": " Api Top", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of a given plugin limited to the top nb items.\nIt is used to reduce the payload of the HTTP response (example: processlist).\n\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_top_api_4__plugin__top__nb__get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "nb", "in": "path", "required": true, "schema": {"type": "integer", "title": "Nb"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/limits": {"get": {"summary": " Api Limits", "description": "Glances API RESTful implementation.\n\nReturn the JSON limits of a given plugin\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_limits_api_4__plugin__limits_get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/views": {"get": {"summary": " Api Views", "description": "Glances API RESTful implementation.\n\nReturn the JSON views of a given plugin\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_views_api_4__plugin__views_get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/{item}": {"get": {"summary": " Api Item", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of the couple plugin/item\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_item_api_4__plugin___item__get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "item", "in": "path", "required": true, "schema": {"type": "string", "title": "Item"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/{item}/views": {"get": {"summary": " Api Item Views", "description": "Glances API RESTful implementation.\n\nReturn the JSON view representation of the couple plugin/item\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_item_views_api_4__plugin___item__views_get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "item", "in": "path", "required": true, "schema": {"type": "string", "title": "Item"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/{item}/history": {"get": {"summary": " Api Item History", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of the couple plugin/history of item\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_item_history_api_4__plugin___item__history_get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "item", "in": "path", "required": true, "schema": {"type": "string", "title": "Item"}}, {"name": "nb", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "title": "Nb"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/{item}/history/{nb}": {"get": {"summary": " Api Item History", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of the couple plugin/history of item\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_item_history_api_4__plugin___item__history__nb__get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "item", "in": "path", "required": true, "schema": {"type": "string", "title": "Item"}}, {"name": "nb", "in": "path", "required": true, "schema": {"type": "integer", "title": "Nb"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/{item}/description": {"get": {"summary": " Api Item Description", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of the couple plugin/item description\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_item_description_api_4__plugin___item__description_get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "item", "in": "path", "required": true, "schema": {"type": "string", "title": "Item"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/{item}/unit": {"get": {"summary": " Api Item Unit", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of the couple plugin/item unit\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_item_unit_api_4__plugin___item__unit_get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "item", "in": "path", "required": true, "schema": {"type": "string", "title": "Item"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/{item}/value/{value}": {"get": {"summary": " Api Value", "description": "Glances API RESTful implementation.\n\nReturn the process stats (dict) for the given item=value\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_value_api_4__plugin___item__value__value__get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "item", "in": "path", "required": true, "schema": {"type": "string", "title": "Item"}}, {"name": "value", "in": "path", "required": true, "schema": {"anyOf": [{"type": "string"}, {"type": "integer"}, {"type": "number"}], "title": "Value"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/{item}/{key}": {"get": {"summary": " Api Key", "description": "Glances API RESTful implementation.\n\nReturn the JSON representation of plugin/item/key\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_key_api_4__plugin___item___key__get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "item", "in": "path", "required": true, "schema": {"type": "string", "title": "Item"}}, {"name": "key", "in": "path", "required": true, "schema": {"type": "string", "title": "Key"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/4/{plugin}/{item}/{key}/views": {"get": {"summary": " Api Key Views", "description": "Glances API RESTful implementation.\n\nReturn the JSON view representation of plugin/item/key\nHTTP/200 if OK\nHTTP/400 if plugin is not found\nHTTP/404 if others error", "operationId": "_api_key_views_api_4__plugin___item___key__views_get", "parameters": [{"name": "plugin", "in": "path", "required": true, "schema": {"type": "string", "title": "Plugin"}}, {"name": "item", "in": "path", "required": true, "schema": {"type": "string", "title": "Item"}}, {"name": "key", "in": "path", "required": true, "schema": {"type": "string", "title": "Key"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/": {"get": {"summary": " Index", "description": "Return main index.html (/) file.\n\nParameters are available through the request object.\nExample: http://localhost:61208/?refresh=5\n\nNote: This function is only called the first time the page is loaded.", "operationId": "_index__get", "responses": {"200": {"description": "Successful Response", "content": {"text/html": {"schema": {"type": "string"}}}}}}}}, "components": {"schemas": {"HTTPValidationError": {"properties": {"detail": {"items": {"$ref": "#/components/schemas/ValidationError"}, "type": "array", "title": "Detail"}}, "type": "object", "title": "HTTPValidationError"}, "ValidationError": {"properties": {"loc": {"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]}, "type": "array", "title": "Location"}, "msg": {"type": "string", "title": "Message"}, "type": {"type": "string", "title": "Error Type"}, "input": {"title": "Input"}, "ctx": {"type": "object", "title": "Context"}}, "type": "object", "required": ["loc", "msg", "type"], "title": "ValidationError"}}}} \ No newline at end of file diff --git a/docs/api/restful.rst b/docs/api/restful.rst index 55a9fab134..e5be6b6577 100644 --- a/docs/api/restful.rst +++ b/docs/api/restful.rst @@ -1945,6 +1945,11 @@ Get all Glances stats:: # curl http://localhost:61208/api/4/all Return a very big dictionary with all stats +Get all Glances stats encoded with msgpack (binary, ~25% smaller than JSON):: + + # curl http://localhost:61208/api/4/all/msgpack + Return the same dictionary as /all, serialized with msgpack + Note: Update is done automatically every time /all or / is called. GET stats of a specific process diff --git a/glances/outputs/glances_restful_api.py b/glances/outputs/glances_restful_api.py index af562ac0f2..01040e243d 100644 --- a/glances/outputs/glances_restful_api.py +++ b/glances/outputs/glances_restful_api.py @@ -38,6 +38,14 @@ except ImportError: MCP_AVAILABLE = False GlancesMcpServer = None +# msgspec import with fallback (optional, used by the /all/msgpack endpoint) +try: + import msgspec + + MSGSPEC_AVAILABLE = True +except ImportError: + MSGSPEC_AVAILABLE = False + msgspec = None from glances.plugins.plugin.dag import get_plugin_dependencies from glances.processes import glances_processes @@ -51,7 +59,7 @@ from fastapi import APIRouter, Depends, FastAPI, HTTPException, Request, status from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.gzip import GZipMiddleware - from fastapi.responses import HTMLResponse, JSONResponse + from fastapi.responses import HTMLResponse, JSONResponse, Response from fastapi.security import HTTPBasic, HTTPBasicCredentials from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates @@ -179,6 +187,21 @@ def render(self, content: Any) -> bytes: return json_dumps(content) +class GlancesMsgpackResponse(Response): + """ + Glances msgpack response, a compact binary alternative to GlancesJSONResponse. + + Stats are serialized to the MessagePack format using msgspec. The decoded + payload is identical to the JSON one (datetime objects become ISO 8601 + strings), just more compact on the wire. + """ + + media_type = "application/msgpack" + + def render(self, content: Any) -> bytes: + return msgspec.msgpack.encode(content) + + class GlancesUvicornServer(uvicorn.Server): def install_signal_handlers(self): pass @@ -545,6 +568,7 @@ def _router(self) -> APIRouter: f'{base_path}/args/{{item}}': self._api_args_item, f'{base_path}/help': self._api_help, f'{base_path}/all': self._api_all, + f'{base_path}/all/msgpack': self._api_all_msgpack, f'{base_path}/all/limits': self._api_all_limits, f'{base_path}/all/views': self._api_all_views, f'{base_path}/pluginslist': self._api_plugins, @@ -952,6 +976,31 @@ def _api_all(self): return GlancesJSONResponse(statval) + def _api_all_msgpack(self): + """Glances API RESTful implementation. + + Return a msgpack (binary) representation of all the plugins. + This is a compact alternative to the (potentially huge) /all JSON endpoint. + HTTP/200 if OK + HTTP/404 if stats cannot be retrieved + HTTP/501 if the msgspec library is not installed + """ + if not MSGSPEC_AVAILABLE: + raise HTTPException( + status.HTTP_501_NOT_IMPLEMENTED, + "The msgspec library is not installed (pip install msgspec)", + ) + + # Update the stat + self.__update_stats() + + try: + statval = self.stats.getAllAsDict() + except Exception as e: + raise HTTPException(status.HTTP_404_NOT_FOUND, f"Cannot get stats ({str(e)})") + + return GlancesMsgpackResponse(statval) + def _api_all_limits(self): """Glances API RESTful implementation. diff --git a/glances/outputs/glances_stdout_api_restful_doc.py b/glances/outputs/glances_stdout_api_restful_doc.py index 78e5da95eb..12b546a215 100644 --- a/glances/outputs/glances_stdout_api_restful_doc.py +++ b/glances/outputs/glances_stdout_api_restful_doc.py @@ -417,6 +417,11 @@ def print_all(): print(f' # curl {API_URL}/all') print(' Return a very big dictionary with all stats') print('') + print('Get all Glances stats encoded with msgpack (binary, ~25% smaller than JSON)::') + print('') + print(f' # curl {API_URL}/all/msgpack') + print(' Return the same dictionary as /all, serialized with msgpack') + print('') print('Note: Update is done automatically every time /all or / is called.') print('') diff --git a/pyproject.toml b/pyproject.toml index f434d7bbb8..7138e5c7c2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -106,6 +106,7 @@ snmp = ["pysnmp-lextudio<6.2.0"] sparklines = ["sparklines"] web = [ "fastapi>=0.82.0", + "msgspec", "python-jose[cryptography]>=3.3.0", "requests", "uvicorn", diff --git a/tests/test_restful.py b/tests/test_restful.py index 83723759db..596cdabc18 100755 --- a/tests/test_restful.py +++ b/tests/test_restful.py @@ -333,6 +333,26 @@ def test_017_item_key(self): self.assertIsInstance(req.json(), dict) self.assertIsInstance(req.json()[item], int) + def test_018_all_msgpack(self): + """All stats encoded with msgpack (binary, compact alternative to /all).""" + import json + + import msgspec + + method = "all/msgpack" + print('INFO: [TEST_018] Get all stats (msgpack encoding)') + print(f"HTTP RESTful request: {URL}/{method}") + req = self.http_get(f"{URL}/{method}") + + self.assertTrue(req.ok) + self.assertEqual(req.headers['Content-Type'], 'application/msgpack') + # The body is valid msgpack and decodes to a dict of plugins + stats = msgspec.msgpack.decode(req.content) + self.assertIsInstance(stats, dict) + self.assertIn('cpu', stats) + # The msgpack payload must be more compact than the equivalent JSON + self.assertLess(len(req.content), len(json.dumps(stats).encode())) + def test_050_start_cors_server(self): """Start a second Web server with a wildcard+trusted multi-origin allowlist.