ebird-api-data 0.2.0__tar.gz → 0.2.2__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 (43) hide show
  1. ebird_api_data-0.2.2/PKG-INFO +179 -0
  2. ebird_api_data-0.2.2/README.md +149 -0
  3. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/pyproject.toml +10 -10
  4. ebird_api_data-0.2.2/src/ebird/api/data/__init__.py +1 -0
  5. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/loaders.py +8 -10
  6. ebird_api_data-0.2.2/src/ebird/api/data/migrations/0008_rename_created_checklist_added.py +23 -0
  7. ebird_api_data-0.2.2/src/ebird/api/data/migrations/0009_add_created_timestamps.py +58 -0
  8. ebird_api_data-0.2.2/src/ebird/api/data/migrations/0010_alter_species_category.py +18 -0
  9. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/models/checklist.py +22 -2
  10. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/models/country.py +4 -0
  11. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/models/county.py +4 -0
  12. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/models/filter.py +4 -0
  13. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/models/location.py +4 -0
  14. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/models/observation.py +4 -0
  15. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/models/observer.py +4 -0
  16. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/models/species.py +10 -3
  17. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/models/state.py +4 -0
  18. ebird_api_data-0.2.0/PKG-INFO +0 -185
  19. ebird_api_data-0.2.0/README.rst +0 -155
  20. ebird_api_data-0.2.0/src/ebird/api/data/__init__.py +0 -1
  21. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/.gitignore +0 -0
  22. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/LICENSE +0 -0
  23. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/admin.py +0 -0
  24. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/apps.py +0 -0
  25. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/fields.py +0 -0
  26. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/locale/en/LC_MESSAGES/django.mo +0 -0
  27. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/locale/en/LC_MESSAGES/django.po +0 -0
  28. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/management/__init__.py +0 -0
  29. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/management/commands/__init__.py +0 -0
  30. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/management/commands/add_checklists.py +0 -0
  31. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/migrations/0001_initial.py +0 -0
  32. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/migrations/0002_convert_foreign_keys_to_integers.py +0 -0
  33. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/migrations/0003_make_codes_and_identifiers_primary_keys.py +0 -0
  34. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/migrations/0004_rename_foreign_keys.py +0 -0
  35. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/migrations/0005_add_new_foreign_keys.py +0 -0
  36. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/migrations/0006_set_new_foreign_keys.py +0 -0
  37. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/migrations/0007_remove_old_fields_and_ids.py +0 -0
  38. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/migrations/__init__.py +0 -0
  39. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/models/__init__.py +0 -0
  40. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/templates/admin/data/species/change_list_object_tools.html +0 -0
  41. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/templates/admin/data/species/fetch_species.html +0 -0
  42. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/templates/data/widgets/translation_field.html +0 -0
  43. {ebird_api_data-0.2.0 → ebird_api_data-0.2.2}/src/ebird/api/data/widgets.py +0 -0
