1

So I'm making an API in a Django app and I have a class NodeID that follows the pattern:

class NodeID(enum.IntEnum):
    EIGENVECTOR = 0

A simplified version of what I return in my view function is this:

return json.dumps({'eigenvector': NodeID.EIGENVECTOR})

When I view the result of my API in a browser, it shows the value of 'eigenvector' to be NodeID.EIGENVECTOR as opposed to the integer 0.

{"eigenvector": NodeID.EIGENVECTOR }

This makes it such that my front end can't handle it (it has no idea what NodeID is, obviously). How can I make it so that the call receives the value of NodeID.EIGENVECTOR instead of the variable?

Corey McMahon
  • 305
  • 2
  • 9
  • 2
    The code you've shown here should be working as you want it to work. Can you show the code that hasn't been simplified, or an executable sample that demonstrates the same problem? – Tim Saylor Apr 20 '15 at 17:05

1 Answers1

1

This has to do with Python's implementation of enum, which uses a custom metaclass that modifies access to its class properties:

Accessing only the value works like this:

>>> member = NodeID.EIGENVECTOR
>>> member.value
0

So returning it from your simplified example would be like:

return {'eigenvector': NodeID.EIGENVECTOR.value}

Update: if using Python 3.4 and targeting an output as JSON, Python's own json.dumps() natively expands the values into the serialized representation. (I found that on this answer)

Example w/ json.dumps():

>>> class Foo(IntEnum):
...     bam = 0
...     bar = 1
...
>>> Foo.bam
<Foo.bam: 0>
>>> json.dumps(Foo.bam)
'0'

Example w/ nested structure:

>>> something = {'a': Foo.bam, 'b': { 'c': Foo.bar}}
>>> something 
{'a': <Foo.bam: 0>, 'b': {'c': <Foo.bar: 1>}}
>>> json.dumps(something) 
'{"a": 0, "b": {"c": 1}}'
Community
  • 1
  • 1
sthzg
  • 5,514
  • 2
  • 29
  • 50
  • You are right, thanks! The problem is that I have a nested dict with values of this metaclass type. Is there a way to blanket apply the .value to everything returned in my view function? Or are my only choices a) making sure the .value is applied as I construct the return object or b) tree walking over the return object before I return? – Corey McMahon Apr 21 '15 at 16:00
  • I updated the answer, because I think if your are eventually heading for an output as JSON then `json.dumps()` might already provide what you need. Everything else is hard to say /wo more information about your code. You could open a new question for that if necessary. – sthzg Apr 21 '15 at 17:33
  • I have been using json.dumps() and still having these problems. I'm hoping to find something in the documentation for it (currently reading). I recreated your example and did not get the behavior you stated. Instead I got: `'{"a": Foo.bam, "b": {"c": Foo.bar}}'` – Corey McMahon Apr 21 '15 at 17:44
  • I should have put that I am using json.dumps() in the original question, but it slipped my mind because I have it hidden away in a view function decorator. Will update now. – Corey McMahon Apr 21 '15 at 17:46
  • A user in [these comments](http://stackoverflow.com/a/24482131/870769) states something similar for Python 3.2. Which Python version are you using? (if other than 3.4, from where do you import `enum`?) – sthzg Apr 21 '15 at 17:51
  • That's it. I'm using an old Python version. It looks like my solution is going to be to .value everything until I update Python. Thank you so much! – Corey McMahon Apr 21 '15 at 18:01