Skip to content

Commit 6f5d229

Browse files
authored
New get_stat_value and get_stat_series functions (#142)
Also: * Made tests work for python2, add python2 to run_tests_local.sh. * Add payload option to _send_request
1 parent 6d09ca1 commit 6f5d229

12 files changed

Lines changed: 499 additions & 61 deletions

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ $ cloud-build-local --config=cloudbuild.yaml --dryrun=false .
5454

5555
Both commands will run the same set of tests.
5656

57+
To run the examples:
58+
59+
```
60+
$ python -m datacommons.examples.XXX
61+
```
62+
63+
where XXX is the module you want to run.
64+
5765
## Release to PyPI
5866

5967
- Update "VERSION" in setup.py

datacommons/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from datacommons.core import get_property_labels, get_property_values, get_triples
2020
from datacommons.places import get_places_in, get_related_places, get_stats
2121
from datacommons.populations import get_populations, get_observations, get_pop_obs, get_place_obs
22+
from datacommons.stat_vars import get_stat_value, get_stat_series
2223

2324
# Other utilities
2425
from .utils import set_api_key

datacommons/examples/stat_vars.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Copyright 2020 Google Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
"""Basic examples for StatisticalVariable-based param_set Commons API functions."""
15+
16+
from __future__ import absolute_import
17+
from __future__ import division
18+
from __future__ import print_function
19+
20+
import datacommons as dc
21+
22+
23+
def main():
24+
param_sets = [
25+
{
26+
'place': 'geoId/06085',
27+
'stat_var': 'Count_Person',
28+
},
29+
{
30+
'place': 'geoId/06085',
31+
'stat_var': 'Count_Person',
32+
'date': '2018',
33+
},
34+
{
35+
'place': 'geoId/06085',
36+
'stat_var': 'Count_Person',
37+
'date': '2018',
38+
'measurement_method': 'CensusACS5yrSurvey',
39+
},
40+
{
41+
'place': 'geoId/06085',
42+
'stat_var': 'UnemploymentRate_Person',
43+
},
44+
{
45+
'place': 'geoId/06085',
46+
'stat_var': 'UnemploymentRate_Person',
47+
'observation_period': "P1Y",
48+
},
49+
{
50+
'place': 'geoId/06085',
51+
'stat_var': 'UnemploymentRate_Person',
52+
'observation_period': "P1Y",
53+
'measurement_method': "BLSSeasonallyUnadjusted",
54+
},
55+
{
56+
'place':
57+
'nuts/HU22',
58+
'stat_var':
59+
'Amount_EconomicActivity_GrossDomesticProduction_Nominal',
60+
},
61+
{
62+
'place':
63+
'nuts/HU22',
64+
'stat_var':
65+
'Amount_EconomicActivity_GrossDomesticProduction_Nominal',
66+
'observation_period':
67+
"P1Y",
68+
'unit':
69+
"PurchasingPowerStandard"
70+
},
71+
]
72+
73+
def call_str(pvs):
74+
"""Helper function to print the minimal call string."""
75+
s = "'{}', '{}'".format(pvs.get('place'), pvs.get('stat_var'))
76+
if pvs.get('measurement_method'):
77+
s += ", measurement_method='{}'".format(
78+
pvs.get('measurement_method'))
79+
if pvs.get('observation_period'):
80+
s += ", observation_period='{}'".format(
81+
pvs.get('observation_period'))
82+
if pvs.get('unit'):
83+
s += ", unit='{}'".format(pvs.get('unit'))
84+
if pvs.get('scaling_factor'):
85+
s += ", scaling_factor={}".format(pvs.get('scaling_factor'))
86+
return s
87+
88+
for pvs in param_sets:
89+
print('\nget_stat_value({})'.format(call_str(pvs)))
90+
print(
91+
'>>> ',
92+
dc.get_stat_value(pvs.get('place'),
93+
pvs.get('stat_var'),
94+
date=pvs.get('date'),
95+
measurement_method=pvs.get('measurement_method'),
96+
observation_period=pvs.get('observation_period'),
97+
unit=pvs.get('unit'),
98+
scaling_factor=pvs.get('scaling_factor')))
99+
for pvs in param_sets:
100+
pvs.pop('date', None)
101+
print('\nget_stat_series({})'.format(call_str(pvs)))
102+
print(
103+
'>>> ',
104+
dc.get_stat_series(pvs.get('place'),
105+
pvs.get('stat_var'),
106+
measurement_method=pvs.get('measurement_method'),
107+
observation_period=pvs.get('observation_period'),
108+
unit=pvs.get('unit'),
109+
scaling_factor=pvs.get('scaling_factor')))
110+
111+
112+
if __name__ == '__main__':
113+
main()

datacommons/stat_vars.py

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# Copyright 2020 Google Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
"""Data Commons Python API Stat Module.
15+
16+
Provides functions for getting data on StatVars from Data Commons Graph.
17+
"""
18+
19+
from __future__ import absolute_import
20+
from __future__ import division
21+
from __future__ import print_function
22+
23+
from datacommons.utils import _API_ROOT, _API_ENDPOINTS, _ENV_VAR_API_KEY
24+
25+
import json
26+
import os
27+
import six.moves.urllib.error
28+
import six.moves.urllib.request
29+
30+
import datacommons.utils as utils
31+
32+
33+
def get_stat_value(place,
34+
stat_var,
35+
date=None,
36+
measurement_method=None,
37+
observation_period=None,
38+
unit=None,
39+
scaling_factor=None):
40+
"""Returns a value for :code:`place` based on the :code:`stat_var`.
41+
42+
Args:
43+
place (:obj:`iterable` of :obj:`str`): The dcid of `Place` to query for.
44+
stat_var (:obj:`str`): The dcid of the `StatisticalVariable`.
45+
date (:obj:`str`): Optional, the preferred date of observation
46+
in ISO 8601 format. If not specified, returns the latest observation.
47+
measurement_method (:obj:`str`): Optional, the dcid of the preferred
48+
`measurementMethod` value.
49+
observation_period (:obj:`str`): Optional, the preferred
50+
`observationPeriod` value.
51+
unit (:obj:`str`): Optional, the dcid of the preferred `unit` value.
52+
scaling_factor (:obj:`int`): Optional, the preferred `scalingFactor` value.
53+
Returns:
54+
A :obj:`float` the value of :code:`stat_var` for :code:`place`, filtered
55+
by optional args.
56+
57+
Raises:
58+
ValueError: If the payload returned by the Data Commons REST API is
59+
malformed.
60+
61+
Examples:
62+
>>> get_stat_value("geoId/05", "Count_Person")
63+
366331
64+
"""
65+
url = utils._API_ROOT + utils._API_ENDPOINTS['get_stat_value']
66+
url += '?place={}&stat_var={}'.format(place, stat_var)
67+
if date:
68+
url += '&date={}'.format(date)
69+
if measurement_method:
70+
url += '&measurement_method={}'.format(measurement_method)
71+
if observation_period:
72+
url += '&observation_period={}'.format(observation_period)
73+
if unit:
74+
url += '&unit={}'.format(unit)
75+
if scaling_factor:
76+
url += '&scaling_factor={}'.format(scaling_factor)
77+
78+
res_json = utils._send_request(url, post=False, use_payload=False)
79+
80+
if 'value' not in res_json:
81+
raise ValueError('No data in response.')
82+
return res_json['value']
83+
84+
85+
def get_stat_series(place,
86+
stat_var,
87+
measurement_method=None,
88+
observation_period=None,
89+
unit=None,
90+
scaling_factor=None):
91+
"""Returns a :obj:`dict` for :code:`place` based on the :code:`stat_var`.
92+
93+
Args:
94+
place (:obj:`iterable` of :obj:`str`): The dcid of `Place` to query for.
95+
stat_var (:obj:`str`): The dcid of the `StatisticalVariable`.
96+
measurement_method (:obj:`str`): Optional, the dcid of the preferred
97+
`measurementMethod` value.
98+
observation_period (:obj:`str`): Optional, the preferred
99+
`observationPeriod` value.
100+
unit (:obj:`str`): Optional, the dcid of the preferred `unit` value.
101+
scaling_factor (:obj:`int`): Optional, the preferred `scalingFactor` value.
102+
Returns:
103+
A :obj:`dict` mapping dates to value of :code:`stat_var` for :code:`place`,
104+
filtered by optional args.
105+
106+
Raises:
107+
ValueError: If the payload returned by the Data Commons REST API is
108+
malformed.
109+
110+
Examples:
111+
>>> get_stat_series("geoId/05", "Count_Person")
112+
{"1962":17072000,"2009":36887615,"1929":5531000,"1930":5711000}
113+
"""
114+
url = utils._API_ROOT + utils._API_ENDPOINTS['get_stat_series']
115+
url += '?place={}&stat_var={}'.format(place, stat_var)
116+
if measurement_method:
117+
url += '&measurement_method={}'.format(measurement_method)
118+
if observation_period:
119+
url += '&observation_period={}'.format(observation_period)
120+
if unit:
121+
url += '&unit={}'.format(unit)
122+
if scaling_factor:
123+
url += '&scaling_factor={}'.format(scaling_factor)
124+
125+
res_json = utils._send_request(url, post=False, use_payload=False)
126+
127+
if 'series' not in res_json:
128+
raise ValueError('No data in response.')
129+
return res_json['series']

0 commit comments

Comments
 (0)