Code Monkey home page Code Monkey logo

pygeoogc's Introduction

https://raw.githubusercontent.com/hyriver/HyRiver-examples/main/notebooks/_static/pygeoogc_logo.png

JOSS

Package Description Status
PyNHD Navigate and subset NHDPlus (MR and HR) using web services Github Actions
Py3DEP Access topographic data through National Map's 3DEP web service Github Actions
PyGeoHydro Access NWIS, NID, WQP, eHydro, NLCD, CAMELS, and SSEBop databases Github Actions
PyDaymet Access daily, monthly, and annual climate data via Daymet Github Actions
PyGridMET Access daily climate data via GridMET Github Actions
PyNLDAS2 Access hourly NLDAS-2 data via web services Github Actions
HydroSignatures A collection of tools for computing hydrological signatures Github Actions
AsyncRetriever High-level API for asynchronous requests with persistent caching Github Actions
PyGeoOGC Send queries to any ArcGIS RESTful-, WMS-, and WFS-based services Github Actions
PyGeoUtils Utilities for manipulating geospatial, (Geo)JSON, and (Geo)TIFF data Github Actions

PyGeoOGC: Retrieve Data from RESTful, WMS, and WFS Services

PyPi Conda Version CodeCov Python Versions Downloads

Security Status CodeFactor Ruff pre-commit Binder

Features

PyGeoOGC is a part of HyRiver software stack that is designed to aid in hydroclimate analysis through web services. This package provides general interfaces to web services that are based on ArcGIS RESTful, WMS, and WFS. Although all these web services have limits on the number of features per request (e.g., 1000 object IDs for a RESTful request or 8 million pixels for a WMS request), PyGeoOGC, first, divides the large requests into smaller chunks, and then returns the merged results.

Moreover, under the hood, PyGeoOGC uses AsyncRetriever for making requests asynchronously with persistent caching. This improves the reliability and speed of data retrieval significantly. AsyncRetriever caches all request/response pairs and upon making an already cached request, it will retrieve the responses from the cache if the server's response is unchanged.

You can control the request/response caching behavior and verbosity of the package by setting the following environment variables:

  • HYRIVER_CACHE_NAME: Path to the caching SQLite database for asynchronous HTTP requests. It defaults to ./cache/aiohttp_cache.sqlite
  • HYRIVER_CACHE_NAME_HTTP: Path to the caching SQLite database for HTTP requests. It defaults to ./cache/http_cache.sqlite
  • HYRIVER_CACHE_EXPIRE: Expiration time for cached requests in seconds. It defaults to one week.
  • HYRIVER_CACHE_DISABLE: Disable reading/writing from/to the cache. The default is false.
  • HYRIVER_SSL_CERT: Path to a SSL certificate file.

For example, in your code before making any requests you can do:

import os

os.environ["HYRIVER_CACHE_NAME"] = "path/to/aiohttp_cache.sqlite"
os.environ["HYRIVER_CACHE_NAME_HTTP"] = "path/to/http_cache.sqlite"
os.environ["HYRIVER_CACHE_EXPIRE"] = "3600"
os.environ["HYRIVER_CACHE_DISABLE"] = "true"
os.environ["HYRIVER_SSL_CERT"] = "path/to/cert.pem"

There is also an inventory of URLs for some of these web services in form of a class called ServiceURL. These URLs are in four categories: ServiceURL().restful, ServiceURL().wms, ServiceURL().wfs, and ServiceURL().http. These URLs provide you with some examples of the services that PyGeoOGC supports. If you have success using PyGeoOGC with a web service please consider submitting a request to be added to this URL inventory. You can get all the URLs in the ServiceURL class by just printing it print(ServiceURL()).

