17

The HTTPRequest class in the tornado* web framework helpfully maps GET and POST arguments to lists. I understand why -- in case a given argument name is used multiple times. But for some RequestHandlers, this is a pain. For instance, if I want to pass a json object and parse it as-is on the server.

What's the most straightforward way to disable the map-to-list behavior so that I can send unaltered json to a tornado/cyclone server?

*Cyclone, actually, in case there's an implementation difference here.

Abe
  • 22,738
  • 26
  • 82
  • 111

2 Answers2

39

Instead of accessing self.request.arguments directly you should use the accessor functions:

self.get_argument("ID", default=None, strip=False)

This returns a single item.

If you want to turn the arguments into a JSON object you can quite easily do so:

json.dumps({ k: self.get_argument(k) for k in self.request.arguments })
Glycerine
  • 7,157
  • 4
  • 39
  • 65
koblas
  • 25,410
  • 6
  • 39
  • 49
  • Thanks! What if I just want to return the whole set of arguments as a single json object? I could reconstruct it by iterating over the whole dictionary and calling get_argument for each key, but that seems inefficient. – Abe Apr 28 '12 at 01:05
  • 5
    json.dumps({ k: self.get_argument(k) for k in self.request.arguments }) - it's not really that inefficient. – koblas Apr 28 '12 at 13:39
4

I'm going to go with "you're out of luck." You could re-write the class in question (looks like that would not be fun), but aside from that I don't see many options.


I would just use a dict comprehension.

{k:''.join(v) for k,v in  self.request.arguments.iteritems()}
cwallenpoole
  • 79,954
  • 26
  • 128
  • 166