diff --git a/api/api.py b/api/api.py index 2ec4764b61f7e9c4606010a27d2758826484a822..a66cc36e912498cdd5dc09faa145562a39d22f79 100644 --- a/api/api.py +++ b/api/api.py @@ -11,6 +11,7 @@ from . import base from .jobs.jobs import Job from .jobs.handlers import JobsHandler, JobHandler from .dao.containerutil import FileReference, ContainerReference +from . import encoder from . import root from . import util from . import config @@ -106,7 +107,7 @@ class Config(base.RequestHandler): self.response.write( 'config = ' + - json.dumps( self.get(), sort_keys=True, indent=4, separators=(',', ': '), default=util.custom_json_serializer,) + + json.dumps( self.get(), sort_keys=True, indent=4, separators=(',', ': '), default=encoder.custom_json_serializer,) + ';' ) @@ -261,20 +262,11 @@ routes = [ ] -def custom_json_serializer(obj): - if isinstance(obj, bson.objectid.ObjectId): - return str(obj) - elif isinstance(obj, datetime.datetime): - return pytz.timezone('UTC').localize(obj).isoformat() - elif isinstance(obj, Job): - return obj.map() - raise TypeError(repr(obj) + " is not JSON serializable") - def dispatcher(router, request, response): try: rv = router.default_dispatcher(request, response) if rv is not None: - response.write(json.dumps(rv, default=custom_json_serializer)) + response.write(json.dumps(rv, default=encoder.custom_json_serializer)) response.headers['Content-Type'] = 'application/json; charset=utf-8' except webapp2.exc.HTTPException as e: util.send_json_http_exception(response, str(e), e.code) diff --git a/api/encoder.py b/api/encoder.py new file mode 100644 index 0000000000000000000000000000000000000000..e81cc46a332fb48490b597f721afb2bc8d0d8f87 --- /dev/null +++ b/api/encoder.py @@ -0,0 +1,42 @@ +import bson.objectid +import datetime +import json +import pytz + +from .jobs.jobs import Job + +def custom_json_serializer(obj): + if isinstance(obj, bson.objectid.ObjectId): + return str(obj) + elif isinstance(obj, datetime.datetime): + return pytz.timezone('UTC').localize(obj).isoformat() + elif isinstance(obj, Job): + return obj.map() + raise TypeError(repr(obj) + " is not JSON serializable") + + +def sse_pack(d): + """ + Format a map with Server-Sent-Event-meaningful keys into a string for transport. + + Happily borrowed from: http://taoofmac.com/space/blog/2014/11/16/1940 + For reading on web usage: http://www.html5rocks.com/en/tutorials/eventsource/basics + For reading on the format: https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format + """ + + buffer = '' + + for k in ['retry', 'id', 'event', 'data']: + if k in d.keys(): + buffer += '%s: %s\n' % (k, d[k]) + + return buffer + '\n' + +def json_sse_pack(d): + """ + Variant of sse_pack that will json-encode your data blob. + """ + + d['data'] = json.dumps(d['data'], default=custom_json_serializer) + + return sse_pack(d) diff --git a/api/placer.py b/api/placer.py index a6884084355b5ac4787a954443b6325ae3349643..25e7dc0de077fb285351430f4b07987f42776444 100644 --- a/api/placer.py +++ b/api/placer.py @@ -9,6 +9,7 @@ import zipfile from . import base from . import config +from . import encoder from . import files from .jobs import rules from . import tempdir as tempfile @@ -355,7 +356,7 @@ class PackfilePlacer(Placer): # Report progress complete += 1 - yield util.json_sse_pack({ + yield encoder.json_sse_pack({ 'event': 'progress', 'data': { 'done': complete, 'total': max, 'percent': (complete / float(max)) * 100 }, }) @@ -470,7 +471,7 @@ class PackfilePlacer(Placer): } # Report result - yield util.json_sse_pack({ + yield encoder.json_sse_pack({ 'event': 'result', 'data': result, }) diff --git a/api/util.py b/api/util.py index d01ed013f269dafcc1278219b8216321335fa00b..f1a9b5df291e7bd273b077766b4f17735cf3f994 100644 --- a/api/util.py +++ b/api/util.py @@ -198,29 +198,3 @@ def mkdir_p(path): pass else: raise - -def sse_pack(d): - """ - Format a map with Server-Sent-Event-meaningful keys into a string for transport. - - Happily borrowed from: http://taoofmac.com/space/blog/2014/11/16/1940 - For reading on web usage: http://www.html5rocks.com/en/tutorials/eventsource/basics - For reading on the format: https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format - """ - - buffer = '' - - for k in ['retry', 'id', 'event', 'data']: - if k in d.keys(): - buffer += '%s: %s\n' % (k, d[k]) - - return buffer + '\n' - -def json_sse_pack(d): - """ - Variant of sse_pack that will json-encode your data blob. - """ - - d['data'] = json.dumps(d['data'], default=custom_json_serializer) - - return sse_pack(d)