PyGeoOGC has three main classes:

  • ArcGISRESTful: This class can be instantiated by providing the target layer URL. For example, for getting Watershed Boundary Data we can use ServiceURL().restful.wbd. By looking at the web service's website we see that there are nine layers. For example, 1 for 2-digit HU (Region), 6 for 12-digit HU (Subregion), and so on. We can pass the URL to the target layer directly, like this f"{ServiceURL().restful.wbd}/6" or as a separate argument via layer.

    Afterward, we request for the data in two steps. First, we need to get the target object IDs using oids_bygeom (within a geometry), oids_byfield (specific field IDs), or oids_bysql (any valid SQL 92 WHERE clause) class methods. Then, we can get the target features using get_features class method. The returned response can be converted into a geopandas.GeoDataFrame using json2geodf function from PyGeoUtils.

  • WMS: Instantiation of this class requires at least 3 arguments: service URL, layer name(s), and output format. Additionally, target CRS and the web service version can be provided. Upon instantiation, we can use getmap_bybox method class to get the target raster data within a bounding box. The box can be in any valid CRS and if it is different from the default CRS, EPSG:4326, it should be passed using box_crs argument. The service response can be converted into a xarray.Dataset using gtiff2xarray function from PyGeoUtils.

  • WFS: Instantiation of this class is similar to WMS. The only difference is that only one layer name can be passed. Upon instantiation there are three ways to get the data:

    • getfeature_bybox: Get all the target features within a bounding box in any valid CRS.
    • getfeature_byid: Get all the target features based on the IDs. Note that two arguments should be provided: featurename, and featureids. You can get a list of valid feature names using get_validnames class method.
    • getfeature_byfilter: Get the data based on any valid CQL filter.

    You can convert the returned response of this function to a GeoDataFrame using json2geodf function from PyGeoUtils package.

PyGeoOGC also includes several utilities:

  • streaming_download for downloading large files in parallel and in chunks, efficiently.
  • traverse_json for traversing a nested JSON object.
  • match_crs for reprojecting a geometry or bounding box to any valid CRS.

You can find some example notebooks here.

Furthermore, you can also try using PyGeoOGC without installing it on your system by clicking on the binder badge. A Jupyter Lab instance with the HyRiver stack pre-installed will be launched in your web browser, and you can start coding!

Moreover, requests for additional functionalities can be submitted via issue tracker.

Citation

If you use any of HyRiver packages in your research, we appreciate citations:

@article{Chegini_2021,
    author = {Chegini, Taher and Li, Hong-Yi and Leung, L. Ruby},
    doi = {10.21105/joss.03175},
    journal = {Journal of Open Source Software},
    month = {10},
    number = {66},
    pages = {1--3},
    title = {{HyRiver: Hydroclimate Data Retriever}},
    volume = {6},
    year = {2021}
}

Installation

You can install PyGeoOGC using pip:

$ pip install pygeoogc

Alternatively, PyGeoOGC can be installed from the conda-forge repository using Conda or Mamba:

$ conda install -c conda-forge pygeoogc

Quick start

We can access NHDPlus HR via RESTful service, National Wetlands Inventory from WMS, and FEMA National Flood Hazard via WFS. The output for these functions are of type requests.Response that can be converted to GeoDataFrame or xarray.Dataset using PyGeoUtils.

Let's start the National Map's NHDPlus HR web service. We can query the flowlines that are within a geometry as follows:

from pygeoogc import ArcGISRESTful, WFS, WMS, ServiceURL
import pygeoutils as geoutils
from pynhd import NLDI

basin_geom = NLDI().get_basins("01031500").geometry[0]

hr = ArcGISRESTful(ServiceURL().restful.nhdplushr, 2, outformat="json")

resp = hr.get_features(hr.oids_bygeom(basin_geom, 4326))
flowlines = geoutils.json2geodf(resp)

Note oids_bygeom has three additional arguments: sql_clause, spatial_relation, and distance. We can use sql_clause for passing any valid SQL WHERE clauses and spatial_relation for specifying the target predicate such as intersect, contain, cross, etc. The default predicate is intersect (esriSpatialRelIntersects). Additionally, we can use distance for specifying the buffer distance from the input geometry for getting features.

We can also submit a query based on IDs of any valid field in the database. If the measure property is desired you can pass return_m as True to the get_features class method:

oids = hr.oids_byfield("PERMANENT_IDENTIFIER", ["103455178", "103454362", "103453218"])
resp = hr.get_features(oids, return_m=True)
flowlines = geoutils.json2geodf(resp)

Additionally, any valid SQL 92 WHERE clause can be used. For more details look here. For example, let's limit our first request to only include catchments with areas larger than 0.5 sqkm.

oids = hr.oids_bygeom(basin_geom, geo_crs=4326, sql_clause="AREASQKM > 0.5")
resp = hr.get_features(oids)
catchments = geoutils.json2geodf(resp)

