[Git][debian-gis-team/owslib][master] 4 commits: New upstream version 0.23.0
Bas Couwenberg
gitlab at salsa.debian.org
Sat Feb 6 06:09:21 GMT 2021
Bas Couwenberg pushed to branch master at Debian GIS Project / owslib
Commits:
c9a19efa by Bas Couwenberg at 2021-02-06T06:55:55+01:00
New upstream version 0.23.0
- - - - -
dc812391 by Bas Couwenberg at 2021-02-06T06:56:01+01:00
Update upstream source from tag 'upstream/0.23.0'
Update to upstream version '0.23.0'
with Debian dir f099d42159daa0a41aa1da03d772bd51df45fa6f
- - - - -
3fff354b by Bas Couwenberg at 2021-02-06T06:56:17+01:00
New upstream release.
- - - - -
13415940 by Bas Couwenberg at 2021-02-06T06:57:07+01:00
Set distribution to unstable.
- - - - -
19 changed files:
- CHANGES.rst
- VERSION.txt
- debian/changelog
- owslib/__init__.py
- owslib/coverage/wcs100.py
- owslib/coverage/wcs110.py
- owslib/coverage/wcs200.py
- owslib/coverage/wcs201.py
- owslib/coverage/wcsBase.py
- owslib/iso.py
- owslib/map/wms130.py
- owslib/ows.py
- owslib/util.py
- owslib/wcs.py
- â tests/doctests/gm03_parse.txt
- tests/resources/iso_mi.xml
- + tests/test_gm03.py
- tests/test_iso_parsing.py
- tests/test_wfs_generic.py
Changes:
=====================================
CHANGES.rst
=====================================
@@ -1,6 +1,37 @@
Changes
=======
+0.23.0 (2021-02-04)
+-------------------
+
+A full list of commits for 0.23.0 can be found at:
+
+https://github.com/geopython/OWSLib/commits/0.23.0
+
+- WMS: Handle empty <DataURL>.<Format> element in GetCapabilities (#739)
+- WCS: Feature/wcs headers integration (#741)
+- Tests: fix WFS tests (#743)
+- Auth: Support requests AuthBase in addition to basic password authentication (#724)
+- WCS: Fix bug with timeout not assigned (#738)
+- Tests: restore ISO GM03 tests as pytests (#734)
+- ISO: OWS/ISO metadata updates (#736)
+- ISO: add support for ISO 19115 keyword thesaurus URLs via gmx:Anchor (#735)
+- ISO: fix reference (#733)
+
+
+0.22.0 (2021-01-21)
+-------------------
+
+A full list of commits for 0.22.0 can be found at:
+
+https://github.com/geopython/OWSLib/commits/0.22.0
+
+- Tests: Fix tests coveralls (#732)
+- WCS, WFS: Add timeout to get capabilities (#730)
+- Tests: migrate to GitHub actions (#727)
+- ISO: add support for ISO 19115-2 (#726)
+
+
0.21.0 (2020-12-09)
-------------------
=====================================
VERSION.txt
=====================================
@@ -1 +1 @@
-0.22.0
+0.23.0
=====================================
debian/changelog
=====================================
@@ -1,3 +1,10 @@
+owslib (0.23.0-1) unstable; urgency=medium
+
+ * Team upload.
+ * New upstream release.
+
+ -- Bas Couwenberg <sebastic at debian.org> Sat, 06 Feb 2021 06:56:56 +0100
+
owslib (0.22.0-1) unstable; urgency=medium
* Team upload.
=====================================
owslib/__init__.py
=====================================
@@ -1 +1 @@
-__version__ = '0.22.0'
+__version__ = '0.23.0'
=====================================
owslib/coverage/wcs100.py
=====================================
@@ -38,14 +38,14 @@ class WebCoverageService_1_0_0(WCSBase):
else:
raise KeyError("No content named %s" % name)
- def __init__(self, url, xml, cookies, auth=None, timeout=30):
- super(WebCoverageService_1_0_0, self).__init__(auth)
+ def __init__(self, url, xml, cookies, auth=None, timeout=30, headers=None):
+ super(WebCoverageService_1_0_0, self).__init__(auth, headers=headers)
self.version = '1.0.0'
self.url = url
self.cookies = cookies
self.timeout = timeout
# initialize from saved capability document or access the server
- reader = WCSCapabilitiesReader(self.version, self.cookies, self.auth)
+ reader = WCSCapabilitiesReader(self.version, self.cookies, self.auth, headers=self.headers)
if xml:
self._capabilities = reader.readString(xml)
else:
@@ -155,7 +155,7 @@ class WebCoverageService_1_0_0(WCSBase):
data = urlencode(request)
log.debug('WCS 1.0.0 DEBUG: Second part of URL: %s' % data)
- u = openURL(base_url, data, method, self.cookies, auth=self.auth, timeout=timeout)
+ u = openURL(base_url, data, method, self.cookies, auth=self.auth, timeout=timeout, headers=self.headers)
return u
def getOperationByName(self, name):
=====================================
owslib/coverage/wcs110.py
=====================================
@@ -51,13 +51,14 @@ class WebCoverageService_1_1_0(WCSBase):
else:
raise KeyError("No content named %s" % name)
- def __init__(self, url, xml, cookies, auth=None, timeout=30):
- super(WebCoverageService_1_1_0, self).__init__(auth=auth)
+ def __init__(self, url, xml, cookies, auth=None, timeout=30, headers=None):
+ super(WebCoverageService_1_1_0, self).__init__(auth=auth, headers=headers)
self.url = url
self.cookies = cookies
+ self.timeout = timeout
# initialize from saved capability document or access the server
- reader = WCSCapabilitiesReader(self.version, self.cookies, self.auth)
+ reader = WCSCapabilitiesReader(self.version, self.cookies, self.auth, headers=self.headers)
if xml:
self._capabilities = reader.readString(xml)
else:
@@ -87,7 +88,7 @@ class WebCoverageService_1_1_0(WCSBase):
# serviceOperations
self.operations = []
for elem in self._capabilities.findall(
- self.ns.WCS_OWS('OperationsMetadata') + '/' + self.ns.WCS_OWS('Operation') + '/'):
+ self.ns.OWS('OperationsMetadata') + '/' + self.ns.OWS('Operation')):
self.operations.append(Operation(elem, self.ns))
# exceptions - ***********TO DO *************
@@ -205,7 +206,7 @@ class WebCoverageService_1_1_0(WCSBase):
# encode and request
data = urlencode(request)
- u = openURL(base_url, data, method, self.cookies, auth=self.auth, timeout=timeout)
+ u = openURL(base_url, data, method, self.cookies, auth=self.auth, timeout=timeout, headers=self.headers)
return u
def getOperationByName(self, name):
=====================================
owslib/coverage/wcs200.py
=====================================
@@ -53,14 +53,15 @@ class WebCoverageService_2_0_0(WCSBase):
else:
raise KeyError("No content named %s" % name)
- def __init__(self, url, xml, cookies, auth=None, timeout=30):
- super(WebCoverageService_2_0_0, self).__init__(auth=auth)
+ def __init__(self, url, xml, cookies, auth=None, timeout=30, headers=None):
+ super(WebCoverageService_2_0_0, self).__init__(auth=auth, headers=headers)
self.version = "2.0.0"
self.url = url
self.cookies = cookies
+ self.timeout = timeout
self.ows_common = OwsCommon(version="2.0.0")
# initialize from saved capability document or access the server
- reader = WCSCapabilitiesReader(self.version, self.cookies, self.auth)
+ reader = WCSCapabilitiesReader(self.version, self.cookies, self.auth, headers=self.headers)
if xml:
self._capabilities = reader.readString(xml)
else:
@@ -214,7 +215,7 @@ class WebCoverageService_2_0_0(WCSBase):
data += param_list_to_url_string(sizes, 'size')
log.debug("WCS 2.0.0 DEBUG: Second part of URL: %s" % data)
- u = openURL(base_url, data, method, self.cookies, auth=self.auth, timeout=timeout)
+ u = openURL(base_url, data, method, self.cookies, auth=self.auth, timeout=timeout, headers=self.headers)
return u
def getOperationByName(self, name):
=====================================
owslib/coverage/wcs201.py
=====================================
@@ -53,14 +53,15 @@ class WebCoverageService_2_0_1(WCSBase):
else:
raise KeyError("No content named %s" % name)
- def __init__(self, url, xml, cookies, auth=None, timeout=30):
- super(WebCoverageService_2_0_1, self).__init__(auth=auth)
+ def __init__(self, url, xml, cookies, auth=None, timeout=30, headers=None):
+ super(WebCoverageService_2_0_1, self).__init__(auth=auth, headers=headers)
self.version = "2.0.1"
self.url = url
self.cookies = cookies
+ self.timeout = timeout
self.ows_common = OwsCommon(version="2.0.1")
# initialize from saved capability document or access the server
- reader = WCSCapabilitiesReader(self.version, self.cookies, self.auth)
+ reader = WCSCapabilitiesReader(self.version, self.cookies, self.auth, headers=self.headers)
if xml:
self._capabilities = reader.readString(xml)
else:
@@ -215,7 +216,7 @@ class WebCoverageService_2_0_1(WCSBase):
log.debug("WCS 2.0.1 DEBUG: Second part of URL: %s" % data)
- u = openURL(base_url, data, method, self.cookies, auth=self.auth, timeout=timeout)
+ u = openURL(base_url, data, method, self.cookies, auth=self.auth, timeout=timeout, headers=self.headers)
return u
def getOperationByName(self, name):
=====================================
owslib/coverage/wcsBase.py
=====================================
@@ -33,7 +33,7 @@ class ServiceException(Exception):
class WCSBase(object):
"""Base class to be subclassed by version dependent WCS classes. Provides 'high-level'
version independent methods"""
- def __new__(self, url, xml, cookies, auth=None):
+ def __new__(self, url, xml, cookies, auth=None, headers=None):
""" overridden __new__ method
@type url: string
@@ -41,22 +41,25 @@ class WCSBase(object):
@type xml: string
@param xml: elementtree object
@param auth: instance of owslib.util.Authentication
+ @param headers: dict for geoserver's request's headers
@return: inititalised WCSBase object
"""
obj = object.__new__(self)
- obj.__init__(url, xml, cookies, auth=auth)
+ obj.__init__(url, xml, cookies, auth=auth, headers=headers)
self.cookies = cookies
+ self.headers = headers
self._describeCoverage = {} # cache for DescribeCoverage responses
return obj
- def __init__(self, auth=None):
+ def __init__(self, auth=None, headers=None):
self.auth = auth or Authentication()
+ self.headers = headers
def getDescribeCoverage(self, identifier):
''' returns a describe coverage document - checks the internal cache to see if it has been fetched before '''
if identifier not in list(self._describeCoverage.keys()):
reader = DescribeCoverageReader(
- self.version, identifier, self.cookies, self.auth)
+ self.version, identifier, self.cookies, self.auth, self.headers)
self._describeCoverage[identifier] = reader.read(self.url)
return self._describeCoverage[identifier]
@@ -65,7 +68,7 @@ class WCSCapabilitiesReader(object):
"""Read and parses WCS capabilities document into a lxml.etree infoset
"""
- def __init__(self, version=None, cookies=None, auth=None):
+ def __init__(self, version=None, cookies=None, auth=None, headers=None):
"""Initialize
@type version: string
@param version: WCS Version parameter e.g '1.0.0'
@@ -73,6 +76,7 @@ class WCSCapabilitiesReader(object):
self.version = version
self._infoset = None
self.cookies = cookies
+ self.headers = headers
self.auth = auth or Authentication()
def capabilities_url(self, service_url):
@@ -109,7 +113,7 @@ class WCSCapabilitiesReader(object):
@return: An elementtree tree representation of the capabilities document
"""
request = self.capabilities_url(service_url)
- u = openURL(request, timeout=timeout, cookies=self.cookies, auth=self.auth)
+ u = openURL(request, timeout=timeout, cookies=self.cookies, auth=self.auth, headers=self.headers)
return etree.fromstring(u.read())
def readString(self, st):
@@ -124,7 +128,7 @@ class DescribeCoverageReader(object):
"""Read and parses WCS DescribeCoverage document into a lxml.etree infoset
"""
- def __init__(self, version, identifier, cookies, auth=None):
+ def __init__(self, version, identifier, cookies, auth=None, headers=None):
"""Initialize
@type version: string
@param version: WCS Version parameter e.g '1.0.0'
@@ -133,6 +137,7 @@ class DescribeCoverageReader(object):
self._infoset = None
self.identifier = identifier
self.cookies = cookies
+ self.headers = headers
self.auth = auth or Authentication()
def descCov_url(self, service_url):
@@ -186,5 +191,5 @@ class DescribeCoverageReader(object):
"""
request = self.descCov_url(service_url)
- u = openURL(request, cookies=self.cookies, timeout=timeout, auth=self.auth)
+ u = openURL(request, cookies=self.cookies, timeout=timeout, auth=self.auth, headers=self.headers)
return etree.fromstring(u.read())
=====================================
owslib/iso.py
=====================================
@@ -171,6 +171,8 @@ class MD_Metadata(object):
val = md.find(util.nspath_eval('gmi:acquisitionInformation/gmi:MI_AcquisitionInformation', namespaces))
if val is not None:
self.acquisition = MI_AcquisitionInformation(val)
+ else:
+ self.acquisition = None
def get_default_locale(self):
""" get default gmd:PT_Locale based on gmd:language """
@@ -323,6 +325,13 @@ class MD_Keywords(object):
thesaurus = val.find(util.nspath_eval('gmd:title/gco:CharacterString', namespaces))
self.thesaurus['title'] = util.testXMLValue(thesaurus)
+ self.thesaurus['url'] = None
+
+ if self.thesaurus['title'] is None: # try gmx:Anchor
+ t = val.find(util.nspath_eval('gmd:title/gmx:Anchor', namespaces))
+ if t is not None:
+ self.thesaurus['title'] = util.testXMLValue(t)
+ self.thesaurus['url'] = t.attrib.get(util.nspath_eval('xlink:href', namespaces))
thesaurus = val.find(util.nspath_eval('gmd:date/gmd:CI_Date/gmd:date/gco:Date', namespaces))
self.thesaurus['date'] = util.testXMLValue(thesaurus)
=====================================
owslib/map/wms130.py
=====================================
@@ -665,9 +665,11 @@ class ContentMetadata(AbstractContentMetadata):
self.dataUrls = []
for m in elem.findall(nspath('DataURL', WMS_NAMESPACE)):
dataUrl = {
- 'format': m.find(nspath('Format', WMS_NAMESPACE)).text.strip(),
+ 'format': m.find(nspath('Format', WMS_NAMESPACE)).text,
'url': m.find(nspath('OnlineResource', WMS_NAMESPACE)).attrib['{http://www.w3.org/1999/xlink}href']
}
+ if dataUrl['format'] is not None:
+ dataUrl['format'] = dataUrl['format'].strip()
self.dataUrls.append(dataUrl)
# FeatureListURLs
=====================================
owslib/ows.py
=====================================
@@ -62,6 +62,9 @@ class ServiceIdentification(object):
if f.text is not None:
self.keywords.append(f.text)
+ val = self._root.find(util.nspath('Keywords/Type', namespace))
+ self.keywords_type = util.testXMLValue(val)
+
val = self._root.find(util.nspath('AccessConstraints', namespace))
self.accessconstraints = util.testXMLValue(val)
=====================================
owslib/util.py
=====================================
@@ -15,7 +15,7 @@ from datetime import datetime, timedelta
import pytz
from owslib.etree import etree, ParseError
from owslib.namespaces import Namespaces
-from urllib.parse import urlsplit, urlencode, urlparse, parse_qs, urlunparse, parse_qsl
+from urllib.parse import urlsplit, urlencode, urlparse, parse_qs, urlunparse, parse_qsl, unquote
import copy
from io import StringIO, BytesIO
@@ -24,6 +24,7 @@ import re
from copy import deepcopy
import warnings
import requests
+from requests.auth import AuthBase
import codecs
"""
@@ -173,8 +174,12 @@ def openURL(url_base, data=None, method='Get', cookies=None, username=None, pass
verify = verify and auth.verify
else:
auth = Authentication(username, password, cert, verify)
+
if auth.username and auth.password:
rkwargs['auth'] = (auth.username, auth.password)
+ elif auth.auth_delegate is not None:
+ rkwargs['auth'] = auth.auth_delegate
+
rkwargs['cert'] = auth.cert
rkwargs['verify'] = verify
@@ -192,7 +197,7 @@ def openURL(url_base, data=None, method='Get', cookies=None, username=None, pass
rkwargs['data'] = data
elif method.lower() == 'get':
- rkwargs['params'] = data
+ rkwargs['params'] = unquote(data) if data else None
else:
raise ValueError("Unknown method ('%s'), expected 'get' or 'post'" % method)
@@ -419,6 +424,8 @@ def http_post(url=None, request=None, lang='en-US', timeout=10, username=None, p
auth = Authentication(username, password)
if auth.username is not None and auth.password is not None:
rkwargs['auth'] = (auth.username, auth.password)
+ elif auth.auth_delegate is not None:
+ rkwargs['auth'] = auth.auth_delegate
rkwargs['verify'] = auth.verify
rkwargs['cert'] = auth.cert
@@ -451,6 +458,8 @@ def http_get(*args, **kwargs):
# Build keyword args for call to requests.get()
if auth.username and auth.password:
rkwargs.setdefault('auth', (auth.username, auth.password))
+ elif auth.auth_delegate is not None:
+ rkwargs['auth'] = auth.auth_delegate
else:
rkwargs.setdefault('auth', None)
rkwargs.setdefault('cert', rkwargs.get('cert'))
@@ -837,11 +846,13 @@ class Authentication(object):
_USERNAME = None
_PASSWORD = None
+ _AUTH_DELEGATE = None
_CERT = None
_VERIFY = None
def __init__(self, username=None, password=None,
- cert=None, verify=True, shared=False):
+ cert=None, verify=True, shared=False,
+ auth_delegate=None):
'''
:param str username=None: Username for basic authentication, None for
unauthenticated access (or if using cert/verify)
@@ -856,12 +867,16 @@ class Authentication(object):
:param bool shared=False: Set to True to make the values be class-level
attributes (shared among instances where shared=True) instead of
instance-level (shared=False, default)
+ :param AuthBase auth_delegate=None: Instance of requests' AuthBase to
+ allow arbitrary authentication schemes - mutually exclusive with
+ username/password arguments.
'''
self.shared = shared
self.username = username
self.password = password
self.cert = cert
self.verify = verify
+ self.auth_delegate = auth_delegate
@property
def username(self):
@@ -871,10 +886,15 @@ class Authentication(object):
@username.setter
def username(self, value):
- if value is None:
- pass
- elif not isinstance(value, str):
- raise TypeError('Value for "username" must be a str')
+ if value is not None:
+
+ if not isinstance(value, str):
+ raise TypeError('Value for "username" must be a str')
+
+ if self.auth_delegate is not None:
+ raise ValueError('Authentication instances may have username/password or auth_delegate set,'
+ ' but not both')
+
if self.shared:
self.__class__._USERNAME = value
else:
@@ -888,10 +908,15 @@ class Authentication(object):
@password.setter
def password(self, value):
- if value is None:
- pass
- elif not isinstance(value, str):
- raise TypeError('Value for "password" must be a str')
+ if value is not None:
+
+ if not isinstance(value, str):
+ raise TypeError('Value for "password" must be a str')
+
+ if self.auth_delegate is not None:
+ raise ValueError('Authentication instances may have username/password or auth_delegate set,'
+ ' but not both')
+
if self.shared:
self.__class__._PASSWORD = value
else:
@@ -951,8 +976,32 @@ class Authentication(object):
else:
self._verify = value
+ @property
+ def auth_delegate(self):
+ if self.shared:
+ return self._AUTH_DELEGATE
+ return self._auth_delegate
+
+ @auth_delegate.setter
+ def auth_delegate(self, value):
+ if value is not None:
+ if not isinstance(value, AuthBase):
+ raise TypeError('Value for "auth_delegate" must be an instance of AuthBase')
+
+ if self.username is not None or self.password is not None:
+ raise ValueError('Authentication instances may have username/password or auth_delegate set,'
+ ' but not both')
+
+ if self.shared:
+ self.__class__._AUTH_DELEGATE = value
+ else:
+ self._auth_delegate = value
+
@property
def urlopen_kwargs(self):
+ if self.auth_delegate is not None:
+ raise NotImplementedError("The urlopen_kwargs property is not supported when auth_delegate is set")
+
return {
'username': self.username,
'password': self.password,
@@ -961,5 +1010,6 @@ class Authentication(object):
}
def __repr__(self, *args, **kwargs):
- return '<{} shared={} username={} password={} cert={} verify={}>'.format(
- self.__class__.__name__, self.shared, self.username, self.password, self.cert, self.verify)
+ return '<{} shared={} username={} password={} cert={} verify={} auth_delegate={}>'.format(
+ self.__class__.__name__, self.shared, self.username, self.password, self.cert, self.verify,
+ self.auth_delegate)
=====================================
owslib/wcs.py
=====================================
@@ -18,7 +18,7 @@ from .coverage import wcs100, wcs110, wcs111, wcsBase, wcs200, wcs201
from owslib.util import clean_ows_url, Authentication, openURL
-def WebCoverageService(url, version=None, xml=None, cookies=None, timeout=30, auth=None):
+def WebCoverageService(url, version=None, xml=None, cookies=None, timeout=30, auth=None, headers=None):
''' wcs factory function, returns a version specific WebCoverageService object '''
if not auth:
@@ -26,10 +26,10 @@ def WebCoverageService(url, version=None, xml=None, cookies=None, timeout=30, au
if version is None:
if xml is None:
- reader = wcsBase.WCSCapabilitiesReader(auth=auth)
+ reader = wcsBase.WCSCapabilitiesReader(auth=auth, headers=headers)
request = reader.capabilities_url(url)
xml = openURL(
- request, cookies=cookies, timeout=timeout, auth=auth).read()
+ request, cookies=cookies, timeout=timeout, auth=auth, headers=headers).read()
capabilities = etree.etree.fromstring(xml)
version = capabilities.get('version')
@@ -39,16 +39,16 @@ def WebCoverageService(url, version=None, xml=None, cookies=None, timeout=30, au
if version == '1.0.0':
return wcs100.WebCoverageService_1_0_0.__new__(
- wcs100.WebCoverageService_1_0_0, clean_url, xml, cookies, auth=auth)
+ wcs100.WebCoverageService_1_0_0, clean_url, xml, cookies, auth=auth, headers=headers)
elif version == '1.1.0':
return wcs110.WebCoverageService_1_1_0.__new__(
- wcs110.WebCoverageService_1_1_0, url, xml, cookies, auth=auth)
+ wcs110.WebCoverageService_1_1_0, url, xml, cookies, auth=auth, headers=headers)
elif version == '1.1.1':
return wcs111.WebCoverageService_1_1_1.__new__(
- wcs111.WebCoverageService_1_1_1, url, xml, cookies, auth=auth)
+ wcs111.WebCoverageService_1_1_1, url, xml, cookies, auth=auth, headers=headers)
elif version == '2.0.0':
return wcs200.WebCoverageService_2_0_0.__new__(
- wcs200.WebCoverageService_2_0_0, url, xml, cookies, auth=auth)
+ wcs200.WebCoverageService_2_0_0, url, xml, cookies, auth=auth, headers=headers)
elif version == '2.0.1':
return wcs201.WebCoverageService_2_0_1.__new__(
- wcs201.WebCoverageService_2_0_1, url, xml, cookies, auth=auth)
+ wcs201.WebCoverageService_2_0_1, url, xml, cookies, auth=auth, headers=headers)
=====================================
tests/doctests/gm03_parse.txt deleted
=====================================
@@ -1,60 +0,0 @@
-
-Imports
-
- >>> from tests.utils import resource_file
- >>> from owslib.etree import etree
- >>> from owslib.gm03 import GM03
-
-Print testing some metadata elements
-
- >>> e = etree.parse(resource_file('gm03_example1.xml'))
- >>> gm03 = GM03(e)
- >>> gm03.header.version
- '2.3'
- >>> gm03.header.sender
- 'geocat.ch'
- >>> hasattr(gm03.data, 'core')
- False
- >>> hasattr(gm03.data, 'comprehensive')
- True
- >>> len(gm03.data.comprehensive.elements)
- 13
- >>> sorted(list(gm03.data.comprehensive.elements.keys()))
- ['address', 'citation', 'contact', 'data_identification', 'date', 'extent', 'extent_geographic_element', 'geographic_bounding_box', 'identification_point_of_contact', 'keywords', 'metadata', 'metadata_point_of_contact', 'responsible_party']
- >>> isinstance(gm03.data.comprehensive.date, list)
- True
- >>> len(gm03.data.comprehensive.date)
- 1
- >>> gm03.data.comprehensive.metadata.file_identifier
- '41ac321f632e55cebf0508a2cea5d9023fd12d9ad46edd679f2c275127c88623fb9c9d29726bef7c'
- >>> gm03.data.comprehensive.metadata.date_stamp
- '1999-12-31T12:00:00'
- >>> gm03.data.comprehensive.metadata.language
- 'de'
-
-Test TID searching
-
- >>> gm03.data.comprehensive.metadata.tid
- 'xN6509077498146737843'
- >>> search_tid = gm03.data.comprehensive.metadata.tid
- >>> gm03.data.comprehensive.get_element_by_tid('404') is None
- True
- >>> gm03.data.comprehensive.get_element_by_tid(search_tid) is None
- False
- >>> search_tid2 = gm03.data.comprehensive.extent.data_identification.ref
- >>> search_tid2
- 'xN8036063300808707346'
- >>> gm03.data.comprehensive.get_element_by_tid(search_tid2) is None
- False
- >>> e = etree.parse(resource_file('gm03_example2.xml'))
- >>> gm03 = GM03(e)
- >>> gm03.data.comprehensive.geographic_bounding_box.extent_type_code
- 'false'
- >>> gm03.data.comprehensive.geographic_bounding_box.north_bound_latitude
- '47.1865387201702'
- >>> gm03.data.comprehensive.geographic_bounding_box.south_bound_latitude
- '47.1234508676764'
- >>> gm03.data.comprehensive.geographic_bounding_box.east_bound_longitude
- '9.10597474389878'
- >>> gm03.data.comprehensive.geographic_bounding_box.west_bound_longitude
- '9.23798212070671'
=====================================
tests/resources/iso_mi.xml
=====================================
@@ -1,5 +1,5 @@
<?xml version="1.0" ?>
-<gmi:MI_Metadata xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gmi="http://www.isotc211.org/2005/gmi" xmlns:gml="http://www.opengis.net/gml" xmlns:gmx="http://www.isotc211.org/2005/gmx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://www.isotc211.org/2005/gmd/gmd.xsd http://www.isotc211.org/2005/gmx http://www.isotc211.org/2005/gmx/gmx.xsd http://www.isotc211.org/2005/gmi http://www.isotc211.org/2005/gmx/gmi.xsd">
+<gmi:MI_Metadata xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gmi="http://www.isotc211.org/2005/gmi" xmlns:gml="http://www.opengis.net/gml" xmlns:gmx="http://www.isotc211.org/2005/gmx" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://www.isotc211.org/2005/gmd/gmd.xsd http://www.isotc211.org/2005/gmx http://www.isotc211.org/2005/gmx/gmx.xsd http://www.isotc211.org/2005/gmi http://www.isotc211.org/2005/gmx/gmi.xsd">
<gmd:fileIdentifier>
<gco:CharacterString>3f342f64-9348-11df-ba6a-0014c2c00eab</gco:CharacterString>
</gmd:fileIdentifier>
@@ -268,6 +268,19 @@
<gmd:type>
<gmd:MD_KeywordTypeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_KeywordTypeCode" codeListValue="theme" codeSpace="ISOTC211/19115">theme</gmd:MD_KeywordTypeCode>
</gmd:type>
+ <gmd:thesaurusName>
+ <gmd:CI_Citation>
+ <gmd:title>
+ <gmx:Anchor xlink:title="My Vocabulary" xlink:href="https://example.org/my-vocab">My Vocabulary</gmx:Anchor>
+ </gmd:title>
+ <gmd:date>
+ <gmd:CI_Date>
+ <gmd:date gco:nilReason="missing"/>
+ <gmd:dateType gco:nilReason="missing"/>
+ </gmd:CI_Date>
+ </gmd:date>
+ </gmd:CI_Citation>
+ </gmd:thesaurusName>
</gmd:MD_Keywords>
</gmd:descriptiveKeywords>
<gmd:descriptiveKeywords>
=====================================
tests/test_gm03.py
=====================================
@@ -0,0 +1,41 @@
+
+from tests.utils import resource_file
+from owslib.etree import etree
+from owslib.gm03 import GM03
+
+
+def test_gm03():
+ """Test GM03 parsing"""
+
+ e = etree.parse(resource_file('gm03_example1.xml'))
+ gm03 = GM03(e)
+ assert gm03.header.version == '2.3'
+ assert gm03.header.sender == 'geocat.ch'
+ assert not hasattr(gm03.data, 'core')
+ assert hasattr(gm03.data, 'comprehensive')
+ assert len(gm03.data.comprehensive.elements) == 13
+ assert sorted(list(gm03.data.comprehensive.elements.keys())) == ['address', 'citation', 'contact', 'data_identification', 'date', 'extent', 'extent_geographic_element', 'geographic_bounding_box', 'identification_point_of_contact', 'keywords', 'metadata', 'metadata_point_of_contact', 'responsible_party'] # noqa
+ assert isinstance(gm03.data.comprehensive.date, list)
+ assert len(gm03.data.comprehensive.date) == 1
+ assert gm03.data.comprehensive.metadata.file_identifier == '41ac321f632e55cebf0508a2cea5d9023fd12d9ad46edd679f2c275127c88623fb9c9d29726bef7c' # noqa
+ assert gm03.data.comprehensive.metadata.date_stamp == '1999-12-31T12:00:00'
+ assert gm03.data.comprehensive.metadata.language == 'de'
+
+ # Test TID searching
+
+ assert gm03.data.comprehensive.metadata.tid == 'xN6509077498146737843'
+
+ search_tid = gm03.data.comprehensive.metadata.tid
+ assert gm03.data.comprehensive.get_element_by_tid('404') is None
+ assert gm03.data.comprehensive.get_element_by_tid(search_tid) is not None
+ search_tid2 = gm03.data.comprehensive.extent.data_identification.ref
+ assert search_tid2 == 'xN8036063300808707346'
+ assert gm03.data.comprehensive.get_element_by_tid(search_tid2) is not None
+
+ e = etree.parse(resource_file('gm03_example2.xml'))
+ gm03 = GM03(e)
+ assert gm03.data.comprehensive.geographic_bounding_box.extent_type_code == 'false'
+ assert gm03.data.comprehensive.geographic_bounding_box.north_bound_latitude == '47.1865387201702'
+ assert gm03.data.comprehensive.geographic_bounding_box.south_bound_latitude == '47.1234508676764'
+ assert gm03.data.comprehensive.geographic_bounding_box.east_bound_longitude == '9.10597474389878'
+ assert gm03.data.comprehensive.geographic_bounding_box.west_bound_longitude == '9.23798212070671'
=====================================
tests/test_iso_parsing.py
=====================================
@@ -570,6 +570,12 @@ def test_md_parsing_19115_2():
assert md.identifier == '3f342f64-9348-11df-ba6a-0014c2c00eab'
+ iden = md.identificationinfo[0]
+
+ assert len(iden.keywords2) == 3
+ assert iden.keywords2[1].thesaurus['title'] == 'My Vocabulary'
+ assert iden.keywords2[1].thesaurus['url'] == 'https://example.org/my-vocab'
+
ci = md.contentinfo[0]
assert ci.type == 'image'
assert ci.cloud_cover == '72'
=====================================
tests/test_wfs_generic.py
=====================================
@@ -1,4 +1,5 @@
from owslib.wfs import WebFeatureService
+from owslib.util import ServiceException
from urllib.parse import urlparse
from tests.utils import resource_file, sorted_url_query, service_ok
@@ -58,7 +59,7 @@ def test_outputformat_wfs_100():
version='1.0.0')
feature = wfs.getfeature(
typename=['sb:Project_Area'], maxfeatures=1, propertyname=None, outputFormat='application/json')
- assert json.dumps(json.loads(feature.read())) == '{...}'
+ assert len(json.loads(feature.read())['features']) == 1
@pytest.mark.online
@@ -70,7 +71,7 @@ def test_outputformat_wfs_110():
version='1.1.0')
feature = wfs.getfeature(
typename=['sb:Project_Area'], maxfeatures=1, propertyname=None, outputFormat='application/json')
- assert json.dumps(json.loads(feature.read())) == '{...}'
+ assert len(json.loads(feature.read())['features']) == 1
@pytest.mark.online
@@ -82,7 +83,7 @@ def test_outputformat_wfs_200():
version='2.0.0')
feature = wfs.getfeature(
typename=['sb:Project_Area'], maxfeatures=1, propertyname=None, outputFormat='application/json')
- assert json.dumps(json.loads(feature.read())) == '{...}'
+ assert len(json.loads(feature.read())['features']) == 1
@pytest.mark.online
@@ -92,10 +93,11 @@ def test_srsname_wfs_100():
import json
wfs = WebFeatureService('https://www.sciencebase.gov/catalogMaps/mapping/ows/53398e51e4b0db25ad10d288',
version='1.0.0')
- feature = wfs.getfeature(
- typename=['sb:Project_Area'], maxfeatures=1, propertyname=None, outputFormat='application/json',
- srsname="EPSG:99999999")
# ServiceException: Unable to support srsName: EPSG:99999999
+ with pytest.raises(ServiceException):
+ feature = wfs.getfeature(
+ typename=['sb:Project_Area'], maxfeatures=1, propertyname=None, outputFormat='application/json',
+ srsname="EPSG:99999999")
import json
wfs = WebFeatureService('https://www.sciencebase.gov/catalogMaps/mapping/ows/53398e51e4b0db25ad10d288',
@@ -103,7 +105,7 @@ def test_srsname_wfs_100():
feature = wfs.getfeature(
typename=['sb:Project_Area'], maxfeatures=1, propertyname=None, outputFormat='application/json',
srsname="urn:x-ogc:def:crs:EPSG:4326")
- assert json.dumps(json.loads(feature.read())) == '{...}'
+ assert len(json.loads(feature.read())['features']) == 1
@pytest.mark.online
@@ -114,10 +116,11 @@ def test_srsname_wfs_110():
wfs = WebFeatureService(
'https://www.sciencebase.gov/catalogMaps/mapping/ows/53398e51e4b0db25ad10d288',
version='1.1.0')
- feature = wfs.getfeature(
- typename=['sb:Project_Area'], maxfeatures=1, propertyname=None, outputFormat='application/json',
- srsname="EPSG:99999999")
- # ServiceException: SRSNAME EPSG:99999999 not supported. Options: urn:x-ogc:def:crs:EPSG:102715
+ # ServiceException: Unable to support srsName: EPSG:99999999
+ with pytest.raises(ServiceException):
+ feature = wfs.getfeature(
+ typename=['sb:Project_Area'], maxfeatures=1, propertyname=None, outputFormat='application/json',
+ srsname="EPSG:99999999")
import json
wfs = WebFeatureService(
@@ -126,7 +129,7 @@ def test_srsname_wfs_110():
feature = wfs.getfeature(
typename=['sb:Project_Area'], maxfeatures=1, propertyname=None, outputFormat='application/json',
srsname="urn:x-ogc:def:crs:EPSG:4326")
- assert json.dumps(json.loads(feature.read())) == '{...}'
+ assert len(json.loads(feature.read())['features']) == 1
@pytest.mark.online
View it on GitLab: https://salsa.debian.org/debian-gis-team/owslib/-/compare/6680ab425f343379388c47f384caa0cbcea1fb80...13415940204bd14ef38cc541730b43e897baeb19
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/owslib/-/compare/6680ab425f343379388c47f384caa0cbcea1fb80...13415940204bd14ef38cc541730b43e897baeb19
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20210206/94f4efd8/attachment-0001.html>
More information about the Pkg-grass-devel
mailing list