Skip to content

Commit 367c467

Browse files
author
Jonathan Van Eenwyk
committed
Fix encoding json with Attachments
When using Attachments, we need to properly encode them into json to share them outside. OutputToJSON handled this correctly, but both MfgInspector and StationServer did not. Move TestRecordEncoder into openhtf.util.json, so that it can be shared by all three. For station_server, patch the tornado json encoder, so that all values being sent to the client through tornado are properly encoded.
1 parent 95f15c4 commit 367c467

File tree

4 files changed

+37
-11
lines changed

4 files changed

+37
-11
lines changed

openhtf/output/callbacks/json_factory.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,10 @@
66
from openhtf.core import test_record
77
from openhtf.output import callbacks
88
from openhtf.util import data
9+
from openhtf.util.json_encoder import TestRecordEncoder
910
import six
1011

1112

12-
class TestRecordEncoder(json.JSONEncoder):
13-
14-
def default(self, obj):
15-
if isinstance(obj, test_record.Attachment):
16-
dct = obj._asdict()
17-
dct['data'] = base64.standard_b64encode(obj.data).decode('utf-8')
18-
return dct
19-
return super(TestRecordEncoder, self).default(obj)
20-
21-
2213
class OutputToJSON(callbacks.OutputToFile):
2314
"""Return an output callback that writes JSON Test Records.
2415

openhtf/output/proto/mfg_event_converter.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from openhtf.util import data as htf_data
2424
from openhtf.util import units
2525
from openhtf.util import validators
26+
from openhtf.util.json_encoder import TestRecordEncoder
2627

2728

2829
from past.builtins import unicode
@@ -172,7 +173,7 @@ def _convert_object_to_json(obj):
172173
# Since there will be parts of this that may have unicode, either as
173174
# measurement or in the logs, we have to be careful and convert everything
174175
# to unicode, merge, then encode to UTF-8 to put it into the proto.
175-
json_encoder = json.JSONEncoder(sort_keys=True, indent=2, ensure_ascii=False)
176+
json_encoder = TestRecordEncoder(sort_keys=True, indent=2, ensure_ascii=False)
176177
pieces = []
177178
for piece in json_encoder.iterencode(obj):
178179
if isinstance(piece, bytes):

openhtf/output/servers/station_server.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from openhtf.util import logs
3030
from openhtf.util import multicast
3131
from openhtf.util import timeouts
32+
from openhtf.util.json_encoder import TestRecordEncoder
3233

3334
STATION_SERVER_TYPE = 'station'
3435

@@ -556,6 +557,11 @@ def __init__(self, history_path=None):
556557
if not tornado_logger.handlers:
557558
tornado_logger.addHandler(logging.NullHandler())
558559

560+
# Override tornado's json encoding to handle our Attachments.
561+
def _json_encode(value):
562+
return TestRecordEncoder().encode(value)
563+
sockjs.tornado.proto.json_encode = _json_encode
564+
559565
# Bind port early so that the correct port number can be used in the routes.
560566
sockets, port = web_gui_server.bind_port(int(conf.station_server_port))
561567

openhtf/util/json_encoder.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Copyright 2016 Google Inc. All Rights Reserved.
2+
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import base64
16+
import json
17+
18+
from openhtf.core import test_record
19+
20+
21+
class TestRecordEncoder(json.JSONEncoder):
22+
"""JSON encoder that supports Attachments."""
23+
def default(self, obj):
24+
if isinstance(obj, test_record.Attachment):
25+
dct = obj._asdict()
26+
dct['data'] = base64.standard_b64encode(obj.data).decode('utf-8')
27+
return dct
28+
return super(TestRecordEncoder, self).default(obj)

0 commit comments

Comments
 (0)