TransWikia.com

Why does QGIS fail to include authentication manager overlays when using standalone exportToPDF?

Geographic Information Systems Asked by Paul Wittle on April 7, 2021

I have an existing layout and I’m trying to export it to PDF from a standalone script after the data is updated automatically. If I open QGIS and export all is good but when I call it from Python I get the basemap and point overlay only. My polygon layer is missing.

I had to unlock/lock the layers then save the layout to get the points to display in the exported PDF but no joy for the polygons.

Both the point and polygon layer come from an Oracle database layer but only the polygon layer uses the authentication manager for the credentials (i.e. authcfg).

Code example:

#!/usr/bin/env python3
import os, time
from qgis.PyQt.QtCore import QSettings
from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery
from qgis.core import (QgsProject, QgsLayoutExporter, QgsApplication, QgsAuthManager, QgsFeedback)

QgsApplication.setPrefixPath("/usr", True)

gui_flag = False
app = QgsApplication([], gui_flag)

app.initQgis()

project_path = os.getcwd() + '/project.qgs'

project_instance = QgsProject.instance()
project_instance.setFileName(project_path)
project_instance.read()

authMgr = QgsApplication.authManager()
if authMgr.authenticationDatabasePath():
    print('INFO: Auth already initilised => we are inside a QGIS app.')
    msg = 'Inside QGIS'
else:
    print('WARNING: outside qgis, e.g. in a testing environment => setup env var before')
    # db init
    os.environ['QGIS_AUTH_DB_DIR_PATH'] = "profile/qgis-auth.db"
    msg = 'Master password could not be set'
    assert authMgr.setMasterPassword("password", True), msg
    authMgr.init( "profile/qgis-auth.db" )

if not QSqlDatabase.isDriverAvailable('QOCISPATIAL'):
    print("WARNING: Oracle not available")
else:
    db = QSqlDatabase.addDatabase("QOCISPATIAL")
    db.setDatabaseName("oracleDatabase:1521/dbName")
    db.setUserName("username")
    db.setPassword("password")
    
    if db.isValid():
        if not db.open():
            print("WARNING: Oracle not available")
        else:
            print("INFO: Oracle database available")
            
manager = QgsProject.instance().layoutManager()
timestr = time.strftime("%Y%m%d-%H%M%S")

feedback = QgsFeedback()

layout = manager.layoutByName("layoutName") # name of the layout
# or layout = manager.layouts()[0] # first layout

exportSettings = QgsLayoutExporter.PdfExportSettings()
exportSettings.flags = layout.renderContext().flags()
exportSettings.dpi = 150
exportSettings.forceVectorOutput = True
exportSettings.writeGeoPdf = True
exportSettings.includeGeoPdfFeatures = False

exporter = QgsLayoutExporter(layout)
exporter.exportToPdf(project_instance.absolutePath() + "/layoutName-" + timestr + ".pdf",
                     exportSettings)

app.exitQgis()

You can see that I have already put in a number of, largely unnecessary, checks to ensure that it is connecting to the Oracle database and those seem to be working. In addition it now draws the point layer which is also coming from the Oracle database.

My working hypothesis is that the authentication credentials are failing but I don’t get an error so it is difficult to debug that. Since changing from QgsLayoutExporter.PdfExportSettings() to defining them manually I now get errors about the Dimensions of the inserted PDF page differing from the output PDF page but I’m not sure they are linked as the PDF is still created successfully; just without the polygon layer.

Update

I have now tried the script again using the username and password typed into the project and I can confirm the layer is always missing if I use an authcfg and works fine if the username and password are in the project file.

My question is therefore changed to; how can you use the authentication manager for a layer and still be able to export to PDF using a standalone python script?

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP