ebird-api 3.0.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ebird/api/__init__.py +51 -0
- ebird/api/checklists.py +97 -0
- ebird/api/client.py +338 -0
- ebird/api/constants.py +93 -0
- ebird/api/hotspots.py +143 -0
- ebird/api/observations.py +629 -0
- ebird/api/regions.py +109 -0
- ebird/api/statistics.py +86 -0
- ebird/api/taxonomy.py +181 -0
- ebird/api/utils.py +165 -0
- ebird/api/validation.py +329 -0
- ebird_api-3.0.6.dist-info/LICENSE.txt +21 -0
- ebird_api-3.0.6.dist-info/METADATA +321 -0
- ebird_api-3.0.6.dist-info/RECORD +16 -0
- ebird_api-3.0.6.dist-info/WHEEL +6 -0
- ebird_api-3.0.6.dist-info/top_level.txt +1 -0
ebird/api/regions.py
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"""Functions for fetching information about regions."""
|
|
2
|
+
|
|
3
|
+
from ebird.api.utils import call
|
|
4
|
+
|
|
5
|
+
from ebird.api.validation import clean_region, clean_region_type
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
REGION_LIST_URL = 'https://ebird.org/ws2.0/ref/region/list/%s/%s.json'
|
|
9
|
+
ADJACENT_REGIONS_URL = 'https://ebird.org/ws2.0/ref/adjacent/%s'
|
|
10
|
+
REGION_INFO_URL = 'https://ebird.org/ws2.0/ref/region/info/%s'
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_regions(token, rtype, region):
|
|
14
|
+
"""Get the list of sub-regions or a given region.
|
|
15
|
+
|
|
16
|
+
This maps to the end point in the eBird API 2.0,
|
|
17
|
+
https://documenter.getpostman.com/view/664302/S1ENwy59?version=latest#e25218db-566b-4d8b-81ca-e79a8f68c599
|
|
18
|
+
|
|
19
|
+
Not all combinations of region type and region code are supported.
|
|
20
|
+
You can get all the subnational2 regions of a country but you cannot
|
|
21
|
+
get the subnational2 regions for the world.
|
|
22
|
+
|
|
23
|
+
:param token: the token needed to access the API.
|
|
24
|
+
|
|
25
|
+
:param rtype: the region type, either 'country', 'subnational1' or 'subnational2'.
|
|
26
|
+
|
|
27
|
+
:param region: the name of the region, either 'world', a country or a subnational1 code.
|
|
28
|
+
|
|
29
|
+
:return: the list of sub-regions within the given region.
|
|
30
|
+
|
|
31
|
+
:raises ValueError: if an invalid region type is given.
|
|
32
|
+
|
|
33
|
+
:raises URLError if there is an error with the connection to the
|
|
34
|
+
eBird site.
|
|
35
|
+
|
|
36
|
+
:raises HTTPError if the eBird API returns an error.
|
|
37
|
+
|
|
38
|
+
"""
|
|
39
|
+
url = REGION_LIST_URL % (clean_region_type(rtype), clean_region(region))
|
|
40
|
+
|
|
41
|
+
headers = {
|
|
42
|
+
'X-eBirdApiToken': token,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return call(url, {}, headers)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def get_adjacent_regions(token, region):
|
|
49
|
+
"""Get the regions adjacent to a given region.
|
|
50
|
+
|
|
51
|
+
This maps to the end point in the eBird API 2.0,
|
|
52
|
+
https://documenter.getpostman.com/view/664302/S1ENwy59?version=latest#3aca0519-3105-47fc-8611-a4dfd500a32f
|
|
53
|
+
|
|
54
|
+
:param token: the token needed to access the API.
|
|
55
|
+
|
|
56
|
+
:param region: the name of the region, either a country, a subnational1 or a subnational2 code.
|
|
57
|
+
|
|
58
|
+
:return: the list of regions bordering the specified region.
|
|
59
|
+
|
|
60
|
+
:raises ValueError: if an invalid region code.
|
|
61
|
+
|
|
62
|
+
:raises URLError if there is an error with the connection to the
|
|
63
|
+
eBird site.
|
|
64
|
+
|
|
65
|
+
:raises HTTPError if the eBird API returns an error.
|
|
66
|
+
|
|
67
|
+
"""
|
|
68
|
+
url = ADJACENT_REGIONS_URL % clean_region(region)
|
|
69
|
+
|
|
70
|
+
headers = {
|
|
71
|
+
'X-eBirdApiToken': token,
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return call(url, {}, headers)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def get_region(token, region):
|
|
78
|
+
"""Get the geographical details of a country, region or sub-region.
|
|
79
|
+
|
|
80
|
+
This maps to the end point in the eBird API 2.0,
|
|
81
|
+
https://documenter.getpostman.com/view/664302/S1ENwy59?version=latest#e25218db-566b-4d8b-81ca-e79a8f68c599
|
|
82
|
+
|
|
83
|
+
There are two query parameters supported by the API, regionNameFormat
|
|
84
|
+
and delim. These are used to control how the name of the region that the
|
|
85
|
+
region code corresponds to is presented, e.g. US-NY returns "New York,
|
|
86
|
+
United States". The utility of these is rather limited so they are
|
|
87
|
+
currently not supported.
|
|
88
|
+
|
|
89
|
+
:param token: the token needed to access the API.
|
|
90
|
+
|
|
91
|
+
:param region: the code for the region, eg. US-NV.
|
|
92
|
+
|
|
93
|
+
:return: the latitude, longitude, name, region, etc. for the area.
|
|
94
|
+
|
|
95
|
+
:raises ValueError: if an invalid region code is given.
|
|
96
|
+
|
|
97
|
+
:raises URLError if there is an error with the connection to the
|
|
98
|
+
eBird site.
|
|
99
|
+
|
|
100
|
+
:raises HTTPError if the eBird API returns an error.
|
|
101
|
+
|
|
102
|
+
"""
|
|
103
|
+
url = REGION_INFO_URL % clean_region(region)
|
|
104
|
+
|
|
105
|
+
headers = {
|
|
106
|
+
'X-eBirdApiToken': token,
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return call(url, {}, headers)
|
ebird/api/statistics.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"""Functions for fetching basic statistics about observers and observations."""
|
|
2
|
+
|
|
3
|
+
from ebird.api.utils import call
|
|
4
|
+
|
|
5
|
+
from ebird.api.validation import clean_area, clean_date, clean_max_observers, \
|
|
6
|
+
clean_region, clean_rank
|
|
7
|
+
|
|
8
|
+
TOP_100_URL = 'https://ebird.org/ws2.0/product/top100/%s/%s'
|
|
9
|
+
TOTALS_URL = 'https://ebird.org/ws2.0/product/stats/%s/%s'
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def get_top_100(token, region, date, rank='spp', max_results=100):
|
|
13
|
+
"""
|
|
14
|
+
Get the observers who have seen the most species or submitted the
|
|
15
|
+
greatest number of checklists on a given date.
|
|
16
|
+
|
|
17
|
+
The maps to the end point in the eBird API 2.0,
|
|
18
|
+
https://documenter.getpostman.com/view/664302/S1ENwy59?version=latest#2d8d3f94-c4b0-42bd-9c8e-71edfa6347ba
|
|
19
|
+
|
|
20
|
+
:param token: the token needed to access the API.
|
|
21
|
+
|
|
22
|
+
:param region: the code for the region, eg. US-NV.
|
|
23
|
+
|
|
24
|
+
:param date: the date, since Jan 1st 1800.
|
|
25
|
+
|
|
26
|
+
:param rank: order results by species seen (spp) or checklists submitted (cl).
|
|
27
|
+
|
|
28
|
+
:param max_results: the maximum number of entries to return from
|
|
29
|
+
1 to 100. The default value is 100.
|
|
30
|
+
|
|
31
|
+
:return: the list of observers.
|
|
32
|
+
|
|
33
|
+
:raises ValueError: if any of the arguments fail the validation checks.
|
|
34
|
+
|
|
35
|
+
:raises URLError if there is an error with the connection to the
|
|
36
|
+
eBird site.
|
|
37
|
+
|
|
38
|
+
:raises HTTPError if the eBird API returns an error.
|
|
39
|
+
|
|
40
|
+
"""
|
|
41
|
+
url = TOP_100_URL % (
|
|
42
|
+
clean_region(region), date.strftime('%Y/%m/%d'))
|
|
43
|
+
|
|
44
|
+
params = {
|
|
45
|
+
'maxObservers': clean_max_observers(max_results),
|
|
46
|
+
'rankedBy': clean_rank(rank),
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
headers = {
|
|
50
|
+
'X-eBirdApiToken': token,
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return call(url, params, headers)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def get_totals(token, area, date):
|
|
57
|
+
"""
|
|
58
|
+
Get the number of contributors, checklists submitted and species seen on a given date.
|
|
59
|
+
|
|
60
|
+
The maps to the end point in the eBird API 2.0,
|
|
61
|
+
https://documenter.getpostman.com/view/664302/S1ENwy59?version=latest#4416a7cc-623b-4340-ab01-80c599ede73e
|
|
62
|
+
|
|
63
|
+
:param token: the token needed to access the API.
|
|
64
|
+
|
|
65
|
+
:param area: the code for a country subnational1 , subnational2 region or location
|
|
66
|
+
|
|
67
|
+
:param date: the date, since Jan 1st 1800.
|
|
68
|
+
|
|
69
|
+
:return: the totals for the given date
|
|
70
|
+
|
|
71
|
+
:raises ValueError: if any of the arguments fail the validation checks.
|
|
72
|
+
|
|
73
|
+
:raises URLError if there is an error with the connection to the
|
|
74
|
+
eBird site.
|
|
75
|
+
|
|
76
|
+
:raises HTTPError if the eBird API returns an error.
|
|
77
|
+
|
|
78
|
+
"""
|
|
79
|
+
url = TOTALS_URL % (
|
|
80
|
+
clean_area(area), clean_date(date))
|
|
81
|
+
|
|
82
|
+
headers = {
|
|
83
|
+
'X-eBirdApiToken': token,
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return call(url, {}, headers)
|
ebird/api/taxonomy.py
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"""Functions for fetching information about the taxonomy used by eBird."""
|
|
2
|
+
|
|
3
|
+
from ebird.api.utils import call
|
|
4
|
+
|
|
5
|
+
from ebird.api.validation import clean_categories, clean_locale, clean_ordering, \
|
|
6
|
+
clean_species_code, clean_codes
|
|
7
|
+
|
|
8
|
+
TAXONOMY_URL = 'https://ebird.org/ws2.0/ref/taxonomy/ebird'
|
|
9
|
+
TAXONOMY_FORMS_URL = 'https://ebird.org/ws2.0/ref/taxon/forms/%s'
|
|
10
|
+
TAXONOMY_GROUPS_URL = 'https://ebird.org/ws2.0/ref/sppgroup/%s'
|
|
11
|
+
TAXONOMY_VERSIONS_URL = 'https://ebird.org/ws2.0/ref/taxonomy/versions'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def get_taxonomy(token, category=None, locale='en', version=None, species=None):
|
|
15
|
+
"""Get the full or specific subset of the taxonomy used by eBird.
|
|
16
|
+
|
|
17
|
+
The maps to the end point in the eBird API 2.0,
|
|
18
|
+
https://documenter.getpostman.com/view/664302/S1ENwy59?version=latest#952a4310-536d-4ad1-8f3e-77cfb624d1bc
|
|
19
|
+
|
|
20
|
+
:param token: the token needed to access the API.
|
|
21
|
+
|
|
22
|
+
:param category: one or more categories of species to return: 'domestic',
|
|
23
|
+
'form', 'hybrid', 'intergrade', 'issf', 'slash', 'species' or 'spuh'.
|
|
24
|
+
More than one value can be given in a comma-separated string.
|
|
25
|
+
|
|
26
|
+
:param locale: the language (to use) for the species common names. The
|
|
27
|
+
default of 'en' will use species names from the eBird/Clements checklist.
|
|
28
|
+
This can be any locale for which eBird has translations available. For a
|
|
29
|
+
complete list see, http://help.ebird.org/customer/portal/articles/1596582.
|
|
30
|
+
|
|
31
|
+
:param version: the version number of the taxonomy to return,
|
|
32
|
+
see get_taxonomy_versions()
|
|
33
|
+
|
|
34
|
+
:param species: a comma-separate string or list containing scientific
|
|
35
|
+
names or 6-letter species codes.
|
|
36
|
+
|
|
37
|
+
:return: the list of entries matching the category.
|
|
38
|
+
|
|
39
|
+
:raises ValueError: if an invalid category or locale is given.
|
|
40
|
+
|
|
41
|
+
:raises ValueError: if both a category and species are used. In this case
|
|
42
|
+
the eBird API ignore the species and returns only results for the category.
|
|
43
|
+
|
|
44
|
+
:raises URLError if there is an error with the connection to the
|
|
45
|
+
eBird site.
|
|
46
|
+
|
|
47
|
+
:raises HTTPError if the eBird API returns an error.
|
|
48
|
+
|
|
49
|
+
"""
|
|
50
|
+
params = {
|
|
51
|
+
'sppLocale': clean_locale(locale),
|
|
52
|
+
'fmt': 'json'
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if category is not None:
|
|
56
|
+
params['cat'] = ','.join(clean_categories(category))
|
|
57
|
+
|
|
58
|
+
if version is not None:
|
|
59
|
+
params['version'] = version
|
|
60
|
+
|
|
61
|
+
if species is not None:
|
|
62
|
+
params['species'] = ','.join(clean_codes(species))
|
|
63
|
+
|
|
64
|
+
headers = {
|
|
65
|
+
'X-eBirdApiToken': token,
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return call(TAXONOMY_URL, params, headers)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def get_taxonomy_forms(token, species):
|
|
72
|
+
"""Get all the sub-specific forms of a given species.
|
|
73
|
+
|
|
74
|
+
The maps to the end point in the eBird API 2.0,
|
|
75
|
+
https://documenter.getpostman.com/view/664302/S1ENwy59?version=latest#e338e5a6-919d-4603-a7db-6c690fa62371
|
|
76
|
+
|
|
77
|
+
NOTE: the get_taxonomy() API call returns 6-letter species codes.
|
|
78
|
+
|
|
79
|
+
:param token: the token needed to access the API.
|
|
80
|
+
|
|
81
|
+
:param species: the 6-letter eBird species code, e.g. horlar (Horned Lark).
|
|
82
|
+
|
|
83
|
+
:return: the list of codes of each sub-species.
|
|
84
|
+
|
|
85
|
+
:raises ValueError is the species code is invalid (not 6 letters).
|
|
86
|
+
|
|
87
|
+
:raises URLError if there is an error with the connection to the
|
|
88
|
+
eBird site.
|
|
89
|
+
|
|
90
|
+
:raises HTTPError if the eBird API returns an error.
|
|
91
|
+
|
|
92
|
+
"""
|
|
93
|
+
url = TAXONOMY_FORMS_URL % clean_species_code(species)
|
|
94
|
+
|
|
95
|
+
headers = {
|
|
96
|
+
'X-eBirdApiToken': token,
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return call(url, {}, headers)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def get_taxonomy_groups(token, ordering='ebird', locale='en'):
|
|
103
|
+
"""Get the names of the groups of species used in the taxonomy.
|
|
104
|
+
|
|
105
|
+
The maps to the end point in the eBird API 2.0,
|
|
106
|
+
https://documenter.getpostman.com/view/664302/S1ENwy59?version=latest#aa9804aa-dbf9-4a53-bbf4-48e214e4677a
|
|
107
|
+
|
|
108
|
+
NOTE: Not all the locales supported by the eBird site or apps
|
|
109
|
+
are available in the API. The following locales are not
|
|
110
|
+
supported, (language, locale code):
|
|
111
|
+
|
|
112
|
+
Croatian, hr
|
|
113
|
+
Croatian, hr
|
|
114
|
+
Faroese, fo
|
|
115
|
+
Finnish, fi
|
|
116
|
+
Haitian, ht_HT
|
|
117
|
+
Hungarian, hu
|
|
118
|
+
Indonesian, id
|
|
119
|
+
Italian, it
|
|
120
|
+
Japanese, ja
|
|
121
|
+
Korean, ko
|
|
122
|
+
Latvian, lv
|
|
123
|
+
Lithuanian, lt
|
|
124
|
+
Malayalam, ml
|
|
125
|
+
Mongolian, mn
|
|
126
|
+
Polish, pl
|
|
127
|
+
Slovenian, sl
|
|
128
|
+
Swedish, sv
|
|
129
|
+
Ukrainian, uk
|
|
130
|
+
|
|
131
|
+
:param token: the token needed to access the API.
|
|
132
|
+
|
|
133
|
+
:param ordering: order groups using taxonomic order, 'ebird' or by
|
|
134
|
+
likeness, 'merlin'.
|
|
135
|
+
|
|
136
|
+
:param locale: the language (to use) for the group names.
|
|
137
|
+
|
|
138
|
+
:return: the list of species groups.
|
|
139
|
+
|
|
140
|
+
:raises ValueError: if an invalid ordering or locale is given.
|
|
141
|
+
|
|
142
|
+
:raises URLError if there is an error with the connection to the
|
|
143
|
+
eBird site.
|
|
144
|
+
|
|
145
|
+
:raises HTTPError if the eBird API returns an error.
|
|
146
|
+
|
|
147
|
+
"""
|
|
148
|
+
url = TAXONOMY_GROUPS_URL % clean_ordering(ordering)
|
|
149
|
+
|
|
150
|
+
params = {
|
|
151
|
+
'groupNameLocale': clean_locale(locale),
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
headers = {
|
|
155
|
+
'X-eBirdApiToken': token,
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return call(url, params, headers)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def get_taxonomy_versions(token):
|
|
162
|
+
"""Get all versions of the taxonomy, indicating which is the latest.
|
|
163
|
+
|
|
164
|
+
The maps to the end point in the eBird API 2.0,
|
|
165
|
+
https://documenter.getpostman.com/view/664302/S1ENwy59?version=latest#9bba1ff5-6eb2-4f9a-91fd-e5ed34e51500
|
|
166
|
+
|
|
167
|
+
:param token: the token needed to access the API.
|
|
168
|
+
|
|
169
|
+
:return: a list of all the taxonomy versions used by eBird.
|
|
170
|
+
|
|
171
|
+
:raises URLError if there is an error with the connection to the
|
|
172
|
+
eBird site.
|
|
173
|
+
|
|
174
|
+
:raises HTTPError if the eBird API returns an error.
|
|
175
|
+
|
|
176
|
+
"""
|
|
177
|
+
headers = {
|
|
178
|
+
'X-eBirdApiToken': token,
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return call(TAXONOMY_VERSIONS_URL, {}, headers)
|
ebird/api/utils.py
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"""Various functions used in the API."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
from urllib.request import Request, urlopen
|
|
6
|
+
from urllib.parse import urlencode
|
|
7
|
+
|
|
8
|
+
from ebird.api import constants
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
_parameter_defaults = {
|
|
12
|
+
'back': constants.DEFAULT_BACK,
|
|
13
|
+
'cat': constants.DEFAULT_SPECIES_CATEGORY,
|
|
14
|
+
'detail': constants.DEFAULT_DETAIL,
|
|
15
|
+
'dist': constants.DEFAULT_DISTANCE,
|
|
16
|
+
'groupNameLocale': constants.DEFAULT_LOCALE,
|
|
17
|
+
'hotspot': constants.DEFAULT_HOTSPOTS_ONLY,
|
|
18
|
+
'includeProvisional': constants.DEFAULT_PROVISIONAL,
|
|
19
|
+
'sort': constants.DEFAULT_OBSERVATION_ORDER,
|
|
20
|
+
'sppLocale': constants.DEFAULT_LOCALE,
|
|
21
|
+
'maxObservations': constants.DEFAULT_MAX_OBSERVATIONS,
|
|
22
|
+
'maxObservers': constants.DEFAULT_MAX_OBSERVERS,
|
|
23
|
+
'maxVisits': constants.DEFAULT_MAX_CHECKLISTS,
|
|
24
|
+
'rankedBy': constants.DEFAULT_TOP_100_RANK
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
_parameter_map = {
|
|
28
|
+
'maxObservations': 'maxResults',
|
|
29
|
+
'maxObservers': 'maxResults',
|
|
30
|
+
'maxVisits': 'maxResults',
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def map_parameters(params):
|
|
35
|
+
"""Translate the names of the query parameters to match those used
|
|
36
|
+
in the API.
|
|
37
|
+
|
|
38
|
+
:param params: a dict contains the GET parameters for the request that
|
|
39
|
+
will be sent to the eBird API.
|
|
40
|
+
|
|
41
|
+
:return: a copy of the params dictionary with only the parameters
|
|
42
|
+
that are not set to a default value.
|
|
43
|
+
|
|
44
|
+
"""
|
|
45
|
+
mapped = {}
|
|
46
|
+
|
|
47
|
+
for key, value in params.items():
|
|
48
|
+
key = _parameter_map.get(key, key)
|
|
49
|
+
mapped[key] = value
|
|
50
|
+
|
|
51
|
+
return mapped
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def filter_parameters(params):
|
|
55
|
+
"""Filter out any parameter which matches the eBird API default value.
|
|
56
|
+
|
|
57
|
+
:param params: a dict contains the GET parameters for the request that
|
|
58
|
+
will be sent to the eBird API.
|
|
59
|
+
|
|
60
|
+
:return: a copy of the params dictionary with only the parameters
|
|
61
|
+
that are not set to a default value.
|
|
62
|
+
|
|
63
|
+
"""
|
|
64
|
+
filtered = {}
|
|
65
|
+
|
|
66
|
+
defaults = _parameter_defaults.copy()
|
|
67
|
+
|
|
68
|
+
for key, value in params.items():
|
|
69
|
+
if key in defaults:
|
|
70
|
+
if value != defaults[key]:
|
|
71
|
+
filtered[key] = value
|
|
72
|
+
else:
|
|
73
|
+
filtered[key] = value
|
|
74
|
+
|
|
75
|
+
return filtered
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def get_response(url, params=None, headers=None):
|
|
79
|
+
"""Get the content from the eBird API.
|
|
80
|
+
|
|
81
|
+
:param url: the URL for the API call.
|
|
82
|
+
:type url: str
|
|
83
|
+
|
|
84
|
+
:param params: the query parameters for the API call.
|
|
85
|
+
:type params: dict
|
|
86
|
+
|
|
87
|
+
:param headers: the headers to add to the request.
|
|
88
|
+
:type params: dict
|
|
89
|
+
|
|
90
|
+
:return: the content returned by the API
|
|
91
|
+
:rtype: str
|
|
92
|
+
|
|
93
|
+
:raises URLError if there is an error with the connection to the
|
|
94
|
+
eBird site.
|
|
95
|
+
|
|
96
|
+
:raises HTTPError if the eBird API returns an error.
|
|
97
|
+
|
|
98
|
+
"""
|
|
99
|
+
if params:
|
|
100
|
+
url += '?' + urlencode(params, doseq=True)
|
|
101
|
+
|
|
102
|
+
request = Request(url)
|
|
103
|
+
|
|
104
|
+
if headers:
|
|
105
|
+
for name, value in headers.items():
|
|
106
|
+
request.add_header(name, value)
|
|
107
|
+
|
|
108
|
+
return urlopen(request).read()
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def get_json(content):
|
|
112
|
+
"""Decode the JSON records from the response.
|
|
113
|
+
|
|
114
|
+
:param content: the content returned by the eBird API.
|
|
115
|
+
:type content: http.client.HTTPResponse:
|
|
116
|
+
|
|
117
|
+
:return: the records decoded from the JSON payload.
|
|
118
|
+
:rtype: list
|
|
119
|
+
|
|
120
|
+
"""
|
|
121
|
+
return json.loads(content.decode('utf-8'))
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def save_json(filename, data, indent=None):
|
|
125
|
+
"""Save results to a file.
|
|
126
|
+
|
|
127
|
+
:param filename: the name of the file to save. The .json
|
|
128
|
+
extension will be added if not present.
|
|
129
|
+
|
|
130
|
+
:param data: the list of records to save.
|
|
131
|
+
|
|
132
|
+
:param indent: whether to pretty-print results by adding indentation
|
|
133
|
+
for each level. The default is no formatting.
|
|
134
|
+
|
|
135
|
+
"""
|
|
136
|
+
if not filename.endswith('.json'):
|
|
137
|
+
filename += '.json'
|
|
138
|
+
with open(filename, 'w') as outfile:
|
|
139
|
+
json.dump(data, outfile, indent=indent)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def call(url, params, headers):
|
|
143
|
+
"""Call the eBird API.
|
|
144
|
+
|
|
145
|
+
:param url: the URL for the API call.
|
|
146
|
+
:type url: str
|
|
147
|
+
|
|
148
|
+
:param params: the query parameters for the API call.
|
|
149
|
+
:type params: dict
|
|
150
|
+
|
|
151
|
+
:param headers: the headers to add to the request.
|
|
152
|
+
:type params: dict
|
|
153
|
+
|
|
154
|
+
:return: the content returned by the API
|
|
155
|
+
:rtype: str
|
|
156
|
+
|
|
157
|
+
:raises URLError if there is an error with the connection to the
|
|
158
|
+
eBird site.
|
|
159
|
+
|
|
160
|
+
:raises HTTPError if the eBird API returns an error.
|
|
161
|
+
|
|
162
|
+
"""
|
|
163
|
+
filtered = filter_parameters(params)
|
|
164
|
+
mapped = map_parameters(filtered)
|
|
165
|
+
return get_json(get_response(url, mapped, headers))
|