@@ -0,0 +1,179 @@
1
+ Metadata-Version: 2.4
2
+ Name: ebird-api-data
3
+ Version: 0.2.2
4
+ Summary: eBird API Data is a reusable Django app for loading data from eBird into a database.
5
+ Author-email: Stuart MacKay <smackay@flagstonesoftware.com>
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Keywords: Django,checklists,eBird,models,observations,species
9
+ Classifier: Development Status :: 5 - Production/Stable
10
+ Classifier: Framework :: Django
11
+ Classifier: Framework :: Django :: 4.2
12
+ Classifier: Framework :: Django :: 5.0
13
+ Classifier: Framework :: Django :: 5.1
14
+ Classifier: Framework :: Django :: 5.2
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: Natural Language :: English
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Scientific/Engineering
22
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
23
+ Requires-Python: >=3.10
24
+ Requires-Dist: beautifulsoup4>=4.13.3
25
+ Requires-Dist: django>=4.2
26
+ Requires-Dist: ebird-api-requests>=4.0.1
27
+ Requires-Dist: ebird-codes>=0.0.2
28
+ Requires-Dist: lxml>=6.0.0
29
+ Description-Content-Type: text/markdown
30
+
31
+ # eBird API Data
32
+
33
+ eBird API Data is a reusable Django app for loading data from eBird into a database.
34
+
35
+ ## Overview
36
+
37
+ The Cornell Laboratory of Ornithology in Ithaca, New York runs the eBird database
38
+ which collects observations of birds from all over the world. All the observations
39
+ are published on [eBird.org](https://ebird.org), and they also make them available
40
+ via an [API](https://documenter.getpostman.com/view/664302/S1ENwy59). This project
41
+ contains a loader and models to take data from the API and load it into a database.
42
+ From there you can analyse the data with python, jupyter notebooks, or build a web
43
+ site.
44
+
45
+ To get started, you will need to
46
+ [sign up](https://secure.birds.cornell.edu/identity/account/create)
47
+ for an eBird account, if you don't already have one and
48
+ [register](https://ebird.org/data/download)
49
+ to get an API key. Make sure you read and understand the
50
+ [Terms of use](https://www.birds.cornell.edu/home/ebird-api-terms-of-use/),
51
+ and remember bandwidth and servers cost money, so don't abuse the service. If you
52
+ need large numbers of observations, then sign up to receive the
53
+ [eBird Basic Dataset](https://science.ebird.org/en/use-ebird-data/download-ebird-data-products).
54
+
55
+ ## Install
56
+
57
+ You can use either [pip](https://pip.pypa.io/en/stable/) or [uv](https://docs.astral.sh/uv/)
58
+ to download the [package](https://pypi.org/project/ebird-api-data/) from PyPI and
59
+ install it into a virtualenv:
60
+
61
+ ```shell
62
+ pip install ebird-api-data
63
+ ```
64
+
65
+ or:
66
+
67
+ ```shell
68
+ uv add ebird-api-data
69
+ ```
70
+
71
+ Update `INSTALLED_APPS` in your Django setting:
72
+
73
+ ```python
74
+ INSTALLED_APPS = [
75
+ ...
76
+ ebird.api.data
77
+ ]
78
+ ```
79
+
80
+ Finally, run the migrations to create the tables:
81
+
82
+ ```python
83
+ python manage.py migrate
84
+ ```
85
+
86
+ ## Demo
87
+
88
+ If you check out the code from the repository there is a fully functioning
89
+ Django site. It contains pages for checklists, observations and species,
90
+ where you can browse the records or search by location, observer. date. etc.
91
+ The Django Admin lets you browse and edit the records in the database.
92
+
93
+ ```shell
94
+ git clone git@github.com:StuartMacKay/ebird-api-data.git
95
+ cd ebird-api-data
96
+ ```
97
+
98
+ Create the virtual environment:
99
+ ```shell
100
+ uv venv
101
+ ```
102
+
103
+ Activate it:
104
+ ```shell
105
+ source .venv/bin/activate
106
+ ```
107
+
108
+ Install the requirements:
109
+ ```shell
110
+ uv sync
111
+ ```
112
+
113
+ Create a copy of the .env.example file and add your API key:
114
+ ```shell
115
+ cp .env.example .env
116
+ ```
117
+
118
+ For example:
119
+ ```shell
120
+ EBIRD_API_KEY=<my api key>
121
+ ```
122
+
123
+ Run the database migrations:
124
+ ```shell
125
+ python manage.py migrate
126
+ ```
127
+
128
+ Create a user:
129
+ ```shell
130
+ python manage.py createsuperuser
131
+ ```
132
+
133
+ Create a copy of the .env.example file and add your API key:
134
+ ```shell
135
+ cp .env.example .env
136
+ ```
137
+
138
+ ```shell
139
+ EBIRD_API_KEY=<my api key>
140
+ ```
141
+
142
+ Now, download data from the API:
143
+
144
+ ```shell
145
+ python manage.py add_checklists --days 2 US-NY-109
146
+ ```
147
+
148
+ This loads all the checklists, submitted in the past two days by birders in
149
+ Tompkins County, New York, where the Cornell Lab is based. You can use any
150
+ location code used by eBird, whether it's for a country, state/region, or
151
+ county. Remember, read the terms of use.
152
+
153
+ Run the demo:
154
+
155
+ ```shell
156
+ python manage.py runserver
157
+ ```
158
+
159
+ Now, either visit the site, http:localhost:8000/, or log into the Django Admin,
160
+ http:localhost:8000/admin to browse the tables.
161
+
162
+ ## Project Information
163
+
164
+ * Documentation: https://ebird-api-data.readthedocs.io/en/latest/
165
+ * Issues: https://todo.sr.ht/~smackay/ebird-api-data
166
+ * Repository: https://git.sr.ht/~smackay/ebird-api-data
167
+ * Announcements: https://lists.sr.ht/~smackay/ebirders-announce
168
+ * Discussions: https://lists.sr.ht/~smackay/ebirders-discuss
169
+ * Development: https://lists.sr.ht/~smackay/ebirders-develop
170
+
171
+ The repository is also mirrored on Github:
172
+
173
+ * Repository: https://github.com/StuartMacKay/ebird-api-data
174
+
175
+ The app is tested on Python 3.10+, and officially supports Django 4.2, 5.0 and 5.1.
176
+
177
+ ## License
178
+
179
+ eBird API Data is released under the terms of the [MIT](https://opensource.org/licenses/MIT) license.
@@ -0,0 +1,149 @@
1
+ # eBird API Data
2
+
3
+ eBird API Data is a reusable Django app for loading data from eBird into a database.
4
+
5
+ ## Overview
6
+
7
+ The Cornell Laboratory of Ornithology in Ithaca, New York runs the eBird database
8
+ which collects observations of birds from all over the world. All the observations
9
+ are published on [eBird.org](https://ebird.org), and they also make them available
10
+ via an [API](https://documenter.getpostman.com/view/664302/S1ENwy59). This project
11
+ contains a loader and models to take data from the API and load it into a database.
12
+ From there you can analyse the data with python, jupyter notebooks, or build a web
13
+ site.
14
+
15
+ To get started, you will need to
16
+ [sign up](https://secure.birds.cornell.edu/identity/account/create)
17
+ for an eBird account, if you don't already have one and
18
+ [register](https://ebird.org/data/download)
19
+ to get an API key. Make sure you read and understand the
20
+ [Terms of use](https://www.birds.cornell.edu/home/ebird-api-terms-of-use/),
21
+ and remember bandwidth and servers cost money, so don't abuse the service. If you
22
+ need large numbers of observations, then sign up to receive the
23
+ [eBird Basic Dataset](https://science.ebird.org/en/use-ebird-data/download-ebird-data-products).
24
+
25
+ ## Install
26
+
27
+ You can use either [pip](https://pip.pypa.io/en/stable/) or [uv](https://docs.astral.sh/uv/)
28
+ to download the [package](https://pypi.org/project/ebird-api-data/) from PyPI and
29
+ install it into a virtualenv:
30
+
31
+ ```shell
32
+ pip install ebird-api-data
33
+ ```
34
+
35
+ or:
36
+
37
+ ```shell
38
+ uv add ebird-api-data
39
+ ```
40
+
41
+ Update `INSTALLED_APPS` in your Django setting:
42
+
43
+ ```python
44
+ INSTALLED_APPS = [
45
+ ...
46
+ ebird.api.data
47
+ ]
48
+ ```
49
+
50
+ Finally, run the migrations to create the tables:
51
+
52
+ ```python
53
+ python manage.py migrate
54
+ ```
55
+
56
+ ## Demo
57
+
58
+ If you check out the code from the repository there is a fully functioning
59
+ Django site. It contains pages for checklists, observations and species,
60
+ where you can browse the records or search by location, observer. date. etc.
61
+ The Django Admin lets you browse and edit the records in the database.
62
+
63
+ ```shell
64
+ git clone git@github.com:StuartMacKay/ebird-api-data.git
65
+ cd ebird-api-data
66
+ ```
67
+
68
+ Create the virtual environment:
69
+ ```shell
70
+ uv venv
71
+ ```
72
+
73
+ Activate it:
74
+ ```shell
75
+ source .venv/bin/activate
76
+ ```
77
+
78
+ Install the requirements:
79
+ ```shell
80
+ uv sync
81
+ ```
82
+
83
+ Create a copy of the .env.example file and add your API key:
84
+ ```shell
85
+ cp .env.example .env
86
+ ```
87
+
88
+ For example:
89
+ ```shell
90
+ EBIRD_API_KEY=<my api key>
91
+ ```
92
+
93
+ Run the database migrations:
94
+ ```shell
95
+ python manage.py migrate
96
+ ```
97
+
98
+ Create a user:
99
+ ```shell
100
+ python manage.py createsuperuser
101
+ ```
102
+
103
+ Create a copy of the .env.example file and add your API key:
104
+ ```shell
105
+ cp .env.example .env
106
+ ```
107
+
108
+ ```shell
109
+ EBIRD_API_KEY=<my api key>
110
+ ```
111
+
112
+ Now, download data from the API:
113
+
114
+ ```shell
115
+ python manage.py add_checklists --days 2 US-NY-109
116
+ ```
117
+
118
+ This loads all the checklists, submitted in the past two days by birders in
119
+ Tompkins County, New York, where the Cornell Lab is based. You can use any
120
+ location code used by eBird, whether it's for a country, state/region, or
121
+ county. Remember, read the terms of use.
122
+
123
+ Run the demo:
124
+
125
+ ```shell
126
+ python manage.py runserver
127
+ ```
128
+
129
+ Now, either visit the site, http:localhost:8000/, or log into the Django Admin,
130
+ http:localhost:8000/admin to browse the tables.
131
+
132
+ ## Project Information
133
+
134
+ * Documentation: https://ebird-api-data.readthedocs.io/en/latest/
135
+ * Issues: https://todo.sr.ht/~smackay/ebird-api-data
136
+ * Repository: https://git.sr.ht/~smackay/ebird-api-data
137
+ * Announcements: https://lists.sr.ht/~smackay/ebirders-announce
138
+ * Discussions: https://lists.sr.ht/~smackay/ebirders-discuss
139
+ * Development: https://lists.sr.ht/~smackay/ebirders-develop
140
+
141
+ The repository is also mirrored on Github:
142
+
143
+ * Repository: https://github.com/StuartMacKay/ebird-api-data
144
+
145
+ The app is tested on Python 3.10+, and officially supports Django 4.2, 5.0 and 5.1.
146
+
147
+ ## License
148
+
149
+ eBird API Data is released under the terms of the [MIT](https://opensource.org/licenses/MIT) license.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ebird-api-data"
3
- version = "0.2.0"
3
+ version = "0.2.2"
4
4
  description = "eBird API Data is a reusable Django app for loading data from eBird into a database."
5
5
  keywords = ["checklists", "observations", "species", "Django", "eBird", "models"]
6
6
  license = "MIT"
@@ -8,7 +8,7 @@ license-files = ["LICENSE"]
8
8
  authors = [
9
9
  {name = "Stuart MacKay", email = "smackay@flagstonesoftware.com"},
10
10
  ]
11
- readme = "README.rst"
11
+ readme = "README.md"
12
12
  requires-python = ">=3.10"
13
13
  dependencies = [
14
14
  "beautifulsoup4>=4.13.3",
@@ -61,10 +61,11 @@ dev-dependencies = [
61
61
  "django-extensions>=3.2.3",
62
62
  "psycopg2-binary>=2.9.10",
63
63
  "ipython>=8.37.0",
64
+ "django-autocomplete-light>=3.12.1",
64
65
  ]
65
66
 
66
67
  [tool.bumpversion]
67
- current_version = "0.2.0"
68
+ current_version = "0.2.2"
68
69
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
69
70
  serialize = ["{major}.{minor}.{patch}"]
70
71
  ignore_missing_version = false
@@ -89,16 +90,15 @@ search = 'release = "{current_version}"'
89
90
  replace = 'release = "{new_version}"'
90
91
 
91
92
  [[tool.bumpversion.files]]
92
- filename = "CHANGELOG.rst"
93
+ filename = "CHANGELOG.md"
93
94
  search = """
94
- Latest
95
- ------"""
95
+ ## Latest
96
+ """
96
97
  replace = """
97
- Latest
98
- ------
98
+ ## Latest
99
99
 
100
- {new_version} ({now:%Y-%m-%d})
101
- ------------------"""
100
+ ## {new_version} ({now:%Y-%m-%d})
101
+ """
102
102
 
103
103
  [[tool.bumpversion.files]]
104
104
  filename = "pyproject.toml"
@@ -0,0 +1 @@
1
+ __version__ = "0.2.2"
@@ -308,22 +308,17 @@ class APILoader:
308
308
  identifier = self.get_observer_identifier(data)
309
309
  observer, created = Observer.objects.get_or_create(
310
310
  identifier=identifier,
311
- defaults={
312
- "name":name,
313
- "original": random_word(8)
314
- }
311
+ defaults={"name": name, "original": random_word(8)},
315
312
  )
316
313
  else:
317
314
  if observer := Observer.objects.filter(original=name).first():
318
315
  created = False
319
316
  else:
320
317
  identifier = self.get_observer_identifier(data)
321
- observer = Observer.objects.create(
318
+ observer, created = Observer.objects.get_or_create(
322
319
  identifier=identifier,
323
- name=name,
324
- original=name,
320
+ defaults={"name": name, "original": name},
325
321
  )
326
- created = True
327
322
 
328
323
  if created:
329
324
  logger.info("Added observer: %s", name)
@@ -394,15 +389,18 @@ class APILoader:
394
389
  if duration := data.get("durationHrs"):
395
390
  values["duration"] = int(duration * 60.0)
396
391
 
397
- if data["protocolId"] == "P22":
392
+ if data["protocolId"] == Checklist.Protocol.TRAVELLING.value:
398
393
  # The distance travelled might not be reported.
399
394
  if "effortDistanceKm" in data:
400
395
  dist: str = data["effortDistanceKm"]
401
396
  values["distance"] = round(Decimal(dist), 3)
402
- elif data["protocolId"] == "P23":
397
+ elif data["protocolId"] == Checklist.Protocol.AREA.value:
403
398
  area: str = data["effortAreaHa"]
404
399
  values["area"] = round(Decimal(area), 3)
405
400
 
401
+ if data["protocolId"] not in Checklist.Protocol.values:
402
+ logger.info("New protocol: %s", data["protocolId"])
403
+
406
404
  if "comments" in data:
407
405
  values["comments"] = data["comments"]
408
406
 
@@ -0,0 +1,23 @@
1
+ # Generated by Django 5.2.4 on 2025-07-17 06:10
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('data', '0007_remove_old_fields_and_ids'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.RenameField(
14
+ model_name='checklist',
15
+ old_name='created',
16
+ new_name='added',
17
+ ),
18
+ migrations.AlterField(
19
+ model_name='checklist',
20
+ name='added',
21
+ field=models.DateTimeField(blank=True, help_text='The date and time the checklist was added to eBird.', null=True, verbose_name='added'),
22
+ ),
23
+ ]
@@ -0,0 +1,58 @@
1
+ # Generated by Django 5.2.4 on 2025-07-17 06:18
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('data', '0008_rename_created_checklist_added'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AddField(
14
+ model_name='checklist',
15
+ name='created',
16
+ field=models.DateTimeField(auto_now_add=True, help_text='When was the record created.', null=True),
17
+ ),
18
+ migrations.AddField(
19
+ model_name='country',
20
+ name='created',
21
+ field=models.DateTimeField(auto_now_add=True, help_text='When was the record created.', null=True),
22
+ ),
23
+ migrations.AddField(
24
+ model_name='county',
25
+ name='created',
26
+ field=models.DateTimeField(auto_now_add=True, help_text='When was the record created.', null=True),
27
+ ),
28
+ migrations.AddField(
29
+ model_name='filter',
30
+ name='created',
31
+ field=models.DateTimeField(auto_now_add=True, help_text='When was the record created.', null=True),
32
+ ),
33
+ migrations.AddField(
34
+ model_name='location',
35
+ name='created',
36
+ field=models.DateTimeField(auto_now_add=True, help_text='When was the record created.', null=True),
37
+ ),
38
+ migrations.AddField(
39
+ model_name='observation',
40
+ name='created',
41
+ field=models.DateTimeField(auto_now_add=True, help_text='When was the record created.', null=True),
42
+ ),
43
+ migrations.AddField(
44
+ model_name='observer',
45
+ name='created',
46
+ field=models.DateTimeField(auto_now_add=True, help_text='When was the record created.', null=True),
47
+ ),
48
+ migrations.AddField(
49
+ model_name='species',
50
+ name='created',
51
+ field=models.DateTimeField(auto_now_add=True, help_text='When was the record created.', null=True),
52
+ ),
53
+ migrations.AddField(
54
+ model_name='state',
55
+ name='created',
56
+ field=models.DateTimeField(auto_now_add=True, help_text='When was the record created.', null=True),
57
+ ),
58
+ ]
@@ -0,0 +1,18 @@
1
+ # Generated by Django 5.2.4 on 2025-07-23 12:44
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('data', '0009_add_created_timestamps'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name='species',
15
+ name='category',
16
+ field=models.TextField(blank=True, choices=[('species', 'Species'), ('slash', 'Species pairs'), ('issf', 'Subspecies'), ('domestic', 'Domestic species'), ('hybrid', 'Hybrids'), ('form', 'Species forms'), ('spuh', 'Unidentified species'), ('intergrade', 'Intergrades')], help_text='The category from the eBird/Clements taxonomy.', verbose_name='category'),
17
+ ),
18
+ ]
@@ -3,15 +3,28 @@ from django.utils.translation import gettext_lazy as _
3
3
 
4
4
 
5
5
  class Checklist(models.Model):
6
+ class Protocol(models.TextChoices):
7
+ INCIDENTAL = "P20", _("Incidental")
8
+ STATIONARY = "P21", _("Stationary")
9
+ TRAVELLING = "P22", _("Travelling")
10
+ AREA = "P23", _("Area")
11
+ BANDING = "P33", _("Banding")
12
+ NOCTURNAL = "P54", _("Nocturnal Flight Call Count")
13
+ PELAGIC = "P60", _("Pelagic")
14
+ HISTORICAL = "P62", _("Historical")
15
+ BREEDING_BIRD_ATLAS = "P65", _("Breeding Bird Atlas")
16
+ COMMON_BIRD_SURVEY = "P67", _("Common Bird Survey")
17
+ RAM = "P68", _("RAM--Iberian Seawatch Network")
18
+
6
19
  class Meta:
7
20
  verbose_name = _("checklist")
8
21
  verbose_name_plural = _("checklists")
9
22
 
10
- created = models.DateTimeField(
23
+ added = models.DateTimeField(
11
24
  blank=True,
12
25
  null=True,
13
26
  help_text=_("The date and time the checklist was added to eBird."),
14
- verbose_name=_("created"),
27
+ verbose_name=_("added"),
15
28
  )
16
29
 
17
30
  edited = models.DateTimeField(
@@ -116,6 +129,9 @@ class Checklist(models.Model):
116
129
  help_text=_("The code used to identify the protocol."),
117
130
  )
118
131
 
132
+ # Protocol is not used to set the choices, as we still want to load
133
+ # the checklist when a protocol not defined in the class is used.
134
+
119
135
  project_code = models.TextField(
120
136
  blank=True,
121
137
  verbose_name=_("project code"),
@@ -172,6 +188,10 @@ class Checklist(models.Model):
172
188
  blank=True,
173
189
  )
174
190
 
191
+ created = models.DateTimeField(
192
+ null=True, auto_now_add=True, help_text=_("When was the record created.")
193
+ )
194
+
175
195
  def __repr__(self) -> str:
176
196
  return str(self.identifier)
177
197
 
@@ -22,6 +22,10 @@ class Country(models.Model):
22
22
  verbose_name=_("place"), help_text=_("The hierarchical name of the country.")
23
23
  )
24
24
 
25
+ created = models.DateTimeField(
26
+ null=True, auto_now_add=True, help_text=_("When was the record created.")
27
+ )
28
+
25
29
  def __repr__(self) -> str:
26
30
  return str(self.code)
27
31
 
@@ -22,6 +22,10 @@ class County(models.Model):
22
22
  verbose_name=_("place"), help_text=_("The hierarchical name of the county.")
23
23
  )
24
24
 
25
+ created = models.DateTimeField(
26
+ null=True, auto_now_add=True, help_text=_("When was the record created.")
27
+ )
28
+
25
29
  def __repr__(self) -> str:
26
30
  return str(self.code)
27
31
 
@@ -48,6 +48,10 @@ class Filter(models.Model):
48
48
  help_text=_("Matching Observations are updated to this species."),
49
49
  )
50
50
 
51
+ created = models.DateTimeField(
52
+ null=True, auto_now_add=True, help_text=_("When was the record created.")
53
+ )
54
+
51
55
  def __repr__(self) -> str:
52
56
  return str(self.name)
53
57
 
@@ -147,6 +147,10 @@ class Location(models.Model):
147
147
  blank=True,
148
148
  )
149
149
 
150
+ created = models.DateTimeField(
151
+ null=True, auto_now_add=True, help_text=_("When was the record created.")
152
+ )
153
+
150
154
  def __repr__(self) -> str:
151
155
  return str(self.identifier)
152
156
 
@@ -171,6 +171,10 @@ class Observation(models.Model):
171
171
  blank=True,
172
172
  )
173
173
 
174
+ created = models.DateTimeField(
175
+ null=True, auto_now_add=True, help_text=_("When was the record created.")
176
+ )
177
+
174
178
  def __repr__(self) -> str:
175
179
  return str(self.identifier)
176
180
 
@@ -43,6 +43,10 @@ class Observer(models.Model):
43
43
  blank=True,
44
44
  )
45
45
 
46
+ created = models.DateTimeField(
47
+ null=True, auto_now_add=True, help_text=_("When was the record created.")
48
+ )
49
+
46
50
  def __repr__(self) -> str:
47
51
  return str(self.identifier)
48
52
 
@@ -12,11 +12,14 @@ log = logging.getLogger(__name__)
12
12
 
13
13
  class Species(models.Model):
14
14
  class Category(models.TextChoices):
15
- ALL = "", _("All categories")
16
15
  SPECIES = "species", _("Species")
16
+ SLASH = "slash", _("Species pairs")
17
17
  SUBSPECIES = "issf", _("Subspecies")
18
- DOMESTIC = "domestic", _("Domestic")
19
- HYBRID = "hybrid", _("Hybrid")
18
+ DOMESTIC = "domestic", _("Domestic species")
19
+ HYBRID = "hybrid", _("Hybrids")
20
+ FORM = "form", _("Species forms")
21
+ SPUH = "spuh", _("Unidentified species")
22
+ INTERGRADE = "intergrade", _("Intergrades")
20
23
 
21
24
  class Meta:
22
25
  verbose_name = _("species")
@@ -90,6 +93,10 @@ class Species(models.Model):
90
93
  blank=True,
91
94
  )
92
95
 
96
+ created = models.DateTimeField(
97
+ null=True, auto_now_add=True, help_text=_("When was the record created.")
98
+ )
99
+
93
100
  def __repr__(self) -> str:
94
101
  return str(self.species_code)
95
102
 
@@ -22,6 +22,10 @@ class State(models.Model):
22
22
  verbose_name=_("place"), help_text=_("The hierarchical name of the state.")
23
23
  )
24
24
 
25
+ created = models.DateTimeField(
26
+ null=True, auto_now_add=True, help_text=_("When was the record created.")
27
+ )
28
+
25
29
  def __repr__(self) -> str:
26
30
  return str(self.code)
27
31
 
@@ -1,185 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: ebird-api-data
3
- Version: 0.2.0
4
- Summary: eBird API Data is a reusable Django app for loading data from eBird into a database.
5
- Author-email: Stuart MacKay <smackay@flagstonesoftware.com>
6
- License-Expression: MIT
7
- License-File: LICENSE
8
- Keywords: Django,checklists,eBird,models,observations,species
9
- Classifier: Development Status :: 5 - Production/Stable
10
- Classifier: Framework :: Django
11
- Classifier: Framework :: Django :: 4.2
12
- Classifier: Framework :: Django :: 5.0
13
- Classifier: Framework :: Django :: 5.1
14
- Classifier: Framework :: Django :: 5.2
15
- Classifier: Intended Audience :: Science/Research
16
- Classifier: Natural Language :: English
17
- Classifier: Programming Language :: Python :: 3.10
18
- Classifier: Programming Language :: Python :: 3.11
19
- Classifier: Programming Language :: Python :: 3.12
20
- Classifier: Programming Language :: Python :: 3.13
21
- Classifier: Topic :: Scientific/Engineering
22
- Classifier: Topic :: Scientific/Engineering :: Information Analysis
23
- Requires-Python: >=3.10
24
- Requires-Dist: beautifulsoup4>=4.13.3
25
- Requires-Dist: django>=4.2
26
- Requires-Dist: ebird-api-requests>=4.0.1
27
- Requires-Dist: ebird-codes>=0.0.2
28
- Requires-Dist: lxml>=6.0.0
29
- Description-Content-Type: text/x-rst
30
-
31
- eBird API Data
32
- ==============
33
- eBird API Data is a reusable Django app for loading data from eBird into a database.
34
-
35
- Overview
36
- --------
37
- .. overview-start
38
-
39
- The Cornell Laboratory of Ornithology in Ithaca, New York runs the eBird database
40
- which collects observations of birds from all over the world. All the observations
41
- are published on `eBird.org`_, and they also make them available via an `API`_.
42
- This project contains a loader and models to take data from the API and load it into
43
- a database. From there you can analyse the data with python, jupyter notebooks, or
44
- build a web site.
45
-
46
- To get started, you will need to `sign up`_ for an eBird account, if you don't
47
- already have one and `register`_ to get an API key. Make sure you read and
48
- understand the `Terms of use`_, and remember bandwidth and servers cost money,
49
- so don't abuse the service. If you need large numbers of observations, then
50
- sign up to receive the `eBird Basic Dataset`_.
51
-
52
- .. _eBird.org: https://ebird.org
53
- .. _API: https://documenter.getpostman.com/view/664302/S1ENwy59
54
- .. _sign up: https://secure.birds.cornell.edu/identity/account/create
55
- .. _register: https://ebird.org/data/download
56
- .. _Terms of use: https://www.birds.cornell.edu/home/ebird-api-terms-of-use/
57
- .. _eBird Basic Dataset: https://science.ebird.org/en/use-ebird-data/download-ebird-data-products
58
-
59
- .. overview-end
60
-
61
- Install
62
- -------
63
- .. install-start
64
-
65
- You can use either `pip`_ or `uv`_ to download the `package`_ from PyPI and
66
- install it into a virtualenv:
67
-
68
- .. code-block:: console
69
-
70
- pip install ebird-api-data
71
-
72
- or:
73
-
74
- .. code-block:: console
75
-
76
- uv add ebird-api-data
77
-
78
- Update ``INSTALLED_APPS`` in your Django setting:
79
-
80
- .. code-block:: python
81
-
82
- INSTALLED_APPS = [
83
- ...
84
- ebird.api.data
85
- ]
86
-
87
- Finally, run the migrations to create the tables:
88
-
89
- .. code-block:: python
90
-
91
- python manage.py migrate
92
-
93
- .. _pip: https://pip.pypa.io/en/stable/
94
- .. _uv: https://docs.astral.sh/uv/
95
- .. _package: https://pypi.org/project/ebird-api-data/
96
-
97
- .. install-end
98
-
99
- Demo
100
- ----
101
-
102
- .. demo-start
103
-
104
- If you check out the code from the repository there is a fully functioning
105
- Django site. It only contains the admin pages, but that is sufficient for
106
- you to browse the data.
107
-
108
- .. code-block:: console
109
-
110
- git clone git@github.com:StuartMacKay/ebird-api-data.git
111
- cd ebird-api-data
112
-
113
- Create the virtual environment:
114
-
115
- .. code-block:: console
116
-
117
- uv venv
118
-
119
- Activate it:
120
-
121
- .. code-block:: console
122
-
123
- source venv/bin/activate
124
-
125
- Install the requirements:
126
-
127
- .. code-block:: console
128
-
129
- uv sync
130
-
131
- Run the database migrations:
132
-
133
- .. code-block:: console
134
-
135
- python manage.py migrate
136
-
137
- Create a user:
138
-
139
- .. code-block:: console
140
-
141
- python manage.py createsuperuser
142
-
143
- Create a copy of the .env.example file and add your API key:
144
-
145
- .. code-block:: console
146
-
147
- cp .env.example .env
148
-
149
- .. code-block:: console
150
-
151
- EBIRD_API_KEY=<my api key>
152
-
153
- Now, download data from the API:
154
-
155
- .. code-block:: console
156
-
157
- python manage.py add_checklists --days 2 US-NY-109
158
-
159
- This loads all the checklists, submitted in the past two days by birders in
160
- Tompkins County, New York, where the Cornell Lab is based. You can use any
161
- location code used by eBird, whether it's for a country, state/region, or
162
- county. Remember, read the terms of use.
163
-
164
- Run the demo:
165
-
166
- .. code-block:: console
167
-
168
- python manage.py runserver
169
-
170
- Now log into the `Django Admin <http:localhost:8000/admin>` to browse the tables.
171
-
172
- .. demo-end
173
-
174
- Project Information
175
- -------------------
176
-
177
- * Documentation: https://ebird-api-data.readthedocs.io/en/latest/
178
- * Issues: https://github.com/StuartMacKay/ebird-api-data/issues
179
- * Repository: https://github.com/StuartMacKay/ebird-api-data
180
-
181
- The app is tested on Python 3.10+, and officially supports Django 4.2, 5.0 and 5.1.
182
-
183
- eBird API Data is released under the terms of the `MIT`_ license.
184
-
185
- .. _MIT: https://opensource.org/licenses/MIT
@@ -1,155 +0,0 @@
1
- eBird API Data
2
- ==============
3
- eBird API Data is a reusable Django app for loading data from eBird into a database.
4
-
5
- Overview
6
- --------
7
- .. overview-start
8
-
9
- The Cornell Laboratory of Ornithology in Ithaca, New York runs the eBird database
10
- which collects observations of birds from all over the world. All the observations
11
- are published on `eBird.org`_, and they also make them available via an `API`_.
12
- This project contains a loader and models to take data from the API and load it into
13
- a database. From there you can analyse the data with python, jupyter notebooks, or
14
- build a web site.
15
-
16
- To get started, you will need to `sign up`_ for an eBird account, if you don't
17
- already have one and `register`_ to get an API key. Make sure you read and
18
- understand the `Terms of use`_, and remember bandwidth and servers cost money,
19
- so don't abuse the service. If you need large numbers of observations, then
20
- sign up to receive the `eBird Basic Dataset`_.
21
-
22
- .. _eBird.org: https://ebird.org
23
- .. _API: https://documenter.getpostman.com/view/664302/S1ENwy59
24
- .. _sign up: https://secure.birds.cornell.edu/identity/account/create
25
- .. _register: https://ebird.org/data/download
26
- .. _Terms of use: https://www.birds.cornell.edu/home/ebird-api-terms-of-use/
27
- .. _eBird Basic Dataset: https://science.ebird.org/en/use-ebird-data/download-ebird-data-products
28
-
29
- .. overview-end
30
-
31
- Install
32
- -------
33
- .. install-start
34
-
35
- You can use either `pip`_ or `uv`_ to download the `package`_ from PyPI and
36
- install it into a virtualenv:
37
-
38
- .. code-block:: console
39
-
40
- pip install ebird-api-data
41
-
42
- or:
43
-
44
- .. code-block:: console
45
-
46
- uv add ebird-api-data
47
-
48
- Update ``INSTALLED_APPS`` in your Django setting:
49
-
50
- .. code-block:: python
51
-
52
- INSTALLED_APPS = [
53
- ...
54
- ebird.api.data
55
- ]
56
-
57
- Finally, run the migrations to create the tables:
58
-
59
- .. code-block:: python
60
-
61
- python manage.py migrate
62
-
63
- .. _pip: https://pip.pypa.io/en/stable/
64
- .. _uv: https://docs.astral.sh/uv/
65
- .. _package: https://pypi.org/project/ebird-api-data/
66
-
67
- .. install-end
68
-
69
- Demo
70
- ----
71
-
72
- .. demo-start
73
-
74
- If you check out the code from the repository there is a fully functioning
75
- Django site. It only contains the admin pages, but that is sufficient for
76
- you to browse the data.
77
-
78
- .. code-block:: console
79
-
80
- git clone git@github.com:StuartMacKay/ebird-api-data.git
81
- cd ebird-api-data
82
-
83
- Create the virtual environment:
84
-
85
- .. code-block:: console
86
-
87
- uv venv
88
-
89
- Activate it:
90
-
91
- .. code-block:: console
92
-
93
- source venv/bin/activate
94
-
95
- Install the requirements:
96
-
97
- .. code-block:: console
98
-
99
- uv sync
100
-
101
- Run the database migrations:
102
-
103
- .. code-block:: console
104
-
105
- python manage.py migrate
106
-
107
- Create a user:
108
-
109
- .. code-block:: console
110
-
111
- python manage.py createsuperuser
112
-
113
- Create a copy of the .env.example file and add your API key:
114
-
115
- .. code-block:: console
116
-
117
- cp .env.example .env
118
-
119
- .. code-block:: console
120
-
121
- EBIRD_API_KEY=<my api key>
122
-
123
- Now, download data from the API:
124
-
125
- .. code-block:: console
126
-
127
- python manage.py add_checklists --days 2 US-NY-109
128
-
129
- This loads all the checklists, submitted in the past two days by birders in
130
- Tompkins County, New York, where the Cornell Lab is based. You can use any
131
- location code used by eBird, whether it's for a country, state/region, or
132
- county. Remember, read the terms of use.
133
-
134
- Run the demo:
135
-
136
- .. code-block:: console
137
-
138
- python manage.py runserver
139
-
140
- Now log into the `Django Admin <http:localhost:8000/admin>` to browse the tables.
141
-
142
- .. demo-end
143
-
144
- Project Information
145
- -------------------
146
-
147
- * Documentation: https://ebird-api-data.readthedocs.io/en/latest/
148
- * Issues: https://github.com/StuartMacKay/ebird-api-data/issues
149
- * Repository: https://github.com/StuartMacKay/ebird-api-data
150
-
151
- The app is tested on Python 3.10+, and officially supports Django 4.2, 5.0 and 5.1.
152
-
153
- eBird API Data is released under the terms of the `MIT`_ license.
154
-
155
- .. _MIT: https://opensource.org/licenses/MIT
@@ -1 +0,0 @@
1
- __version__ = "0.2.0"
File without changes