PyQGIS – How to Get Source Path of Layer File in PyQGIS

pyqgispythonqgis-plugins

I need the exact source path of layer files as shown by QGIS Layer Properties Information Window:

enter image description here

I know how to retrieve the layer source URI (and using the data provider gives the same result):

    layer = qgis.utils.iface.activeLayer()
    uri = layer.source()
    # uri = layer.dataProvider().dataSourceUri()

Now retrieving the exact layer source path from the URI is not a trivial thing, as it contains information depending on the data provider type.

layer.providerType() == 'delimitedtext' can look something like that:

"file:///home/ubuntu/QGIS/Ciutat%20pr%C3%B2xima%201.0/EDUCACI%C3%93/opendatabcn_llista-equipaments_educacio-csv.csv?encoding=UTF-16&type=csv&maxFields=10000&detectTypes=yes&xField=geo_epgs_25831_x&yField=geo_epgs_25831_y&crs=EPSG:25831&spatialIndex=no&subsetIndex=no&watchFile=no&subset=%20%22secondary_filters_name%22%20%3D%20'Universitat'%20or%20%22secondary_filters_name%22%20%3D%20'Educaci%C3%B3%20secund%C3%A0ria'%20or%20%22secondary_filters_name%22%20%3D%20'Educaci%C3%B3%20prim%C3%A0ria'%20or%20%20%22secondary_filters_name%22%20%3D%20%20%20'Ensenyament%20infantil%20(3-6%20anys)'%20%20%20or%20%20%22secondary_filters_name%22%20%3D%20%20'Ensenyament%20infantil%20(0-3%20anys)'%20or%20%22secondary_filters_name%22%20%3D%20%20%20'Escoles%20Bressol%20municipals'%20"

layer.providerType() == 'ogr' could look like that:

'/vsizip//home/ubuntu/QGIS/Ciutat pròxima 1.0/DEMOGRAFIA/BCN_UNITATS_ADM.zip/0301100100_UNITATS_ADM_POLIGONS.json|layername=0301100100_UNITATS_ADM_POLIGONS|geometrytype=Polygon|subset="CONJ_DESCR"=\'Districtes\''

So it's actually possible to get the layer source path as shown in QGIS, but is there a easy way to do that?

PS: I know this question in a quite similar way has been asked before, but always in a different context or with ambiguous descriptions, like this one (which asked 2 questions at the same time) and this one (which asks about running it as a daemon).

Best Answer

There is a method called decodeURI which can be used to break down the data source URI into the core path and all other components.

The documentation states that this function may not be supported by all provider types, but for delimited text layers and ogr it definitely works as shown below:

>>> layer = iface.activeLayer()
>>> uri_components = QgsProviderRegistry.instance().decodeUri(layer.dataProvider().name(), layer.publicSource());
>>> layer.source()
'file:///D:/Downloads/agency.txt?type=csv&maxFields=10000&detectTypes=yes&geomType=none&subsetIndex=no&watchFile=no'

>>> uri_components['path']
'D:/Downloads/agency.txt'