Skip to content

Commit

Permalink
Merge branch 'master' into getcapabilities-errors
Browse files Browse the repository at this point in the history
  • Loading branch information
geographika authored Oct 19, 2024
2 parents 58f7a29 + a713c62 commit 48da7a9
Show file tree
Hide file tree
Showing 13 changed files with 767 additions and 91 deletions.
2 changes: 1 addition & 1 deletion etc/RPM/python-owslib.spec
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ BuildRequires: python-devel
BuildRequires: python-setuptools
BuildRequires: fdupes
Requires: python
Requires: python-dateutil python-pytz
Requires: python-dateutil

%description
OWSLib is a Python package for client programming with Open Geospatial Consortium (OGC) web service (hence OWS) interface standards, and their related content models.
Expand Down
17 changes: 12 additions & 5 deletions owslib/feature/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from urllib.parse import urlencode
from owslib.crs import Crs
from owslib.util import Authentication
from owslib.util import Authentication, build_get_url
from owslib.feature.schema import get_schema
from owslib.feature.postrequest import PostRequest_1_1_0, PostRequest_2_0_0

Expand Down Expand Up @@ -160,6 +160,7 @@ def getGETGetFeatureRequest(
featureversion=None,
propertyname=None,
maxfeatures=None,
srsname=None,
storedQueryID=None,
storedQueryParams=None,
outputFormat=None,
Expand All @@ -183,6 +184,8 @@ def getGETGetFeatureRequest(
List of feature property names. '*' matches all.
maxfeatures : int
Maximum number of features to be returned.
srsname: string
EPSG code to request the data in
method : string
Qualified name of the HTTP DCP method to use.
outputFormat: string (optional)
Expand All @@ -209,7 +212,6 @@ def getGETGetFeatureRequest(
if m.get("type").lower() == method.lower()
)
)
base_url = base_url if base_url.endswith("?") else base_url + "?"

request = {"service": "WFS", "version": self.version, "request": "GetFeature"}

Expand Down Expand Up @@ -239,6 +241,13 @@ def getGETGetFeatureRequest(
request["count"] = str(maxfeatures)
else:
request["maxfeatures"] = str(maxfeatures)
if srsname:
request["srsname"] = str(srsname)

# Check if desired SRS is supported by the service for each
# typename. Warning will be thrown if that SRS is not allowed.
for name in typename:
_ = self.getSRS(srsname, name)
if startindex:
request["startindex"] = str(startindex)
if storedQueryID:
Expand All @@ -248,9 +257,7 @@ def getGETGetFeatureRequest(
if outputFormat is not None:
request["outputFormat"] = outputFormat

data = urlencode(request, doseq=True)

return base_url + data
return build_get_url(base_url, request)

def getPOSTGetFeatureRequest(
self,
Expand Down
4 changes: 4 additions & 0 deletions owslib/feature/wfs200.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ def getfeature(
featureversion=None,
propertyname=None,
maxfeatures=None,
srsname=None,
storedQueryID=None,
storedQueryParams=None,
method="Get",
Expand Down Expand Up @@ -254,6 +255,8 @@ def getfeature(
For Post request, leave blank (None) to get all properties.
maxfeatures : int
Maximum number of features to be returned.
srsname: string
EPSG code to request the data in
storedQueryID : string
A name identifying a prepared set available in WFS-service
storedQueryParams : dict
Expand Down Expand Up @@ -298,6 +301,7 @@ def getfeature(
featureversion,
propertyname,
maxfeatures,
srsname,
storedQueryID,
storedQueryParams,
outputFormat,
Expand Down
31 changes: 28 additions & 3 deletions owslib/iso.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,23 +407,48 @@ def __init__(self, md=None, identtype=None):

self.uricode = []
_values = md.findall(util.nspath_eval(
'gmd:citation/gmd:CI_Citation/gmd:identifier/gmd:MD_Identifier/gmd:code/gco:CharacterString',
namespaces))
_values += md.findall(util.nspath_eval(
'gmd:citation/gmd:CI_Citation/gmd:identifier/gmd:RS_Identifier/gmd:code/gco:CharacterString',
namespaces))
for i in _values:
val = util.testXMLValue(i)
if val not in [None,'']:
self.uricode.append(val)

_values = md.findall(util.nspath_eval(
'gmd:citation/gmd:CI_Citation/gmd:identifier/gmd:MD_Identifier/gmd:code/gmx:Anchor',
namespaces))
_values += md.findall(util.nspath_eval(
'gmd:citation/gmd:CI_Citation/gmd:identifier/gmd:MD_Identifier/gmd:code/gco:CharacterString',
'gmd:citation/gmd:CI_Citation/gmd:identifier/gmd:RS_Identifier/gmd:code/gmx:Anchor',
namespaces))
for i in _values:
val = util.testXMLValue(i)
if val is not None:
val1 = i.attrib.get(util.nspath_eval('xlink:href', namespaces))
if val1 not in [None,'']:
self.uricode.append(val1)
elif val not in [None,'']:
self.uricode.append(val)


self.uricodespace = []
for i in md.findall(util.nspath_eval(
'gmd:citation/gmd:CI_Citation/gmd:identifier/gmd:RS_Identifier/gmd:codeSpace/gco:CharacterString',
namespaces)):
val = util.testXMLValue(i)
if val is not None:
if val not in [None,'']:
self.uricodespace.append(val)
for i in md.findall(util.nspath_eval(
'gmd:citation/gmd:CI_Citation/gmd:identifier/gmd:RS_Identifier/gmd:codeSpace/gmx:Anchor',
namespaces)):
val = util.testXMLValue(i)
val1 = i.attrib.get(util.nspath_eval('xlink:href', namespaces))
if val1 not in [None,'']:
self.uricode.append(val1)
elif val not in [None,'']:
self.uricode.append(val)


self.date = []
self.datetype = []
Expand Down
10 changes: 4 additions & 6 deletions owslib/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
import sys
from collections import OrderedDict
from dateutil import parser
from datetime import datetime, timedelta
import pytz
from datetime import datetime, timedelta, timezone
from owslib.etree import etree, ParseError
from owslib.namespaces import Namespaces
from urllib.parse import urlsplit, urlencode, urlparse, parse_qs, urlunparse, parse_qsl
Expand Down Expand Up @@ -600,7 +599,7 @@ def getNamespace(element):
return ""


def build_get_url(base_url, params, overwrite=False):
def build_get_url(base_url, params, overwrite=False, doseq=False):
''' Utility function to build a full HTTP GET URL from the service base URL and a dictionary of HTTP parameters.
TODO: handle parameters case-insensitive?
Expand Down Expand Up @@ -632,7 +631,7 @@ def build_get_url(base_url, params, overwrite=False):
if key not in pars:
qs.append((key, value))

urlqs = urlencode(tuple(qs))
urlqs = urlencode(tuple(qs), doseq=doseq)
return base_url.split('?')[0] + '?' + urlqs


Expand Down Expand Up @@ -682,8 +681,7 @@ def extract_time(element):
except Exception:
att = testXMLValue(element.attrib.get('indeterminatePosition'), True)
if att and att == 'now':
dt = datetime.utcnow()
dt.replace(tzinfo=pytz.utc)
dt = datetime.utcnow().replace(tzinfo=timezone.utc)
else:
dt = None
return dt
Expand Down
26 changes: 15 additions & 11 deletions owslib/wmts.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,9 @@ def gather_layers(parent_elem, parent_metadata):
parse_remote_metadata=parse_remote_metadata)
if cm.id:
if cm.id in self.contents:
raise KeyError('Content metadata for layer "%s" '
'already exists' % cm.id)
msg = ('Content metadata for layer "%s" '
'already exists' % cm.id)
warnings.warn(msg, RuntimeWarning)
self.contents[cm.id] = cm
gather_layers(elem, cm)
gather_layers(caps, None)
Expand All @@ -252,17 +253,19 @@ def gather_layers(parent_elem, parent_metadata):
tms = TileMatrixSet(elem)
if tms.identifier:
if tms.identifier in self.tilematrixsets:
raise KeyError('TileMatrixSet with identifier "%s" '
'already exists' % tms.identifier)
msg = ('TileMatrixSet with identifier "%s" '
'already exists' % tms.identifier)
warnings.warn(msg, RuntimeWarning)
self.tilematrixsets[tms.identifier] = tms

self.themes = {}
for elem in self._capabilities.findall(_THEMES_TAG + '/' + _THEME_TAG):
theme = Theme(elem)
if theme.identifier:
if theme.identifier in self.themes:
raise KeyError('Theme with identifier "%s" already exists'
% theme.identifier)
msg = ('Theme with identifier "%s" already exists'
% theme.identifier)
warnings.warn(msg, RuntimeWarning)
self.themes[theme.identifier] = theme

serviceMetadataURL = self._capabilities.find(_SERVICE_METADATA_URL_TAG)
Expand Down Expand Up @@ -519,8 +522,9 @@ def __init__(self, elem):
tm = TileMatrix(tilematrix)
if tm.identifier:
if tm.identifier in self.tilematrix:
raise KeyError('TileMatrix with identifier "%s" '
'already exists' % tm.identifier)
msg = ('TileMatrix with identifier "%s" '
'already exists' % tm.identifier)
warnings.warn(msg, RuntimeWarning)
self.tilematrix[tm.identifier] = tm


Expand Down Expand Up @@ -748,9 +752,9 @@ def __init__(self, elem, parent=None, index=0, parse_remote_metadata=False):
for tmsl in tile_matrix_set_links:
if tmsl.tilematrixset:
if tmsl.tilematrixset in self.tilematrixsetlinks:
raise KeyError('TileMatrixSetLink with tilematrixset "%s"'
' already exists' %
tmsl.tilematrixset)
msg = ('TileMatrixSetLink with tilematrixset "%s"'
' already exists' % tmsl.tilematrixset)
warnings.warn(msg, RuntimeWarning)
self.tilematrixsetlinks[tmsl.tilematrixset] = tmsl

self.resourceURLs = []
Expand Down
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
lxml
python-dateutil
pytz
pyyaml
requests
1 change: 0 additions & 1 deletion tests/doctests/sml_52n_network.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ Imports
>>> from tests.utils import resource_file
>>> from owslib.swe.sensor.sml import SensorML
>>> from dateutil import parser
>>> import pytz

Initialize

Expand Down
4 changes: 2 additions & 2 deletions tests/doctests/sml_ndbc_station.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Imports
>>> from tests.utils import resource_file
>>> from owslib.swe.sensor.sml import SensorML
>>> from dateutil import parser
>>> import pytz
>>> from datetime import timezone

Initialize

Expand Down Expand Up @@ -104,7 +104,7 @@ History
2

>>> event = his[0]
>>> parser.parse(event.date).replace(tzinfo=pytz.utc).isoformat()
>>> parser.parse(event.date).replace(tzinfo=timezone.utc).isoformat()
'2010-01-12T00:00:00+00:00'
>>> event.description
'Deployment start event'
Expand Down
Loading

0 comments on commit 48da7a9

Please sign in to comment.