ebird-api 3.2.2__tar.gz → 3.3.0__tar.gz

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.
Files changed (23) hide show
  1. {ebird_api-3.2.2 → ebird_api-3.3.0}/CHANGELOG.md +4 -0
  2. {ebird_api-3.2.2/src/ebird_api.egg-info → ebird_api-3.3.0}/PKG-INFO +1 -1
  3. {ebird_api-3.2.2 → ebird_api-3.3.0}/pyproject.toml +2 -2
  4. {ebird_api-3.2.2 → ebird_api-3.3.0}/src/ebird/api/__init__.py +7 -2
  5. {ebird_api-3.2.2 → ebird_api-3.3.0}/src/ebird/api/hotspots.py +93 -0
  6. {ebird_api-3.2.2 → ebird_api-3.3.0}/src/ebird/api/utils.py +1 -1
  7. {ebird_api-3.2.2 → ebird_api-3.3.0/src/ebird_api.egg-info}/PKG-INFO +1 -1
  8. {ebird_api-3.2.2 → ebird_api-3.3.0}/LICENSE.txt +0 -0
  9. {ebird_api-3.2.2 → ebird_api-3.3.0}/README.md +0 -0
  10. {ebird_api-3.2.2 → ebird_api-3.3.0}/setup.cfg +0 -0
  11. {ebird_api-3.2.2 → ebird_api-3.3.0}/setup.py +0 -0
  12. {ebird_api-3.2.2 → ebird_api-3.3.0}/src/ebird/api/checklists.py +0 -0
  13. {ebird_api-3.2.2 → ebird_api-3.3.0}/src/ebird/api/client.py +0 -0
  14. {ebird_api-3.2.2 → ebird_api-3.3.0}/src/ebird/api/constants.py +0 -0
  15. {ebird_api-3.2.2 → ebird_api-3.3.0}/src/ebird/api/observations.py +0 -0
  16. {ebird_api-3.2.2 → ebird_api-3.3.0}/src/ebird/api/regions.py +0 -0
  17. {ebird_api-3.2.2 → ebird_api-3.3.0}/src/ebird/api/species.py +0 -0
  18. {ebird_api-3.2.2 → ebird_api-3.3.0}/src/ebird/api/statistics.py +0 -0
  19. {ebird_api-3.2.2 → ebird_api-3.3.0}/src/ebird/api/taxonomy.py +0 -0
  20. {ebird_api-3.2.2 → ebird_api-3.3.0}/src/ebird/api/validation.py +0 -0
  21. {ebird_api-3.2.2 → ebird_api-3.3.0}/src/ebird_api.egg-info/SOURCES.txt +0 -0
  22. {ebird_api-3.2.2 → ebird_api-3.3.0}/src/ebird_api.egg-info/dependency_links.txt +0 -0
  23. {ebird_api-3.2.2 → ebird_api-3.3.0}/src/ebird_api.egg-info/top_level.txt +0 -0
@@ -8,6 +8,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
8
8
  This project adheres to [PEP440](https://www.python.org/dev/peps/pep-0440/)
9
9
  and by implication, [Semantic Versioning](http://semver.org/).
10
10
 
11
+ ## [3.3.0] - 2025-02-01
12
+ - Added get_location() which works like get_hotspot() but return data for
13
+ hotspots and private locations.
14
+
11
15
  ## [3.2.2] - 2025-01-10
12
16
  ### Added
13
17
  - Added constant API_MAX_RESULTS for the maximum number of results returned
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: ebird-api
3
- Version: 3.2.2
3
+ Version: 3.3.0
4
4
  Summary: Wrapper for accessing the eBird API
5
5
  Author-email: Project Babbler <projectbabbler@gmail.com>
6
6
  License: MIT License
@@ -30,7 +30,7 @@ license = {text = "MIT License"}
30
30
  name = "ebird-api"
31
31
  readme = "README.md"
32
32
  requires-python = ">= 3.8"
33
- version = "3.2.2"
33
+ version = "3.3.0"
34
34
 
35
35
  [project.urls]
36
36
  Repository = "https://github.com/ProjectBabbler/ebird-api.git"
@@ -38,7 +38,7 @@ Issues = "https://github.com/ProjectBabbler/ebird-api/issues"
38
38
  Changelog = "https://github.com/ProjectBabbler/ebird-api/blob/master/CHANGELOG.md"
39
39
 
40
40
  [tool.bumpversion]
41
- current_version = "3.2.2"
41
+ current_version = "3.3.0"
42
42
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
43
43
  serialize = ["{major}.{minor}.{patch}"]
44
44
  ignore_missing_version = false
@@ -2,12 +2,17 @@
2
2
 
3
3
  """A set of wrapper functions for accessing the eBird API."""
4
4
 
5
- __version__ = "3.2.2"
5
+ __version__ = "3.3.0"
6
6
 
7
7
  from ebird.api.checklists import get_checklist, get_visits
8
8
  from ebird.api.client import Client
9
9
  from ebird.api.constants import LOCALES
10
- from ebird.api.hotspots import get_hotspot, get_hotspots, get_nearby_hotspots
10
+ from ebird.api.hotspots import (
11
+ get_hotspot,
12
+ get_hotspots,
13
+ get_location,
14
+ get_nearby_hotspots,
15
+ )
11
16
  from ebird.api.observations import (
12
17
  get_historic_observations,
13
18
  get_nearby_notable,
@@ -1,5 +1,7 @@
1
1
  """Functions for fetching information about hotspots."""
2
2
 
3
+ from urllib.error import HTTPError
4
+
3
5
  from ebird.api.utils import call
4
6
  from ebird.api.validation import (
5
7
  clean_back,
@@ -13,6 +15,7 @@ from ebird.api.validation import (
13
15
  REGION_HOTSPOTS_URL = "https://api.ebird.org/v2/ref/hotspot/%s"
14
16
  NEARBY_HOTSPOTS_URL = "https://api.ebird.org/v2/ref/hotspot/geo"
15
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"
16
19
 
17
20
 
18
21
  def get_hotspots(token, region, back=None):
@@ -120,6 +123,10 @@ def get_nearby_hotspots(token, lat, lng, dist=25, back=None):
120
123
  def get_hotspot(token, loc_id):
121
124
  """Get the geographical details of a hotspot.
122
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
+
123
130
  This maps to the end point in the eBird API 2.0,
124
131
  https://documenter.getpostman.com/view/664302/S1ENwy59?version=latest#e25218db-566b-4d8b-81ca-e79a8f68c599
125
132
 
@@ -144,3 +151,89 @@ def get_hotspot(token, loc_id):
144
151
  }
145
152
 
146
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
@@ -151,7 +151,7 @@ def call(url, params, headers):
151
151
  :type params: dict
152
152
 
153
153
  :return: the content returned by the API
154
- :rtype: str
154
+ :rtype: dict | list
155
155
 
156
156
  :raises URLError if there is an error with the connection to the
157
157
  eBird site.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: ebird-api
3
- Version: 3.2.2
3
+ Version: 3.3.0
4
4
  Summary: Wrapper for accessing the eBird API
5
5
  Author-email: Project Babbler <projectbabbler@gmail.com>
6
6
  License: MIT License
File without changes
File without changes
File without changes
File without changes