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