Skip to content
Commits on Source (5)
language: python language: python
python: python:
- "2.7" - "2.7"
- "3.4" - "3.5"
- "3.6" - "3.6"
# - "pypy" # Enable 3.7 without globally enabling sudo and dist: xenial for other build jobs
matrix:
include:
- python: 3.7
dist: xenial
sudo: true
env: LMXL=true
- python: 3.7
dist: xenial
sudo: true
env: LMXL=false
sudo: false sudo: false
env: env:
- LXML=true - LXML=true
......
owslib (0.18.0-1~exp1) experimental; urgency=medium
* Team upload.
* New upstream release.
* Add upstream metadata.
-- Bas Couwenberg <sebastic@debian.org> Tue, 25 Jun 2019 05:48:02 +0200
owslib (0.17.1-1) unstable; urgency=medium owslib (0.17.1-1) unstable; urgency=medium
* Team upload. * Team upload.
......
---
Bug-Database: https://github.com/geopython/OWSLib/issues
Bug-Submit: https://github.com/geopython/OWSLib/issues/new
Name: OWSLib
Repository: https://github.com/geopython/OWSLib.git
Repository-Browse: https://github.com/geopython/OWSLib
...@@ -294,13 +294,14 @@ WFS 3.0 is a clean break from the traditional OGC service architecture ...@@ -294,13 +294,14 @@ WFS 3.0 is a clean break from the traditional OGC service architecture
.. code-block:: python .. code-block:: python
>>> from owslib.wfs import WebFeatureService >>> from owslib.wfs import WebFeatureService
>>> w = WebFeatureService('https://geo.kralidis.ca/pygeoapi, version='3.0') >>> w = WebFeatureService('https://geo.kralidis.ca/pygeoapi', version='3.0')
>>> w.url >>> w.url
'http://geo.kralidis.ca/pygeoapi/' 'http://geo.kralidis.ca/pygeoapi/'
>>> w.version >>> w.version
'3.0' '3.0'
>>> conformance = w.conformance() >>> conformance = w.conformance()
{u'conformsTo': [u'http://www.opengis.net/spec/wfs-1/3.0/req/core', u'http://www.opengis.net/spec/wfs-1/3.0/req/oas30', u'http://www.opengis.net/spec/wfs-1/3.0/req/html', u'http://www.opengis.net/spec/wfs-1/3.0/req/geojson']} {u'conformsTo': [u'http://www.opengis.net/spec/wfs-1/3.0/req/core', u'http://www.opengis.net/spec/wfs-1/3.0/req/oas30', u'http://www.opengis.net/spec/wfs-1/3.0/req/html', u'http://www.opengis.net/spec/wfs-1/3.0/req/geojson']}
>>> api = w.api() # OpenAPI definition
>>> collections = w.collections() >>> collections = w.collections()
>>> len(collections) >>> len(collections)
3 3
...@@ -575,7 +576,7 @@ The OWSLib wiki is located at https://github.com/geopython/OWSLib/wiki ...@@ -575,7 +576,7 @@ The OWSLib wiki is located at https://github.com/geopython/OWSLib/wiki
The OWSLib source code is available at https://github.com/geopython/OWSLib The OWSLib source code is available at https://github.com/geopython/OWSLib
You can find out about software metrics at the OWSLib ohloh page at http://www.ohloh.net/p/OWSLib. You can find out about software metrics at the OWSLib OpenHub page at https://www.openhub.net/p/OWSLib.
Testing Testing
------- -------
...@@ -604,7 +605,7 @@ Support ...@@ -604,7 +605,7 @@ Support
Mailing Lists Mailing Lists
------------- -------------
OWSLib provides users and developers mailing lists. Subscription options and archives are available at http://lists.osgeo.org/mailman/listinfo/owslib-users and http://lists.osgeo.org/mailman/listinfo/owslib-devel. OWSLib provides users and developers mailing lists. Subscription options and archives are available at https://lists.osgeo.org/mailman/listinfo/owslib-users and https://lists.osgeo.org/mailman/listinfo/owslib-devel.
Submitting Questions to Community Submitting Questions to Community
--------------------------------- ---------------------------------
...@@ -614,12 +615,12 @@ To submit questions to a mailing list, first join the list by following the subs ...@@ -614,12 +615,12 @@ To submit questions to a mailing list, first join the list by following the subs
Searching the Archives Searching the Archives
---------------------- ----------------------
All Community archives are located in http://lists.osgeo.org/pipermail/owslib-users/ http://lists.osgeo.org/pipermail/owslib-devel/ All Community archives are located in https://lists.osgeo.org/pipermail/owslib-users/ https://lists.osgeo.org/pipermail/owslib-devel/
Metrics Metrics
------- -------
You can find out about software metrics at the OWSLib `ohloh`_ page. You can find out about software metrics at the OWSLib `OpenHub`_ page.
IRC IRC
--- ---
...@@ -676,28 +677,28 @@ Credits ...@@ -676,28 +677,28 @@ Credits
.. include:: ../../AUTHORS.rst .. include:: ../../AUTHORS.rst
.. _`Open Geospatial Consortium`: http://www.opengeospatial.org/ .. _`Open Geospatial Consortium`: https://www.opengeospatial.org/
.. _`OGC WMS`: http://www.opengeospatial.org/standards/wms .. _`OGC WMS`: https://www.opengeospatial.org/standards/wms
.. _`OGC WFS`: http://www.opengeospatial.org/standards/wfs .. _`OGC WFS`: https://www.opengeospatial.org/standards/wfs
.. _`OGC WCS`: http://www.opengeospatial.org/standards/wcs .. _`OGC WCS`: https://www.opengeospatial.org/standards/wcs
.. _`OGC WMC`: http://www.opengeospatial.org/standards/wmc .. _`OGC WMC`: https://www.opengeospatial.org/standards/wmc
.. _`OGC WPS`: http://www.opengeospatial.org/standards/wps .. _`OGC WPS`: https://www.opengeospatial.org/standards/wps
.. _`OGC SOS`: http://www.opengeospatial.org/standards/sos .. _`OGC SOS`: https://www.opengeospatial.org/standards/sos
.. _`OGC O&M`: http://www.opengeospatial.org/standards/om .. _`OGC O&M`: https://www.opengeospatial.org/standards/om
.. _`OGC WaterML2.0`: http://www.opengeospatial.org/standards/waterml .. _`OGC WaterML2.0`: https://www.opengeospatial.org/standards/waterml
.. _`OGC SensorML`: http://www.opengeospatial.org/standards/sensorml .. _`OGC SensorML`: https://www.opengeospatial.org/standards/sensorml
.. _`OGC CSW`: http://www.opengeospatial.org/standards/cat .. _`OGC CSW`: https://www.opengeospatial.org/standards/cat
.. _`OGC WMTS`: http://www.opengeospatial.org/standards/wmts .. _`OGC WMTS`: https://www.opengeospatial.org/standards/wmts
.. _`OGC Filter`: http://www.opengeospatial.org/standards/filter .. _`OGC Filter`: https://www.opengeospatial.org/standards/filter
.. _`OGC OWS Common`: http://www.opengeospatial.org/standards/common .. _`OGC OWS Common`: https://www.opengeospatial.org/standards/common
.. _`OGC OWS Context`: http://www.opengeospatial.org/standards/owc .. _`OGC OWS Context`: https://www.opengeospatial.org/standards/owc
.. _`NASA DIF`: http://gcmd.nasa.gov/User/difguide/ .. _`NASA DIF`: https://earthdata.nasa.gov/esdis/eso/standards-and-references/directory-interchange-format-dif-standard
.. _`FGDC CSDGM`: http://www.fgdc.gov/metadata/csdgm .. _`FGDC CSDGM`: https://www.fgdc.gov/metadata/csdgm-standard
.. _`ISO 19115`: http://www.iso.org/iso/catalogue_detail.htm?csnumber=26020 .. _`ISO 19115`: https://www.iso.org/standard/26020.html
.. _`ISO 19139`: http://www.iso.org/iso/catalogue_detail.htm?csnumber=32557 .. _`ISO 19139`: https://www.iso.org/standard/32557.html
.. _`Dublin Core`: http://www.dublincore.org/ .. _`Dublin Core`: https://www.dublincore.org/
.. _`freenode`: http://freenode.net/ .. _`freenode`: https://freenode.net/
.. _`ohloh`: http://www.ohloh.net/p/OWSLib .. _`OpenHub`: https://www.openhub.net/p/OWSLib
.. _`CIA.vc`: http://cia.vc/stats/project/OWSLib .. _`CIA.vc`: http://cia.vc/stats/project/OWSLib
.. _`WaterML`: http://his.cuahsi.org/wofws.html#waterml .. _`WaterML`: http://his.cuahsi.org/wofws.html#waterml
.. _`Swiss GM03`: http://www.geocat.ch/internet/geocat/en/home/documentation/gm03.html .. _`Swiss GM03`: https://www.geocat.admin.ch/en/dokumentation/gm03.html
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__version__ = '0.17.1' __version__ = '0.18.0'
...@@ -32,6 +32,7 @@ class WebCoverageService_1_0_0(WCSBase): ...@@ -32,6 +32,7 @@ class WebCoverageService_1_0_0(WCSBase):
"""Abstraction for OGC Web Coverage Service (WCS), version 1.0.0 """Abstraction for OGC Web Coverage Service (WCS), version 1.0.0
Implements IWebCoverageService. Implements IWebCoverageService.
""" """
def __getitem__(self,name): def __getitem__(self,name):
''' check contents dictionary to allow dict like access to service layers''' ''' check contents dictionary to allow dict like access to service layers'''
if name in self.__getattribute__('contents').keys(): if name in self.__getattribute__('contents').keys():
...@@ -39,12 +40,13 @@ class WebCoverageService_1_0_0(WCSBase): ...@@ -39,12 +40,13 @@ class WebCoverageService_1_0_0(WCSBase):
else: else:
raise KeyError("No content named %s" % name) raise KeyError("No content named %s" % name)
def __init__(self,url,xml, cookies): def __init__(self,url,xml, cookies, auth=None):
super(WebCoverageService_1_0_0, self).__init__(auth)
self.version='1.0.0' self.version='1.0.0'
self.url = url self.url = url
self.cookies=cookies self.cookies=cookies
# initialize from saved capability document or access the server # initialize from saved capability document or access the server
reader = WCSCapabilitiesReader(self.version, self.cookies) reader = WCSCapabilitiesReader(self.version, self.cookies, self.auth)
if xml: if xml:
self._capabilities = reader.readString(xml) self._capabilities = reader.readString(xml)
else: else:
...@@ -88,7 +90,6 @@ class WebCoverageService_1_0_0(WCSBase): ...@@ -88,7 +90,6 @@ class WebCoverageService_1_0_0(WCSBase):
self.exceptions = [f.text for f \ self.exceptions = [f.text for f \
in self._capabilities.findall('Capability/Exception/Format')] in self._capabilities.findall('Capability/Exception/Format')]
def items(self): def items(self):
'''supports dict-like items() access''' '''supports dict-like items() access'''
items=[] items=[]
...@@ -161,13 +162,9 @@ class WebCoverageService_1_0_0(WCSBase): ...@@ -161,13 +162,9 @@ class WebCoverageService_1_0_0(WCSBase):
if log.isEnabledFor(logging.DEBUG): if log.isEnabledFor(logging.DEBUG):
log.debug('WCS 1.0.0 DEBUG: Second part of URL: %s'%data) log.debug('WCS 1.0.0 DEBUG: Second part of URL: %s'%data)
u = openURL(base_url, data, method, self.cookies, auth=self.auth)
u=openURL(base_url, data, method, self.cookies)
return u return u
def getOperationByName(self, name): def getOperationByName(self, name):
"""Return a named operation item.""" """Return a named operation item."""
for item in self.operations: for item in self.operations:
......
...@@ -54,12 +54,13 @@ class WebCoverageService_1_1_0(WCSBase): ...@@ -54,12 +54,13 @@ class WebCoverageService_1_1_0(WCSBase):
else: else:
raise KeyError("No content named %s" % name) raise KeyError("No content named %s" % name)
def __init__(self,url,xml, cookies): def __init__(self,url,xml, cookies, auth=None):
super(WebCoverageService_1_1_0, self).__init__(auth=auth)
self.url = url self.url = url
self.cookies=cookies self.cookies=cookies
# initialize from saved capability document or access the server # initialize from saved capability document or access the server
reader = WCSCapabilitiesReader(self.version) reader = WCSCapabilitiesReader(self.version, self.cookies, self.auth)
if xml: if xml:
self._capabilities = reader.readString(xml) self._capabilities = reader.readString(xml)
else: else:
...@@ -200,7 +201,7 @@ class WebCoverageService_1_1_0(WCSBase): ...@@ -200,7 +201,7 @@ class WebCoverageService_1_1_0(WCSBase):
#encode and request #encode and request
data = urlencode(request) data = urlencode(request)
u=openURL(base_url, data, method, self.cookies) u = openURL(base_url, data, method, self.cookies, auth=self.auth)
return u return u
......
...@@ -48,13 +48,14 @@ class WebCoverageService_2_0_0(WCSBase): ...@@ -48,13 +48,14 @@ class WebCoverageService_2_0_0(WCSBase):
else: else:
raise KeyError("No content named %s" % name) raise KeyError("No content named %s" % name)
def __init__(self,url,xml, cookies): def __init__(self,url,xml, cookies, auth=None):
super(WebCoverageService_2_0_0, self).__init__(auth=auth)
self.version='2.0.0' self.version='2.0.0'
self.url = url self.url = url
self.cookies=cookies self.cookies=cookies
self.ows_common = OwsCommon(version='2.0.0') self.ows_common = OwsCommon(version='2.0.0')
# initialize from saved capability document or access the server # initialize from saved capability document or access the server
reader = WCSCapabilitiesReader(self.version, self.cookies) reader = WCSCapabilitiesReader(self.version, self.cookies, self.auth)
if xml: if xml:
self._capabilities = reader.readString(xml) self._capabilities = reader.readString(xml)
else: else:
...@@ -175,8 +176,7 @@ class WebCoverageService_2_0_0(WCSBase): ...@@ -175,8 +176,7 @@ class WebCoverageService_2_0_0(WCSBase):
if log.isEnabledFor(logging.DEBUG): if log.isEnabledFor(logging.DEBUG):
log.debug('WCS 2.0.0 DEBUG: Second part of URL: %s'%data) log.debug('WCS 2.0.0 DEBUG: Second part of URL: %s'%data)
u=openURL(base_url, data, method, self.cookies) u = openURL(base_url, data, method, self.cookies, auth=self.auth)
return u return u
def is_number(self,s): def is_number(self,s):
......
...@@ -48,13 +48,14 @@ class WebCoverageService_2_0_1(WCSBase): ...@@ -48,13 +48,14 @@ class WebCoverageService_2_0_1(WCSBase):
else: else:
raise KeyError("No content named %s" % name) raise KeyError("No content named %s" % name)
def __init__(self,url,xml, cookies): def __init__(self,url,xml, cookies, auth=None):
super(WebCoverageService_2_0_1, self).__init__(auth=auth)
self.version='2.0.1' self.version='2.0.1'
self.url = url self.url = url
self.cookies=cookies self.cookies=cookies
self.ows_common = OwsCommon(version='2.0.1') self.ows_common = OwsCommon(version='2.0.1')
# initialize from saved capability document or access the server # initialize from saved capability document or access the server
reader = WCSCapabilitiesReader(self.version, self.cookies) reader = WCSCapabilitiesReader(self.version, self.cookies, self.auth)
if xml: if xml:
self._capabilities = reader.readString(xml) self._capabilities = reader.readString(xml)
else: else:
...@@ -175,8 +176,7 @@ class WebCoverageService_2_0_1(WCSBase): ...@@ -175,8 +176,7 @@ class WebCoverageService_2_0_1(WCSBase):
if log.isEnabledFor(logging.DEBUG): if log.isEnabledFor(logging.DEBUG):
log.debug('WCS 2.0.1 DEBUG: Second part of URL: %s'%data) log.debug('WCS 2.0.1 DEBUG: Second part of URL: %s'%data)
u=openURL(base_url, data, method, self.cookies) u = openURL(base_url, data, method, self.cookies, auth=self.auth)
return u return u
def is_number(self,s): def is_number(self,s):
......
...@@ -19,7 +19,7 @@ from owslib.etree import etree ...@@ -19,7 +19,7 @@ from owslib.etree import etree
import cgi import cgi
from six.moves import cStringIO as StringIO from six.moves import cStringIO as StringIO
import six import six
from owslib.util import openURL from owslib.util import Authentication, openURL
class ServiceException(Exception): class ServiceException(Exception):
...@@ -39,28 +39,30 @@ class ServiceException(Exception): ...@@ -39,28 +39,30 @@ class ServiceException(Exception):
class WCSBase(object): class WCSBase(object):
"""Base class to be subclassed by version dependent WCS classes. Provides 'high-level' version independent methods""" """Base class to be subclassed by version dependent WCS classes. Provides 'high-level' version independent methods"""
def __new__(self,url, xml, cookies): def __new__(self,url, xml, cookies, auth=None):
""" overridden __new__ method """ overridden __new__ method
@type url: string @type url: string
@param url: url of WCS capabilities document @param url: url of WCS capabilities document
@type xml: string @type xml: string
@param xml: elementtree object @param xml: elementtree object
@param auth: instance of owslib.util.Authentication
@return: inititalised WCSBase object @return: inititalised WCSBase object
""" """
obj=object.__new__(self) obj=object.__new__(self)
obj.__init__(url, xml, cookies) obj.__init__(url, xml, cookies, auth=auth)
self.cookies=cookies self.cookies=cookies
self._describeCoverage = {} #cache for DescribeCoverage responses self._describeCoverage = {} #cache for DescribeCoverage responses
return obj return obj
def __init__(self): def __init__(self, auth=None):
pass self.auth = auth or Authentication()
def getDescribeCoverage(self, identifier): def getDescribeCoverage(self, identifier):
''' returns a describe coverage document - checks the internal cache to see if it has been fetched before ''' ''' returns a describe coverage document - checks the internal cache to see if it has been fetched before '''
if identifier not in self._describeCoverage.keys(): if identifier not in self._describeCoverage.keys():
reader = DescribeCoverageReader(self.version, identifier, self.cookies) reader = DescribeCoverageReader(
self.version, identifier, self.cookies, self.auth)
self._describeCoverage[identifier] = reader.read(self.url) self._describeCoverage[identifier] = reader.read(self.url)
return self._describeCoverage[identifier] return self._describeCoverage[identifier]
...@@ -69,7 +71,7 @@ class WCSCapabilitiesReader(object): ...@@ -69,7 +71,7 @@ class WCSCapabilitiesReader(object):
"""Read and parses WCS capabilities document into a lxml.etree infoset """Read and parses WCS capabilities document into a lxml.etree infoset
""" """
def __init__(self, version=None, cookies = None): def __init__(self, version=None, cookies=None, auth=None):
"""Initialize """Initialize
@type version: string @type version: string
@param version: WCS Version parameter e.g '1.0.0' @param version: WCS Version parameter e.g '1.0.0'
...@@ -77,6 +79,7 @@ class WCSCapabilitiesReader(object): ...@@ -77,6 +79,7 @@ class WCSCapabilitiesReader(object):
self.version = version self.version = version
self._infoset = None self._infoset = None
self.cookies = cookies self.cookies = cookies
self.auth = auth or Authentication()
def capabilities_url(self, service_url): def capabilities_url(self, service_url):
"""Return a capabilities url """Return a capabilities url
...@@ -112,7 +115,7 @@ class WCSCapabilitiesReader(object): ...@@ -112,7 +115,7 @@ class WCSCapabilitiesReader(object):
@return: An elementtree tree representation of the capabilities document @return: An elementtree tree representation of the capabilities document
""" """
request = self.capabilities_url(service_url) request = self.capabilities_url(service_url)
u = openURL(request, timeout=timeout, cookies=self.cookies) u = openURL(request, timeout=timeout, cookies=self.cookies, auth=self.auth)
return etree.fromstring(u.read()) return etree.fromstring(u.read())
def readString(self, st): def readString(self, st):
...@@ -126,7 +129,7 @@ class DescribeCoverageReader(object): ...@@ -126,7 +129,7 @@ class DescribeCoverageReader(object):
"""Read and parses WCS DescribeCoverage document into a lxml.etree infoset """Read and parses WCS DescribeCoverage document into a lxml.etree infoset
""" """
def __init__(self, version, identifier, cookies): def __init__(self, version, identifier, cookies, auth=None):
"""Initialize """Initialize
@type version: string @type version: string
@param version: WCS Version parameter e.g '1.0.0' @param version: WCS Version parameter e.g '1.0.0'
...@@ -135,6 +138,7 @@ class DescribeCoverageReader(object): ...@@ -135,6 +138,7 @@ class DescribeCoverageReader(object):
self._infoset = None self._infoset = None
self.identifier=identifier self.identifier=identifier
self.cookies = cookies self.cookies = cookies
self.auth = auth or Authentication()
def descCov_url(self, service_url): def descCov_url(self, service_url):
"""Return a describe coverage url """Return a describe coverage url
...@@ -187,6 +191,6 @@ class DescribeCoverageReader(object): ...@@ -187,6 +191,6 @@ class DescribeCoverageReader(object):
""" """
request = self.descCov_url(service_url) request = self.descCov_url(service_url)
u = openURL(request, cookies=self.cookies, timeout=timeout) u = openURL(request, cookies=self.cookies, timeout=timeout, auth=self.auth)
return etree.fromstring(u.read()) return etree.fromstring(u.read())
...@@ -24,8 +24,6 @@ try: # Python 3 ...@@ -24,8 +24,6 @@ try: # Python 3
except ImportError: # Python 2 except ImportError: # Python 2
from urllib import urlencode from urllib import urlencode
from owslib.util import OrderedDict
from owslib.etree import etree from owslib.etree import etree
from owslib import fes from owslib import fes
from owslib import util from owslib import util
...@@ -35,7 +33,7 @@ from owslib.fgdc import Metadata ...@@ -35,7 +33,7 @@ from owslib.fgdc import Metadata
from owslib.dif import DIF from owslib.dif import DIF
from owslib.gm03 import GM03 from owslib.gm03 import GM03
from owslib.namespaces import Namespaces from owslib.namespaces import Namespaces
from owslib.util import cleanup_namespaces, bind_url, add_namespaces, openURL from owslib.util import cleanup_namespaces, bind_url, add_namespaces, OrderedDict, Authentication, openURL, http_post
# default variables # default variables
outputformat = 'application/xml' outputformat = 'application/xml'
...@@ -50,7 +48,7 @@ schema_location = '%s %s' % (namespaces['csw'], schema) ...@@ -50,7 +48,7 @@ schema_location = '%s %s' % (namespaces['csw'], schema)
class CatalogueServiceWeb(object): class CatalogueServiceWeb(object):
""" csw request class """ """ csw request class """
def __init__(self, url, lang='en-US', version='2.0.2', timeout=10, skip_caps=False, def __init__(self, url, lang='en-US', version='2.0.2', timeout=10, skip_caps=False,
username=None, password=None): username=None, password=None, auth=None):
""" """
Construct and process a GetCapabilities request Construct and process a GetCapabilities request
...@@ -65,15 +63,19 @@ class CatalogueServiceWeb(object): ...@@ -65,15 +63,19 @@ class CatalogueServiceWeb(object):
- skip_caps: whether to skip GetCapabilities processing on init (default is False) - skip_caps: whether to skip GetCapabilities processing on init (default is False)
- username: username for HTTP basic authentication - username: username for HTTP basic authentication
- password: password for HTTP basic authentication - password: password for HTTP basic authentication
- auth: instance of owslib.util.Authentication
""" """
if auth:
if username:
auth.username = username
if password:
auth.password = password
self.url = util.clean_ows_url(url) self.url = util.clean_ows_url(url)
self.lang = lang self.lang = lang
self.version = version self.version = version
self.timeout = timeout self.timeout = timeout
self.username = username self.auth = auth or Authentication(username, password)
self.password = password
self.service = 'CSW' self.service = 'CSW'
self.exceptionreport = None self.exceptionreport = None
self.owscommon = ows.OwsCommon('1.0.0') self.owscommon = ows.OwsCommon('1.0.0')
...@@ -658,7 +660,9 @@ class CatalogueServiceWeb(object): ...@@ -658,7 +660,9 @@ class CatalogueServiceWeb(object):
if isinstance(self.request, six.string_types): # GET KVP if isinstance(self.request, six.string_types): # GET KVP
self.request = '%s%s' % (bind_url(request_url), self.request) self.request = '%s%s' % (bind_url(request_url), self.request)
self.response = openURL(self.request, None, 'Get', username=self.username, password=self.password, timeout=self.timeout).read() self.response = openURL(
self.request, None, 'Get', timeout=self.timeout, auth=self.auth
).read()
else: else:
self.request = cleanup_namespaces(self.request) self.request = cleanup_namespaces(self.request)
# Add any namespaces used in the "typeNames" attribute of the # Add any namespaces used in the "typeNames" attribute of the
...@@ -674,7 +678,7 @@ class CatalogueServiceWeb(object): ...@@ -674,7 +678,7 @@ class CatalogueServiceWeb(object):
self.request = util.element_to_string(self.request, encoding='utf-8') self.request = util.element_to_string(self.request, encoding='utf-8')
self.response = util.http_post(request_url, self.request, self.lang, self.timeout, self.username, self.password) self.response = http_post(request_url, self.request, self.lang, self.timeout, auth=self.auth)
# parse result see if it's XML # parse result see if it's XML
self._exml = etree.parse(BytesIO(self.response)) self._exml = etree.parse(BytesIO(self.response))
......
...@@ -14,12 +14,15 @@ try: ...@@ -14,12 +14,15 @@ try:
except ImportError: except ImportError:
from urllib.parse import urlencode from urllib.parse import urlencode
import logging import logging
from owslib.util import log from owslib.util import log, Authentication
from owslib.feature.schema import get_schema from owslib.feature.schema import get_schema
class WebFeatureService_(object): class WebFeatureService_(object):
"""Base class for WebFeatureService implementations""" """Base class for WebFeatureService implementations"""
def __init__(self, auth=None):
self.auth = auth or Authentication()
def getBBOXKVP (self,bbox,typename): def getBBOXKVP (self,bbox,typename):
"""Formate bounding box for KVP request type (HTTP GET) """Formate bounding box for KVP request type (HTTP GET)
...@@ -162,12 +165,8 @@ class WebFeatureService_(object): ...@@ -162,12 +165,8 @@ class WebFeatureService_(object):
return base_url+data return base_url+data
def get_schema(self, typename): def get_schema(self, typename):
""" """
Get layer schema compatible with :class:`fiona` schema object Get layer schema compatible with :class:`fiona` schema object
""" """
return get_schema(self.url, typename, self.version, auth=self.auth)
return get_schema(self.url, typename, self.version)
import cgi import cgi
from owslib.etree import etree from owslib.etree import etree
from owslib.util import openURL from owslib.util import Authentication, openURL
try: try:
from urllib import urlencode from urllib import urlencode
...@@ -13,11 +13,15 @@ class WFSCapabilitiesReader(object): ...@@ -13,11 +13,15 @@ class WFSCapabilitiesReader(object):
"""Read and parse capabilities document into a lxml.etree infoset """Read and parse capabilities document into a lxml.etree infoset
""" """
def __init__(self, version='1.0', username=None, password=None): def __init__(self, version='1.0', username=None, password=None, auth=None):
"""Initialize""" """Initialize"""
if auth:
if username:
auth.username = username
if password:
auth.password = password
self.auth = auth or Authentication(username, password)
self.version = version self.version = version
self.username = username
self.password = password
self._infoset = None self._infoset = None
def capabilities_url(self, service_url): def capabilities_url(self, service_url):
...@@ -51,8 +55,7 @@ class WFSCapabilitiesReader(object): ...@@ -51,8 +55,7 @@ class WFSCapabilitiesReader(object):
A timeout value (in seconds) for the request. A timeout value (in seconds) for the request.
""" """
request = self.capabilities_url(url) request = self.capabilities_url(url)
u = openURL(request, timeout=timeout, u = openURL(request, timeout=timeout, auth=self.auth)
username=self.username, password=self.password)
return etree.fromstring(u.read()) return etree.fromstring(u.read())
def readString(self, st): def readString(self, st):
...@@ -67,5 +70,9 @@ class WFSCapabilitiesReader(object): ...@@ -67,5 +70,9 @@ class WFSCapabilitiesReader(object):
class AbstractContentMetadata(object): class AbstractContentMetadata(object):
def __init__(self, auth=None):
self.auth = auth or Authentication()
def get_metadata(self): def get_metadata(self):
return [m['metadata'] for m in self.metadataUrls if m.get('metadata', None) is not None] return [m['metadata'] for m in self.metadataUrls if m.get('metadata', None) is not None]
...@@ -10,14 +10,13 @@ generating layer schema description compatible with `fiona` ...@@ -10,14 +10,13 @@ generating layer schema description compatible with `fiona`
""" """
import cgi, sys import cgi, sys
from owslib.util import openURL
try: try:
from urllib import urlencode from urllib import urlencode
except ImportError: except ImportError:
from urllib.parse import urlencode from urllib.parse import urlencode
from owslib.etree import etree from owslib.etree import etree
from owslib.namespaces import Namespaces from owslib.namespaces import Namespaces
from owslib.util import which_etree, findall from owslib.util import which_etree, findall, Authentication, openURL
MYNS = Namespaces() MYNS = Namespaces()
XS_NAMESPACE = MYNS.get_namespace('xs') XS_NAMESPACE = MYNS.get_namespace('xs')
...@@ -26,7 +25,8 @@ GML_NAMESPACES = (MYNS.get_namespace('gml'), ...@@ -26,7 +25,8 @@ GML_NAMESPACES = (MYNS.get_namespace('gml'),
MYNS.get_namespace('gml32')) MYNS.get_namespace('gml32'))
def get_schema(url, typename, version='1.0.0', timeout=30, username=None, password=None): def get_schema(url, typename, version='1.0.0', timeout=30,
username=None, password=None, auth=None):
"""Parses DescribeFeatureType response and creates schema compatible """Parses DescribeFeatureType response and creates schema compatible
with :class:`fiona` with :class:`fiona`
...@@ -34,10 +34,19 @@ def get_schema(url, typename, version='1.0.0', timeout=30, username=None, passwo ...@@ -34,10 +34,19 @@ def get_schema(url, typename, version='1.0.0', timeout=30, username=None, passwo
:param str version: version of the service :param str version: version of the service
:param str typename: name of the layer :param str typename: name of the layer
:param int timeout: request timeout :param int timeout: request timeout
:param str username: service authentication username
:param str password: service authentication password
:param Authentication auth: instance of owslib.util.Authentication
""" """
if auth:
if username:
auth.username = username
if password:
auth.password = password
else:
auth = Authentication(username, password)
url = _get_describefeaturetype_url(url, version, typename) url = _get_describefeaturetype_url(url, version, typename)
res = openURL(url, timeout=timeout, username=username, password=password) res = openURL(url, timeout=timeout, auth=auth)
root = etree.fromstring(res.read()) root = etree.fromstring(res.read())
if ':' in typename: if ':' in typename:
......
...@@ -17,13 +17,12 @@ try: ...@@ -17,13 +17,12 @@ try:
from urllib import urlencode from urllib import urlencode
except ImportError: except ImportError:
from urllib.parse import urlencode from urllib.parse import urlencode
from owslib.util import openURL, testXMLValue, extract_xml_list, ServiceException, xmltag_split from owslib.util import testXMLValue, extract_xml_list, ServiceException, xmltag_split, Authentication, openURL, log
from owslib.etree import etree from owslib.etree import etree
from owslib.fgdc import Metadata from owslib.fgdc import Metadata
from owslib.iso import MD_Metadata from owslib.iso import MD_Metadata
from owslib.crs import Crs from owslib.crs import Crs
from owslib.namespaces import Namespaces from owslib.namespaces import Namespaces
from owslib.util import log
from owslib.feature.schema import get_schema from owslib.feature.schema import get_schema
from owslib.feature.common import WFSCapabilitiesReader, \ from owslib.feature.common import WFSCapabilitiesReader, \
AbstractContentMetadata AbstractContentMetadata
...@@ -62,7 +61,7 @@ class WebFeatureService_1_0_0(object): ...@@ -62,7 +61,7 @@ class WebFeatureService_1_0_0(object):
Implements IWebFeatureService. Implements IWebFeatureService.
""" """
def __new__(self,url, version, xml, parse_remote_metadata=False, timeout=30, def __new__(self,url, version, xml, parse_remote_metadata=False, timeout=30,
username=None, password=None): username=None, password=None, auth=None):
""" overridden __new__ method """ overridden __new__ method
@type url: string @type url: string
...@@ -74,11 +73,12 @@ class WebFeatureService_1_0_0(object): ...@@ -74,11 +73,12 @@ class WebFeatureService_1_0_0(object):
@param timeout: time (in seconds) after which requests should timeout @param timeout: time (in seconds) after which requests should timeout
@param username: service authentication username @param username: service authentication username
@param password: service authentication password @param password: service authentication password
@param auth: instance of owslib.util.Authentication
@return: initialized WebFeatureService_1_0_0 object @return: initialized WebFeatureService_1_0_0 object
""" """
obj=object.__new__(self) obj=object.__new__(self)
obj.__init__(url, version, xml, parse_remote_metadata, timeout, obj.__init__(url, version, xml, parse_remote_metadata, timeout,
username=username, password=password) username=username, password=password, auth=auth)
return obj return obj
def __getitem__(self,name): def __getitem__(self,name):
...@@ -88,17 +88,20 @@ class WebFeatureService_1_0_0(object): ...@@ -88,17 +88,20 @@ class WebFeatureService_1_0_0(object):
else: else:
raise KeyError("No content named %s" % name) raise KeyError("No content named %s" % name)
def __init__(self, url, version, xml=None, parse_remote_metadata=False, timeout=30, def __init__(self, url, version, xml=None, parse_remote_metadata=False, timeout=30,
username=None, password=None): username=None, password=None, auth=None):
"""Initialize.""" """Initialize."""
if auth:
if username:
auth.username = username
if password:
auth.password = password
self.url = url self.url = url
self.version = version self.version = version
self.timeout = timeout self.timeout = timeout
self.username = username self.auth = auth or Authentication(username, password)
self.password = password
self._capabilities = None self._capabilities = None
reader = WFSCapabilitiesReader(self.version, self.username, self.password) reader = WFSCapabilitiesReader(self.version, auth=self.auth)
if xml: if xml:
self._capabilities = reader.readString(xml) self._capabilities = reader.readString(xml)
else: else:
...@@ -130,7 +133,8 @@ class WebFeatureService_1_0_0(object): ...@@ -130,7 +133,8 @@ class WebFeatureService_1_0_0(object):
featuretypelist=self._capabilities.find(nspath('FeatureTypeList')) featuretypelist=self._capabilities.find(nspath('FeatureTypeList'))
features = self._capabilities.findall(nspath('FeatureTypeList/FeatureType')) features = self._capabilities.findall(nspath('FeatureTypeList/FeatureType'))
for feature in features: for feature in features:
cm=ContentMetadata(feature, featuretypelist, parse_remote_metadata) cm = ContentMetadata(
feature, featuretypelist, parse_remote_metadata, auth=self.auth)
self.contents[cm.id]=cm self.contents[cm.id]=cm
#exceptions #exceptions
...@@ -141,9 +145,9 @@ class WebFeatureService_1_0_0(object): ...@@ -141,9 +145,9 @@ class WebFeatureService_1_0_0(object):
"""Request and return capabilities document from the WFS as a """Request and return capabilities document from the WFS as a
file-like object. file-like object.
NOTE: this is effectively redundant now""" NOTE: this is effectively redundant now"""
reader = WFSCapabilitiesReader(self.version) reader = WFSCapabilitiesReader(self.version, auth=self.auth)
return openURL(reader.capabilities_url(self.url), timeout=self.timeout, return openURL(reader.capabilities_url(self.url),
username=self.username, password=self.password) timeout=self.timeout, auth=self.auth)
def items(self): def items(self):
'''supports dict-like items() access''' '''supports dict-like items() access'''
...@@ -235,9 +239,7 @@ class WebFeatureService_1_0_0(object): ...@@ -235,9 +239,7 @@ class WebFeatureService_1_0_0(object):
data = urlencode(request) data = urlencode(request)
log.debug("Making request: %s?%s" % (base_url, data)) log.debug("Making request: %s?%s" % (base_url, data))
u = openURL(base_url, data, method, timeout=self.timeout, u = openURL(base_url, data, method, timeout=self.timeout, auth=self.auth)
username=self.username, password=self.password)
# check for service exceptions, rewrap, and return # check for service exceptions, rewrap, and return
# We're going to assume that anything with a content-length > 32k # We're going to assume that anything with a content-length > 32k
...@@ -283,8 +285,7 @@ class WebFeatureService_1_0_0(object): ...@@ -283,8 +285,7 @@ class WebFeatureService_1_0_0(object):
Get layer schema compatible with :class:`fiona` schema object Get layer schema compatible with :class:`fiona` schema object
""" """
return get_schema(self.url, typename, self.version) return get_schema(self.url, typename, self.version, auth=self.auth)
class ServiceIdentification(object): class ServiceIdentification(object):
...@@ -314,8 +315,9 @@ class ContentMetadata(AbstractContentMetadata): ...@@ -314,8 +315,9 @@ class ContentMetadata(AbstractContentMetadata):
Implements IMetadata. Implements IMetadata.
""" """
def __init__(self, elem, parent, parse_remote_metadata=False, timeout=30): def __init__(self, elem, parent, parse_remote_metadata=False, timeout=30, auth=None):
""".""" """."""
super(ContentMetadata, self).__init__(auth)
self.id = testXMLValue(elem.find(nspath('Name'))) self.id = testXMLValue(elem.find(nspath('Name')))
self.title = testXMLValue(elem.find(nspath('Title'))) self.title = testXMLValue(elem.find(nspath('Title')))
self.abstract = testXMLValue(elem.find(nspath('Abstract'))) self.abstract = testXMLValue(elem.find(nspath('Abstract')))
...@@ -378,7 +380,8 @@ class ContentMetadata(AbstractContentMetadata): ...@@ -378,7 +380,8 @@ class ContentMetadata(AbstractContentMetadata):
if metadataUrl['url'] is not None \ if metadataUrl['url'] is not None \
and metadataUrl['format'].lower() == 'xml': and metadataUrl['format'].lower() == 'xml':
try: try:
content = openURL(metadataUrl['url'], timeout=timeout) content = openURL(
metadataUrl['url'], timeout=timeout, auth=self.auth)
doc = etree.fromstring(content.read()) doc = etree.fromstring(content.read())
if metadataUrl['type'] == 'FGDC': if metadataUrl['type'] == 'FGDC':
mdelem = doc.find('.//metadata') mdelem = doc.find('.//metadata')
......
...@@ -15,7 +15,8 @@ try: ...@@ -15,7 +15,8 @@ try:
from urllib import urlencode from urllib import urlencode
except ImportError: except ImportError:
from urllib.parse import urlencode from urllib.parse import urlencode
from owslib.util import openURL, testXMLValue, nspath_eval, ServiceException from owslib.util import testXMLValue, nspath_eval, ServiceException, Authentication,\
openURL
from owslib.etree import etree from owslib.etree import etree
from owslib.fgdc import Metadata from owslib.fgdc import Metadata
from owslib.iso import MD_Metadata from owslib.iso import MD_Metadata
...@@ -26,7 +27,7 @@ from owslib.feature import WebFeatureService_ ...@@ -26,7 +27,7 @@ from owslib.feature import WebFeatureService_
from owslib.feature.common import WFSCapabilitiesReader, \ from owslib.feature.common import WFSCapabilitiesReader, \
AbstractContentMetadata AbstractContentMetadata
from owslib.namespaces import Namespaces from owslib.namespaces import Namespaces
from owslib.util import log from owslib.util import log, openURL
def get_namespaces(): def get_namespaces():
...@@ -40,7 +41,7 @@ class WebFeatureService_1_1_0(WebFeatureService_): ...@@ -40,7 +41,7 @@ class WebFeatureService_1_1_0(WebFeatureService_):
Implements IWebFeatureService. Implements IWebFeatureService.
""" """
def __new__(self,url, version, xml, parse_remote_metadata=False, timeout=30, def __new__(self,url, version, xml, parse_remote_metadata=False, timeout=30,
username=None, password=None): username=None, password=None, auth=None):
""" overridden __new__ method """ overridden __new__ method
@type url: string @type url: string
...@@ -52,11 +53,12 @@ class WebFeatureService_1_1_0(WebFeatureService_): ...@@ -52,11 +53,12 @@ class WebFeatureService_1_1_0(WebFeatureService_):
@param timeout: time (in seconds) after which requests should timeout @param timeout: time (in seconds) after which requests should timeout
@param username: service authentication username @param username: service authentication username
@param password: service authentication password @param password: service authentication password
@param auth: instance of owslib.util.Authentication
@return: initialized WebFeatureService_1_1_0 object @return: initialized WebFeatureService_1_1_0 object
""" """
obj=object.__new__(self) obj=object.__new__(self)
obj.__init__(url, version, xml, parse_remote_metadata, timeout, obj.__init__(url, version, xml, parse_remote_metadata, timeout,
username=username, password=password) username=username, password=password, auth=auth)
return obj return obj
def __getitem__(self,name): def __getitem__(self,name):
...@@ -66,18 +68,23 @@ class WebFeatureService_1_1_0(WebFeatureService_): ...@@ -66,18 +68,23 @@ class WebFeatureService_1_1_0(WebFeatureService_):
else: else:
raise KeyError("No content named %s" % name) raise KeyError("No content named %s" % name)
def __init__(self, url, version, xml=None, parse_remote_metadata=False, timeout=30, def __init__(self, url, version, xml=None, parse_remote_metadata=False, timeout=30,
username=None, password=None): username=None, password=None, auth=None):
"""Initialize.""" """Initialize."""
if auth:
if username:
auth.username = username
if password:
auth.password = password
else:
auth = Authentication(username, password)
super(WebFeatureService_1_1_0, self).__init__(auth)
self.url = url self.url = url
self.version = version self.version = version
self.timeout = timeout self.timeout = timeout
self.username = username
self.password = password
self._capabilities = None self._capabilities = None
self.owscommon = OwsCommon('1.0.0') self.owscommon = OwsCommon('1.0.0')
reader = WFSCapabilitiesReader(self.version, username=username, password=password) reader = WFSCapabilitiesReader(self.version, auth=self.auth)
if xml: if xml:
self._capabilities = reader.readString(xml) self._capabilities = reader.readString(xml)
else: else:
...@@ -118,7 +125,7 @@ class WebFeatureService_1_1_0(WebFeatureService_): ...@@ -118,7 +125,7 @@ class WebFeatureService_1_1_0(WebFeatureService_):
self.contents={} self.contents={}
features = self._capabilities.findall(nspath_eval('wfs:FeatureTypeList/wfs:FeatureType', namespaces)) features = self._capabilities.findall(nspath_eval('wfs:FeatureTypeList/wfs:FeatureType', namespaces))
for feature in features: for feature in features:
cm=ContentMetadata(feature, parse_remote_metadata) cm=ContentMetadata(feature, parse_remote_metadata, auth=self.auth)
self.contents[cm.id]=cm self.contents[cm.id]=cm
#exceptions #exceptions
...@@ -129,9 +136,9 @@ class WebFeatureService_1_1_0(WebFeatureService_): ...@@ -129,9 +136,9 @@ class WebFeatureService_1_1_0(WebFeatureService_):
"""Request and return capabilities document from the WFS as a """Request and return capabilities document from the WFS as a
file-like object. file-like object.
NOTE: this is effectively redundant now""" NOTE: this is effectively redundant now"""
reader = WFSCapabilitiesReader(self.version) reader = WFSCapabilitiesReader(self.version, auth=self.auth)
return openURL(reader.capabilities_url(self.url), timeout=self.timeout, return openURL(reader.capabilities_url(self.url),
username=self.username, password=self.password) timeout=self.timeout, auth=self.auth)
def items(self): def items(self):
'''supports dict-like items() access''' '''supports dict-like items() access'''
...@@ -246,8 +253,7 @@ class WebFeatureService_1_1_0(WebFeatureService_): ...@@ -246,8 +253,7 @@ class WebFeatureService_1_1_0(WebFeatureService_):
data = urlencode(request) data = urlencode(request)
log.debug("Making request: %s?%s" % (base_url, data)) log.debug("Making request: %s?%s" % (base_url, data))
u = openURL(base_url, data, method, timeout=self.timeout, u = openURL(base_url, data, method, timeout=self.timeout, auth=self.auth)
username=self.username, password=self.password)
# check for service exceptions, rewrap, and return # check for service exceptions, rewrap, and return
# We're going to assume that anything with a content-length > 32k # We're going to assume that anything with a content-length > 32k
...@@ -295,8 +301,9 @@ class ContentMetadata(AbstractContentMetadata): ...@@ -295,8 +301,9 @@ class ContentMetadata(AbstractContentMetadata):
Implements IMetadata. Implements IMetadata.
""" """
def __init__(self, elem, parse_remote_metadata=False, timeout=30): def __init__(self, elem, parse_remote_metadata=False, timeout=30, auth=None):
""".""" """."""
super(ContentMetadata, self).__init__(auth)
self.id = testXMLValue(elem.find(nspath_eval('wfs:Name', namespaces))) self.id = testXMLValue(elem.find(nspath_eval('wfs:Name', namespaces)))
self.title = testXMLValue(elem.find(nspath_eval('wfs:Title', namespaces))) self.title = testXMLValue(elem.find(nspath_eval('wfs:Title', namespaces)))
self.abstract = testXMLValue(elem.find(nspath_eval('wfs:Abstract', namespaces))) self.abstract = testXMLValue(elem.find(nspath_eval('wfs:Abstract', namespaces)))
...@@ -349,7 +356,8 @@ class ContentMetadata(AbstractContentMetadata): ...@@ -349,7 +356,8 @@ class ContentMetadata(AbstractContentMetadata):
if metadataUrl['url'] is not None \ if metadataUrl['url'] is not None \
and metadataUrl['format'].lower() == 'text/xml': and metadataUrl['format'].lower() == 'text/xml':
try: try:
content = openURL(metadataUrl['url'], timeout=timeout) content = openURL(
metadataUrl['url'], timeout=timeout)
doc = etree.fromstring(content.read()) doc = etree.fromstring(content.read())
if metadataUrl['type'] == 'FGDC': if metadataUrl['type'] == 'FGDC':
......
...@@ -14,7 +14,7 @@ from owslib.fgdc import Metadata ...@@ -14,7 +14,7 @@ from owslib.fgdc import Metadata
from owslib.iso import MD_Metadata from owslib.iso import MD_Metadata
from owslib.ows import ServiceIdentification, ServiceProvider, OperationsMetadata from owslib.ows import ServiceIdentification, ServiceProvider, OperationsMetadata
from owslib.etree import etree from owslib.etree import etree
from owslib.util import nspath, testXMLValue, openURL from owslib.util import nspath, testXMLValue, openURL, Authentication
from owslib.crs import Crs from owslib.crs import Crs
from owslib.feature import WebFeatureService_ from owslib.feature import WebFeatureService_
from owslib.feature.common import WFSCapabilitiesReader, \ from owslib.feature.common import WFSCapabilitiesReader, \
...@@ -50,7 +50,7 @@ class WebFeatureService_2_0_0(WebFeatureService_): ...@@ -50,7 +50,7 @@ class WebFeatureService_2_0_0(WebFeatureService_):
Implements IWebFeatureService. Implements IWebFeatureService.
""" """
def __new__(self,url, version, xml, parse_remote_metadata=False, timeout=30, def __new__(self,url, version, xml, parse_remote_metadata=False, timeout=30,
username=None, password=None): username=None, password=None, auth=None):
""" overridden __new__ method """ overridden __new__ method
@type url: string @type url: string
...@@ -62,11 +62,12 @@ class WebFeatureService_2_0_0(WebFeatureService_): ...@@ -62,11 +62,12 @@ class WebFeatureService_2_0_0(WebFeatureService_):
@param timeout: time (in seconds) after which requests should timeout @param timeout: time (in seconds) after which requests should timeout
@param username: service authentication username @param username: service authentication username
@param password: service authentication password @param password: service authentication password
@param auth: instance of owslib.util.Authentication
@return: initialized WebFeatureService_2_0_0 object @return: initialized WebFeatureService_2_0_0 object
""" """
obj=object.__new__(self) obj=object.__new__(self)
obj.__init__(url, version, xml, parse_remote_metadata, timeout, obj.__init__(url, version, xml, parse_remote_metadata, timeout,
username=username, password=password) username=username, password=password, auth=auth)
return obj return obj
def __getitem__(self,name): def __getitem__(self,name):
...@@ -76,19 +77,24 @@ class WebFeatureService_2_0_0(WebFeatureService_): ...@@ -76,19 +77,24 @@ class WebFeatureService_2_0_0(WebFeatureService_):
else: else:
raise KeyError("No content named %s" % name) raise KeyError("No content named %s" % name)
def __init__(self, url, version, xml=None, parse_remote_metadata=False, timeout=30, def __init__(self, url, version, xml=None, parse_remote_metadata=False, timeout=30,
username=None, password=None): username=None, password=None, auth=None):
"""Initialize.""" """Initialize."""
if auth:
if username:
auth.username = username
if password:
auth.password = password
else:
auth = Authentication()
super(WebFeatureService_2_0_0, self).__init__(auth)
if log.isEnabledFor(logging.DEBUG): if log.isEnabledFor(logging.DEBUG):
log.debug('building WFS %s'%url) log.debug('building WFS %s'%url)
self.url = url self.url = url
self.version = version self.version = version
self.timeout = timeout self.timeout = timeout
self.username = username
self.password = password
self._capabilities = None self._capabilities = None
reader = WFSCapabilitiesReader(self.version, username=username, password=password) reader = WFSCapabilitiesReader(self.version, auth=self.auth)
if xml: if xml:
self._capabilities = reader.readString(xml) self._capabilities = reader.readString(xml)
else: else:
...@@ -140,7 +146,8 @@ class WebFeatureService_2_0_0(WebFeatureService_): ...@@ -140,7 +146,8 @@ class WebFeatureService_2_0_0(WebFeatureService_):
featuretypelist=self._capabilities.find(nspath('FeatureTypeList',ns=WFS_NAMESPACE)) featuretypelist=self._capabilities.find(nspath('FeatureTypeList',ns=WFS_NAMESPACE))
features = self._capabilities.findall(nspath('FeatureTypeList/FeatureType', ns=WFS_NAMESPACE)) features = self._capabilities.findall(nspath('FeatureTypeList/FeatureType', ns=WFS_NAMESPACE))
for feature in features: for feature in features:
cm=ContentMetadata(feature, featuretypelist, parse_remote_metadata) cm = ContentMetadata(
feature, featuretypelist, parse_remote_metadata, auth=self.auth)
self.contents[cm.id]=cm self.contents[cm.id]=cm
#exceptions #exceptions
...@@ -151,9 +158,9 @@ class WebFeatureService_2_0_0(WebFeatureService_): ...@@ -151,9 +158,9 @@ class WebFeatureService_2_0_0(WebFeatureService_):
"""Request and return capabilities document from the WFS as a """Request and return capabilities document from the WFS as a
file-like object. file-like object.
NOTE: this is effectively redundant now""" NOTE: this is effectively redundant now"""
reader = WFSCapabilitiesReader(self.version) reader = WFSCapabilitiesReader(self.version, auth=self.auth)
return openURL(reader.capabilities_url(self.url), timeout=self.timeout, return openURL(reader.capabilities_url(self.url),
username=self.username, password=self.password) timeout=self.timeout, auth=self.auth)
def items(self): def items(self):
'''supports dict-like items() access''' '''supports dict-like items() access'''
...@@ -228,8 +235,7 @@ class WebFeatureService_2_0_0(WebFeatureService_): ...@@ -228,8 +235,7 @@ class WebFeatureService_2_0_0(WebFeatureService_):
# If method is 'Post', data will be None here # If method is 'Post', data will be None here
u = openURL(url, data, method, timeout=self.timeout, u = openURL(url, data, method, timeout=self.timeout, auth=self.auth)
username=self.username, password=self.password)
# check for service exceptions, rewrap, and return # check for service exceptions, rewrap, and return
# We're going to assume that anything with a content-length > 32k # We're going to assume that anything with a content-length > 32k
...@@ -262,7 +268,6 @@ class WebFeatureService_2_0_0(WebFeatureService_): ...@@ -262,7 +268,6 @@ class WebFeatureService_2_0_0(WebFeatureService_):
return self._makeStringIO(data) return self._makeStringIO(data)
return u return u
def getpropertyvalue(self, query=None, storedquery_id=None, valuereference=None, typename=None, method=nspath('Get'),**kwargs): def getpropertyvalue(self, query=None, storedquery_id=None, valuereference=None, typename=None, method=nspath('Get'),**kwargs):
''' the WFS GetPropertyValue method''' ''' the WFS GetPropertyValue method'''
try: try:
...@@ -282,11 +287,9 @@ class WebFeatureService_2_0_0(WebFeatureService_): ...@@ -282,11 +287,9 @@ class WebFeatureService_2_0_0(WebFeatureService_):
for kw in kwargs.keys(): for kw in kwargs.keys():
request[kw]=str(kwargs[kw]) request[kw]=str(kwargs[kw])
encoded_request=urlencode(request) encoded_request=urlencode(request)
u = openURL(base_url + encoded_request, timeout=self.timeout, u = openURL(base_url + encoded_request, timeout=self.timeout, auth=self.auth)
username=self.username, password=self.password)
return u.read() return u.read()
def _getStoredQueries(self): def _getStoredQueries(self):
''' gets descriptions of the stored queries available on the server ''' ''' gets descriptions of the stored queries available on the server '''
sqs=[] sqs=[]
...@@ -302,8 +305,7 @@ class WebFeatureService_2_0_0(WebFeatureService_): ...@@ -302,8 +305,7 @@ class WebFeatureService_2_0_0(WebFeatureService_):
request = {'service': 'WFS', 'version': self.version, 'request': 'ListStoredQueries'} request = {'service': 'WFS', 'version': self.version, 'request': 'ListStoredQueries'}
encoded_request = urlencode(request) encoded_request = urlencode(request)
u = openURL(base_url, data=encoded_request, timeout=self.timeout, u = openURL(base_url, data=encoded_request, timeout=self.timeout, auth=self.auth)
username=self.username, password=self.password)
tree=etree.fromstring(u.read()) tree=etree.fromstring(u.read())
tempdict={} tempdict={}
for sqelem in tree[:]: for sqelem in tree[:]:
...@@ -323,8 +325,7 @@ class WebFeatureService_2_0_0(WebFeatureService_): ...@@ -323,8 +325,7 @@ class WebFeatureService_2_0_0(WebFeatureService_):
base_url = self.url base_url = self.url
request = {'service': 'WFS', 'version': self.version, 'request': 'DescribeStoredQueries'} request = {'service': 'WFS', 'version': self.version, 'request': 'DescribeStoredQueries'}
encoded_request = urlencode(request) encoded_request = urlencode(request)
u = openURL(base_url, data=encoded_request, timeout=self.timeout, u = openURL(base_url, data=encoded_request, timeout=self.timeout, auth=self.auth)
username=self.username, password=self.password)
tree=etree.fromstring(u.read()) tree=etree.fromstring(u.read())
tempdict2={} tempdict2={}
for sqelem in tree[:]: for sqelem in tree[:]:
...@@ -373,8 +374,9 @@ class ContentMetadata(AbstractContentMetadata): ...@@ -373,8 +374,9 @@ class ContentMetadata(AbstractContentMetadata):
Implements IMetadata. Implements IMetadata.
""" """
def __init__(self, elem, parent, parse_remote_metadata=False, timeout=30): def __init__(self, elem, parent, parse_remote_metadata=False, timeout=30, auth=None):
""".""" """."""
super(ContentMetadata, self).__init__(auth)
self.id = elem.find(nspath('Name',ns=WFS_NAMESPACE)).text self.id = elem.find(nspath('Name',ns=WFS_NAMESPACE)).text
self.title = elem.find(nspath('Title',ns=WFS_NAMESPACE)).text self.title = elem.find(nspath('Title',ns=WFS_NAMESPACE)).text
abstract = elem.find(nspath('Abstract',ns=WFS_NAMESPACE)) abstract = elem.find(nspath('Abstract',ns=WFS_NAMESPACE))
...@@ -439,7 +441,8 @@ class ContentMetadata(AbstractContentMetadata): ...@@ -439,7 +441,8 @@ class ContentMetadata(AbstractContentMetadata):
for metadataUrl in self.metadataUrls: for metadataUrl in self.metadataUrls:
if metadataUrl['url'] is not None: if metadataUrl['url'] is not None:
try: try:
content = openURL(metadataUrl['url'], timeout=timeout) content = openURL(
metadataUrl['url'], timeout=timeout)
doc = etree.fromstring(content.read()) doc = etree.fromstring(content.read())
mdelem = doc.find('.//metadata') mdelem = doc.find('.//metadata')
......
...@@ -10,9 +10,9 @@ import json ...@@ -10,9 +10,9 @@ import json
import logging import logging
from six.moves.urllib.parse import urljoin from six.moves.urllib.parse import urljoin
import requests
from owslib import __version__ from owslib import __version__
from owslib.util import Authentication, http_get
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
...@@ -25,7 +25,7 @@ REQUEST_HEADERS = { ...@@ -25,7 +25,7 @@ REQUEST_HEADERS = {
class WebFeatureService_3_0_0(object): class WebFeatureService_3_0_0(object):
"""Abstraction for OGC Web Feature Service (WFS) version 3.0""" """Abstraction for OGC Web Feature Service (WFS) version 3.0"""
def __init__(self, url, version, json_, timeout=30, username=None, def __init__(self, url, version, json_, timeout=30, username=None,
password=None): password=None, auth=None):
""" """
initializer; implements Requirement 1 (/req/core/root-op) initializer; implements Requirement 1 (/req/core/root-op)
...@@ -36,6 +36,7 @@ class WebFeatureService_3_0_0(object): ...@@ -36,6 +36,7 @@ class WebFeatureService_3_0_0(object):
@param timeout: time (in seconds) after which requests should timeout @param timeout: time (in seconds) after which requests should timeout
@param username: service authentication username @param username: service authentication username
@param password: service authentication password @param password: service authentication password
@param auth: instance of owslib.util.Authentication
@return: initialized WebFeatureService_3_0_0 object @return: initialized WebFeatureService_3_0_0 object
""" """
...@@ -49,15 +50,31 @@ class WebFeatureService_3_0_0(object): ...@@ -49,15 +50,31 @@ class WebFeatureService_3_0_0(object):
self.version = version self.version = version
self.json_ = json_ self.json_ = json_
self.timeout = timeout self.timeout = timeout
self.username = username if auth:
self.password = password if username:
auth.username = username
if password:
auth.password = password
self.auth = auth or Authentication(username, password)
if json_ is not None: # static JSON string if json_ is not None: # static JSON string
self.links = json.loads(json_)['links'] self.links = json.loads(json_)['links']
else: else:
response = requests.get(url, headers=REQUEST_HEADERS).json() response = http_get(url, headers=REQUEST_HEADERS, auth=self.auth).json()
self.links = response['links'] self.links = response['links']
def api(self):
"""
implements Requirement 3 (/req/core/api-definition-op)
@returns: OpenAPI definition object
"""
url = self._build_url('api')
LOGGER.debug('Request: {}'.format(url))
response = http_get(url, headers=REQUEST_HEADERS, auth=self.auth).json()
return response
def conformance(self): def conformance(self):
""" """
implements Requirement 5 (/req/core/conformance-op) implements Requirement 5 (/req/core/conformance-op)
...@@ -67,7 +84,7 @@ class WebFeatureService_3_0_0(object): ...@@ -67,7 +84,7 @@ class WebFeatureService_3_0_0(object):
url = self._build_url('conformance') url = self._build_url('conformance')
LOGGER.debug('Request: {}'.format(url)) LOGGER.debug('Request: {}'.format(url))
response = requests.get(url, headers=REQUEST_HEADERS).json() response = http_get(url, headers=REQUEST_HEADERS, auth=self.auth).json()
return response return response
def collections(self): def collections(self):
...@@ -79,7 +96,7 @@ class WebFeatureService_3_0_0(object): ...@@ -79,7 +96,7 @@ class WebFeatureService_3_0_0(object):
url = self._build_url('collections') url = self._build_url('collections')
LOGGER.debug('Request: {}'.format(url)) LOGGER.debug('Request: {}'.format(url))
response = requests.get(url, headers=REQUEST_HEADERS).json() response = http_get(url, headers=REQUEST_HEADERS, auth=self.auth).json()
return response['collections'] return response['collections']
def collection(self, collection_name): def collection(self, collection_name):
...@@ -95,7 +112,7 @@ class WebFeatureService_3_0_0(object): ...@@ -95,7 +112,7 @@ class WebFeatureService_3_0_0(object):
path = 'collections/{}'.format(collection_name) path = 'collections/{}'.format(collection_name)
url = self._build_url(path) url = self._build_url(path)
LOGGER.debug('Request: {}'.format(url)) LOGGER.debug('Request: {}'.format(url))
response = requests.get(url, headers=REQUEST_HEADERS).json() response = http_get(url, headers=REQUEST_HEADERS, auth=self.auth).json()
return response return response
def collection_items(self, collection_name, **kwargs): def collection_items(self, collection_name, **kwargs):
...@@ -122,8 +139,7 @@ class WebFeatureService_3_0_0(object): ...@@ -122,8 +139,7 @@ class WebFeatureService_3_0_0(object):
path = 'collections/{}/items'.format(collection_name) path = 'collections/{}/items'.format(collection_name)
url = self._build_url(path) url = self._build_url(path)
LOGGER.debug('Request: {}'.format(url)) LOGGER.debug('Request: {}'.format(url))
response = requests.get(url, headers=REQUEST_HEADERS, response = http_get(url, headers=REQUEST_HEADERS, params=kwargs, auth=self.auth).json()
params=kwargs).json()
return response return response
def collection_item(self, collection_name, identifier): def collection_item(self, collection_name, identifier):
...@@ -141,7 +157,7 @@ class WebFeatureService_3_0_0(object): ...@@ -141,7 +157,7 @@ class WebFeatureService_3_0_0(object):
path = 'collections/{}/items/{}'.format(collection_name, identifier) path = 'collections/{}/items/{}'.format(collection_name, identifier)
url = self._build_url(path) url = self._build_url(path)
LOGGER.debug('Request: {}'.format(url)) LOGGER.debug('Request: {}'.format(url))
response = requests.get(url, headers=REQUEST_HEADERS).json() response = http_get(url, headers=REQUEST_HEADERS, auth=self.auth).json()
return response return response
def _build_url(self, path=None): def _build_url(self, path=None):
......
...@@ -7,22 +7,27 @@ except ImportError: # Python 2 ...@@ -7,22 +7,27 @@ except ImportError: # Python 2
from urllib import urlencode from urllib import urlencode
from owslib.etree import etree from owslib.etree import etree
from owslib.util import openURL, strip_bom from owslib.util import strip_bom, Authentication, openURL
class WMSCapabilitiesReader(object): class WMSCapabilitiesReader(object):
"""Read and parse capabilities document into a lxml.etree infoset """Read and parse capabilities document into a lxml.etree infoset
""" """
def __init__(self, version='1.1.1', url=None, un=None, pw=None, headers=None): def __init__(self, version='1.1.1', url=None, un=None, pw=None, headers=None, auth=None):
"""Initialize""" """Initialize"""
self.version = version self.version = version
self._infoset = None self._infoset = None
self.url = url self.url = url
self.username = un if auth:
self.password = pw if un:
auth.username = un
if pw:
auth.password = pw
self.headers = headers self.headers = headers
self.request = None self.request = None
self.auth = auth or Authentication(un, pw)
#if self.username and self.password: #if self.username and self.password:
## Provide login information in order to use the WMS server ## Provide login information in order to use the WMS server
...@@ -65,10 +70,7 @@ class WMSCapabilitiesReader(object): ...@@ -65,10 +70,7 @@ class WMSCapabilitiesReader(object):
# now split it up again to use the generic openURL function... # now split it up again to use the generic openURL function...
spliturl = self.request.split('?') spliturl = self.request.split('?')
u = openURL(spliturl[0], spliturl[1], method='Get', u = openURL(spliturl[0], spliturl[1], method='Get',
username=self.username, timeout=timeout, headers=self.headers, auth=self.auth)
password=self.password,
timeout=timeout,
headers=self.headers)
raw_text = strip_bom(u.read()) raw_text = strip_bom(u.read())
return etree.fromstring(raw_text) return etree.fromstring(raw_text)
...@@ -85,5 +87,9 @@ class WMSCapabilitiesReader(object): ...@@ -85,5 +87,9 @@ class WMSCapabilitiesReader(object):
class AbstractContentMetadata(object): class AbstractContentMetadata(object):
def __init__(self, auth=None):
self.auth = auth or Authentication()
def get_metadata(self): def get_metadata(self):
return [m['metadata'] for m in self.metadataUrls if m.get('metadata', None) is not None] return [m['metadata'] for m in self.metadataUrls if m.get('metadata', None) is not None]