mirror of https://github.com/nicolargo/glances
Add methods to the Restfull/API
parent
2749e967bb
commit
09ec93a9d9
|
@ -592,13 +592,15 @@ CSV files have two lines per stats:
|
|||
- Stats description
|
||||
- Stats (comma separated)
|
||||
|
||||
API Documentation
|
||||
=================
|
||||
APIs Documentations
|
||||
===================
|
||||
|
||||
Glances uses a `XML-RPC server`_ and can be used by another client software.
|
||||
Glances includes a `XML-RPC server`_ and a `RESTFULL-JSON`_ API which and can be used by another client software.
|
||||
|
||||
API documentation is available at
|
||||
https://github.com/nicolargo/glances/wiki/The-Glances-2.x-API-How-to.
|
||||
APIs documentations are available at:
|
||||
|
||||
- XML-RPC: https://github.com/nicolargo/glances/wiki/The-Glances-2.x-API-How-to
|
||||
- RESTFULL-JSON: https://github.com/nicolargo/glances/wiki/The-Glances-RESTFULL-JSON-API
|
||||
|
||||
Support
|
||||
=======
|
||||
|
@ -614,3 +616,4 @@ Feel free to contribute!
|
|||
|
||||
.. _psutil: https://code.google.com/p/psutil/
|
||||
.. _XML-RPC server: http://docs.python.org/2/library/simplexmlrpcserver.html
|
||||
.. _RESTFULL-JSON: http://jsonapi.org/
|
|
@ -127,9 +127,13 @@ class GlancesStats(object):
|
|||
self.__update__(input_stats)
|
||||
|
||||
def getAll(self):
|
||||
"""Return all the stats."""
|
||||
"""Return all the stats (list)"""
|
||||
return [self._plugins[p].get_raw() for p in self._plugins]
|
||||
|
||||
def getAllAsDict(self):
|
||||
"""Return all the stats (dict)"""
|
||||
return {p: self._plugins[p].get_raw() for p in self._plugins}
|
||||
|
||||
def get_plugin_list(self):
|
||||
"""Return the plugin list."""
|
||||
self._plugins
|
||||
|
@ -163,9 +167,13 @@ class GlancesStatsServer(GlancesStats):
|
|||
self.all_stats[p] = self._plugins[p].get_raw()
|
||||
|
||||
def getAll(self):
|
||||
"""Return the stats as a dict."""
|
||||
"""Return the stats as a list"""
|
||||
return self.all_stats
|
||||
|
||||
def getAllAsDict(self):
|
||||
"""Return the stats as a dict"""
|
||||
return {p: self.all_stats[p] for p in self._plugins}
|
||||
|
||||
def getAllPlugins(self):
|
||||
"""Return the plugins list."""
|
||||
return [p for p in self._plugins]
|
||||
|
|
|
@ -27,7 +27,7 @@ from glances.core.glances_globals import logger
|
|||
|
||||
# Import mandatory Bottle lib
|
||||
try:
|
||||
from bottle import Bottle, template, static_file, TEMPLATE_PATH, abort
|
||||
from bottle import Bottle, template, static_file, TEMPLATE_PATH, abort, response
|
||||
except ImportError:
|
||||
logger.critical('Bottle module not found. Glances cannot start in web server mode.')
|
||||
print(_("Install it using pip: # pip install bottle"))
|
||||
|
@ -84,10 +84,11 @@ class GlancesBottle(object):
|
|||
self._app.route('/<filename:re:.*\.css>', method="GET", callback=self._css)
|
||||
self._app.route('/<filename:re:.*\.js>', method="GET", callback=self._js)
|
||||
# REST API
|
||||
self._app.route('/api/pluginslist', method="GET", callback=self._api_plugins)
|
||||
self._app.route('/api/:plugin', method="GET", callback=self._api)
|
||||
self._app.route('/api/:plugin/:item', method="GET", callback=self._api_item)
|
||||
self._app.route('/api/:plugin/:item/:value', method="GET", callback=self._api_value)
|
||||
self._app.route('/api/2/pluginslist', method="GET", callback=self._api_plugins)
|
||||
self._app.route('/api/2/all', method="GET", callback=self._api_all)
|
||||
self._app.route('/api/2/:plugin', method="GET", callback=self._api)
|
||||
self._app.route('/api/2/:plugin/:item', method="GET", callback=self._api_item)
|
||||
self._app.route('/api/2/:plugin/:item/:value', method="GET", callback=self._api_value)
|
||||
|
||||
def start(self, stats):
|
||||
"""Start the bottle."""
|
||||
|
@ -109,6 +110,7 @@ class GlancesBottle(object):
|
|||
|
||||
def _index(self, refresh_time=None):
|
||||
"""Bottle callback for index.html (/) file."""
|
||||
response.content_type = 'text/html'
|
||||
# Manage parameter
|
||||
if refresh_time is None:
|
||||
refresh_time = self.args.time
|
||||
|
@ -121,11 +123,13 @@ class GlancesBottle(object):
|
|||
|
||||
def _css(self, filename):
|
||||
"""Bottle callback for *.css files."""
|
||||
response.content_type = 'text/html'
|
||||
# Return the static file
|
||||
return static_file(filename, root=os.path.join(self.STATIC_PATH, 'css'))
|
||||
|
||||
def _js(self, filename):
|
||||
"""Bottle callback for *.js files."""
|
||||
response.content_type = 'text/html'
|
||||
# Return the static file
|
||||
return static_file(filename, root=os.path.join(self.STATIC_PATH, 'js'))
|
||||
|
||||
|
@ -135,20 +139,53 @@ class GlancesBottle(object):
|
|||
Return the plugin list
|
||||
or 404 error
|
||||
"""
|
||||
response.content_type = 'application/vnd.api+json'
|
||||
|
||||
# Update the stat
|
||||
self.stats.update()
|
||||
|
||||
try:
|
||||
plist = json.dumps(self.plugins_list)
|
||||
except Exception as e:
|
||||
abort(404, "Can not get plugin list (%s)" % str(e))
|
||||
return plist
|
||||
|
||||
def _api_all(self):
|
||||
"""
|
||||
Glances API RESTFULL implementation
|
||||
Return the JSON representation of all the plugins
|
||||
HTTP/200 if OK
|
||||
HTTP/400 if plugin is not found
|
||||
HTTP/404 if others error
|
||||
"""
|
||||
response.content_type = 'application/vnd.api+json'
|
||||
|
||||
# Update the stat
|
||||
self.stats.update()
|
||||
|
||||
try:
|
||||
# Get the JSON value of the stat ID
|
||||
statval = json.dumps(self.stats.getAllAsDict())
|
||||
except Exception as e:
|
||||
abort(404, "Can not get stats (%s)" % str(e))
|
||||
return statval
|
||||
|
||||
def _api(self, plugin):
|
||||
"""
|
||||
Glances API RESTFULL implementation
|
||||
Return the JSON representation of a given plugin
|
||||
or 404 error
|
||||
HTTP/200 if OK
|
||||
HTTP/400 if plugin is not found
|
||||
HTTP/404 if others error
|
||||
"""
|
||||
response.content_type = 'application/vnd.api+json'
|
||||
|
||||
if plugin not in self.plugins_list:
|
||||
abort(404, "Unknown plugin %s (available plugins: %s)" % (plugin, self.plugins_list))
|
||||
abort(400, "Unknown plugin %s (available plugins: %s)" % (plugin, self.plugins_list))
|
||||
|
||||
# Update the stat
|
||||
self.stats.update()
|
||||
|
||||
try:
|
||||
# Get the JSON value of the stat ID
|
||||
statval = self.stats.get_plugin(plugin).get_stats()
|
||||
|
@ -160,11 +197,21 @@ class GlancesBottle(object):
|
|||
"""
|
||||
Glances API RESTFULL implementation
|
||||
Return the JSON represenation of the couple plugin/item
|
||||
or 404 error
|
||||
HTTP/200 if OK
|
||||
HTTP/400 if plugin is not found
|
||||
HTTP/404 if others error
|
||||
|
||||
"""
|
||||
response.content_type = 'application/vnd.api+json'
|
||||
|
||||
if plugin not in self.plugins_list:
|
||||
abort(404, "Unknown plugin %s (available plugins: %s)" % (plugin, self.plugins_list))
|
||||
abort(400, "Unknown plugin %s (available plugins: %s)" % (plugin, self.plugins_list))
|
||||
|
||||
# Update the stat
|
||||
self.stats.update()
|
||||
|
||||
plist = self.stats.get_plugin(plugin).get_stats_item(item)
|
||||
|
||||
if plist is None:
|
||||
abort(404, "Can not get item %s in plugin %s" % (item, plugin))
|
||||
else:
|
||||
|
@ -174,11 +221,20 @@ class GlancesBottle(object):
|
|||
"""
|
||||
Glances API RESTFULL implementation
|
||||
Return the process stats (dict) for the given item=value
|
||||
or 404 error
|
||||
HTTP/200 if OK
|
||||
HTTP/400 if plugin is not found
|
||||
HTTP/404 if others error
|
||||
"""
|
||||
response.content_type = 'application/vnd.api+json'
|
||||
|
||||
if plugin not in self.plugins_list:
|
||||
abort(404, "Unknown plugin %s (available plugins: %s)" % (plugin, self.plugins_list))
|
||||
abort(400, "Unknown plugin %s (available plugins: %s)" % (plugin, self.plugins_list))
|
||||
|
||||
# Update the stat
|
||||
self.stats.update()
|
||||
|
||||
pdict = self.stats.get_plugin(plugin).get_stats_value(item, value)
|
||||
|
||||
if pdict is None:
|
||||
abort(404, "Can not get item(%s)=value(%s) in plugin %s" % (item, value, plugin))
|
||||
else:
|
||||
|
|
|
@ -158,7 +158,7 @@ class GlancesPlugin(object):
|
|||
if type(self.stats) is not list:
|
||||
if type(self.stats) is dict:
|
||||
try:
|
||||
return json.dumps(self.stats[item])
|
||||
return json.dumps({ item: self.stats[item] })
|
||||
except KeyError as e:
|
||||
logger.error(_("Can not get item %s (%s)") % (item, e))
|
||||
else:
|
||||
|
@ -166,7 +166,7 @@ class GlancesPlugin(object):
|
|||
else:
|
||||
try:
|
||||
# Source: http://stackoverflow.com/questions/4573875/python-get-index-of-dictionary-item-in-list
|
||||
return json.dumps(map(itemgetter(item), self.stats))
|
||||
return json.dumps({ item: map(itemgetter(item), self.stats) })
|
||||
except (KeyError, ValueError) as e:
|
||||
logger.error(_("Can not get item %s (%s)") % (item, e))
|
||||
return None
|
||||
|
@ -182,7 +182,7 @@ class GlancesPlugin(object):
|
|||
if value.isdigit():
|
||||
value = int(value)
|
||||
try:
|
||||
return json.dumps([i for i in self.stats if i[item] == value])
|
||||
return json.dumps({ value: [i for i in self.stats if i[item] == value] })
|
||||
except (KeyError, ValueError) as e:
|
||||
logger.error(_("Can not get item(%s)=value(%s) (%s)") % (item, value,e))
|
||||
return None
|
||||
|
|
Loading…
Reference in New Issue