Friday, 2 March 2018

qgis - Download file from network using PyQGIS 2.x


I have a python plugin targeting QGIS 1.8 that uses QgsNetworkAccessManager and QNetworkRequest to issue a GetCapabilities request to WMS servers.


With 1.8 everything was working fine. Now we are porting this plugin to QGIS 2.x (tested on 2.6 and 2.7 of 16/02/2015) and have found that some errors are being displayed.


As far as our python code can tell everything is working as expected, however 20 seconds after a network request is initiated a "Network request ... timed out" message is displayed in the messages log and in a banner at the top of the map pane.




I have created a minimal example that can be copy/pasted into the python console:


from datetime import datetime

from PyQt4.QtCore import SIGNAL, QUrl
from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest

def request_download():
global reply
manager = QgsNetworkAccessManager.instance()
url = QUrl("http://www.example.net")
request = QNetworkRequest(url)
print "Download start time: {}".format(datetime.now())
reply = manager.createRequest(QNetworkAccessManager.GetOperation, request)

reply.connect(reply, SIGNAL("finished()"), handle_download)

def handle_download():
global reply
print "Download finish time: {}".format(datetime.now())
print "Finished: {}".format(reply.isFinished())
print "Bytes received: {}".format(len(reply.readAll()))

request_download()


# python console:
# Download start time: 2015-02-23 15:24:39.887000
# Download finish time: 2015-02-23 15:24:41.077000
# Finished: True
# Bytes received: 1270
#
# message log:
# 2015-02-23T15:25:01 1 Network request http://www.example.com timed out




As this example shows the download appears to succeed:



  1. The finish() signal is emitted.

  2. The reply.isFinished() method returns True.

  3. The reply.readAll() method returns the correct data.


However the time out error message is displayed :



  1. Prominently on a yellow banner at the top of the map pane.

  2. Under the Network tab on the Log Messages panel.



How do I perform a download without triggering this error?



Answer



If you are fine with a solution that uses QNetworkAccessManager from Qt (instead of the manager from QGIS libs), you can do it this way:


from datetime import datetime
from PyQt4.QtCore import QUrl
from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest

def request_download(manager):
url = QUrl("http://www.geotux.tuxfamily.org")

request = QNetworkRequest(url)
print "Download start time: {}".format(datetime.now())
manager.get( request )

def handle_download(reply):
print "Download finish time: {}".format(datetime.now())
print "Finished: {}".format(reply.isFinished())
print "Bytes received: {}".format(len(reply.readAll()))

manager = QNetworkAccessManager()

manager.finished.connect( handle_download )
request_download(manager)

As you can see, you don't need to use global variables.




BTW, I couldn't use your code from a QGIS Python console, it threw this error: RuntimeError: no access to protected functions or signals for objects not created from Python


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...