I struggle with accessing a WFS (Cyclomedia Atlas Recordings) with the following code from a PyQGIS plugin:
import urllib.parse
from qgis.core import QgsVectorLayer, QgsDataSourceUri
wfs_params = {'service': 'WFS',
'version': '1.1.0',
'request': 'GetFeature',
'typename': 'atlas:Recording',
'srsname': 'EPSG:25832'}
uri = QgsDataSourceUri()
uri.setEncodedUri('https://atlas.cyclomedia.com/recordings/wfs?' + urllib.parse.unquote(urllib.parse.urlencode(wfs_params)))
uri.setUsername('me')
uri.setPassword('my_password')
cyclom_photos_lyr = QgsVectorLayer(uri.uri(), 'Cyclorama Locations', 'WFS')
The relevant parts of the WFS' capabilities response look like this (it's password protected):
<ows:Operation name="GetFeature">
<ows:DCP>
<ows:HTTP>
<ows:Get xlink:href="https://atlas.cyclomedia.com/recordings/wfs"/>
<ows:Post xlink:href="https://atlas.cyclomedia.com/recording/wfs"/>
</ows:HTTP></ows:DCP><ows:Parameter name="resultType">
...
<wfs:FeatureTypeList>
<wfs:Operations>
<wfs:Operation>
Query
</wfs:Operation>
</wfs:Operations><!--
<wfs:FeatureType>
<wfs:Name>atlas:Recording</wfs:Name>
<wfs:Title>Recording</wfs:Title>
<wfs:DefaultSRS>EPSG:4326</wfs:DefaultSRS><!--NAD83-->
...
<wfs:OtherSRS>EPSG:25832</wfs:OtherSRS><!--ETRS89-->
...
I am not using the uri directly as described in the documentation (https://docs.qgis.org/3.4/en/docs/pyqgis_developer_cookbook/loadlayer.html) because I'm not aware of passing credentials to the service directly via uri, therefore the QgsDataSourceUri().setUsername()...
construct.
The above code gives me the following error:
2019-10-08T12:08:54 WARNING GetCapabilities failed for url user='me' password='my_password' https://atlas.cyclomedia.com/recordings/wfs?service='WFS' request='GetFeature' srsname='EPSG:25832' typename='atlas:Recordings' version='1.1.0' table="" sql=: unexpected end of file
2019-10-08T12:08:54 WARNING Download of capabilities failed: Protocol "" is unknown
What am I doing wrong or what am I probably missing?
The WFS is accessible via Data Source Manager without any problem (dots in the screenshot below), but I need to add it programmatically for convenience reasons.