I am trying to understand why I get the following error that comes about when I try to evaluate the contents of a cell, some function is either not returning or I don't understand how this stuff works.
2012-11-08 04:30:45-0800 [HTTPPageGetter,client] handling data: None
2012-11-08 04:30:45-0800 [HTTPPageGetter,client] Unhandled Error
Traceback (most recent call last):
File "path/to/python/lib/python2.7/site-packages/twisted/internet/defer.py", line 1101, in gotResult
_inlineCallbacks(r, g, deferred)
File "path/to/python/lib/python2.7/site-packages/twisted/internet/defer.py", line 1048, in _inlineCallbacks
deferred.callback(None)
File "path/ib/python2.7/site-packages/twisted/internet/defer.py", line 368, in callback
self._startRunCallbacks(result)
File "path/lib/python2.7/site-packages/twisted/internet/defer.py", line 464, in _startRunCallbacks
self._runCallbacks()
--- <exception caught here> ---
File "path/lib/python2.7/site-packages/twisted/internet/defer.py", line 551, in _runCallbacks
current.result = callback(current.result, *args, **kw)
File "/path/to/lib/python2.7/site-packages/codenode/frontend/async/backend.py", line 223, in _success
if 'cellstyle' in data and data['cellstyle'] == 'outputimage':
exceptions.TypeError: argument of type 'NoneType' is not iterable
2012-11-08 04:30:45-0800 [HTTPPageGetter,client] Stopping factory
here is the relevant part of the code (I think): there is a suspicious part in the addcallback(three params none of which are data) but in the _success (three apart from self one of which is data), if this is the issue whee do I pass the data?.
def render(self, request):
"""
This is where we un-serialize the content sent between the frontend
and backend engine bus.
"""
content = request.content.read()
if content:
msg = json.loads(content)
log.msg('Engine message deserialized %s' % str(msg))
else:
return
cellid = msg.get('cellid', '')
d = self.engine_bus.handleRequest(self.notebook_id, msg)
d.addCallback(self._success, request, cellid)
d.addErrback(self._fail, request)
return server.NOT_DONE_YET
def _success(self, data, request, cellid):
"""
horrible. not always eval...
"""
log.msg('handling data: %s' % str(data))
if 'cellstyle' in data and data['cellstyle'] == 'outputimage':
image_data = pickle.loads(data['out']).getvalue()
image_file_name = write_image(image_data)
data['out'] = image_file_name
data['cellid'] = cellid
jsobj = json.dumps(data)
request.write(jsobj)
request.finish()
Admittedly this is not by own work, and i have little understanding of it, and its pretty dated. here is more of the code: github python file
[EDIT] here is a little more : the initialization:
class EngineSessionAdapter(resource.Resource):
"""
There should be a better way to do this, have to figure that out.
"""
isLeaf = True
def __init__(self, engine_bus, notebook_id):
resource.Resource.__init__(self)
self.engine_bus = engine_bus
self.notebook_id = notebook_id
self.putChild("", self)
and this is the engine object:
class EngineBusAdapter(resource.Resource):
def __init__(self, engine_bus):
resource.Resource.__init__(self)
self.engine_bus = engine_bus
self.putChild("", self)
def getChild(self, path, request):
"""XXX Can this refer back to itself?
"""
return EngineSessionAdapter(self.engine_bus, path)
[2nd Edit] here is the Enginebus definition:
class EngineBus(object):
"""
Common entry point for all engine requests.
Look up engine client by access_id.
This is responsible for routing the engine message
from the browser/frontend to the engine by access_id.
This does not need to process the message (un-serialize, inspect,
or otherwise).
"""
def __init__(self, backend):
self.backend = backend
@defer.inlineCallbacks
def handleRequest(self, access_id, msg):
"""
msg comes in as dictionary
"""
log.msg('handling engine request for %s' % access_id)
try:
engine_client = yield self.backend.getEngine(access_id)
log.msg('got engine Client %s' % str(engine_client))
except InvalidAccessId:
err = {'status':'ERR', 'response':'InvalidAccessId'}
log.err('InvalidAccessId %s' % access_id)
defer.returnValue(err)
result = yield engine_client.send(msg)
sucs = {'status':'OK', 'response':result}
defer.returnValue(sucs)
EDIT: Finally solved it: here is the diff:
- result = yield meth(engine_arg, cellid)
+ result = yield defer.maybeDeferred(meth,engine_arg, cellid)
defer.returnValue(result)
- @defer.inlineCallbacks
def engine_start(self, args, arg):
"""dummy
"""
- defer.returnValue({'result':'started'})
+ return {'result':'started'}
here it is in context: the commit diff on github for backend/engine.py
if 'cellstyle' in data and data['cellstyle'] == 'outputimage': exceptions.TypeError: argument of type 'NoneType' is not iterable
'cellstyle' in data
requires data
to be iterable - it is not iterable, but None