ebird-api-requests 4.0.0__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/requests/__init__.py +39 -0
- ebird/api/requests/checklists.py +101 -0
- ebird/api/requests/client.py +410 -0
- ebird/api/requests/constants.py +108 -0
- ebird/api/requests/hotspots.py +239 -0
- ebird/api/requests/observations.py +707 -0
- ebird/api/requests/regions.py +110 -0
- ebird/api/requests/species.py +37 -0
- ebird/api/requests/statistics.py +90 -0
- ebird/api/requests/taxonomy.py +213 -0
- ebird/api/requests/utils.py +164 -0
- ebird/api/requests/validation.py +348 -0
- ebird_api_requests-4.0.0.dist-info/METADATA +389 -0
- ebird_api_requests-4.0.0.dist-info/RECORD +17 -0
- ebird_api_requests-4.0.0.dist-info/WHEEL +5 -0
- ebird_api_requests-4.0.0.dist-info/licenses/LICENSE.txt +21 -0
- ebird_api_requests-4.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
"""Functions for fetching information about hotspots."""
|
|
2
|
+
|
|
3
|
+
from urllib.error import HTTPError
|
|
4
|
+
|
|
5
|
+
from ebird.api.requests.utils import call
|
|
6
|
+
from ebird.api.requests.validation import (
|
|
7
|
+
clean_back,
|
|
8
|
+
clean_dist,
|
|
9
|
+
clean_lat,
|
|
10
|
+
clean_lng,
|
|
11
|
+
clean_location,
|
|
12
|
+
clean_region,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
REGION_HOTSPOTS_URL = "https://api.ebird.org/v2/ref/hotspot/%s"
|
|
16
|
+
NEARBY_HOTSPOTS_URL = "https://api.ebird.org/v2/ref/hotspot/geo"
|
|
17
|
+
HOTSPOT_INFO_URL = "https://api.ebird.org/v2/ref/hotspot/info/%s"
|
|
18
|
+
LOCATION_INFO_URL = "https://api.ebird.org/v2/ref/region/info/%s"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_hotspots(token, region, back=None):
|
|
22
|
+
"""List all hotspots within a region.
|
|
23
|
+
|
|
24
|
+
If back is specified then only the hotspots visited in the given number
|
|
25
|
+
of days are returned.
|
|
26
|
+
|
|
27
|
+
Fetch all the hotspots visited in a country, subnational1 or subnational2
|
|
28
|
+
area recently (up to 30 days ago).
|
|
29
|
+
|
|
30
|
+
This maps to the end point in the eBird API 2.0,
|
|
31
|
+
https://documenter.getpostman.com/view/664302/S1ENwy59?version=latest#f4f59f90-854e-4ba6-8207-323a8cf0bfe0
|
|
32
|
+
|
|
33
|
+
The API supports the option of returning records either in JSON or
|
|
34
|
+
CSV format. Currently results are always returned in JSON format
|
|
35
|
+
since that is consistent with the other functions.
|
|
36
|
+
|
|
37
|
+
:param token: the token needed to access the API.
|
|
38
|
+
|
|
39
|
+
:param region: the code for a country, subnational1 or subnational2 region.
|
|
40
|
+
|
|
41
|
+
:param back: the past number of days to check, default is 14.
|
|
42
|
+
|
|
43
|
+
:return: the list of hotspots.
|
|
44
|
+
|
|
45
|
+
:raises ValueError: if an invalid region code is given or if the value for
|
|
46
|
+
'back', if given, is not in the range 1..30.
|
|
47
|
+
|
|
48
|
+
:raises URLError if there is an error with the connection to the
|
|
49
|
+
eBird site.
|
|
50
|
+
|
|
51
|
+
:raises HTTPError if the eBird API returns an error.
|
|
52
|
+
|
|
53
|
+
"""
|
|
54
|
+
url = REGION_HOTSPOTS_URL % clean_region(region)
|
|
55
|
+
|
|
56
|
+
params = {"fmt": "json"}
|
|
57
|
+
|
|
58
|
+
if back is not None:
|
|
59
|
+
params["back"] = clean_back(back)
|
|
60
|
+
|
|
61
|
+
headers = {
|
|
62
|
+
"X-eBirdApiToken": token,
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return call(url, params, headers)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def get_nearby_hotspots(token, lat, lng, dist=25, back=None):
|
|
69
|
+
"""Get the list of nearby hotspots.
|
|
70
|
+
|
|
71
|
+
Get the list of hotspots closest to a set of coordinates (latitude,
|
|
72
|
+
longitude) up to a distance of 50km. If back is specified then only
|
|
73
|
+
the hotspots visited in the given number of days are returned.
|
|
74
|
+
|
|
75
|
+
The maps to the end point in the eBird API 2.0,
|
|
76
|
+
https://documenter.getpostman.com/view/664302/S1ENwy59?version=latest#674e81c1-6a0c-4836-8a7e-6ea1fe8e6677
|
|
77
|
+
|
|
78
|
+
The API supports the option of returning records either in JSON or
|
|
79
|
+
CSV format. Currently results are always returned in JSON format
|
|
80
|
+
since that is consistent with the other functions.
|
|
81
|
+
|
|
82
|
+
:param token: the token needed to access the API.
|
|
83
|
+
|
|
84
|
+
:param lat: the latitude, which will be rounded to 2 decimal places.
|
|
85
|
+
|
|
86
|
+
:param lng: the longitude, which will be rounded to 2 decimal places.
|
|
87
|
+
|
|
88
|
+
:param dist: include all sites within this distance, from 0 to 50km
|
|
89
|
+
with a default of 25km.
|
|
90
|
+
|
|
91
|
+
:param back: include only visits to the hotspots from 1 to 30 days.
|
|
92
|
+
The default value of None will include all hotspots.
|
|
93
|
+
|
|
94
|
+
:return: the list of hotspots nearest to the given set of coordinates.
|
|
95
|
+
|
|
96
|
+
:raises ValueError: if the coordinates are out of range, if the value
|
|
97
|
+
for 'dist' is not in the range 1..50 or if the value for 'back', if
|
|
98
|
+
specified, is not in the range 1..30.
|
|
99
|
+
|
|
100
|
+
:raises URLError if there is an error with the connection to the
|
|
101
|
+
eBird site.
|
|
102
|
+
|
|
103
|
+
:raises HTTPError if the eBird API returns an error.
|
|
104
|
+
|
|
105
|
+
"""
|
|
106
|
+
params = {
|
|
107
|
+
"lat": clean_lat(lat),
|
|
108
|
+
"lng": clean_lng(lng),
|
|
109
|
+
"dist": clean_dist(dist),
|
|
110
|
+
"fmt": "json",
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if back is not None:
|
|
114
|
+
params["back"] = clean_back(back)
|
|
115
|
+
|
|
116
|
+
headers = {
|
|
117
|
+
"X-eBirdApiToken": token,
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return call(NEARBY_HOTSPOTS_URL, params, headers)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def get_hotspot(token, loc_id):
|
|
124
|
+
"""Get the geographical details of a hotspot.
|
|
125
|
+
|
|
126
|
+
The call only work for hotspots. If you use the identifier for a private
|
|
127
|
+
location the eBird API will return HTTP 410 Gone and an HttpError will be
|
|
128
|
+
raised.
|
|
129
|
+
|
|
130
|
+
This maps to the end point in the eBird API 2.0,
|
|
131
|
+
https://documenter.getpostman.com/view/664302/S1ENwy59?version=latest#e25218db-566b-4d8b-81ca-e79a8f68c599
|
|
132
|
+
|
|
133
|
+
:param token: the token needed to access the API.
|
|
134
|
+
|
|
135
|
+
:param loc_id: the location code for a hotspot, eg. L374326.
|
|
136
|
+
|
|
137
|
+
:return: the latitude, longitude, name, region, etc. for the hotspot.
|
|
138
|
+
|
|
139
|
+
:raises ValueError: if an invalid location code is given.
|
|
140
|
+
|
|
141
|
+
:raises URLError if there is an error with the connection to the
|
|
142
|
+
eBird site.
|
|
143
|
+
|
|
144
|
+
:raises HTTPError if the eBird API returns an error.
|
|
145
|
+
|
|
146
|
+
"""
|
|
147
|
+
url = HOTSPOT_INFO_URL % clean_location(loc_id)
|
|
148
|
+
|
|
149
|
+
headers = {
|
|
150
|
+
"X-eBirdApiToken": token,
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return call(url, {}, headers)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def get_location(token, loc_id):
|
|
157
|
+
"""Get the geographical details of a location (hotspot or private).
|
|
158
|
+
|
|
159
|
+
This maps to the end point in the eBird API 2.0,
|
|
160
|
+
https://documenter.getpostman.com/view/664302/S1ENwy59?version=latest#e25218db-566b-4d8b-81ca-e79a8f68c599
|
|
161
|
+
|
|
162
|
+
This uses the same API call for get_region, however the data is flattened
|
|
163
|
+
so it matches the format returned by get_hotspot(). As result you can use
|
|
164
|
+
this as a drop-in replacement for get_hotspot() which will work with any
|
|
165
|
+
location.
|
|
166
|
+
|
|
167
|
+
NOTE: There is one difference between get_hotspot(). The 'hierarchicalName'
|
|
168
|
+
attribute ends with the name of the country. In get_hotspot() is ends with
|
|
169
|
+
the country code.
|
|
170
|
+
|
|
171
|
+
:param token: the token needed to access the API.
|
|
172
|
+
|
|
173
|
+
:param loc_id: the code for the location, eg. L34742596.
|
|
174
|
+
|
|
175
|
+
:return: the latitude, longitude, name, region, etc. for the location.
|
|
176
|
+
|
|
177
|
+
:raises ValueError: if an invalid region code is given.
|
|
178
|
+
|
|
179
|
+
:raises URLError if there is an error with the connection to the
|
|
180
|
+
eBird site.
|
|
181
|
+
|
|
182
|
+
:raises HTTPError if the eBird API returns an error.
|
|
183
|
+
|
|
184
|
+
"""
|
|
185
|
+
|
|
186
|
+
# get_region() does not return "isHotspot" in the results, so we
|
|
187
|
+
# try get_hotspot() first and if the call fails with HTTP 410 Gone,
|
|
188
|
+
# indicating it's a private location, we call get_region and
|
|
189
|
+
# massage the result.
|
|
190
|
+
|
|
191
|
+
try:
|
|
192
|
+
return get_hotspot(token, loc_id)
|
|
193
|
+
except HTTPError as err:
|
|
194
|
+
if err.code != 410:
|
|
195
|
+
raise
|
|
196
|
+
|
|
197
|
+
url = LOCATION_INFO_URL % clean_location(loc_id)
|
|
198
|
+
|
|
199
|
+
headers = {
|
|
200
|
+
"X-eBirdApiToken": token,
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
data: dict = call(url, {}, headers)
|
|
204
|
+
|
|
205
|
+
result = {
|
|
206
|
+
"locId": data["code"],
|
|
207
|
+
"name": data["result"],
|
|
208
|
+
"latitude": data["latitude"],
|
|
209
|
+
"longitude": data["longitude"],
|
|
210
|
+
"isHotspot": False,
|
|
211
|
+
"locName": data["result"],
|
|
212
|
+
"lat": data["latitude"],
|
|
213
|
+
"lng": data["longitude"],
|
|
214
|
+
"locID": data["code"],
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
# Get all the parent regions in reverse order
|
|
218
|
+
items = [data["parent"]]
|
|
219
|
+
while "parent" in items[-1]:
|
|
220
|
+
items.append(items[-1].pop("parent"))
|
|
221
|
+
parents = items[::-1]
|
|
222
|
+
|
|
223
|
+
# if the name contains the parent, remove it
|
|
224
|
+
full_name = ", " + parents[0]["result"]
|
|
225
|
+
for parent in parents[1:]:
|
|
226
|
+
if parent["result"].endswith(full_name):
|
|
227
|
+
parent["result"] = parent["result"][: -len(full_name)]
|
|
228
|
+
full_name = ", " + parent["result"] + full_name
|
|
229
|
+
|
|
230
|
+
# Add the processed regions to the record
|
|
231
|
+
for parent in parents:
|
|
232
|
+
kind = parent["type"]
|
|
233
|
+
name = parent["result"]
|
|
234
|
+
result["%sName" % kind] = name
|
|
235
|
+
result["%sCode" % kind] = parent["code"]
|
|
236
|
+
|
|
237
|
+
result["hierarchicalName"] = result["name"] + full_name
|
|
238
|
+
|
|
239
|
+
return result
|