ebird-api 3.2.1__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.1 → ebird_api-3.3.0}/CHANGELOG.md +11 -0
  2. {ebird_api-3.2.1/src/ebird_api.egg-info → ebird_api-3.3.0}/PKG-INFO +2 -2
  3. {ebird_api-3.2.1 → ebird_api-3.3.0}/pyproject.toml +2 -2
  4. {ebird_api-3.2.1 → ebird_api-3.3.0}/src/ebird/api/__init__.py +7 -2
  5. {ebird_api-3.2.1 → ebird_api-3.3.0}/src/ebird/api/client.py +5 -4
  6. {ebird_api-3.2.1 → ebird_api-3.3.0}/src/ebird/api/constants.py +2 -0
  7. {ebird_api-3.2.1 → ebird_api-3.3.0}/src/ebird/api/hotspots.py +93 -0
  8. {ebird_api-3.2.1 → ebird_api-3.3.0}/src/ebird/api/utils.py +1 -1
  9. {ebird_api-3.2.1 → ebird_api-3.3.0}/src/ebird/api/validation.py +1 -1
  10. {ebird_api-3.2.1 → ebird_api-3.3.0/src/ebird_api.egg-info}/PKG-INFO +2 -2
  11. {ebird_api-3.2.1 → ebird_api-3.3.0}/LICENSE.txt +0 -0
  12. {ebird_api-3.2.1 → ebird_api-3.3.0}/README.md +0 -0
  13. {ebird_api-3.2.1 → ebird_api-3.3.0}/setup.cfg +0 -0
  14. {ebird_api-3.2.1 → ebird_api-3.3.0}/setup.py +0 -0
  15. {ebird_api-3.2.1 → ebird_api-3.3.0}/src/ebird/api/checklists.py +0 -0
  16. {ebird_api-3.2.1 → ebird_api-3.3.0}/src/ebird/api/observations.py +0 -0
  17. {ebird_api-3.2.1 → ebird_api-3.3.0}/src/ebird/api/regions.py +0 -0
  18. {ebird_api-3.2.1 → ebird_api-3.3.0}/src/ebird/api/species.py +0 -0
  19. {ebird_api-3.2.1 → ebird_api-3.3.0}/src/ebird/api/statistics.py +0 -0
  20. {ebird_api-3.2.1 → ebird_api-3.3.0}/src/ebird/api/taxonomy.py +0 -0
  21. {ebird_api-3.2.1 → ebird_api-3.3.0}/src/ebird_api.egg-info/SOURCES.txt +0 -0
  22. {ebird_api-3.2.1 → ebird_api-3.3.0}/src/ebird_api.egg-info/dependency_links.txt +0 -0
  23. {ebird_api-3.2.1 → ebird_api-3.3.0}/src/ebird_api.egg-info/top_level.txt +0 -0
@@ -8,10 +8,21 @@ 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
+
15
+ ## [3.2.2] - 2025-01-10
16
+ ### Added
17
+ - Added constant API_MAX_RESULTS for the maximum number of results returned
18
+ by an API call.
19
+
11
20
  ## [3.2.1] - 2024-12-31
21
+ ### Updated
12
22
  - Remove the '.json' suffix from the URL from get_regions()
13
23
 
14
24
  ## [3.2.0] - 2024-12-30
25
+ ### Added
15
26
  - Add get_species_list which returns the list of codes for species seen
16
27
  in a country, subnational1 are, subnational2 area or hotspot.
17
28
 
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: ebird-api
3
- Version: 3.2.1
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.1"
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.1"
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.1"
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,
@@ -4,6 +4,7 @@
4
4
 
5
5
  from ebird.api import (
6
6
  checklists,
7
+ constants,
7
8
  hotspots,
8
9
  observations,
9
10
  regions,
@@ -31,12 +32,12 @@ class Client:
31
32
  self.api_key = api_key
32
33
  self.locale = clean_locale(locale)
33
34
  self.max_observations = None
34
- self.max_visits = 200
35
- self.max_observers = 100
36
- self.back = 14
35
+ self.max_visits = constants.API_MAX_RESULTS
36
+ self.max_observers = constants.DEFAULT_MAX_OBSERVERS
37
+ self.back = constants.DEFAULT_BACK
37
38
  self.category = None
38
39
  self.detail = "full"
39
- self.dist = 25
40
+ self.dist = constants.DEFAULT_DISTANCE
40
41
  self.hotspot = False
41
42
  self.provisional = True
42
43
  self.sort = "date"
@@ -14,6 +14,8 @@ DEFAULT_MAX_OBSERVERS = 100
14
14
  DEFAULT_MAX_CHECKLISTS = 10
15
15
  DEFAULT_TOP_100_RANK = "spp"
16
16
 
17
+ API_MAX_RESULTS = 200
18
+
17
19
  LOCALES = {
18
20
  "Bulgarian": "bg",
19
21
  "Chinese": "zh",
@@ -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.
@@ -175,7 +175,7 @@ def clean_max_observers(value):
175
175
 
176
176
 
177
177
  def clean_max_checklists(value):
178
- return clean_max_results(value, 200)
178
+ return clean_max_results(value, constants.API_MAX_RESULTS)
179
179
 
180
180
 
181
181
  def clean_locale(value):
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: ebird-api
3
- Version: 3.2.1
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