diff --git a/owslib/feature/common.py b/owslib/feature/common.py index d9165c378..c4e692d72 100644 --- a/owslib/feature/common.py +++ b/owslib/feature/common.py @@ -21,8 +21,9 @@ class WFSCapabilitiesReader(object): """Read and parse capabilities document into a lxml.etree infoset """ - def __init__(self, version="1.0", username=None, password=None, auth=None): + def __init__(self, version="1.0", username=None, password=None, headers=None, auth=None): """Initialize""" + self.headers = headers if auth: if username: auth.username = username @@ -63,7 +64,7 @@ def read(self, url, timeout=30): A timeout value (in seconds) for the request. """ request = self.capabilities_url(url) - u = openURL(request, timeout=timeout, auth=self.auth) + u = openURL(request, timeout=timeout, headers=self.headers, auth=self.auth) return etree.fromstring(u.read()) def readString(self, st): @@ -80,8 +81,9 @@ def readString(self, st): class AbstractContentMetadata(object): - def __init__(self, auth=None): + def __init__(self, headers=None, auth=None): self.auth = auth or Authentication() + self.headers = headers def get_metadata(self): return [ diff --git a/owslib/feature/schema.py b/owslib/feature/schema.py index dd6791f49..cfd841485 100644 --- a/owslib/feature/schema.py +++ b/owslib/feature/schema.py @@ -26,7 +26,7 @@ def get_schema( - url, typename, version="1.0.0", timeout=30, username=None, password=None, auth=None + url, typename, version="1.0.0", timeout=30, headers=None, username=None, password=None, auth=None ): """Parses DescribeFeatureType response and creates schema compatible with :class:`fiona` @@ -47,7 +47,7 @@ def get_schema( else: auth = Authentication(username, password) url = _get_describefeaturetype_url(url, version, typename) - res = openURL(url, timeout=timeout, auth=auth) + res = openURL(url, timeout=timeout, headers=headers, auth=auth) root = etree.fromstring(res.read()) if ":" in typename: diff --git a/owslib/feature/wfs100.py b/owslib/feature/wfs100.py index 4ac72ddf3..80d6de24d 100644 --- a/owslib/feature/wfs100.py +++ b/owslib/feature/wfs100.py @@ -71,6 +71,7 @@ def __new__( xml, parse_remote_metadata=False, timeout=30, + headers=None, username=None, password=None, auth=None, @@ -83,6 +84,7 @@ def __new__( @param xml: elementtree object @type parse_remote_metadata: boolean @param parse_remote_metadata: whether to fully process MetadataURL elements + @param headers: HTTP headers to send with requests @param timeout: time (in seconds) after which requests should timeout @param username: service authentication username @param password: service authentication password @@ -96,6 +98,7 @@ def __new__( xml, parse_remote_metadata, timeout, + headers=headers, username=username, password=password, auth=auth, @@ -116,6 +119,7 @@ def __init__( xml=None, parse_remote_metadata=False, timeout=30, + headers=None, username=None, password=None, auth=None, @@ -129,9 +133,10 @@ def __init__( self.url = url self.version = version self.timeout = timeout + self.headers = headers self.auth = auth or Authentication(username, password) self._capabilities = None - reader = WFSCapabilitiesReader(self.version, auth=self.auth) + reader = WFSCapabilitiesReader(self.version, headers=self.headers, auth=self.auth) if xml: self._capabilities = reader.readString(xml) else: @@ -178,7 +183,8 @@ def getcapabilities(self): NOTE: this is effectively redundant now""" reader = WFSCapabilitiesReader(self.version, auth=self.auth) return openURL( - reader.capabilities_url(self.url), timeout=self.timeout, auth=self.auth + reader.capabilities_url(self.url), timeout=self.timeout, + headers=self.headers, auth=self.auth ) def items(self): @@ -279,7 +285,8 @@ def getfeature( data = urlencode(request) log.debug("Making request: %s?%s" % (base_url, data)) - u = openURL(base_url, data, method, timeout=self.timeout, auth=self.auth) + u = openURL(base_url, data, method, timeout=self.timeout, + headers=self.headers, auth=self.auth) # check for service exceptions, rewrap, and return # We're going to assume that anything with a content-length > 32k @@ -441,7 +448,7 @@ def parse_remote_metadata(self, timeout=30): ): try: content = openURL( - metadataUrl["url"], timeout=timeout, auth=self.auth + metadataUrl["url"], timeout=timeout, headers=self.headers, auth=self.auth ) doc = etree.fromstring(content.read()) if metadataUrl["type"] == "FGDC": diff --git a/owslib/feature/wfs110.py b/owslib/feature/wfs110.py index a60bf6a9f..7e483ff8b 100644 --- a/owslib/feature/wfs110.py +++ b/owslib/feature/wfs110.py @@ -60,6 +60,7 @@ def __new__( xml, parse_remote_metadata=False, timeout=30, + headers=None, username=None, password=None, auth=None, @@ -72,6 +73,7 @@ def __new__( @param xml: elementtree object @type parse_remote_metadata: boolean @param parse_remote_metadata: whether to fully process MetadataURL elements + @param headers: HTTP headers to send with requests @param timeout: time (in seconds) after which requests should timeout @param username: service authentication username @param password: service authentication password @@ -85,6 +87,7 @@ def __new__( xml, parse_remote_metadata, timeout, + headers=headers, username=username, password=password, auth=auth, @@ -105,6 +108,7 @@ def __init__( xml=None, parse_remote_metadata=False, timeout=30, + headers=None, username=None, password=None, auth=None, @@ -120,10 +124,11 @@ def __init__( super(WebFeatureService_1_1_0, self).__init__(auth) self.url = url self.version = version + self.headers = headers self.timeout = timeout self._capabilities = None self.owscommon = OwsCommon("1.0.0") - reader = WFSCapabilitiesReader(self.version, auth=self.auth) + reader = WFSCapabilitiesReader(self.version, headers=self.headers, auth=self.auth) if xml: self._capabilities = reader.readString(xml) else: @@ -182,7 +187,7 @@ def _buildMetadata(self, parse_remote_metadata=False): nspath_eval("wfs:FeatureTypeList/wfs:FeatureType", namespaces) ) for feature in features: - cm = ContentMetadata(feature, parse_remote_metadata, auth=self.auth) + cm = ContentMetadata(feature, parse_remote_metadata, headers=self.headers, auth=self.auth) self.contents[cm.id] = cm # exceptions @@ -196,7 +201,8 @@ def getcapabilities(self): NOTE: this is effectively redundant now""" reader = WFSCapabilitiesReader(self.version, auth=self.auth) return openURL( - reader.capabilities_url(self.url), timeout=self.timeout, auth=self.auth + reader.capabilities_url(self.url), timeout=self.timeout, + headers=self.headers, auth=self.auth ) def items(self): @@ -318,7 +324,8 @@ def getfeature( data = urlencode(request) log.debug("Making request: %s?%s" % (base_url, data)) - u = openURL(base_url, data, method, timeout=self.timeout, auth=self.auth) + u = openURL(base_url, data, method, timeout=self.timeout, + headers=self.headers, auth=self.auth) # check for service exceptions, rewrap, and return # We're going to assume that anything with a content-length > 32k @@ -365,9 +372,9 @@ class ContentMetadata(AbstractContentMetadata): Implements IMetadata. """ - def __init__(self, elem, parse_remote_metadata=False, timeout=30, auth=None): + def __init__(self, elem, parse_remote_metadata=False, timeout=30, headers=None, auth=None): """.""" - super(ContentMetadata, self).__init__(auth) + super(ContentMetadata, self).__init__(headers=headers, auth=auth) self.id = testXMLValue(elem.find(nspath_eval("wfs:Name", namespaces))) self.title = testXMLValue(elem.find(nspath_eval("wfs:Title", namespaces))) self.abstract = testXMLValue(elem.find(nspath_eval("wfs:Abstract", namespaces))) @@ -442,7 +449,7 @@ def parse_remote_metadata(self, timeout=30): metadataUrl["url"] is not None and metadataUrl["format"].lower() == "text/xml" ): try: - content = openURL(metadataUrl["url"], timeout=timeout) + content = openURL(metadataUrl["url"], timeout=timeout, headers=self.headers, auth=self.auth) doc = etree.fromstring(content.read()) if metadataUrl["type"] == "FGDC": diff --git a/owslib/feature/wfs200.py b/owslib/feature/wfs200.py index 23dd5755f..ddc03e247 100644 --- a/owslib/feature/wfs200.py +++ b/owslib/feature/wfs200.py @@ -53,6 +53,7 @@ def __new__( xml, parse_remote_metadata=False, timeout=30, + headers=None, username=None, password=None, auth=None, @@ -65,6 +66,7 @@ def __new__( @param xml: elementtree object @type parse_remote_metadata: boolean @param parse_remote_metadata: whether to fully process MetadataURL elements + @param headers: HTTP headers to send with requests @param timeout: time (in seconds) after which requests should timeout @param username: service authentication username @param password: service authentication password @@ -78,6 +80,7 @@ def __new__( xml, parse_remote_metadata, timeout, + headers=headers, username=username, password=password, auth=auth, @@ -98,6 +101,7 @@ def __init__( xml=None, parse_remote_metadata=False, timeout=30, + headers=None, username=None, password=None, auth=None, @@ -116,8 +120,9 @@ def __init__( self.url = url self.version = version self.timeout = timeout + self.headers = headers self._capabilities = None - reader = WFSCapabilitiesReader(self.version, auth=self.auth) + reader = WFSCapabilitiesReader(self.version, headers=self.headers, auth=self.auth) if xml: self._capabilities = reader.readString(xml) else: @@ -201,7 +206,8 @@ def getcapabilities(self): NOTE: this is effectively redundant now""" reader = WFSCapabilitiesReader(self.version, auth=self.auth) return openURL( - reader.capabilities_url(self.url), timeout=self.timeout, auth=self.auth + reader.capabilities_url(self.url), timeout=self.timeout, + headers=self.headers, auth=self.auth ) def items(self): @@ -288,7 +294,7 @@ def getfeature( (url, data) = self.getPOSTGetFeatureRequest() # If method is 'Post', data will be None here - u = openURL(url, data, method, timeout=self.timeout, auth=self.auth) + u = openURL(url, data, method, timeout=self.timeout, headers=self.headers, auth=self.auth) # check for service exceptions, rewrap, and return # We're going to assume that anything with a content-length > 32k @@ -358,7 +364,7 @@ def getpropertyvalue( for kw in list(kwargs.keys()): request[kw] = str(kwargs[kw]) encoded_request = urlencode(request) - u = openURL(base_url + encoded_request, timeout=self.timeout, auth=self.auth) + u = openURL(base_url + encoded_request, timeout=self.timeout, headers=self.headers, auth=self.auth) return u.read() def _getStoredQueries(self): @@ -388,7 +394,7 @@ def _getStoredQueries(self): } encoded_request = urlencode(request) u = openURL( - base_url, data=encoded_request, timeout=self.timeout, auth=self.auth + base_url, data=encoded_request, timeout=self.timeout, headers=self.headers, auth=self.auth ) tree = etree.fromstring(u.read()) tempdict = {} @@ -420,7 +426,7 @@ def _getStoredQueries(self): } encoded_request = urlencode(request) u = openURL( - base_url, data=encoded_request, timeout=self.timeout, auth=self.auth + base_url, data=encoded_request, timeout=self.timeout, headers=self.headers, auth=self.auth ) tree = etree.fromstring(u.read()) tempdict2 = {} @@ -483,10 +489,10 @@ class ContentMetadata(AbstractContentMetadata): """ def __init__( - self, elem, parent, parse_remote_metadata=False, timeout=30, auth=None + self, elem, parent, parse_remote_metadata=False, timeout=30, headers=None, auth=None ): """.""" - super(ContentMetadata, self).__init__(auth) + super(ContentMetadata, self).__init__(headers=headers, auth=auth) self.id = elem.find(nspath("Name", ns=WFS_NAMESPACE)).text self.title = elem.find(nspath("Title", ns=WFS_NAMESPACE)).text abstract = elem.find(nspath("Abstract", ns=WFS_NAMESPACE)) @@ -561,7 +567,7 @@ def parse_remote_metadata(self, timeout=30): for metadataUrl in self.metadataUrls: if metadataUrl["url"] is not None: try: - content = openURL(metadataUrl["url"], timeout=timeout) + content = openURL(metadataUrl["url"], timeout=timeout, headers=self.headers, auth=self.auth) doc = etree.fromstring(content.read()) mdelem = doc.find(".//metadata") diff --git a/owslib/feature/wfs300.py b/owslib/feature/wfs300.py index 17d9f8a88..d390fad04 100644 --- a/owslib/feature/wfs300.py +++ b/owslib/feature/wfs300.py @@ -12,7 +12,7 @@ from urllib.parse import urljoin from owslib import __version__ -from owslib.util import Authentication, http_get +from owslib.util import http_get LOGGER = logging.getLogger(__name__) @@ -24,9 +24,7 @@ class WebFeatureService_3_0_0(object): """Abstraction for OGC Web Feature Service (WFS) version 3.0""" - def __init__( - self, url, version, json_, timeout=30, username=None, password=None, auth=None - ): + def __init__(self, url, version, json_, timeout=30, headers=None, auth=None): """ initializer; implements Requirement 1 (/req/core/root-op) @@ -34,6 +32,7 @@ def __init__( @param url: url of WFS root document @type json_: string @param json_: json object + @param headers: HTTP headers to send with requests @param timeout: time (in seconds) after which requests should timeout @param username: service authentication username @param password: service authentication password @@ -51,17 +50,15 @@ def __init__( self.version = version self.json_ = json_ self.timeout = timeout - if auth: - if username: - auth.username = username - if password: - auth.password = password - self.auth = auth or Authentication(username, password) + self.headers = REQUEST_HEADERS + if headers: + self.headers = self.headers.update(headers) + self.auth = auth if json_ is not None: # static JSON string self.links = json.loads(json_)["links"] else: - response = http_get(url, headers=REQUEST_HEADERS, auth=self.auth).json() + response = http_get(url, headers=self.headers, auth=self.auth).json() self.links = response["links"] def api(self): @@ -73,7 +70,7 @@ def api(self): url = self._build_url("api") LOGGER.debug("Request: {}".format(url)) - response = http_get(url, headers=REQUEST_HEADERS, auth=self.auth).json() + response = http_get(url, headers=self.headers, auth=self.auth).json() return response def conformance(self): @@ -85,7 +82,7 @@ def conformance(self): url = self._build_url("conformance") LOGGER.debug("Request: {}".format(url)) - response = http_get(url, headers=REQUEST_HEADERS, auth=self.auth).json() + response = http_get(url, headers=self.headers, auth=self.auth).json() return response def collections(self): @@ -97,7 +94,7 @@ def collections(self): url = self._build_url("collections") LOGGER.debug("Request: {}".format(url)) - response = http_get(url, headers=REQUEST_HEADERS, auth=self.auth).json() + response = http_get(url, headers=self.headers, auth=self.auth).json() return response["collections"] def collection(self, collection_id): @@ -113,7 +110,7 @@ def collection(self, collection_id): path = "collections/{}".format(collection_id) url = self._build_url(path) LOGGER.debug("Request: {}".format(url)) - response = http_get(url, headers=REQUEST_HEADERS, auth=self.auth).json() + response = http_get(url, headers=self.headers, auth=self.auth).json() return response def collection_items(self, collection_id, **kwargs): @@ -141,7 +138,7 @@ def collection_items(self, collection_id, **kwargs): url = self._build_url(path) LOGGER.debug("Request: {}".format(url)) response = http_get( - url, headers=REQUEST_HEADERS, params=kwargs, auth=self.auth + url, headers=self.headers, params=kwargs, auth=self.auth ).json() return response @@ -160,7 +157,7 @@ def collection_item(self, collection_id, identifier): path = "collections/{}/items/{}".format(collection_id, identifier) url = self._build_url(path) LOGGER.debug("Request: {}".format(url)) - response = http_get(url, headers=REQUEST_HEADERS, auth=self.auth).json() + response = http_get(url, headers=self.headers, auth=self.auth).json() return response def _build_url(self, path=None): diff --git a/owslib/tms.py b/owslib/tms.py index f7cb137ea..166c8fff2 100644 --- a/owslib/tms.py +++ b/owslib/tms.py @@ -39,7 +39,7 @@ class TileMapService(object): """ def __init__(self, url, version='1.0.0', xml=None, username=None, password=None, - parse_remote_metadata=False, timeout=30, auth=None): + parse_remote_metadata=False, timeout=30, headers=None, auth=None): """Initialize.""" if auth: if username: @@ -49,6 +49,7 @@ def __init__(self, url, version='1.0.0', xml=None, username=None, password=None, self.url = url self.username = username self.password = password + self.headers = headers self.auth = auth or Authentication(username, password) self.version = version self.timeout = timeout @@ -58,7 +59,7 @@ def __init__(self, url, version='1.0.0', xml=None, username=None, password=None, # Authentication handled by Reader reader = TMSCapabilitiesReader( - self.version, url=self.url, un=self.username, pw=self.password + self.version, url=self.url, un=username, pw=password, headers=self.headers, auth=self.auth ) if xml: # read from stored xml self._capabilities = reader.readString(xml) @@ -88,7 +89,7 @@ def _buildMetadata(self, parse_remote_metadata=False): tilemaps = self._capabilities.find('TileMaps') if tilemaps is not None: for tilemap in tilemaps.findall('TileMap'): - cm = ContentMetadata(tilemap, auth=self.auth) + cm = ContentMetadata(tilemap, headers=self.headers, auth=self.auth) if cm.id: if cm.id in self.contents: raise KeyError('Content metadata for layer "%s" already exists' % cm.id) @@ -124,7 +125,7 @@ def _gettilefromset(self, tilesets, x, y, z, ext, timeout=None): for tileset in tilesets: if tileset['order'] == z: url = tileset['href'] + '/' + str(x) + '/' + str(y) + '.' + ext - u = openURL(url, '', timeout=timeout or self.timeout, auth=self.auth) + u = openURL(url, '', timeout=timeout or self.timeout, headers=self.headers, auth=self.auth) return u else: raise ValueError('cannot find zoomlevel %i for TileMap' % z) @@ -179,7 +180,7 @@ class ContentMetadata(object): def __str__(self): return 'Layer Title: %s, URL: %s' % (self.title, self.id) - def __init__(self, elem, un=None, pw=None, auth=None): + def __init__(self, elem, un=None, pw=None, headers=None, auth=None): if elem.tag != 'TileMap': raise ValueError('%s should be a TileMap' % (elem,)) self.id = elem.attrib['href'] @@ -192,12 +193,13 @@ def __init__(self, elem, un=None, pw=None, auth=None): if pw: auth.password = pw self.auth = auth or Authentication(un, pw) + self.headers = headers self._tile_map = None self.type = elem.attrib.get('type') def _get_tilemap(self): if self._tile_map is None: - self._tile_map = TileMap(self.id, auth=self.auth) + self._tile_map = TileMap(self.id, headers=self.headers, auth=self.auth) assert(self._tile_map.srs == self.srs) return self._tile_map @@ -251,7 +253,7 @@ class TileMap(object): tilesets = None profile = None - def __init__(self, url=None, xml=None, un=None, pw=None, auth=None): + def __init__(self, url=None, xml=None, un=None, pw=None, headers=None, auth=None): self.url = url if auth: if un: @@ -259,6 +261,7 @@ def __init__(self, url=None, xml=None, un=None, pw=None, auth=None): if pw: auth.password = pw self.auth = auth or Authentication(un, pw) + self.headers = headers self.tilesets = [] if xml and not url: self.readString(xml) @@ -301,7 +304,7 @@ def _parse(self, elem): 'order': order}) def read(self, url): - u = openURL(url, '', method='Get', auth=self.auth) + u = openURL(url, '', method='Get', headers=self.headers, auth=self.auth) self._parse(etree.fromstring(u.read())) def readString(self, st): @@ -314,7 +317,7 @@ class TMSCapabilitiesReader(object): """Read and parse capabilities document into a lxml.etree infoset """ - def __init__(self, version='1.0.0', url=None, un=None, pw=None, auth=None): + def __init__(self, version='1.0.0', url=None, un=None, pw=None, headers=None, auth=None): """Initialize""" if auth: if un: @@ -324,13 +327,14 @@ def __init__(self, version='1.0.0', url=None, un=None, pw=None, auth=None): self.version = version self._infoset = None self.url = url + self.headers = headers self.auth = auth or Authentication(un, pw) def read(self, service_url, timeout=30): """Get and parse a TMS capabilities document, returning an elementtree instance """ - u = openURL(service_url, '', method='Get', timeout=timeout, auth=self.auth) + u = openURL(service_url, '', method='Get', timeout=timeout, headers=self.headers, auth=self.auth) return etree.fromstring(u.read()) def readString(self, st): diff --git a/owslib/wfs.py b/owslib/wfs.py index 4ba5ec370..932337e57 100644 --- a/owslib/wfs.py +++ b/owslib/wfs.py @@ -19,7 +19,7 @@ def WebFeatureService(url, version='1.0.0', xml=None, json_=None, parse_remote_metadata=False, timeout=30, username=None, - password=None, auth=None): + password=None, headers=None, auth=None): ''' wfs factory function, returns a version specific WebFeatureService object @type url: string @@ -28,6 +28,7 @@ def WebFeatureService(url, version='1.0.0', xml=None, json_=None, @param xml: elementtree object @type parse_remote_metadata: boolean @param parse_remote_metadata: whether to fully process MetadataURL elements + @param headers: HTTP headers to send with requests @param timeout: time (in seconds) after which requests should timeout @param username: service authentication username @param password: service authentication password @@ -45,13 +46,17 @@ def WebFeatureService(url, version='1.0.0', xml=None, json_=None, if version in ['1.0', '1.0.0']: return wfs100.WebFeatureService_1_0_0( - clean_url, version, xml, parse_remote_metadata, timeout=timeout, auth=auth) + clean_url, version, xml, parse_remote_metadata, + timeout=timeout, headers=headers, auth=auth) elif version in ['1.1', '1.1.0']: return wfs110.WebFeatureService_1_1_0( - clean_url, version, xml, parse_remote_metadata, timeout=timeout, auth=auth) + clean_url, version, xml, parse_remote_metadata, + timeout=timeout, headers=headers, auth=auth) elif version in ['2.0', '2.0.0']: return wfs200.WebFeatureService_2_0_0( - clean_url, version, xml, parse_remote_metadata, timeout=timeout, auth=auth) + clean_url, version, xml, parse_remote_metadata, + timeout=timeout, headers=headers, auth=auth) elif version in ['3.0', '3.0.0']: return wfs300.WebFeatureService_3_0_0( - clean_url, version, json_, timeout=timeout, auth=auth) + clean_url, version, json_, timeout=timeout, + headers=headers, auth=auth) diff --git a/owslib/wms.py b/owslib/wms.py index 1ae016273..16d6c57bc 100644 --- a/owslib/wms.py +++ b/owslib/wms.py @@ -30,6 +30,7 @@ def WebMapService(url, version='1.1.1', xml=None, username=None, password=None, @param xml: elementtree object @type parse_remote_metadata: boolean @param parse_remote_metadata: whether to fully process MetadataURL elements + @param headers: HTTP headers to send with requests @param timeout: time (in seconds) after which requests should timeout @param username: service authentication username @param password: service authentication password @@ -48,7 +49,7 @@ def WebMapService(url, version='1.1.1', xml=None, username=None, password=None, if version in ['1.1.1']: return wms111.WebMapService_1_1_1( clean_url, version=version, xml=xml, parse_remote_metadata=parse_remote_metadata, - timeout=timeout, auth=auth) + timeout=timeout, headers=headers, auth=auth) elif version in ['1.3.0']: return wms130.WebMapService_1_3_0( clean_url, version=version, xml=xml, parse_remote_metadata=parse_remote_metadata, diff --git a/owslib/wmts.py b/owslib/wmts.py index 4e93247aa..6464f3663 100644 --- a/owslib/wmts.py +++ b/owslib/wmts.py @@ -127,7 +127,7 @@ def __getitem__(self, name): raise KeyError("No content named %s" % name) def __init__(self, url, version='1.0.0', xml=None, username=None, password=None, - parse_remote_metadata=False, vendor_kwargs=None, auth=None, + parse_remote_metadata=False, vendor_kwargs=None, headers=None, auth=None, timeout=30): """Initialize. @@ -164,12 +164,13 @@ def __init__(self, url, version='1.0.0', xml=None, username=None, password=None, self.version = version self.vendor_kwargs = vendor_kwargs self._capabilities = None + self.headers = headers self.auth = auth or Authentication(username, password) self.timeout = timeout or 30 # Authentication handled by Reader reader = WMTSCapabilitiesReader( - self.version, url=self.url, auth=self.auth) + self.version, url=self.url, headers=self.headers, auth=self.auth) if xml: # read from stored xml self._capabilities = reader.readString(xml) else: # read from server @@ -190,7 +191,7 @@ def _getcapproperty(self): # TODO: deprecated function. See ticket #453. if not self._capabilities: reader = WMTSCapabilitiesReader( - self.version, url=self.url, auth=self.auth) + self.version, url=self.url, headers=self.headers, auth=self.auth) # xml = reader.read(self.url, self.vendor_kwargs) # self._capabilities = ServiceMetadata(xml) self._capabilities = reader.read(self.url, self.vendor_kwargs) @@ -453,7 +454,7 @@ def gettile(self, base_url=None, layer=None, style=None, format=None, resurl = self.buildTileResource( layer, style, format, tilematrixset, tilematrix, row, column, **vendor_kwargs) - u = openURL(resurl, auth=self.auth, timeout=self.timeout) + u = openURL(resurl, headers=self.headers, auth=self.auth, timeout=self.timeout) return u # KVP implemetation @@ -479,7 +480,7 @@ def gettile(self, base_url=None, layer=None, style=None, format=None, base_url = get_verbs[0].get('url') except StopIteration: pass - u = openURL(base_url, data, auth=self.auth, timeout=self.timeout) + u = openURL(base_url, data, headers=self.headers, auth=self.auth, timeout=self.timeout) # check for service exceptions, and return if u.info()['Content-Type'] == 'application/vnd.ogc.se_xml': @@ -792,7 +793,7 @@ class WMTSCapabilitiesReader: """Read and parse capabilities document into a lxml.etree infoset """ - def __init__(self, version='1.0.0', url=None, un=None, pw=None, auth=None): + def __init__(self, version='1.0.0', url=None, un=None, pw=None, headers=None, auth=None): """Initialize""" self.version = version self._infoset = None @@ -803,6 +804,7 @@ def __init__(self, version='1.0.0', url=None, un=None, pw=None, auth=None): if pw: auth.password = pw self.auth = auth or Authentication(un, pw) + self.headers = headers def capabilities_url(self, service_url, vendor_kwargs=None): """Return a capabilities url @@ -837,7 +839,7 @@ def read(self, service_url, vendor_kwargs=None): # now split it up again to use the generic openURL function... spliturl = getcaprequest.split('?') - u = openURL(spliturl[0], spliturl[1], method='Get', auth=self.auth) + u = openURL(spliturl[0], spliturl[1], method='Get', headers=self.headers, auth=self.auth) return etree.fromstring(u.read()) def readString(self, st): diff --git a/tests/test_tms.py b/tests/test_tms.py new file mode 100644 index 000000000..344747e84 --- /dev/null +++ b/tests/test_tms.py @@ -0,0 +1,21 @@ +from tests.utils import scratch_file +from tests.utils import service_ok + +import pytest + +SERVICE_URL = 'http://geodata.nationaalgeoregister.nl/tiles/service/tms/1.0.0' + + +@pytest.mark.online +@pytest.mark.skipif(not service_ok(SERVICE_URL), + reason="TMS service is unreachable") +def test_tms(): + # Find out what a TMS has to offer. Service metadata: + from owslib.tms import TileMapService + tms = TileMapService(SERVICE_URL) + + # Fetch a tile (using some defaults): + tile = tms.gettile(7, 7, 4, title='brtachtergrondkaart', srs='EPSG:28992', mimetype='image/png') + out = open(scratch_file('brtachtergrondkaart.png'), 'wb') + out.write(tile.read()) + out.close() diff --git a/tests/test_wfs3_pygeoapi.py b/tests/test_wfs3_pygeoapi.py index aee35b6df..42f2c0efb 100644 --- a/tests/test_wfs3_pygeoapi.py +++ b/tests/test_wfs3_pygeoapi.py @@ -34,6 +34,10 @@ def test_wfs3_pygeoapi(): assert lakes['title'] == 'Large Lakes' assert lakes['description'] == 'lakes of the world, public domain' + # Minimum of limit param is 1 + lakes_query = w.collection_items('lakes', limit=0) + assert lakes_query['code'] == 'InvalidParameterValue' + lakes_query = w.collection_items('lakes', limit=1) assert lakes_query['numberMatched'] == 25 assert lakes_query['numberReturned'] == 1