2

I followed this tutorial but I don't know how to get response data from server.

class Service(Resource):
    def render_POST(self, request):
        return 'response message'

I know that the response data will be displayed in the client

 def dataReceived(self, bytes):
        if self.remaining:
            display = bytes[:self.remaining]
            print 'Some data received:'
            print display
            self.remaining -= len(display)

How can I get the returned message from server and store it into a variable?

TomNg
  • 1,897
  • 2
  • 18
  • 25

1 Answers1

2

Just make dataReceived store display in an instance variable, and append to it every time dataReceived is called. Then, once connectionLost is called, you know you have the complete response.

class BeginningPrinter(Protocol):
    def __init__(self, finished):
        self.finished = finished
        self.remaining = 1024 * 10
        self.total_response = ""  # This will store the response.

    def dataReceived(self, bytes):
        if self.remaining:
            display = bytes[:self.remaining]
            self.total_response += display  # Append to our response.
            self.remaining -= len(display)

    def connectionLost(self, reason):
        print 'Finished receiving body:', reason.getErrorMessage()
        print 'response is ',self.total_response
        self.finished.callback(self.total_response)

In the context of the full example:

from pprint import pformat

from twisted.internet import reactor
from twisted.internet.defer import Deferred
from twisted.internet.protocol import Protocol
from twisted.web.client import Agent
from twisted.web.http_headers import Headers

class BeginningPrinter(Protocol):
    def __init__(self, finished):
        self.finished = finished
        self.remaining = 1024 * 10
        self.total_response = ""  # This will store the response.

    def dataReceived(self, bytes):
        if self.remaining:
            display = bytes[:self.remaining]
            self.total_response += display  # Append to our response.
            self.remaining -= len(display)

    def connectionLost(self, reason):
        print 'Finished receiving body:', reason.getErrorMessage()
        print 'response is ',self.total_response
        self.finished.callback(self.total_response)  # Executes all registered callbacks

def handle_result(response):
    print("Got response {}".format(response)

agent = Agent(reactor)
d = agent.request(
    'GET',
    'http://example.com/',
    Headers({'User-Agent': ['Twisted Web Client Example']}),
    None)

def cbRequest(response):
    print 'Response version:', response.version
    print 'Response code:', response.code
    print 'Response phrase:', response.phrase
    print 'Response headers:'
    print pformat(list(response.headers.getAllRawHeaders()))
    finished = Deferred()
    finished.addCallback(handle_result)  # handle_result will be called when the response is ready
    response.deliverBody(BeginningPrinter(finished))
    return finished
d.addCallback(cbRequest)

def cbShutdown(ignored):
    reactor.stop()
d.addBoth(cbShutdown)

reactor.run()
dano
  • 91,354
  • 19
  • 222
  • 219
  • Thanks dano, but how if I want to store the data in a variable that is outside of the BeginningPrinter class? I mean, the data you get is still inside that class. – TomNg Aug 16 '14 at 13:59
  • @coderkisser That's what the `finished` `Deferred` can be used for. I've expanded my answer to demonstrate. – dano Aug 16 '14 at 17:27
  • I still can't get the data in a variable because you get it to a function. I need something like: message = handle_result(). Please kindly to help. – TomNg Aug 18 '14 at 02:43
  • @coderkisser Why do you need that? Programs written with twisted are organized differently from regular programs. The "twisted" way to do something with the response would be to register a callback. It doesn't really make sense to do it any other way, since the whole program runs inside the reactor. – dano Aug 18 '14 at 02:59