6

I'm writing a script that I would like to work outside of QGIS GUI. The script uses the processing algorithm standalone just fine for the native algorithms, however I am experiencing errors when trying to run grass algorithms. The code I am currently using to initialise the environment come from the following post: Using QGIS3 Processing algorithms from standalone PyQGIS scripts (outside of GUI)

import sys
from qgis.core import QgsProcessingRegistry
from qgis.analysis import QgsNativeAlgorithms
from qgis.core import (
     QgsApplication
)

QgsApplication.setPrefixPath('/usr', True)
qgs = QgsApplication([], False)
qgs.initQgis()

# Append the path where processing plugin can be found
sys.path.append('C:/OSGeo4W64/apps/qgis/python/plugins')

from processing.core.Processing import Processing
Processing.initialize()
QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())
import processing

This code works to initialise the environment and allows me to run QGIS native processing operations in standalone scripts. The issue arises when i try to run the following code:

# Grass Process
parameters = {
    '-f': False,
    'GRASS_RASTER_FORMAT_META': '',
    'GRASS_RASTER_FORMAT_OPT': '',
    'GRASS_REGION_CELLSIZE_PARAMETER': 0,
    'GRASS_REGION_PARAMETER': None,
    'areas': 'C:/TEMP/areas.tif',
    'direction': 'C:/TEMP/direction.tif',
    'format': 0,
    'input': 'C:/TEMP/DEM.tif',
    'output': 'C:/TEMP/DEM_Filled.tif'
}
processing.run('grass7:r.fill.dir',parameters)

The process runs successfully from within QGIS running from the python console, however when I run the script externally I get the following error from processing:

File "C:/OSGeo4W64/apps/qgis/python/plugins\processing\tools\general.py", line 96, in run
    return Processing.runAlgorithm(algOrName, parameters, onFinish, feedback, context)
File "C:/OSGeo4W64/apps/qgis/python/plugins\processing\core\Processing.py", line 181, in runAlgorithm
    raise QgsProcessingException(msg)
_core.QgsProcessingException: There were errors executing the algorithm.

I am running the scripts in the python environment initialised by: C:\OSGeo4W64\bin\python-qgis.bat

Dan Knott
  • 151
  • 6
  • Have you added exception and printed it to see the error – lat long Sep 26 '18 at 11:27
  • The processing class already has an exception handler. The last line in the second code block is the exception message: – Dan Knott Sep 27 '18 at 23:16
  • after initializing Processing framework , also import processing and use that to run algo.. from processing.core.Processing import Processing Processing.initialize() import processing – lat long Sep 28 '18 at 07:11
  • I had missed the line import processing in the above code, now edited. This has not fixed the issue with running the grass7 algorithm. – Dan Knott Oct 02 '18 at 07:03
  • Standalone solution for PyCharm: https://gis.stackexchange.com/a/366866/35561 – Comrade Che Jul 05 '20 at 11:32

1 Answers1

9

I've done some more digging in the QGIS code and have found a solution. In the definition for processing.run() I found the method to get the QgsProcessingAlgorithm object from the string name. This class has a method canExecute(). This method returns true for me with no error message and subsequently running the processing algorithm works:

alg = QgsApplication.processingRegistry().createAlgorithmById('grass7:r.fill.dir')
canExecute, errorMessage = alg.canExecute()
print(str(canExecute) + str(errorMessage))
processing.run('grass7:r.fill.dir', parameters)

I traced the canExecute() method through the QGIS code and found the same method within the processing definition for Grass7Algorithm.py. Here I discovered the solution could be simplified to the following two lines:

from processing.algs.grass7.Grass7Utils import Grass7Utils
Grass7Utils.checkGrassIsInstalled()

I hope someone else finds this useful.

Dan Knott
  • 151
  • 6