You can run a QGIS Processing algorithm in standalone (no GUI) mode in this way:
import sys
from qgis.core import (
QgsApplication,
QgsProcessingFeedback,
QgsVectorLayer
)
# See https://gis.stackexchange.com/a/155852/4972 for details about the prefix
QgsApplication.setPrefixPath('/usr', True)
qgs = QgsApplication([], False)
qgs.initQgis()
# Append the path where processing plugin can be found
sys.path.append('/docs/dev/qgis/build/output/python/plugins')
import processing
from processing.core.Processing import Processing
Processing.initialize()
layer1 = QgsVectorLayer('/path/to/geodata/lines_1.shp', 'layer 1', 'ogr')
layer2 = QgsVectorLayer('/path/to/geodata/lines_2.shp', 'layer 2', 'ogr')
# You can see what parameters are needed by the algorithm
# using: processing.algorithmHelp("qgis:union")
params = {
'INPUT' : layer1,
'OVERLAY' : layer2,
'OUTPUT' : '/path/to/output_layer.gpkg|layername=output'
}
feedback = QgsProcessingFeedback()
# See https://gis.stackexchange.com/a/276979/4972 for a list of algorithms
res = processing.run('qgis:union', params, feedback=feedback)
res['OUTPUT'] # Access your output layer
Note for QGIS versions LESS THAN 3.16.5
If you want to use a native algorithm (i.e., an algorithm from the native provider, whose algorithms are written in C++), you need to add the provider after initializing Processing:
import sys
from qgis.core import (
QgsApplication,
QgsProcessingFeedback,
QgsVectorLayer
)
from qgis.analysis import QgsNativeAlgorithms
# See https://gis.stackexchange.com/a/155852/4972 for details about the prefix
QgsApplication.setPrefixPath('/usr', True)
qgs = QgsApplication([], False)
qgs.initQgis()
# Append the path where processing plugin can be found
sys.path.append('/docs/dev/qgis/build/output/python/plugins')
import processing
from processing.core.Processing import Processing
Processing.initialize()
QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())
layer = QgsVectorLayer('/path/to/geodata/lines.shp', 'my layer', 'ogr')
# You can see what parameters are needed by the algorithm
# using: processing.algorithmHelp("native:extractvertices")
params = {
'INPUT': layer,
'OUTPUT': 'memory:'
}
feedback = QgsProcessingFeedback()
# See https://gis.stackexchange.com/a/276979/4972 for a list of algorithms
res = processing.run("native:extractvertices", params, feedback=feedback)
res['OUTPUT'] # Access your output layer
Note: If you actually wrote your own Processing algorithm and would like to run it in a standalone PyQGIS script, see: Using custom Processing algorithm from standalone PyQGIS scripts (outside of GUI)
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.
Best Answer
Based on Using QGIS3 Processing algorithms from standalone PyQGIS scripts (outside of GUI), you need at least 2 new files:
example_algorithm_provider.py
, see sample provider), which helps you register your algorithm, andexample_processing_algorithm.py
, see sample algorithm), where you define the algorithm logic.The PyQGIS standalone script would be like this:
Notes:
QgsApplication.processingRegistry().addProvider(provider)
.example_algorithm_provider.py
and theexample_processing_algorithm.py
) at this GitHub repo: https://github.com/gacarrillor/pyqgis_scripts/tree/master/pyqgis_custom_processing_algorithm_standalone