Hello community, here is the log from the commit of package python-OWSLib for openSUSE:Factory checked in at 2020-12-08 13:24:30 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-OWSLib (Old) and /work/SRC/openSUSE:Factory/.python-OWSLib.new.5913 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-OWSLib" Tue Dec 8 13:24:30 2020 rev:3 rq:853715 version:0.20.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-OWSLib/python-OWSLib.changes 2020-03-03 10:20:21.495161562 +0100 +++ /work/SRC/openSUSE:Factory/.python-OWSLib.new.5913/python-OWSLib.changes 2020-12-08 13:25:49.574747971 +0100 @@ -1,0 +2,11 @@ +Mon Dec 7 09:31:35 UTC 2020 - Bruno Friedmann <[email protected]> + +- update to version 0.20.0 + + Provides initial support for draft OGC API - Records standard. + + WFS: make wfs:FeatureTypeList optional for 1.1 and 2.0 (#673) + + OGC API - Records: initial draft implementation (#679, #693) + + WPS: add support for retrieving data from local filesystem (huard, #681) + + WMTS: add support for boundingboxes (kordian-kowalski, #687) + + Authentication: Enable switching off SSL verification (Samweli, #685) + +------------------------------------------------------------------- Old: ---- OWSLib-0.19.1.tar.gz New: ---- OWSLib-0.20.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-OWSLib.spec ++++++ --- /var/tmp/diff_new_pack.IkRrjU/_old 2020-12-08 13:25:50.082749420 +0100 +++ /var/tmp/diff_new_pack.IkRrjU/_new 2020-12-08 13:25:50.086749431 +0100 @@ -22,14 +22,14 @@ %define oldpython python %define skip_python2 1 Name: python-OWSLib -Version: 0.19.1 +Version: 0.20.0 Release: 0 Summary: Python interface to OGC Web Services License: BSD-3-Clause Group: Productivity/Scientific/Other URL: http://geopython.github.com/OWSLib/ Source: https://files.pythonhosted.org/packages/source/O/OWSLib/OWSLib-%{version}.tar.gz -BuildRequires: %{python_module devel} +BuildRequires: %{python_module devel} > 3.6 BuildRequires: %{python_module setuptools} BuildRequires: fdupes BuildRequires: python-rpm-macros ++++++ OWSLib-0.19.1.tar.gz -> OWSLib-0.20.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/CHANGES.rst new/OWSLib-0.20.0/CHANGES.rst --- old/OWSLib-0.19.1/CHANGES.rst 2020-01-31 17:12:37.000000000 +0100 +++ new/OWSLib-0.20.0/CHANGES.rst 2020-06-05 14:29:33.000000000 +0200 @@ -1,6 +1,42 @@ Changes ======= +0.20.0 (2020-06-05) +------------------- + +This release provides initial support for the draft OGC API - Records +standard. + +A full list of commits for 0.20.0 can be found at: + +https://github.com/geopython/OWSLib/commits/0.20.0 + +- WFS: make wfs:FeatureTypeList optional for 1.1 and 2.0 (#673) +- OGC API - Records: initial draft implementation (#679, #693) +- WPS: add support for retrieving data from local filesystem (huard, #681) +- WMTS: add support for boundingboxes (kordian-kowalski, #687) +- Authentication: Enable switching off SSL verification (Samweli, #685) + + +0.19.2 (2020-03-13) +------------------- + +This release is an update. +It drops Python 3.5 support and adds language support to the WPS module. + +A full list of commits for 0.19.2 can be found at: + +https://github.com/geopython/OWSLib/commits/0.19.2 + +- Dropped Python 3.5 support (#659). +- Fix pyproj deprecation (only use pyproj>=2) (#661). +- WPS: Added support for multiple languages (#654, #655). +- OGC API: fix api media type handling (#653). +- WMTS: fix cartopy examples (#656). +- Tests: fix wms tests (#657). +- WCS: added WCS code example do documentation (#658). +- WCS: fix params list (#663). + 0.19.1 (2020-01-29) ------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/OWSLib.egg-info/PKG-INFO new/OWSLib-0.20.0/OWSLib.egg-info/PKG-INFO --- old/OWSLib-0.19.1/OWSLib.egg-info/PKG-INFO 2020-01-31 17:18:13.000000000 +0100 +++ new/OWSLib-0.20.0/OWSLib.egg-info/PKG-INFO 2020-06-05 14:35:06.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.2 Name: OWSLib -Version: 0.19.1 +Version: 0.20.0 Summary: OGC Web Service utility library Home-page: https://geopython.github.io/OWSLib Author: Sean Gillies @@ -155,7 +155,7 @@ make html ./publish.sh # update on PyPI (must be a maintainer) - python setup.py sdist upload + python setup.py sdist bdist_wheel --universal upload Support ------- @@ -172,4 +172,4 @@ Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Scientific/Engineering :: GIS -Requires-Python: >=3.5 +Requires-Python: >=3.6 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/OWSLib.egg-info/SOURCES.txt new/OWSLib-0.20.0/OWSLib.egg-info/SOURCES.txt --- old/OWSLib-0.19.1/OWSLib.egg-info/SOURCES.txt 2020-01-31 17:18:13.000000000 +0100 +++ new/OWSLib-0.20.0/OWSLib.egg-info/SOURCES.txt 2020-06-05 14:35:06.000000000 +0200 @@ -54,6 +54,7 @@ owslib/map/wms130.py owslib/ogcapi/__init__.py owslib/ogcapi/features.py +owslib/ogcapi/records.py owslib/owscontext/__init__.py owslib/owscontext/atom.py owslib/owscontext/common.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/OWSLib.egg-info/requires.txt new/OWSLib-0.20.0/OWSLib.egg-info/requires.txt --- old/OWSLib-0.19.1/OWSLib.egg-info/requires.txt 2020-01-31 17:18:13.000000000 +0100 +++ new/OWSLib-0.20.0/OWSLib.egg-info/requires.txt 2020-06-05 14:35:06.000000000 +0200 @@ -1,4 +1,5 @@ -pyproj python-dateutil>=1.5 pytz requests>=1.0 +pyproj>=2 +pyyaml diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/PKG-INFO new/OWSLib-0.20.0/PKG-INFO --- old/OWSLib-0.19.1/PKG-INFO 2020-01-31 17:18:13.000000000 +0100 +++ new/OWSLib-0.20.0/PKG-INFO 2020-06-05 14:35:06.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.2 Name: OWSLib -Version: 0.19.1 +Version: 0.20.0 Summary: OGC Web Service utility library Home-page: https://geopython.github.io/OWSLib Author: Sean Gillies @@ -155,7 +155,7 @@ make html ./publish.sh # update on PyPI (must be a maintainer) - python setup.py sdist upload + python setup.py sdist bdist_wheel --universal upload Support ------- @@ -172,4 +172,4 @@ Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Scientific/Engineering :: GIS -Requires-Python: >=3.5 +Requires-Python: >=3.6 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/README.rst new/OWSLib-0.20.0/README.rst --- old/OWSLib-0.19.1/README.rst 2020-01-31 17:12:37.000000000 +0100 +++ new/OWSLib-0.20.0/README.rst 2020-06-05 14:34:23.000000000 +0200 @@ -145,7 +145,7 @@ make html ./publish.sh # update on PyPI (must be a maintainer) - python setup.py sdist upload + python setup.py sdist bdist_wheel --universal upload Support ------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/VERSION.txt new/OWSLib-0.20.0/VERSION.txt --- old/OWSLib-0.19.1/VERSION.txt 2020-01-31 17:13:16.000000000 +0100 +++ new/OWSLib-0.20.0/VERSION.txt 2020-06-05 14:29:33.000000000 +0200 @@ -1 +1 @@ -0.19.1 +0.20.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/owslib/__init__.py new/OWSLib-0.20.0/owslib/__init__.py --- old/OWSLib-0.19.1/owslib/__init__.py 2020-01-31 17:13:09.000000000 +0100 +++ new/OWSLib-0.20.0/owslib/__init__.py 2020-06-05 14:29:33.000000000 +0200 @@ -1 +1 @@ -__version__ = '0.19.1' +__version__ = '0.20.0' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/owslib/coverage/wcs100.py new/OWSLib-0.20.0/owslib/coverage/wcs100.py --- old/OWSLib-0.19.1/owslib/coverage/wcs100.py 2020-01-31 17:12:37.000000000 +0100 +++ new/OWSLib-0.20.0/owslib/coverage/wcs100.py 2020-03-29 03:39:03.000000000 +0200 @@ -18,7 +18,7 @@ import errno import logging -from owslib.util import log +from owslib.util import log, makeString # function to save writing out WCS namespace in full each time @@ -94,14 +94,6 @@ items.append((item, self.contents[item])) return items - def __makeString(self, value): - # using repr unconditionally breaks things in some circumstances if a value is already a string - if type(value) is not str: - sval = repr(value) - else: - sval = value - return sval - def getCoverage(self, identifier=None, bbox=None, time=None, format=None, crs=None, width=None, height=None, resx=None, resy=None, resz=None, parameter=None, method='Get', **kwargs): """Request and return a coverage from the WCS as a file-like object @@ -134,7 +126,7 @@ request['Coverage'] = identifier # request['identifier'] = ','.join(identifier) if bbox: - request['BBox'] = ','.join([self.__makeString(x) for x in bbox]) + request['BBox'] = ','.join([makeString(x) for x in bbox]) else: request['BBox'] = None if time: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/owslib/coverage/wcs200.py new/OWSLib-0.20.0/owslib/coverage/wcs200.py --- old/OWSLib-0.19.1/owslib/coverage/wcs200.py 2020-01-31 17:12:37.000000000 +0100 +++ new/OWSLib-0.20.0/owslib/coverage/wcs200.py 2020-03-29 03:39:03.000000000 +0200 @@ -113,14 +113,6 @@ items.append((item, self.contents[item])) return items - def __makeString(self, value): - # using repr unconditionally breaks things in some circumstances if a value is already a string - if type(value) is not str: - sval = repr(value) - else: - sval = value - return sval - def getCoverage( self, identifier=None, @@ -224,16 +216,6 @@ u = openURL(base_url, data, method, self.cookies, auth=self.auth) return u - def is_number(self, s): - """simple helper to test if value is number as requests with numbers dont - need quote marks - """ - try: - float(s) - return True - except ValueError: - return False - def getOperationByName(self, name): """Return a named operation item.""" for item in self.operations: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/owslib/coverage/wcs201.py new/OWSLib-0.20.0/owslib/coverage/wcs201.py --- old/OWSLib-0.19.1/owslib/coverage/wcs201.py 2020-01-31 17:12:37.000000000 +0100 +++ new/OWSLib-0.20.0/owslib/coverage/wcs201.py 2020-03-29 03:39:03.000000000 +0200 @@ -113,14 +113,6 @@ items.append((item, self.contents[item])) return items - def __makeString(self, value): - # using repr unconditionally breaks things in some circumstances if a value is already a string - if type(value) is not str: - sval = repr(value) - else: - sval = value - return sval - def getCoverage( self, identifier=None, @@ -225,16 +217,6 @@ u = openURL(base_url, data, method, self.cookies, auth=self.auth) return u - def is_number(self, s): - """simple helper to test if value is number as requests with numbers dont - need quote marks - """ - try: - float(s) - return True - except ValueError: - return False - def getOperationByName(self, name): """Return a named operation item.""" for item in self.operations: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/owslib/feature/__init__.py new/OWSLib-0.20.0/owslib/feature/__init__.py --- old/OWSLib-0.19.1/owslib/feature/__init__.py 2020-01-31 17:12:37.000000000 +0100 +++ new/OWSLib-0.20.0/owslib/feature/__init__.py 2020-06-05 13:05:14.000000000 +0200 @@ -176,7 +176,7 @@ request["query"] = str(filter) if typename: typename = ( - [typename] if type(typename) == type("") else typename + [typename] if isinstance(typename, str) else typename ) # noqa: E721 if int(self.version.split(".")[0]) >= 2: request["typenames"] = ",".join(typename) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/owslib/feature/common.py new/OWSLib-0.20.0/owslib/feature/common.py --- old/OWSLib-0.19.1/owslib/feature/common.py 2020-01-31 17:12:37.000000000 +0100 +++ new/OWSLib-0.20.0/owslib/feature/common.py 2020-03-29 03:39:03.000000000 +0200 @@ -1,21 +1,9 @@ -from io import StringIO from owslib.etree import etree from owslib.util import Authentication, openURL from urllib.parse import urlencode, parse_qsl -def makeStringIO(strval): - """ - Helper method to make sure the StringIO being returned will work. - - Differences between Python 2.7/3.x mean we have a lot of cases to handle. - - TODO: skipped Python 2.x support. Is this still necessary? - """ - return StringIO(strval.decode()) - - class WFSCapabilitiesReader(object): """Read and parse capabilities document into a lxml.etree infoset """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/owslib/feature/schema.py new/OWSLib-0.20.0/owslib/feature/schema.py --- old/OWSLib-0.19.1/owslib/feature/schema.py 2020-01-31 17:12:37.000000000 +0100 +++ new/OWSLib-0.20.0/owslib/feature/schema.py 2020-04-23 13:17:57.000000000 +0200 @@ -84,7 +84,8 @@ :return dict: schema """ - + if elements is None: + return None schema = {"properties": {}, "required": [], "geometry": None} schema_key = None diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/owslib/feature/wfs100.py new/OWSLib-0.20.0/owslib/feature/wfs100.py --- old/OWSLib-0.19.1/owslib/feature/wfs100.py 2020-01-31 17:12:37.000000000 +0100 +++ new/OWSLib-0.20.0/owslib/feature/wfs100.py 2020-03-29 03:39:03.000000000 +0200 @@ -8,6 +8,7 @@ from owslib import util +from io import BytesIO from urllib.parse import urlencode from owslib.util import ( testXMLValue, @@ -27,7 +28,6 @@ from owslib.feature.common import ( WFSCapabilitiesReader, AbstractContentMetadata, - makeStringIO, ) import pyproj @@ -308,16 +308,16 @@ tree = etree.fromstring(data) except BaseException: # Not XML - return makeStringIO(data) + return BytesIO(data) else: if tree.tag == "{%s}ServiceExceptionReport" % OGC_NAMESPACE: se = tree.find(nspath("ServiceException", OGC_NAMESPACE)) raise ServiceException(str(se.text).strip()) else: - return makeStringIO(data) + return BytesIO(data) else: if have_read: - return makeStringIO(data) + return BytesIO(data) return u def getOperationByName(self, name): @@ -395,14 +395,16 @@ self.boundingBoxWGS84 = None if b is not None and srs is not None: - wgs84 = pyproj.Proj(init="epsg:4326") + wgs84 = pyproj.Proj("epsg:4326") try: - src_srs = pyproj.Proj(init=srs.text) + src_srs = pyproj.Proj(srs.text) mincorner = pyproj.transform( - src_srs, wgs84, b.attrib["minx"], b.attrib["miny"] + src_srs, wgs84, b.attrib["minx"], b.attrib["miny"], + always_xy=True, ) maxcorner = pyproj.transform( - src_srs, wgs84, b.attrib["maxx"], b.attrib["maxy"] + src_srs, wgs84, b.attrib["maxx"], b.attrib["maxy"], + always_xy=True, ) self.boundingBoxWGS84 = ( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/owslib/feature/wfs110.py new/OWSLib-0.20.0/owslib/feature/wfs110.py --- old/OWSLib-0.19.1/owslib/feature/wfs110.py 2020-01-31 17:12:37.000000000 +0100 +++ new/OWSLib-0.20.0/owslib/feature/wfs110.py 2020-04-23 13:17:57.000000000 +0200 @@ -7,6 +7,7 @@ # Contact email: [email protected] # ============================================================================= +from io import BytesIO from urllib.parse import urlencode from owslib.util import ( testXMLValue, @@ -33,7 +34,6 @@ from owslib.feature.common import ( WFSCapabilitiesReader, AbstractContentMetadata, - makeStringIO, ) from owslib.namespaces import Namespaces from owslib.util import log, openURL @@ -186,9 +186,10 @@ features = self._capabilities.findall( nspath_eval("wfs:FeatureTypeList/wfs:FeatureType", namespaces) ) - for feature in features: - cm = ContentMetadata(feature, parse_remote_metadata, headers=self.headers, auth=self.auth) - self.contents[cm.id] = cm + if features is not None: + for feature in features: + cm = ContentMetadata(feature, parse_remote_metadata, headers=self.headers, auth=self.auth) + self.contents[cm.id] = cm # exceptions self.exceptions = [ @@ -346,16 +347,16 @@ tree = etree.fromstring(data) except BaseException: # Not XML - return makeStringIO(data) + return BytesIO(data) else: if tree.tag == "{%s}ServiceExceptionReport" % namespaces["ogc"]: se = tree.find(nspath_eval("ServiceException", namespaces["ogc"])) raise ServiceException(str(se.text).strip()) else: - return makeStringIO(data) + return BytesIO(data) else: if have_read: - return makeStringIO(data) + return BytesIO(data) return u def getOperationByName(self, name): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/owslib/feature/wfs200.py new/OWSLib-0.20.0/owslib/feature/wfs200.py --- old/OWSLib-0.19.1/owslib/feature/wfs200.py 2020-01-31 17:12:37.000000000 +0100 +++ new/OWSLib-0.20.0/owslib/feature/wfs200.py 2020-04-23 13:17:57.000000000 +0200 @@ -18,11 +18,11 @@ from owslib.feature.common import ( WFSCapabilitiesReader, AbstractContentMetadata, - makeStringIO, ) from owslib.namespaces import Namespaces # other imports +from io import BytesIO from urllib.parse import urlencode import logging @@ -141,16 +141,17 @@ featuretypelistelem = self._capabilities.find( nspath("FeatureTypeList", ns=WFS_NAMESPACE) ) - featuretypeelems = featuretypelistelem.findall( - nspath("FeatureType", ns=WFS_NAMESPACE) - ) - if serviceidentelem is not None: - for f in featuretypeelems: - kwds = f.findall(nspath("Keywords/Keyword", ns=OWS_NAMESPACE)) - if kwds is not None: - for kwd in kwds[:]: - if kwd.text not in self.identification.keywords: - self.identification.keywords.append(kwd.text) + if featuretypelistelem is not None: + featuretypeelems = featuretypelistelem.findall( + nspath("FeatureType", ns=WFS_NAMESPACE) + ) + if serviceidentelem is not None: + for f in featuretypeelems: + kwds = f.findall(nspath("Keywords/Keyword", ns=OWS_NAMESPACE)) + if kwds is not None: + for kwd in kwds[:]: + if kwd.text not in self.identification.keywords: + self.identification.keywords.append(kwd.text) # TODO: update serviceProvider metadata, miss it out for now serviceproviderelem = self._capabilities.find(nspath("ServiceProvider")) @@ -313,16 +314,16 @@ tree = etree.fromstring(data) except BaseException: # Not XML - return makeStringIO(data) + return BytesIO(data) else: if tree.tag == "{%s}ServiceExceptionReport" % OGC_NAMESPACE: se = tree.find(nspath("ServiceException", OGC_NAMESPACE)) raise ServiceException(str(se.text).strip()) else: - return makeStringIO(data) + return BytesIO(data) else: if have_read: - return makeStringIO(data) + return BytesIO(data) return u def getpropertyvalue( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/owslib/fes.py new/OWSLib-0.20.0/owslib/fes.py --- old/OWSLib-0.19.1/owslib/fes.py 2020-01-31 17:12:37.000000000 +0100 +++ new/OWSLib-0.20.0/owslib/fes.py 2020-04-23 13:17:57.000000000 +0200 @@ -184,6 +184,15 @@ """ Abstraction for Filter_Capabilities """ def __init__(self, elem): # Spatial_Capabilities + + if elem is None: + self.spatial_operands = [] + self.spatial_operators = [] + self.temporal_operators = [] + self.temporal_operands = [] + self.scalar_comparison_operators = [] + return + self.spatial_operands = [f.text for f in elem.findall(util.nspath_eval( 'ogc:Spatial_Capabilities/ogc:GeometryOperands/ogc:GeometryOperand', namespaces))] self.spatial_operators = [] @@ -207,6 +216,16 @@ class FilterCapabilities200(object): """Abstraction for Filter_Capabilities 2.0""" def __init__(self, elem): + + if elem is None: + self.spatial_operands = [] + self.spatial_operators = [] + self.temporal_operators = [] + self.temporal_operands = [] + self.scalar_comparison_operators = [] + self.conformance = [] + return + # Spatial_Capabilities self.spatial_operands = [f.attrib.get('name') for f in elem.findall(util.nspath_eval( 'fes:Spatial_Capabilities/fes:GeometryOperands/fes:GeometryOperand', namespaces))] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/owslib/ogcapi/__init__.py new/OWSLib-0.20.0/owslib/ogcapi/__init__.py --- old/OWSLib-0.19.1/owslib/ogcapi/__init__.py 2020-01-31 17:12:37.000000000 +0100 +++ new/OWSLib-0.20.0/owslib/ogcapi/__init__.py 2020-06-05 13:39:21.000000000 +0200 @@ -8,11 +8,13 @@ import json import logging - from urllib.parse import urljoin +import requests +import yaml + from owslib import __version__ -from owslib.util import http_get +from owslib.util import Authentication, http_get LOGGER = logging.getLogger(__name__) @@ -22,14 +24,15 @@ class API(object): - """Abstraction for OGC API Common version 1.0""" + """Abstraction for OGC API - Common version 1.0""" - def __init__(self, url, json_=None, timeout=30, headers=None, auth=None): + def __init__(self, url: str, json_: str = None, timeout: int = 30, + headers: dict = None, auth: Authentication = None): """ Initializer; implements / @type url: string - @param url: url of WFS root document + @param url: url of OGC API landing page document @type json_: string @param json_: json object @param headers: HTTP headers to send with requests @@ -51,7 +54,7 @@ self.timeout = timeout self.headers = REQUEST_HEADERS if headers: - self.headers = self.headers.update(headers) + self.headers.update(headers) self.auth = auth if json_ is not None: # static JSON string @@ -60,7 +63,7 @@ response = http_get(url, headers=self.headers, auth=self.auth).json() self.links = response['links'] - def api(self): + def api(self) -> dict: """ implements /api @@ -68,47 +71,59 @@ """ url = None + openapi_format = None - for l in self.links: - if l['rel'] == 'service-desc': - url = l['href'] + openapi_json_mimetype = 'application/vnd.oai.openapi+json;version=3.0' + openapi_yaml_mimetype = 'application/vnd.oai.openapi;version=3.0' + + LOGGER.debug('Searching for OpenAPI JSON Document') + for link in self.links: + if link['rel'] == 'service-desc' and link['type'] == openapi_json_mimetype: + openapi_format = openapi_json_mimetype + url = link['href'] + break + + LOGGER.debug('Searching for OpenAPI YAML Document') + if url is None: + if link['rel'] == 'service-desc' and link['type'] == openapi_yaml_mimetype: + openapi_format = openapi_yaml_mimetype + url = link['href'] + break if url is not None: LOGGER.debug('Request: {}'.format(url)) - response = http_get(url, headers=REQUEST_HEADERS, auth=self.auth).json() - return response + response = http_get(url, headers=REQUEST_HEADERS, auth=self.auth) + if openapi_format == openapi_json_mimetype: + content = response.json() + elif openapi_format == openapi_yaml_mimetype: + content = yaml.load(response.text) + return content else: msg = 'Did not find service-desc link' LOGGER.error(msg) raise RuntimeError(msg) - def conformance(self): + def conformance(self) -> dict: """ implements /conformance @returns: `dict` of conformance object """ - url = self._build_url('conformance') - LOGGER.debug('Request: {}'.format(url)) - response = http_get(url, headers=self.headers, auth=self.auth).json() + path = 'conformance' + return self._request(path) - return response - - def collections(self): + def collections(self) -> dict: """ implements /collections @returns: `dict` of collections object """ - url = self._build_url('collections') - LOGGER.debug('Request: {}'.format(url)) - response = http_get(url, headers=self.headers, auth=self.auth).json() - - return response['collections'] + path = 'collections' + return self._request(path) - def collection(self, collection_id): + def collection(self, collection_id) -> dict: """ implements /collections/{collectionId} @@ -119,18 +134,27 @@ """ path = 'collections/{}'.format(collection_id) - url = self._build_url(path) - LOGGER.debug('Request: {}'.format(url)) - response = http_get(url, headers=self.headers, auth=self.auth).json() + return self._request(path) + + def collection_queryables(self, collection_id) -> dict: + """ + implements /collections/{collectionId}/queryables + + @type collection_id: string + @param collection_id: id of collection - return response + @returns: `dict` of feature collection queryables + """ + + path = 'collections/{}/queryables'.format(collection_id) + return self._request(path) - def _build_url(self, path=None): + def _build_url(self, path=None) -> str: """ helper function to build an OGC API URL @type path: string - @param path: path of WFS URL + @param path: path of OGC API URL @returns: fully constructed URL path """ @@ -146,3 +170,26 @@ LOGGER.debug('URL: {}'.format(url)) return url + + def _request(self, path=None, kwargs={}) -> dict: + """ + helper function for request/response patterns against OGC API endpoints + + @type path: string + @param path: path of request + @type kwargs: string + @param kwargs: ``dict`` of keyword value pair request parameters + + @returns: response as JSON ``dict`` + """ + + url = self._build_url(path) + + LOGGER.debug('Request: {}'.format(url)) + + response = http_get(url, headers=self.headers, auth=self.auth, + params=kwargs) + if response.status_code != requests.codes.ok: + raise RuntimeError(response.text) + + return response.json() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/owslib/ogcapi/features.py new/OWSLib-0.20.0/owslib/ogcapi/features.py --- old/OWSLib-0.19.1/owslib/ogcapi/features.py 2020-01-31 17:12:37.000000000 +0100 +++ new/OWSLib-0.20.0/owslib/ogcapi/features.py 2020-06-05 13:39:21.000000000 +0200 @@ -6,13 +6,10 @@ # Contact email: [email protected] # ============================================================================= -import json import logging -from urllib.parse import urljoin - -from owslib.ogcapi import API, REQUEST_HEADERS -from owslib.util import http_get +from owslib.ogcapi import API +from owslib.util import Authentication LOGGER = logging.getLogger(__name__) @@ -20,11 +17,12 @@ class Features(API): """Abstraction for OGC API - Features""" - def __init__(self, url, json_=None, timeout=30, headers=None, auth=None): + def __init__(self, url: str, json_: str = None, timeout: int = 30, + headers: dict = None, auth: Authentication = None): __doc__ = API.__doc__ # noqa super().__init__(url, json_, timeout, headers, auth) - def collection_items(self, collection_id, **kwargs): + def collection_items(self, collection_id: str, **kwargs: dict) -> dict: """ implements /collection/{collectionId}/items @@ -38,6 +36,8 @@ @param limit: limit number of features @type startindex: int @param startindex: start position of results + @type q: string + @param q: full text search @returns: feature results """ @@ -46,14 +46,9 @@ kwargs['bbox'] = ','.join(kwargs['bbox']) path = 'collections/{}/items'.format(collection_id) - url = self._build_url(path) - LOGGER.debug('Request: {}'.format(url)) - response = http_get( - url, headers=self.headers, params=kwargs, auth=self.auth - ).json() - return response + return self._request(path, kwargs) - def collection_item(self, collection_id, identifier): + def collection_item(self, collection_id: str, identifier: str) -> dict: """ implements /collections/{collectionId}/items/{featureId} @@ -66,7 +61,4 @@ """ path = 'collections/{}/items/{}'.format(collection_id, identifier) - url = self._build_url(path) - LOGGER.debug('Request: {}'.format(url)) - response = http_get(url, headers=self.headers, auth=self.auth).json() - return response + return self._request(path) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/owslib/ogcapi/records.py new/OWSLib-0.20.0/owslib/ogcapi/records.py --- old/OWSLib-0.19.1/owslib/ogcapi/records.py 1970-01-01 01:00:00.000000000 +0100 +++ new/OWSLib-0.20.0/owslib/ogcapi/records.py 2020-06-05 13:39:21.000000000 +0200 @@ -0,0 +1,23 @@ +# ============================================================================= +# Copyright (c) 2020 Tom Kralidis +# +# Author: Tom Kralidis <[email protected]> +# +# Contact email: [email protected] +# ============================================================================= + +import logging + +from owslib.ogcapi.features import Features +from owslib.util import Authentication + +LOGGER = logging.getLogger(__name__) + + +class Records(Features): + """Abstraction for OGC API - Records""" + + def __init__(self, url: str, json_: str = None, timeout: int = 30, + headers: dict = None, auth: Authentication = None): + __doc__ = Features.__doc__ # noqa + super().__init__(url, json_, timeout, headers, auth) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/owslib/ows.py new/OWSLib-0.20.0/owslib/ows.py --- old/OWSLib-0.19.1/owslib/ows.py 2020-01-31 17:12:37.000000000 +0100 +++ new/OWSLib-0.20.0/owslib/ows.py 2020-04-23 13:17:57.000000000 +0200 @@ -239,7 +239,10 @@ self.miny = None self.maxx = None self.maxy = None - + self.crs = None + self.dimensions = 2 + if elem is None: + return val = elem.attrib.get('crs') or elem.attrib.get('{{{}}}crs'.format(namespace)) if val: try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/owslib/util.py new/OWSLib-0.20.0/owslib/util.py --- old/OWSLib-0.19.1/owslib/util.py 2020-01-31 17:12:37.000000000 +0100 +++ new/OWSLib-0.20.0/owslib/util.py 2020-05-21 03:02:42.000000000 +0200 @@ -170,14 +170,13 @@ auth.password = password if cert: auth.cert = cert - if verify and not auth.verify: - auth.verify = verify + verify = verify and auth.verify else: auth = Authentication(username, password, cert, verify) if auth.username and auth.password: rkwargs['auth'] = (auth.username, auth.password) rkwargs['cert'] = auth.cert - rkwargs['verify'] = auth.verify + rkwargs['verify'] = verify # FIXUP for WFS in particular, remove xml style namespace # @TODO does this belong here? @@ -786,22 +785,43 @@ return datumOrigin + timedelta(ansi) -def param_list_to_url_string(self, param_list, param_name): - """Converts list of tuples for certain WCS GetCoverage keyword arguments (subsets, resolutions, sizes) to a url-enconded - string +def is_number(s): + """simple helper to test if value is number as requests with numbers don't + need quote marks + """ + try: + float(s) + return True + except ValueError: + return False + + +def makeString(value): + # using repr unconditionally breaks things in some circumstances if a + # value is already a string + if type(value) is not str: + sval = repr(value) + else: + sval = value + return sval + + +def param_list_to_url_string(param_list, param_name): + """Converts list of tuples for certain WCS GetCoverage keyword arguments + (subsets, resolutions, sizes) to a url-encoded string """ string = '' for param in param_list: if len(param) > 2: - if not self.is_number(param[1]): - string += "&" + urlencode({param_name: param[0] + '("' + self.__makeString(param[1]) + '","' + self.__makeString(param[2]) + '")'}) # noqa + if not is_number(param[1]): + string += "&" + urlencode({param_name: param[0] + '("' + makeString(param[1]) + '","' + makeString(param[2]) + '")'}) # noqa else: - string += "&" + urlencode({param_name: param[0] + "(" + self.__makeString(param[1]) + "," + self.__makeString(param[2]) + ")"}) # noqa + string += "&" + urlencode({param_name: param[0] + "(" + makeString(param[1]) + "," + makeString(param[2]) + ")"}) # noqa else: - if not self.is_number(param[1]): - string += "&" + urlencode({param_name: param[0] + '("' + self.__makeString(param[1]) + '")'}) + if not is_number(param[1]): + string += "&" + urlencode({param_name: param[0] + '("' + makeString(param[1]) + '")'}) # noqa else: - string += "&" + urlencode({param_name: param[0] + "(" + self.__makeString(param[1]) + ")"}) + string += "&" + urlencode({param_name: param[0] + "(" + makeString(param[1]) + ")"}) # noqa return string diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/owslib/wmts.py new/OWSLib-0.20.0/owslib/wmts.py --- old/OWSLib-0.19.1/owslib/wmts.py 2020-01-31 17:12:37.000000000 +0100 +++ new/OWSLib-0.20.0/owslib/wmts.py 2020-06-05 13:05:14.000000000 +0200 @@ -48,6 +48,7 @@ # Version 1.0.0, document 07-057r7 _ABSTRACT_TAG = _OWS_NS + 'Abstract' +_BOUNDING_BOX_TAG = _OWS_NS + 'BoundingBox' _IDENTIFIER_TAG = _OWS_NS + 'Identifier' _LOWER_CORNER_TAG = _OWS_NS + 'LowerCorner' _OPERATIONS_METADATA_TAG = _OWS_NS + 'OperationsMetadata' @@ -639,7 +640,7 @@ if tml.tilematrix in tilematrixlimits: msg = ('TileMatrixLimits with tileMatrix "%s" ' 'already exists' % tml.tilematrix) - raise KeyError(msg) + warnings.warn(msg, RuntimeWarning) tilematrixlimits[tml.tilematrix] = tml links.append(TileMatrixSetLink(uri, tilematrixlimits)) @@ -659,6 +660,31 @@ return fmt.format(self=self) +class BoundingBox(object): + """ + Represents a BoundingBox element + """ + + def __init__(self, elem) -> None: + if elem.tag != _BOUNDING_BOX_TAG: + raise ValueError('%s should be a BoundingBox' % elem) + + lc = elem.find(_LOWER_CORNER_TAG) + uc = elem.find(_UPPER_CORNER_TAG) + + self.ll = [float(s) for s in lc.text.split()] + self.ur = [float(s) for s in uc.text.split()] + + self.crs = elem.attrib.get('crs') + self.extent = (self.ll[0], self.ll[1], self.ur[0], self.ur[1]) + + def __repr__(self): + fmt = ('<BoundingBox' + ', crs={self.crs}' + ', extent={self.extent}>') + return fmt.format(self=self) + + class ContentMetadata: """ Abstraction for WMTS layer metadata. @@ -684,9 +710,16 @@ self.abstract = testXMLValue(elem.find(_ABSTRACT_TAG)) - # bboxes + # Bounding boxes + # There may be multiple, using different CRSes + self.boundingBox = [] + + bbs = elem.findall(_BOUNDING_BOX_TAG) + for b in bbs: + self.boundingBox.append(BoundingBox(b)) + + # WGS84 Bounding box b = elem.find(_WGS84_BOUNDING_BOX_TAG) - self.boundingBox = None if b is not None: lc = b.find(_LOWER_CORNER_TAG) uc = b.find(_UPPER_CORNER_TAG) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/owslib/wps.py new/OWSLib-0.20.0/owslib/wps.py --- old/OWSLib-0.19.1/owslib/wps.py 2020-01-31 17:12:37.000000000 +0100 +++ new/OWSLib-0.20.0/owslib/wps.py 2020-05-20 17:00:56.000000000 +0200 @@ -84,7 +84,7 @@ * python wps-pml-script-2.py The file wps-client.py contains a command-line client that can be used to submit a "GetCapabilities", -"DescribeProcess" or "Execute" request to an arbitratry WPS server. For example, you can run it as follows: +"DescribeProcess" or "Execute" request to an arbitrary WPS server. For example, you can run it as follows: * cd examples * To prints out usage and example invocations: wps-client -help @@ -224,7 +224,7 @@ """ def __init__(self, url, version=WPS_DEFAULT_VERSION, username=None, password=None, verbose=False, skip_caps=False, - headers=None, verify=None, cert=None, timeout=None, auth=None): + headers=None, verify=None, cert=None, timeout=None, auth=None, language=None): """ Initialization method resets the object status. By default it will execute a GetCapabilities invocation to the remote service, @@ -241,6 +241,7 @@ self.verbose = verbose self.headers = headers self.timeout = timeout + self.language = language # fields populated by method invocations self._capabilities = None @@ -248,6 +249,7 @@ self.provider = None self.operations = [] self.processes = [] + self.languages = None if not skip_caps: self.getcapabilities() @@ -260,7 +262,11 @@ # read capabilities document reader = WPSCapabilitiesReader( - version=self.version, verbose=self.verbose, auth=self.auth) + version=self.version, + verbose=self.verbose, + auth=self.auth, + language=self.language, + ) if xml: # read from stored XML file self._capabilities = reader.readFromString(xml) @@ -283,7 +289,11 @@ # read capabilities document reader = WPSDescribeProcessReader( - version=self.version, verbose=self.verbose, auth=self.auth) + version=self.version, + verbose=self.verbose, + auth=self.auth, + language=self.language, + ) if xml: # read from stored XML file rootElement = reader.readFromString(xml) @@ -333,7 +343,8 @@ verbose=self.verbose, headers=self.headers, timeout=self.timeout, - auth=self.auth + auth=self.auth, + language=self.language, ) # build XML request from parameters @@ -401,7 +412,7 @@ # loop over children WITHOUT requiring a specific namespace for element in root: - # thie element's namespace + # this element's namespace ns = getNamespace(element) # <ows:ServiceIdentification> metadata @@ -448,28 +459,46 @@ if self.verbose is True: dump(self.processes[-1]) + # <wps:Languages> + # <wps:Default> + # <ows:Language>en-US</ows:Language> + # </wps:Default> + # <wps:Supported> + # <ows:Language>en-US</ows:Language> + # <ows:Language>fr-CA</ows:Language> + # ...... + # </wps:Supported> + # </wps:Languages> + elif element.tag.endswith('Languages'): + self.languages = Languages(element) + if self.verbose: + dump(self.languages) + class WPSReader(object): """ Superclass for reading a WPS document into a lxml.etree infoset. """ - def __init__(self, version=WPS_DEFAULT_VERSION, verbose=False, timeout=30, auth=None): + def __init__(self, version=WPS_DEFAULT_VERSION, verbose=False, timeout=30, auth=None, language=None): self.version = version self.verbose = verbose self.timeout = timeout self.auth = auth or Authentication() + self.language = language def _readFromUrl(self, url, data, timeout, method='Get', username=None, password=None, headers=None, verify=True, cert=None): """ Method to get and parse a WPS document, returning an elementtree instance. :param str url: WPS service base url. - :param str data: GET: dictionary of HTTP (key, value) parameter pairs, POST: XML document to post + :param {} data: GET: dictionary of HTTP (key, value) parameter pairs, POST: XML document to post """ _fix_auth(self.auth, username, password, verify, cert) if method == 'Get': # full HTTP request url + if self.language: + data["language"] = self.language request_url = build_get_url(url, data, overwrite=True) log.debug(request_url) @@ -506,10 +535,10 @@ Utility class that reads and parses a WPS GetCapabilities document into a lxml.etree infoset. """ - def __init__(self, version=WPS_DEFAULT_VERSION, verbose=False, timeout=None, auth=None): + def __init__(self, version=WPS_DEFAULT_VERSION, verbose=False, timeout=None, auth=None, language=None): # superclass initializer super(WPSCapabilitiesReader, self).__init__( - version=version, verbose=verbose, timeout=timeout, auth=auth) + version=version, verbose=verbose, timeout=timeout, auth=auth, language=language) def readFromUrl(self, url, username=None, password=None, headers=None, verify=None, cert=None): @@ -532,10 +561,10 @@ Class that reads and parses a WPS DescribeProcess document into a etree infoset """ - def __init__(self, version=WPS_DEFAULT_VERSION, verbose=False, timeout=None, auth=None): + def __init__(self, version=WPS_DEFAULT_VERSION, verbose=False, timeout=None, auth=None, language=None): # superclass initializer super(WPSDescribeProcessReader, self).__init__( - version=version, verbose=verbose, timeout=timeout, auth=auth) + version=version, verbose=verbose, timeout=timeout, auth=auth, language=language) def readFromUrl(self, url, identifier, username=None, password=None, headers=None, verify=None, cert=None): @@ -559,9 +588,9 @@ Class that reads and parses a WPS Execute response document into a etree infoset """ - def __init__(self, verbose=False, timeout=None, auth=None): + def __init__(self, verbose=False, timeout=None, auth=None, language=None): # superclass initializer - super(WPSExecuteReader, self).__init__(verbose=verbose, timeout=timeout, auth=auth) + super(WPSExecuteReader, self).__init__(verbose=verbose, timeout=timeout, auth=auth, language=language) def readFromUrl(self, url, data={}, method='Get', username=None, password=None, headers=None, verify=None, cert=None): @@ -581,7 +610,7 @@ """ def __init__(self, version=WPS_DEFAULT_VERSION, url=None, username=None, password=None, verbose=False, - headers=None, verify=None, cert=None, timeout=None, auth=None): + headers=None, verify=None, cert=None, timeout=None, auth=None, language=None): # initialize fields self.url = url @@ -591,6 +620,7 @@ self.auth = auth or Authentication() _fix_auth(self.auth, username, password, verify, cert) self.timeout = timeout + self.language = language # request document self.request = None @@ -648,6 +678,8 @@ root = etree.Element(nspath_eval('wps:Execute', namespaces)) root.set('service', 'WPS') root.set('version', WPS_DEFAULT_VERSION) + if self.language: + root.set('language', self.language) root.set(nspath_eval('xsi:schemaLocation', namespaces), '%s %s' % (namespaces['wps'], WPS_DEFAULT_SCHEMA_LOCATION)) @@ -765,7 +797,7 @@ :param int sleepSecs: number of seconds to sleep before returning control to the caller. """ - reader = WPSExecuteReader(verbose=self.verbose, auth=self.auth) + reader = WPSExecuteReader(verbose=self.verbose, auth=self.auth, language=self.language) if response is None: # override status location if url is not None: @@ -819,46 +851,52 @@ def isNotComplete(self): return not self.isComplete() - def getOutput(self, filepath=None): + def getOutput(self, filepath=None, identifier=None): """ Method to write the outputs of a WPS process to a file: either retrieves the referenced files from the server, or writes out the content of response embedded output. :param filepath: optional path to the output file, otherwise a file will be created in the local directory with the name assigned by the server, or default name 'wps.out' for embedded output. + :param: identifier: optional identifier of the output that should be written. + For backward compatibility it will default to the first output. """ if self.isSucceded(): content = b'' - for output in self.processOutputs: - - output_content = output.retrieveData( - self.auth.username, self.auth.password, - headers=self.headers, verify=self.auth.verify, cert=self.auth.cert) - + output = None + if self.processOutputs: + if identifier: + # filter outputs by identifier + outputs = [o for o in self.processOutputs if o.identifier == identifier] + if outputs: + output = outputs[0] + else: + # take the first found output + output = self.processOutputs[0] + if output: # ExecuteResponse contains reference to server-side output - if output_content != b'': - content = content + output_content + if output.reference: + content = output.retrieveData( + self.auth.username, self.auth.password, + headers=self.headers, verify=self.auth.verify, cert=self.auth.cert) if filepath is None: filepath = output.fileName - # ExecuteResponse contain embedded output - if len(output.data) > 0: + elif len(output.data) > 0: if filepath is None: filepath = 'wps.out' for data in output.data: content = content + data.encode() - # write out content - if content != '': + if content != b'': out = open(filepath, 'wb') out.write(content) out.close() - log.info('Output written to file: %s' % filepath) - + log.info(f'Output written to file: {filepath}') else: raise Exception( - "Execution not successfully completed: status=%s" % self.status) + f"Execution not successfully completed: status={self.status}") def submitRequest(self, request): """ @@ -1385,19 +1423,28 @@ # a) 'http://cida.usgs.gov/climate/gdp/process/RetrieveResultServlet?id=1318528582026OUTPUT.601bb3d0-547f-4eab-8642-7c7d2834459e' # noqa # b) 'http://rsg.pml.ac.uk/wps/wpsoutputs/outputImage-11294Bd6l2a.tif' log.info('Output URL=%s' % url) + + # Extract output filepath from base URL + self.fileName = url.split('/')[-1] + + # The link is a local file. + # Useful when running local tests during development. + if url.startswith("file://"): + with open(url[7:]) as f: + return f.read() + if '?' in url: spliturl = url.split('?') + # Extract output filepath from URL query string + self.fileName = spliturl[1].split('=')[1] + u = openURL(spliturl[0], spliturl[ 1], method='Get', username=username, password=password, headers=headers, verify=verify, cert=cert) - # extract output filepath from URL query string - self.fileName = spliturl[1].split('=')[1] else: u = openURL( url, '', method='Get', username=username, password=password, headers=headers, verify=verify, cert=cert) - # extract output filepath from base URL - self.fileName = url.split('/')[-1] return u.read() @@ -1407,7 +1454,7 @@ Method to write an output of a WPS process to disk: it either retrieves the referenced file from the server, or write out the content of response embedded output. - :param filepath: optional path to the output file, otherwise a file will be created in the local directory + :param path: optional path to the output file, otherwise a file will be created in the local directory with the name assigned by the server, :param username: credentials to access the remote WPS server :param password: credentials to access the remote WPS server @@ -1914,3 +1961,21 @@ indent, value.reference, value.mimeType))) for datum in value.data: print(('{} Data Value: {}'.format(indent, printValue(datum)))) + + +class Languages(object): + """Initialize a WPS Languages construct""" + def __init__(self, infoset): + self._root = infoset + self.default = None + self.supported = [] + + for element in self._root: + if element.tag.endswith('Default'): + self.default = testXMLValue(element[0]) + elif element.tag.endswith('Supported'): + for child in element: + self.supported.append(testXMLValue(child)) + + def __repr__(self): + return "<owslib.wps.Languages default='{}' supported={}>".format(self.default, self.supported) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/requirements-dev.txt new/OWSLib-0.20.0/requirements-dev.txt --- old/OWSLib-0.19.1/requirements-dev.txt 2020-01-31 17:12:37.000000000 +0100 +++ new/OWSLib-0.20.0/requirements-dev.txt 2020-06-05 14:34:55.000000000 +0200 @@ -3,8 +3,7 @@ pytest>=3.6 pytest-cov Pillow +sphinx tox -# install libraries to stop SSL related InsecurePlatformWarning -pyopenssl ; python_version < '2.7.9' -ndg-httpsclient ; python_version < '2.7.9' -pyasn1 ; python_version < '2.7.9' +twine +wheel diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/requirements.txt new/OWSLib-0.20.0/requirements.txt --- old/OWSLib-0.19.1/requirements.txt 2020-01-31 17:12:37.000000000 +0100 +++ new/OWSLib-0.20.0/requirements.txt 2020-03-29 03:39:03.000000000 +0200 @@ -1,4 +1,5 @@ python-dateutil>=1.5 pytz requests>=1.0 -pyproj +pyproj >=2 +pyyaml diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OWSLib-0.19.1/setup.py new/OWSLib-0.20.0/setup.py --- old/OWSLib-0.19.1/setup.py 2020-01-31 17:12:37.000000000 +0100 +++ new/OWSLib-0.20.0/setup.py 2020-03-29 03:39:03.000000000 +0200 @@ -28,7 +28,7 @@ maintainer_email = '[email protected]', url = 'https://geopython.github.io/OWSLib', install_requires = reqs, - python_requires = '>=3.5', + python_requires = '>=3.6', cmdclass = {'test': PyTest}, packages = find_packages(exclude=["docs", "etc", "examples", "tests"]), classifiers = [ _______________________________________________ openSUSE Commits mailing list -- [email protected] To unsubscribe, email [email protected] List Netiquette: https://en.opensuse.org/openSUSE:Mailing_list_netiquette List Archives: https://lists.opensuse.org/archives/list/[email protected]