A WMS-based example is shown below:

wms = WMS(
    ServiceURL().wms.fws,
    layers="0",
    outformat="image/tiff",
    crs=3857,
)
r_dict = wms.getmap_bybox(
    basin_geom.bounds,
    1e3,
    box_crs=4326,
)
wetlands = geoutils.gtiff2xarray(r_dict, basin_geom, 4326)

Query from a WFS-based web service can be done either within a bounding box or using any valid CQL filter.

wfs = WFS(
    ServiceURL().wfs.fema,
    layer="public_NFHL:Base_Flood_Elevations",
    outformat="esrigeojson",
    crs=4269,
)
r = wfs.getfeature_bybox(basin_geom.bounds, box_crs=4326)
flood = geoutils.json2geodf(r.json(), 4269, 4326)

layer = "wmadata:huc08"
wfs = WFS(
    ServiceURL().wfs.waterdata,
    layer=layer,
    outformat="application/json",
    version="2.0.0",
    crs=4269,
)
r = wfs.getfeature_byfilter(f"huc8 LIKE '13030%'")
huc8 = geoutils.json2geodf(r.json(), 4269, 4326)
https://raw.githubusercontent.com/hyriver/HyRiver-examples/main/notebooks/_static/sql_clause.png

Contributing

Contributions are appreciated and very welcomed. Please read CONTRIBUTING.rst for instructions.

pygeoogc's People

Contributors

