Changeset 21
- Timestamp:
- 02/28/07 14:40:22 (2 years ago)
- Files:
-
- trunk/tgwebservices/controllers.py (modified) (4 diffs)
- trunk/tgwebservices/tests/fixtures.py (modified) (1 diff)
- trunk/tgwebservices/tests/test_controllers.py (modified) (5 diffs)
- trunk/tgwebservices/tests/test_json.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/tgwebservices/controllers.py
r20 r21 14 14 import cElementTree as et 15 15 from genshi.builder import tag, Element 16 import simplejson 16 17 17 18 from turbogears import controllers, expose as tgexpose … … 161 162 return instance 162 163 163 class ComplexConverter(object):164 pass_xml = True165 166 def __init__(self, cls):167 self.cls = cls168 169 def __call__(self, val):170 return _get_single_value(val, self.cls)171 172 164 def _handle_xml_params(body, input_types): 173 165 kw = {} … … 204 196 % (key, input_types.keys()), key, None 205 197 ) 206 198 199 def _get_json_value(value, itype): 200 if isinstance(itype, list): 201 itemtype = itype[0] 202 return [_get_json_value(item, itemtype) for item in value] 203 elif not isinstance(itype, type): 204 return _get_json_value(value, type(itype)) 205 elif itype not in primitives and isinstance(value, dict): 206 return _create_instance_from_json(value, itype) 207 return itype(value) 208 209 def _create_instance_from_json(value, cls): 210 instance = cls() 211 for key in value: 212 try: 213 itype = getattr(cls, key) 214 except AttributeError: 215 raise validators.Invalid("%s is an unknown parameter for a %s" 216 % (key, cls.__name__), 217 key, None) 218 setattr(instance, str(key), _get_json_value(value[key], itype)) 219 return instance 220 221 def _handle_json_params(input, input_types): 222 if isinstance(input, basestring): 223 try: 224 input = simplejson.loads(input) 225 except ValueError: 226 raise validators.Invalid("Invalid JSON input") 227 kw = {} 228 for key in input: 229 if key in input_types: 230 kw[str(key)] = _get_json_value(input[key], input_types[key]) 231 else: 232 raise validators.Invalid( 233 "%s is not a valid parameter (valid values are: %s)" 234 % (key, input_types.keys()), key, None 235 ) 236 return kw 237 238 207 239 def wsvalidate(*args, **kw): 208 240 """Validates and converts incoming parameters. Also registers the … … 240 272 None) 241 273 kw = _handle_xml_params(body, input_types) 274 elif request.headers.get("Content-Type", "") \ 275 .startswith("application/json"): 276 clen = int(request.headers.get('Content-Length')) or 0 277 data = request.body.read(clen) 278 kw = _handle_json_params(data, input_types) 242 279 else: 243 280 _handle_keyword_params(kw, input_types) trunk/tgwebservices/tests/fixtures.py
r20 r21 92 92 def tenyearsolder(self, person): 93 93 person.age = person.age + 10 94 self.last_person = person 94 95 return person 95 96 trunk/tgwebservices/tests/test_controllers.py
r19 r21 1 1 import cElementTree as et 2 2 3 from tgwebservices.controllers import ComplexConverter3 from tgwebservices.controllers import _get_single_value, _handle_json_params 4 4 5 5 class Person(object): … … 14 14 <married>no</married> 15 15 </p>""") 16 cc = ComplexConverter(Person) 17 val = cc(tree) 16 val = _get_single_value(tree, Person) 18 17 print val 19 18 assert isinstance(val, Person) … … 42 41 </family> 43 42 """) 44 cc = ComplexConverter(Family1) 45 val = cc(tree) 43 val = _get_single_value(tree, Family1) 46 44 assert val.lastname == "Brady" 47 45 print val.members … … 92 90 </family> 93 91 """) 94 cc = ComplexConverter(Family2) 95 val = cc(tree) 92 val = _get_single_value(tree, Family2) 96 93 assert val.lastname == "Brady" 97 94 print val.members … … 106 103 <item>true</item> 107 104 </list>""") 108 cc = ComplexConverter([bool]) 109 val = cc(tree) 105 val = _get_single_value(tree, [bool]) 110 106 print val 111 107 assert len(val) == 5 108 109 def test_json_conversion_of_class(): 110 input_types = {"person" : Person} 111 data = {"person" : {"name" : "Fred", "age" : 99}} 112 kw = _handle_json_params(data, input_types) 113 assert isinstance(kw["person"], Person) 114 print kw["person"].age 115 assert kw["person"].age == 99 116 assert kw["person"].name == "Fred" 117 118 def test_json_conversion_of_nested_class(): 119 input_types = {"family" : Family2} 120 data = {"family" : {"lastname" : "Brady", "members" : 121 [{"name" : "Mike", "age" : 42}, {"name" : "Carol", "age" : 40}] 122 }} 123 kw = _handle_json_params(data, input_types) 124 assert isinstance(kw["family"], Family2) 125 assert len(kw["family"].members) == 2 126 assert kw["family"].members[0].name == "Mike" 127 assert kw["family"].members[0].age == 42 trunk/tgwebservices/tests/test_json.py
r15 r21 1 import cStringIO as StringIO 2 1 3 import cherrypy 2 4 from turbogears import testutil … … 64 66 for test in tests: 65 67 yield check, test[0], test[1] 66 68 69 def test_complex_input(): 70 cherrypy.root = ComplexService("http://foo.bar.baz/") 71 72 request = """{ 73 "person" : {"name" : "Fred", "age" : 22} 74 }""" 75 testutil.create_request("/tenyearsolder", rfile=StringIO.StringIO(request), 76 method="POST", 77 headers={"Content-Length" : str(len(request)), 78 "Content-Type" : 79 "application/json; charset=utf-8"}) 80 output = cherrypy.response.body[0] 81 print output 82 print cherrypy.root.last_person.age 83 assert cherrypy.root.last_person.age == 32
