Skip to content

Taxonomy

At a glance

Import and override the species taxonomy that AI providers and classification labels resolve against.

  • Time: ~5 minutes for a standard import
  • Who: admins setting up a fresh deployment, or correcting a species mapping

In v2 the Species table is sourced from the GBIF Backbone Taxonomy instead of the older Catalogue of Life (CoL) export. The stable join key is Species.taxon_id = gbifSpeciesKey — both the bundled CSVs and the AI provider category mappings pivot around it. See Taxonomy & GBIF for why this matters.

What's bundled

The Trapper Expert source ships gzipped CSV exports of the GBIF Backbone under trapper/apps/extra_tables/taxonomy/:

  • gbif_<class>_<rank>.csv.gz per taxonomic class (mammalia, aves, amphibia, and the three reptile orders squamata/testudines/crocodylia — GBIF has no single Reptilia class) × rank (order, family, genus, species).
  • gbif_mammalia_overrides.csv — manual corrections layered on top of the GBIF export (e.g. recently re-classified taxa, known GBIF bugs).
  • get_taxonomy_gbif.py — the helper script used to regenerate the bundles.

Steps

1. Import the taxonomy

The admin wizard runs this for you on a fresh deployment. To re-run later:

python manage.py import_gbif_taxonomy --taxa mammalia --mode create
python manage.py import_gbif_taxonomy --taxa mammalia aves amphibia reptilia
python manage.py import_gbif_taxonomy --taxa aves --mode update --dry-run

--taxa takes one or more space-separated values from mammalia/aves/reptilia/amphibia (not comma-separated) — reptilia covers all three reptile orders bundled under it.

Mode Effect
create (default) Only insert species that don't already exist (matched by taxon_id)
update Also overwrite name/rank/parent fields on existing rows from the bundle
--dry-run Print what would happen, don't write

The command is idempotent — running it twice does not duplicate rows.

The same flow is exposed from the admin via an Import GBIF Taxonomy button on the Species changelist (/admin/extra_tables/species/).

Species changelist with the GBIF import button

2. Add overrides for individual species (optional)

When the bundled GBIF export is wrong or out of date for a specific taxon, append a manual override:

python manage.py add_gbif_override mammalia "Lynx lynx,Capreolus capreolus"

The command queries the GBIF API for each name, picks the highest-confidence match, and appends the row to gbif_mammalia_overrides.csv. mammalia is currently the only taxon with an override file — the command's taxon argument only accepts values present in OVERRIDE_FILES (trapper/apps/extra_tables/gbif_utils.py), which today is just mammalia; running it with aves/reptilia/amphibia fails with an invalid-choice error. Re-run import_gbif_taxonomy afterwards with --mode update to apply the override to your DB.

Verify it worked

Check the Species changelist (/admin/extra_tables/species/) for the expected count of imported species, or query Species.objects.filter(taxon_class="mammalia").count() in the Django shell.

Why this matters for AI providers

Each AI Provider carries a categories JSON copied from trapper-schemas in Camtrap-DP format. Each species AttributeLabel in that JSON has a gbifSpeciesKey. The sync_ai_models command (run automatically by the admin wizard) resolves each label to a local Species row — first by gbifSpeciesKey against Species.taxon_id, falling back to a case-insensitive match on scientificName against Species.latin_name, and creating a new Species row if neither matches — then writes the resulting PK as speciesId in the same JSON. This is how AI predictions get linked to local Species rows; a label that matches by name but not GBIF key (e.g. taxonomy not yet imported) still resolves, but the new/matched row may be missing the GBIF-sourced taxonomic fields (order/family/genus) until the next taxonomy import backfills it.

Warning

Don't hand-edit speciesId — it's computed by sync_ai_models.

Next steps