cheginit avatar dependabot[bot] avatar fernando-aristizabal avatar pre-commit-ci[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

pygeoogc's Issues

Terminology, OGC vs ArcGIS RESTful services

I wanted to point out what I see as an inconsistency in terminology and references.

OGC, the Open Geospatial Consortium, has developed many open, community standards. Two of the oldest and most common ones are WMS and WFS.

ESRI ArcGIS RESTful services (officially the "ArcGIS REST API", I think), while widely used b/c the ESRI platform is widespread, are not an OGC standard. So, having these services in a package that has ogc is confusing, I think. It gets more confusing b/c ArcGIS RESTful services implements its own web map services that ESRI also calls WMS, but it's not OGC WMS.

To avoid ambiguity, OGC standards should be referred to as, say, ogcwms and ogcwfs. I think it'd be better to split your WMS (and WFS) class into OGCWMS vs, say, AGRWMS. You may consider also renaming the package itself to something more generic so it doesn't imply OGC services only; for example, pygeoaccess. But I realize that's a lot more work for you at this stage!

Anyway, just my 2 cents. You've created a set of fantastic packages!

TypeAlias and "|" for unions are python 3.10+ features

What happened?

Forked the development version to prepare a pull request and noticed that in "cache_keys.py" you started using TypeAlias and "|" for unions. I was caught recently taking the advice of a linter, I think pyright that was targeting the very latest python versions but I wanted to support python 3.8+. I noticed that pygeoogc also supports 3.8+ and just wanted to point out the TypeAlias and "|" for unions are 3.10+ features.

Kind regards,
Tim

What did you expect to happen?

No response

Minimal Complete Verifiable Example

No response

MVCE confirmation

  • Minimal example — the example is as focused as reasonably possible to demonstrate the underlying issue.
  • Complete example — the example is self-contained, including all data and the text of any traceback.
  • New issue — a search of GitHub Issues suggests this is not a duplicate.

Relevant log output

No response

Anything else we need to know?

No response

Environment

git fork

README refers to file that does not exist in repo

The readme refers to urls.yml within the static folder, but that folder and file do not seem to exist or have not yet been committed to the repo.

Release 0.2.0 notes...

Moved all the web services URLs to a YAML file that ServiceURL class reads. It makes managing the new URLs easier. The file is located at pygeoogc/static/urls.yml.

But the file seems to have been missed somehow.

WFS request does not work

What happened?

I use the code below but it returns error (shown in example section). I tried everything I knew but unable to get a result.

bounds[0] = (-78.37650499999897, 40.691622000000514, -77.1441599999993, 41.252665000000405)

wfs = WFS(
ServiceURL().wfs.fema,
layer="NFHL:Base_Flood_Elevations",
outformat="geojson",
crs=4326,)
r = wfs.getfeature_bybox(bounds[0], box_crs=4326)

flood = geoutils.json2geodf(r.json(), 4326, 4326)

What did you expect to happen?

to get the map for flood area

Minimal Complete Verifiable Example

ValueError                                Traceback (most recent call last)
File ~\Anaconda3_5\envs\pvlibdev\lib\site-packages\pygeoogc\pygeoogc.py:589, in WFS.getfeature_bybox(self, bbox, box_crs, always_xy, sort_attr)
    588 try:
--> 589     nfeatures = int(resp[0].split(self.nfeat_key)[-1].split(" ")[0].strip('"'))
    590 except (IndexError, ValueError) as ex:

ValueError: invalid literal for int() with base 10: '<?xml'

The above exception was the direct cause of the following exception:

ServiceError                              Traceback (most recent call last)
Cell In[40], line 6
      1 wfs = WFS(
      2     ServiceURL().wfs.fema,
      3     layer="NFHL:Base_Flood_Elevations",
      4     outformat="geojson",
      5     crs=4269,)
----> 6 r = wfs.getfeature_bybox(bounds[0], box_crs=4326)
      7 # r = wfs.getfeature_bygeom(bounds_pgon, geo_crs=4326)
      8 flood = geoutils.json2geodf(r.json(), 4326, 4326)

File ~\Anaconda3_5\envs\pvlibdev\lib\site-packages\pygeoogc\pygeoogc.py:591, in WFS.getfeature_bybox(self, bbox, box_crs, always_xy, sort_attr)
    589     nfeatures = int(resp[0].split(self.nfeat_key)[-1].split(" ")[0].strip('"'))
    590 except (IndexError, ValueError) as ex:
--> 591     raise ServiceError(resp[0], self.url) from ex
    593 payloads = [
    594     {
    595         "service": "wfs",
   (...)
    604     for i in range(0, nfeatures, self.max_nrecords)
    605 ]
    607 return self.retrieve([self.url] * len(payloads), [{"params": p} for p in payloads])

ServiceError: Service returned the following error message:
URL: https://hazards.fema.gov/gis/nfhl/services/public/NFHL/MapServer/WFSServer
ERROR: <?xml version="1.0" encoding="utf-8" ?><wfs:FeatureCollection xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:NFHL="https://hazards.fema.gov/arcgis/admin/services/NFHL/MapServer/WFSServer" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-basic.xsd http://www.opengis.net/gml http://schemas.opengis.net/gml/2.1.2/feature.xsd https://hazards.fema.gov/arcgis/admin/services/NFHL/MapServer/WFSServer https://hazards.fema.gov/nfhl/services/public/NFHL/MapServer/WFSServer?service=wfs%26version=1.0.0%26request=DescribeFeatureType"><gml:boundedBy><gml:Box srsName="EPSG:4269"><gml:coordinates>0.00000000,0.00000000 0.00000000,0.00000000</gml:coordinates>  </gml:Box></gml:boundedBy></wfs:FeatureCollection>

MVCE confirmation

  • Minimal example — the example is as focused as reasonably possible to demonstrate the underlying issue.
  • Complete example — the example is self-contained, including all data and the text of any traceback.
  • New issue — a search of GitHub Issues suggests this is not a duplicate.

Relevant log output

ValueError                                Traceback (most recent call last)
File ~\Anaconda3_5\envs\pvlibdev\lib\site-packages\pygeoogc\pygeoogc.py:589, in WFS.getfeature_bybox(self, bbox, box_crs, always_xy, sort_attr)
    588 try:
--> 589     nfeatures = int(resp[0].split(self.nfeat_key)[-1].split(" ")[0].strip('"'))
    590 except (IndexError, ValueError) as ex:

ValueError: invalid literal for int() with base 10: '<?xml'

The above exception was the direct cause of the following exception:

ServiceError                              Traceback (most recent call last)
Cell In[40], line 6
      1 wfs = WFS(
      2     ServiceURL().wfs.fema,
      3     layer="NFHL:Base_Flood_Elevations",
      4     outformat="geojson",
      5     crs=4269,)
----> 6 r = wfs.getfeature_bybox(bounds[0], box_crs=4326)
      7 # r = wfs.getfeature_bygeom(bounds_pgon, geo_crs=4326)
      8 flood = geoutils.json2geodf(r.json(), 4326, 4326)

File ~\Anaconda3_5\envs\pvlibdev\lib\site-packages\pygeoogc\pygeoogc.py:591, in WFS.getfeature_bybox(self, bbox, box_crs, always_xy, sort_attr)
    589     nfeatures = int(resp[0].split(self.nfeat_key)[-1].split(" ")[0].strip('"'))
    590 except (IndexError, ValueError) as ex:
--> 591     raise ServiceError(resp[0], self.url) from ex
    593 payloads = [
    594     {
    595         "service": "wfs",
   (...)
    604     for i in range(0, nfeatures, self.max_nrecords)
    605 ]
    607 return self.retrieve([self.url] * len(payloads), [{"params": p} for p in payloads])

ServiceError: Service returned the following error message:
URL: https://hazards.fema.gov/gis/nfhl/services/public/NFHL/MapServer/WFSServer
ERROR: <?xml version="1.0" encoding="utf-8" ?><wfs:FeatureCollection xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:NFHL="https://hazards.fema.gov/arcgis/admin/services/NFHL/MapServer/WFSServer" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-basic.xsd http://www.opengis.net/gml http://schemas.opengis.net/gml/2.1.2/feature.xsd https://hazards.fema.gov/arcgis/admin/services/NFHL/MapServer/WFSServer https://hazards.fema.gov/nfhl/services/public/NFHL/MapServer/WFSServer?service=wfs%26version=1.0.0%26request=DescribeFeatureType"><gml:boundedBy><gml:Box srsName="EPSG:4269"><gml:coordinates>0.00000000,0.00000000 0.00000000,0.00000000</gml:coordinates>  </gml:Box></gml:boundedBy></wfs:FeatureCollection>

Anything else we need to know?

Two things:

First in another account, it seems the fws: str = (
"https://www.fws.gov/wetlandsmapservice/services/Wetlands_Raster/ImageServer/WMSServer"

is changed to 'https://www.fws.gov/wetlandsmapservice/services/WetlandsRaster/ImageServer/WMSServer'.

Second back to the issue:

I tried some debugging to see the response from the server and here is the result

ipdb> resp
['<wfs:FeatureCollection xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:NFHL="https://hazards.fema.gov/arcgis/admin/services/NFHL/MapServer/WFSServer" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-basic.xsd http://www.opengis.net/gml http://schemas.opengis.net/gml/2.1.2/feature.xsd https://hazards.fema.gov/arcgis/admin/services/NFHL/MapServer/WFSServer https://hazards.fema.gov/nfhl/services/public/NFHL/MapServer/WFSServer?service=wfs%26version=1.0.0%26request=DescribeFeatureType">gml:boundedBy<gml:Box srsName="EPSG:4269">gml:coordinates0.00000000,0.00000000 0.00000000,0.00000000</gml:coordinates> </gml:Box></gml:boundedBy></wfs:FeatureCollection>']
ipdb> c

Environment

SYS INFO -------- commit: None python: 3.10.9 | packaged by conda-forge | (main, Jan 11 2023, 15:15:40) [MSC v.1916 64 bit (AMD64)] python-bits: 64 OS: Windows OS-release: 10 machine: AMD64 processor: Intel64 Family 6 Model 140 Stepping 1, GenuineIntel byteorder: little LC_ALL: None LANG: None LOCALE: ('English_United States', '1252')

PACKAGE VERSION

async-retriever 0.16.0
pygeoogc 0.16.3
pygeoutils 0.16.3
py3dep 0.16.3
pynhd 0.16.2
pygridmet N/A
pydaymet N/A
hydrosignatures 0.16.0
pynldas2 N/A
pygeohydro 0.16.5
aiohttp 3.9.3
aiohttp-client-cache 0.11.0
aiosqlite 0.20.0
cytoolz 0.12.3
ujson 5.10.0
defusedxml 0.7.1
joblib 1.3.2
multidict 6.0.5
owslib 0.30.0
pyproj 3.6.1
requests 2.32.3
requests-cache 1.2.1
shapely 2.0.4
url-normalize 1.4.3
urllib3 1.26.14
yarl 1.9.4
geopandas 1.0.0
netcdf4 1.6.0
numpy 1.23.5
rasterio 1.3.10
rioxarray 0.15.6
scipy 1.13.1
xarray 2024.6.0
click 8.1.7
pyflwdir N/A
networkx 3.1
pyarrow 15.0.2
folium 0.17.0
h5netcdf 1.3.0
matplotlib 3.9.0
pandas 2.2.2
numba 0.56.4
bottleneck 1.4.0
py7zr N/A
pyogrio 0.9.0

WMS service error

I'm not good at GIS web service and coordinate system. So I don't know what the exact problem is.

I got an error in the third cell in the 3dep notebook.
dem = py3dep.get_map("DEM", geometry, resolution=30, geo_crs="epsg:4326", crs="epsg:3857").
The error is from the WMS server. Do you know how to solve the problem?


HTTPError Traceback (most recent call last)
in
----> 1 dem = py3dep.get_map("DEM", geometry, resolution=30, geo_crs="epsg:4326", crs="epsg:3857")
2 dem.name = "dem"
3 dem.attrs["units"] = "meters"
4 slope = py3dep.get_map("Slope Degrees", geometry, resolution=30)
5 slope = py3dep.deg2mpm(slope)

/srv/conda/envs/notebook/lib/python3.8/site-packages/py3dep/py3dep.py in get_map(layers, geometry, resolution, geo_crs, crs, fill_holes)
76 _layers = [f"3DEPElevation:{lyr}" for lyr in _layers]
77
---> 78 wms = WMS(ServiceURL().wms.nm_3dep, layers=_layers, outformat="image/tiff", crs=crs)
79 r_dict = wms.getmap_bybox(_geometry.bounds, resolution, box_crs=crs)
80

/srv/conda/envs/notebook/lib/python3.8/site-packages/pygeoogc/pygeoogc.py in init(self, url, layers, outformat, version, crs, validation)
456 self.layers = [self.layers] if isinstance(self.layers, str) else self.layers
457 if validation:
--> 458 self.validate_wms()
459
460 def getmap_bybox(

/srv/conda/envs/notebook/lib/python3.8/site-packages/pygeoogc/pygeoogc.py in validate_wms(self)
390 def validate_wms(self) -> None:
391 """Validate input arguments with the WMS service."""
--> 392 wms = WebMapService(self.url, version=self.version)
393
394 valid_layers = {wms[lyr].name: wms[lyr].title for lyr in list(wms.contents)}

/srv/conda/envs/notebook/lib/python3.8/site-packages/owslib/wms.py in WebMapService(url, version, xml, username, password, parse_remote_metadata, timeout, headers, auth)
52 timeout=timeout, headers=headers, auth=auth)
53 elif version in ['1.3.0']:
---> 54 return wms130.WebMapService_1_3_0(
55 clean_url, version=version, xml=xml, parse_remote_metadata=parse_remote_metadata,
56 timeout=timeout, headers=headers, auth=auth)

/srv/conda/envs/notebook/lib/python3.8/site-packages/owslib/map/wms130.py in init(self, url, version, xml, username, password, parse_remote_metadata, timeout, headers, auth)
73 self._capabilities = reader.readString(xml)
74 else: # read from server
---> 75 self._capabilities = reader.read(self.url, timeout=self.timeout)
76
77 self.request = reader.request

/srv/conda/envs/notebook/lib/python3.8/site-packages/owslib/map/common.py in read(self, service_url, timeout)
63 # now split it up again to use the generic openURL function...
64 spliturl = self.request.split('?')
---> 65 u = openURL(spliturl[0], spliturl[1], method='Get',
66 timeout=timeout, headers=self.headers, auth=self.auth)
67

/srv/conda/envs/notebook/lib/python3.8/site-packages/owslib/util.py in openURL(url_base, data, method, cookies, username, password, timeout, headers, verify, cert, auth)
207
208 if req.status_code in [404, 500, 502, 503, 504]: # add more if needed
--> 209 req.raise_for_status()
210
211 # check for service exceptions without the http header set

/srv/conda/envs/notebook/lib/python3.8/site-packages/requests/models.py in raise_for_status(self)
939
940 if http_error_msg:
--> 941 raise HTTPError(http_error_msg, response=self)
942
943 def close(self):

HTTPError: 502 Server Error: Bad Gateway for url: https://elevation.nationalmap.gov/arcgis/services/3DEPElevation/ImageServer/WMSServer?service=WMS&request=GetCapabilities&version=1.3.0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.