Skip to content

Commit

Permalink
Merge pull request #1 from global-water-watch/featurecollection_response
Browse files Browse the repository at this point in the history
list endpoints now return FeatureCollection
  • Loading branch information
Jaapel committed Mar 30, 2023
2 parents 8daf4ef + 4858cf8 commit bd9aa32
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 105 deletions.
122 changes: 62 additions & 60 deletions gwwapi/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,31 @@
start = datetime.datetime(2000, 1, 1)
stop = datetime.datetime(2023, 1, 1)


# Check request function
def _check_request(r):
""" Checks request """
"""Checks request"""
try:
r.raise_for_status()
except requests.RequestException as e:
except requests.RequestException as e:
print(e)
print(r.text)
raise e


# Get Requests
def get_reservoirs(skip=1, limit=5):
"""
Gets reservoirs from API. Return list of reservoirs.
Each list element is a dict representing a reservoir.
The dict will contain the reservoir geometry and a set of reservoir properties.
Gets reservoirs from API. Return a FeatureCollection of reservoirs.
Args:
skip (int): How many reservoir to skip
limit (int): Max number of reservoirs that will be returned.
Returns:
list: Containing reservoirs
Returns:
dictionary with FeatureCollection.
"""


url = f"{base_url}/reservoir"
params = {
"skip": skip,
Expand All @@ -44,113 +43,116 @@ def get_reservoirs(skip=1, limit=5):

r = requests.get(url, params=params, timeout=2)
_check_request(r)
return(r.json())
return r.json()

def get_reservoir_by_id(reservoir_id:int):

def get_reservoir_by_id(reservoir_id: int):
"""
Get reservoir (geometry and props) by ID.
Args:
reservoir_id (int): Global Water Watch ID.
Returns:
Args:
reservoir_id (int): Global Water Watch ID.
Returns:
dict: containing reservoir geometry and properties
"""


url = f"{base_url}/reservoir/{reservoir_id}"

r = requests.get(url)
_check_request(r)
return(r.json())

def get_reservoir_ts(reservoir_id:int, start=start, stop=stop):
return r.json()


def get_reservoir_ts(reservoir_id: int, start=start, stop=stop):
"""
Get time series data for reservoir with given ID. This will return raw data. If you want to obtain post-processed monthly data, use the get_reservoir_ts_monthly function instead.
Args:
Get time series data for reservoir with given ID. This will return raw data. If you want to obtain post-processed monthly data, use the get_reservoir_ts_monthly function instead.
Args:
reservoir_id (str): Global Water Watch Reservoir ID
start (datetime.datetime()): Start
start (datetime.datetime()): Start
stop (datetime.datetime()): Stop
Returns:
Returns:
list: containing dictionaries with time, value, unit and variable name of the reservoir time series
"""
url = f"{base_url}/reservoir/{reservoir_id}/ts/surface_water_area"
params = {
"start": start.strftime("%Y-%m-%dT%H:%M:%S"),
"stop": stop.strftime("%Y-%m-%dT%H:%M:%S")
"stop": stop.strftime("%Y-%m-%dT%H:%M:%S"),
}

r = requests.get(url, params=params)
_check_request(r)
return(r.json())
return r.json()

def get_reservoir_ts_monthly(reservoir_id:int, start=start, stop=stop):

def get_reservoir_ts_monthly(reservoir_id: int, start=start, stop=stop):
"""
Get monthly time series data for reservoir with given ID. Monthly time series data is post-processed from the raw data. If you want to obtain the raw data, use the get_reservoir_ts function instead.
Args:
Get monthly time series data for reservoir with given ID. Monthly time series data is post-processed from the raw data. If you want to obtain the raw data, use the get_reservoir_ts function instead.
Args:
reservoir_id (str): Global Water Watch Reservoir ID
start (datetime.datetime()): Start
start (datetime.datetime()): Start
stop (datetime.datetime()): Stop
Returns:
Returns:
list: containing dictionaries with time, value, unit and variable name of the reservoir time series
"""


url = f"{base_url}/reservoir/{reservoir_id}/ts/surface_water_area_monthly"
params = {
"start": start.strftime("%Y-%m-%dT%H:%M:%S"),
"stop": stop.strftime("%Y-%m-%dT%H:%M:%S")
"stop": stop.strftime("%Y-%m-%dT%H:%M:%S"),
}

r = requests.get(url, params=params)
_check_request(r)
return(r.json())
return r.json()


# Post Requests
def get_reservoirs_by_geom(geom:str):
def get_reservoirs_by_geom(geom: str):
"""
For a geometry, return the list of reservoirs in that geometry. Each element in the list is a dict containing reservoir geometry and properties.
For a geometry, return the FeatureCollection of reservoirs in that geometry.
Args:
Args:
geom (str)
Returns:
Returns:
list: List containing all reservoirs
"""

url = f"{base_url}/reservoir/geometry"
# do post request to end point with the serialized geometry as post data
r = requests.post(url, data=geom)
_check_request(r)
return(r.json())
return r.json()


def get_reservoir_ts_monthly_by_geom(geom:str, start=start, stop=stop):
def get_reservoir_ts_monthly_by_geom(geom: str, start=start, stop=stop):
"""
For a geometry, return all monthly timeseries within that geometry.
For a geometry, return all monthly timeseries within that geometry.
Args:
Args:
geom (str): Input Geometry
start (datetime.datetime()): Start
start (datetime.datetime()): Start
stop (datetime.datetime()): Stop
Returns:
Returns:
list: List containing monthly surface water area time series for all reservoirs within the geometry
"""

url = f"{base_url}/reservoir/geometry/ts/surface_water_area"

params = {
"agg_period": "monthly",
"start": start.strftime("%Y-%m-%dT%H:%M:%S"),
"stop": stop.strftime("%Y-%m-%dT%H:%M:%S")
"stop": stop.strftime("%Y-%m-%dT%H:%M:%S"),
}
# do post request to end point with the serialized geometry as post data
r = requests.post(url, params=params, data=geom)
# _check_request(r)
return(r.json())
return r.json()
14 changes: 7 additions & 7 deletions gwwapi/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,21 @@
import pandas as pd
from shapely.geometry import shape


# Utils
def to_geopandas(data:list):
def to_geopandas(data: list):
"""
Ingests list of reservoirs and converts into a geopandas GeoDataFrame for further analyses.
Args:
data (list): List
Args:
data (list): List
"""
geoms = [shape(f["geometry"]) for f in data]
props = [{**f["properties"], **{"id": f["id"]}} for f in data]
return gpd.GeoDataFrame(props, geometry=geoms, crs=4326)


def to_timeseries(data, name=None):
"""
Convert raw list of jsons to organized pandas.DataFrame
Expand All @@ -27,6 +29,4 @@ def to_timeseries(data, name=None):
t_index = pd.to_datetime([p["t"] for p in data])
v = [{name: p["value"]} for p in data]

return pd.DataFrame(
v,
index=t_index.date)
return pd.DataFrame(v, index=t_index.date)
63 changes: 25 additions & 38 deletions tests/test_pytest.py
Original file line number Diff line number Diff line change
@@ -1,49 +1,36 @@
import pytest
from gwwapi import client as cli
from gwwapi import utils
import json
import pytest
from gwwapi import client as cli
from gwwapi import utils
import json


class TestClass:
def test_get_reservoirs(skip=50, limit=2):
# test if reservoir is retrieved and has the expected id
r = cli.get_reservoirs(skip=50, limit=2)
gdf = utils.to_geopandas(r)
assert gdf.iloc[0]["id"] == 60
gdf = utils.to_geopandas(r["features"])
assert int(gdf.iloc[0]["id"]) == 60

def test_get_reservoir_ts(id=3001):
# test if reservoir ts is retreived and has expected column header
assert cli.get_reservoir_ts(3001)[0]['name'] == 'surface_water_area'
assert cli.get_reservoir_ts(3001)[0]["name"] == "surface_water_area"

def test_get_reservoirs_by_geom(geom):

geom = json.dumps({
"type": "Polygon",
"coordinates": [
[
[
15.97412109375,
49.0880329436187
],
[
16.194190979003906,
49.0880329436187
],
[
16.194190979003906,
49.20503726723141
geom = json.dumps(
{
"type": "Polygon",
"coordinates": [
[
[15.97412109375, 49.0880329436187],
[16.194190979003906, 49.0880329436187],
[16.194190979003906, 49.20503726723141],
[15.97412109375, 49.20503726723141],
[15.97412109375, 49.0880329436187],
]
],
[
15.97412109375,
49.20503726723141
],
[
15.97412109375,
49.0880329436187
]
]
]
})

r = cli.get_reservoirs_by_geom(geom)
assert 'id' in r[0].keys()
assert r[0]['id'] == 60841
}
)

features = cli.get_reservoirs_by_geom(geom)["features"]
assert "id" in features[0].keys()
assert int(features[0]["id"]) == 60841

0 comments on commit bd9aa32

Please sign in to comment.