Usando inlineCallbacks

Soy nuevo en Twisted y estoy tratando de escribir un recurso simple que muestre una lista de nombres de una base de datos, aquí hay una parte de mi código:

#code from my ContactResource class def render_GET(self, request): def print_contacts(contacts, request): for c in contacts: request.write(c.name) if not request.finished: request.finish() d = Contact.find() #Contact is a Twistar DBObject subclass d.addCallback(print_contacts, request) return NOT_DONE_YET 

Mi pregunta es: ¿cómo puedo cambiar este método para usar el decorador inlineCallbacks?

Un método render_GET no puede devolver un Deferred . Solo puede devolver una cadena o NOT_DONE_YET . Cualquier método decorado con inlineCallbacks devolverá un inlineCallbacks . Por lo tanto, no puede decorar render_GET con inlineCallbacks .

Por supuesto, nada le impide llamar a cualquier otra función que desee en render_GET , incluida una que devuelve un Deferred . Simplemente deseche el render_GET lugar de devolverlo desde render_GET (por supuesto, asegúrese de que el Deferred nunca se dispare con una falla, o si lo tira, es posible que falte algún informe de error …).

Así por ejemplo:

 @inlineCallbacks def _renderContacts(self, request): contacts = yield Contact.find() for c in contacts: request.write(c.name) if not request.finished: request.finish() def render_GET(self, request): self._renderContacts(request) return NOT_DONE_YET 

Recomiendo al menos echar un vistazo a txyoga y klein si vas a estar haciendo un desarrollo web serio con Twisted. Incluso si no quieres usarlos, deberían darte algunas buenas ideas sobre cómo puedes estructurar tu código y realizar varias tareas comunes como esta.

Edición: no encontré un ejemplo de cómo combinar twisted.web con inlineCallbacks, pero aquí hay dos sugerencias. Lo primero es preferible, pero no estoy seguro de si funciona.

 @inlineCallbacks def render_GET(self, request): contacts = yield Contact.find() defer.returnValue(''.join(c.name for c in contacts) @inlineCallbacks def render_GET(self, request): contacts = yield Contact.find() for c in contacts: request.write(c.name) if not request.finished: request.finish() defer.returnValue(NOT_DONE_YET)