I have a purest suite for my flask app that works great. However, I want to test some of my code that uses a third-party library (Qt) to send http requests. How is this possible? I see flask-testing
has the live_server
fixture which accomplishes this along with flask.url_for()
, but it takes too much time to start up the server in the fixture.
Is there a faster way to send an http request from a third-party http lib to a flask app?
Thanks!
Turns out you can do this by manually converting the third-party request to the FlaskClient
request, using a monkeypatch
for whatever "send" method the third-party lib uses, then convert the flask.Response
response back to a third-party reply object. All this occurs without using a TCP port.
Here is the fixture I wrote to bridge Qt http requests to the flask app:
@pytest.fixture
def qnam(qApp, client, monkeypatch):
def sendCustomRequest(request, verb, data):
# Qt -> Flask
headers = []
for name in request.rawHeaderList():
key = bytes(name).decode('utf-8')
value = bytes(request.rawHeader(name)).decode('utf-8')
headers.append((key, value))
query_string = None
if request.url().hasQuery():
query_string = request.url().query()
# method = request.attribute(QNetworkRequest.CustomVerbAttribute).decode('utf-8')
# send
response = FlaskClient.open(client,
request.url().path(),
method=verb.decode('utf-8'),
headers=headers,
data=data)
# Flask -> Qt
class NetworkReply(QNetworkReply):
def abort(self):
pass
reply = NetworkReply()
reply.setAttribute(QNetworkRequest.HttpStatusCodeAttribute, response.status_code)
for key, value in response.headers:
reply.setRawHeader(key.encode('utf-8'), value.encode('utf-8'))
reply.open(QIODevice.ReadWrite)
reply.write(response.data)
QTimer.singleShot(10, reply.finished.emit) # after return
return reply
qnam = QNetworkAccessManager.instance() # or wherever you get your instance
monkeypatch.setattr(qnam, 'sendCustomRequest', sendCustomRequest)
return ret