PyQGIS 2.x – How to Download File from Network

pyqgispyqtpythonqgis

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?

Best 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

Related Question