From 0f63e9675bbf5fefeb7bc6a608a83243a7692346 Mon Sep 17 00:00:00 2001 From: Dave Shawley Date: Sun, 19 Feb 2017 21:11:06 -0500 Subject: [PATCH] Implement primitive StatusHandler. This version simply returns a JSON object based on the values passed into the initialize method. --- docs/api.rst | 5 ++++ docs/conf.py | 1 + docs/custom.css | 3 +++ docs/history.rst | 1 + docs/index.rst | 1 + examples/app.py | 24 ++++++++++++++++++ sprockets_status/handlers.py | 48 ++++++++++++++++++++++++++++++++++++ tests.py | 35 ++++++++++++++++++++++++++ 8 files changed, 118 insertions(+) create mode 100644 docs/api.rst create mode 100644 examples/app.py create mode 100644 sprockets_status/handlers.py diff --git a/docs/api.rst b/docs/api.rst new file mode 100644 index 0000000..6a83b83 --- /dev/null +++ b/docs/api.rst @@ -0,0 +1,5 @@ +=== +API +=== +.. autoclass:: sprockets_status.handlers.StatusHandler + :members: diff --git a/docs/conf.py b/docs/conf.py index 9967a53..7066cbf 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -10,6 +10,7 @@ extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx'] master_doc = 'index' source_suffix = '.rst' +html_sidebars = {'**': ['about.html', 'navigation.html']} html_static_path = ['.'] intersphinx_mapping = { 'python': ('http://docs.python.org/3/', None), diff --git a/docs/custom.css b/docs/custom.css index 3d8ad89..c28d9bc 100644 --- a/docs/custom.css +++ b/docs/custom.css @@ -1,3 +1,6 @@ +h1.logo { + font-size: 1em; +} .field-name { -webkit-hyphens: none; hyphens: none; diff --git a/docs/history.rst b/docs/history.rst index 93300f0..2a64e33 100644 --- a/docs/history.rst +++ b/docs/history.rst @@ -4,6 +4,7 @@ Release History `Next Release`_ --------------- +- Added :class:`sprockets_status.handlers.StatusHandler` .. _Next Release: https://github.com/sprockets/sprockets-status/compare/0.0.0...HEAD diff --git a/docs/index.rst b/docs/index.rst index d7b6664..883f511 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,4 +3,5 @@ .. toctree:: :hidden: + api history diff --git a/examples/app.py b/examples/app.py new file mode 100644 index 0000000..78cec7b --- /dev/null +++ b/examples/app.py @@ -0,0 +1,24 @@ +from tornado import ioloop, web + +import sprockets_status.handlers + + +name = 'my-application' +version = '1.2.3' + + +def make_app(**settings): + return web.Application([ + web.url('/status', sprockets_status.handlers.StatusHandler, + {'name': name, 'version': version}), + ], **settings) + + +if __name__ == '__main__': + app = make_app() + iol = ioloop.IOLoop.current() + try: + app.listen(8888) + iol.start() + except KeyboardInterrupt: + iol.stop() diff --git a/sprockets_status/handlers.py b/sprockets_status/handlers.py new file mode 100644 index 0000000..044dac9 --- /dev/null +++ b/sprockets_status/handlers.py @@ -0,0 +1,48 @@ +import json + +from tornado import web + + +class StatusHandler(web.RequestHandler): + """ + Simple handler that returns application status information. + """ + + def __init__(self, *args, **kwargs): + self.name = 'UNKNOWN' + self.version = '0.0.0' + self.status = 'ok' + super(StatusHandler, self).__init__(*args, **kwargs) + + def initialize(self, name, version): + """ + Sets the static information. + + :param str name: name of the application + :param str version: application version number + + """ + self.name = name + self.version = version + + def get(self): + """ + Returns a JSON object containing the application status. + + **Sample Response** + + .. code-block:: json + + { + "name": "application-name", + "version": "1.2.3", + "status": "ok" + } + + """ + self.set_status(200) + self.set_header('Content-Type', 'application/json') + self.write(json.dumps({'name': self.name, + 'version': self.version, + 'status': self.status}).encode('utf-8')) + self.finish() diff --git a/tests.py b/tests.py index e69de29..76c7e54 100644 --- a/tests.py +++ b/tests.py @@ -0,0 +1,35 @@ +import json + +from tornado import testing + +import examples.app + + +class SimpleStatusTests(testing.AsyncHTTPTestCase): + + def get_app(self): + return examples.app.make_app(debug=True) + + def test_that_content_type_is_set(self): + response = self.fetch('/status') + self.assertEqual(response.code, 200) + self.assertTrue( + response.headers['Content-Type'].startswith('application/json')) + + def test_that_application_name_is_included(self): + response = self.fetch('/status') + self.assertEqual(response.code, 200) + body = json.loads(response.body.decode('utf-8')) + self.assertEqual(body['name'], examples.app.name) + + def test_that_application_version_is_included(self): + response = self.fetch('/status') + self.assertEqual(response.code, 200) + body = json.loads(response.body.decode('utf-8')) + self.assertEqual(body['version'], examples.app.version) + + def test_that_application_status_is_included(self): + response = self.fetch('/status') + self.assertEqual(response.code, 200) + body = json.loads(response.body.decode('utf-8')) + self.assertEqual(body['status'], 'ok')