Skip to content

Commit

Permalink
Merge pull request sbuss#6 from CloudCray/master
Browse files Browse the repository at this point in the history
Adds to_dict and to_json methods for Facade
  • Loading branch information
jdavisp3 authored Jan 28, 2017
2 parents 5ba972a + 010aacf commit 7e51cdb
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 0 deletions.
56 changes: 56 additions & 0 deletions tests/test_json_parsing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import unittest
import logging
import sys


from tigershark.facade import f835, f271
from tigershark.parsers import M835_4010_X091_A1, M271_4010_X092_A1, M835_5010_X221_A1, M271_5010_X279_A1


class TestJSONFunction(unittest.TestCase):
def test_json_835(self):
m = M835_4010_X091_A1.parsed_835
with open('tests/835-example.txt') as f:
parsed = m.unmarshall(f.read().strip())
f = f835.F835_4010(parsed)
try:
f.to_json()
except TypeError:
self.fail(".to_json() raised TypeError")

def test_json_271(self):
m = M271_4010_X092_A1.parsed_271
with open('tests/271-example.txt') as f:
parsed = m.unmarshall(f.read().strip())
f = f271.F271_4010(parsed)
try:
f.to_json()
except TypeError:
self.fail(".to_json() raised TypeError")

def test_json_835_5010(self):
m = M835_5010_X221_A1.parsed_835
with open('tests/5010-835-example-1.txt') as f:
parsed = m.unmarshall(f.read().strip())
f = f835.F835_5010(parsed)
try:
f.to_json()
except TypeError:
self.fail(".to_json() raised TypeError")

def test_json_271_5010(self):
m = M271_5010_X279_A1.parsed_271
with open('tests/5010-271-example-1.txt') as f:
parsed = m.unmarshall(f.read().strip())
f = f271.F271_5010(parsed)
try:
f.to_json()
except TypeError:
self.fail(".to_json() raised TypeError")

if __name__ == "__main__":
logging.basicConfig(
stream=sys.stderr,
level=logging.INFO,
)
unittest.main()
47 changes: 47 additions & 0 deletions tigershark/facade/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,12 @@ class and an instance of an :class:`X12.message.X12Loop`. Each bridge has a few
.. autoclass:: MissingSegment
"""
import datetime
import json
import inspect
from decimal import Decimal

from ..X12.message import X12Structure

# Transaction Set ID -> X12 release number -> (facade module, facade name)
FACADE_MAP = {
'270': {
Expand Down Expand Up @@ -289,12 +293,41 @@ def get_facade(transaction_set_id, version_tuple):
return getattr(module, facade_name)


def _to_python_dict(instance):
properties = [x for x in inspect.getmembers(instance) if not x[0].startswith("_")]
record = dict()
for k, v in properties:
if inspect.ismethod(v) or inspect.isbuiltin(v):
pass
elif isinstance(v, X12Structure):
pass
elif isinstance(v, list) or isinstance(v, tuple) or isinstance(v, set):
record[k] = [_to_python_dict(x) for x in v]
elif type(v) in [int, float, str, bool, type(None)]:
record[k] = v
elif type(v) is Decimal:
record[k] = float(v)
elif isinstance(v, datetime.date) or isinstance(v, datetime.time):
record[k] = v.isoformat()
elif isinstance(v, X12LoopBridge) or isinstance(v, X12SegmentBridge) or isinstance(v, Facade):
record[k] = v.to_dict()
else:
raise TypeError("Cannot parse '{0}'; type is '{1}'".format(k, str(type(v))))
return record


class Facade(object):

def loops(self, theClass, anX12Message, *args, **kwargs):
return [theClass(loop, *args, **kwargs) for loop in
anX12Message.descendant("loop", theClass.loopName)]

def to_dict(self):
return _to_python_dict(self)

def to_json(self, **kwargs):
return json.dumps(self.to_dict(), **kwargs)


class MissingSegment(Exception):
"""This exception is raised if the target Segment cannot be found
Expand Down Expand Up @@ -409,6 +442,12 @@ def segment(self, name, qualifierPosition=None,
return None
return X12SegmentBridge(matches[0])

def to_dict(self):
return _to_python_dict(self)

def to_json(self, **kwargs):
return json.dumps(self.to_dict(), **kwargs)


class X12SegmentBridge(object):
"""Bridge between a model and an :class:`X12.message.X12Segment`.
Expand Down Expand Up @@ -444,6 +483,12 @@ def composite(self, *name):
return compList[0]
return None

def to_dict(self):
return _to_python_dict(self)

def to_json(self, **kwargs):
return json.dumps(self.to_dict(), **kwargs)


class SegmentAccess(object):
"""Used to get a single segment.
Expand Down Expand Up @@ -981,6 +1026,8 @@ def __get__(self, instance, owner):
data.append(self.x12type.x12_to_python(raw))
else:
data.append(raw)
if len(data) == 0:
return None
return data[0]

def __set__(self, instance, value):
Expand Down

0 comments on commit 7e51cdb

Please sign in to comment.