-1

I am trying to read the response after I have made a call to an API using python Twisted web client. I have made a POST call to the endpoint passing in a json structure, it should then return a status with either a message (if failed) or a json strucure if successful.

Using the code below I am able to see the message is getting called along with the status code, but I am not seeing the message/json structure.

The 'BeginningPrinter' is never getting called and I don't uderstand why.

Example of output:

$ python sample.py 
Response version: (b'HTTP', 1, 0)
Response code: 401 | phrase : b'UNAUTHORIZED'
Response headers:
Response length: 28

Apologies that the code is so long, but I wanted to make sure it contains everything that I used to run it in it.

from io import BytesIO
import json
from twisted.internet import reactor
from twisted.web.client import Agent
from twisted.web.http_headers import Headers
from twisted.internet.defer import Deferred
from twisted.internet.protocol import Protocol
from twisted.web.client import FileBodyProducer

agent = Agent(reactor)

class BeginningPrinter(Protocol):
    def __init__(self, finished):
        self.finished = finished
        self.remaining = 1024 * 10
        print('begin')

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

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

TESTDATA = { "keySequence": "2019-07-14" }
jsonData = json.dumps(TESTDATA)
body = BytesIO(jsonData.encode('utf-8'))
body = FileBodyProducer(body)
headerDict = \
{
    'User-Agent': ['test'],
    'Content-Type': ['application/json'],
    'APIGUID' : ['ForTesting']
}
header = Headers(headerDict)

d = agent.request(b'POST', b' http://127.0.0.1:5000/receiveKeyCode', header, body)

def cbRequest(response):
    print(f'Response version: {response.version}')
    print(f'Response code: {response.code} | phrase : {response.phrase}')
    print('Response headers:')
    print('Response length:', response.length)
    print(pformat(list(response.headers.getAllRawHeaders())))
    print(response.deliverBody)
    finished = Deferred()
    response.deliverBody(BeginningPrinter(finished))
    return finished

d.addCallback(cbRequest)

def cbShutdown(ignored):
    #reactor.stop()
    pass

d.addBoth(cbShutdown)

reactor.run()
davidism
  • 121,510
  • 29
  • 395
  • 339
Swatcat
  • 73
  • 6
  • 21
  • 57
  • It looks like your HTTP response says you aren't authorized, that seems pretty significant to me...also have you verified that BeginningPrinter is actually not getting called, and have you verified the value of the variable 'finished' yet? – pjmaracs Jul 19 '19 at 12:37
  • @pjmaracs In this case I am raising the 401 request as the APIGUID isn't valid - There is a response string: response = KeypadAPIThread.KeypadAPIEndpoint.response_class( response='Authorisation key is missing', status=401, mimetype='text') return response – Swatcat Jul 19 '19 at 12:49
  • Ok got it, I understand that now. After doing a bit of research, the only thing I can think of is that maybe you aren't using Defered properly... maybe consult [this stack overflow question](https://stackoverflow.com/questions/56995661/why-is-it-wrong-to-use-deferred-result-to-get-the-result-of-a-twisted-deferred-o) – pjmaracs Jul 19 '19 at 13:05

1 Answers1

0

You don't need all of that fluff code, if you are already using Flask then you can write to the API and get the values back in a few lines, If you are not then it makes sense to pip install it as it makes life a lot easier.

import json
import requests

headers = {
    'content-type': 'application/json',
    'APIGUID' : 'ForTesting'
}

conv = {"keySequence": "2019-07-14"}
s = json.dumps(conv) 
res = requests.post("http://127.0.0.1:5000/receiveKeyCode",data=s, headers=headers)
print(res.text)

Reference: See this Stackoverflow link

Swatcat
  • 73
  • 6
  • 21
  • 57
  • Thank you that is so much shorter and cleaner. I am using flask. I am not sure why Davidism removed the original tag. – Swatcat Jul 19 '19 at 13:57
  • This doesn't look like an answer to the question to me. The question seems to be about how to write a Twisted Web-based client to make a request to an HTTP server. It doesn't matter if the server is flask or not. And a requests-based HTTP client is not a Twisted Web-based client. – Jean-Paul Calderone Jul 19 '19 at 14:41
  • @Jean-PaulCalderone I am actually using flask to receive the messages so Lucy Thomas's response felt valid enough as I can use just flask and no longer require the second library (Twisted). – Swatcat Jul 20 '19 at 16:44