Skip to main content

Build Anki flashcard decks for bird identification from allaboutbirds.org

Project description

AviAnki

PyPI Python License Stars Ruff

Build Flashcards with Birds Near You

Drop in your location and AviAnki builds a custom Anki deck — sorted by the species most likely to appear near you — pulling photos, calls, songs, and descriptions from allaboutbirds.org.

Each species gets two card types:

  • Photo → Name — given two photos and audio, identify the bird
  • Description → Name — given audio and a written description, identify the bird

Card examples

Photo → Name — identify the bird from photos and audio:

Photo → Name front

Description → Name — identify the bird from audio and a redacted description:

Description → Name front

Answer — reveals the name, scientific name, photos, audio, and full description:

Answer

Prerequisites

  • uv — for running and installing
  • ffmpeg — for trimming audio clips

Install ffmpeg:

# Windows
winget install ffmpeg

# macOS
brew install ffmpeg

Quick start

  1. Go to allaboutbirds.org/guide/browse
  2. Under Birds Near Me, enter your city, ZIP code, or state/province — set the time of year to Year-round for a complete deck
  3. Click Browse, copy the URL from your browser's address bar, and run:
uvx avianki "https://www.allaboutbirds.org/guide/browse/filter/loc/ChIJGzE9DS1l44kRoOhiASS_fHg/..."

That's it. An .apkg file is written to the current directory — import it into Anki via File → Import.

Use --limit N to cap the number of species for a smaller file size:

uvx avianki "https://www.allaboutbirds.org/guide/browse/..." --limit 30

Usage

From PyPI (recommended):

uvx avianki LOCATION [OPTIONS]

From a local clone:

git clone https://github.com/Ian-Costa18/avianki.git
cd avianki
uv run avianki LOCATION [OPTIONS]

Location formats

allaboutbirds.org browse URL (recommended — species sorted by local frequency, no API key needed):

uvx avianki "https://www.allaboutbirds.org/guide/browse/filter/loc/ChIJGzE9DS1l44kRoOhiASS_fHg/date/all/behavior/all/size/all/colors/all/sort/score/view/list-view"

Google Place ID (shorthand for the above):

uvx avianki ChIJGzE9DS1l44kRoOhiASS_fHg

Find a Place ID at developers.google.com/maps/documentation/javascript/examples/places-placeid-finder.

eBird region code (species in taxonomic order, requires an API key):

uvx avianki US-MA
uvx avianki US-MA-017   # county level

Get a free eBird API key at ebird.org/api/keygen, then set it in a .env file:

EBIRD_API_KEY=your_key_here

Options

Every option can also be set as an environment variable — useful for scripting or keeping a persistent configuration in .env. CLI flags always take precedence over env vars.

Flag Short Env var Description
LOCATION AVIANKI_LOCATION allaboutbirds.org URL, Google Place ID, or eBird region code
--limit N -n AVIANKI_LIMIT Cap the number of species included in the deck
--output FILE -o AVIANKI_OUTPUT Output .apkg path (default: auto-generated from location)
--deck-name NAME -d AVIANKI_DECK_NAME Override the deck name shown in Anki
--no-audio -A AVIANKI_NO_AUDIO Skip downloading call and song audio
--no-images -I AVIANKI_NO_IMAGES Skip downloading photos
--delay SECONDS -D AVIANKI_DELAY Wait between requests in seconds (default: 0.5)
--work-dir DIR -w AVIANKI_WORK_DIR Directory for cached media, logs, and JSON (default: <tmp>/avianki/)
--media-dir DIR -m AVIANKI_MEDIA_DIR Override media subdirectory (default: <work-dir>/media/)
--json-file FILE -j AVIANKI_JSON_FILE Path for birds.json output (default: <work-dir>/birds.json)
--ephemeral -e AVIANKI_EPHEMERAL Run without persisting anything — see Ephemeral mode
--no-cache -X AVIANKI_NO_CACHE Skip cache lookup; delete downloaded media after packaging
--log-file FILE -l AVIANKI_LOG_FILE Log file path (default: <work-dir>/avianki.log)
--verbose -v AVIANKI_VERBOSE Show debug-level output in the console
--quiet -q AVIANKI_QUIET Only show warnings and errors in the console

Boolean env vars (AVIANKI_NO_AUDIO, AVIANKI_NO_IMAGES, AVIANKI_EPHEMERAL, AVIANKI_NO_CACHE, AVIANKI_VERBOSE, AVIANKI_QUIET) are enabled by setting them to 1, true, or yes. See .env.example for a ready-to-copy template.

Examples

# Your local birds, capped to 50 species
uvx avianki "https://www.allaboutbirds.org/guide/browse/..." --limit 50
AVIANKI_LIMIT=50 uvx avianki "https://www.allaboutbirds.org/guide/browse/..."

# Custom output path and deck name
uvx avianki "https://www.allaboutbirds.org/guide/browse/..." --output ~/Desktop/MyBirds.apkg --deck-name "My Birds"

# Images only, no audio
uvx avianki "https://www.allaboutbirds.org/guide/browse/..." --no-audio

# Be polite to the server
uvx avianki "https://www.allaboutbirds.org/guide/browse/..." --delay 1.5

# Fully configured via .env — run with no arguments
# (set AVIANKI_LOCATION and other options in .env)
uvx avianki

Output

An .apkg file is written to the current directory by default (e.g. Birds_ChIJGzE9DS1l44kRoOhiASS_fHg.apkg or Birds_US-MA.apkg). Import it into Anki via File → Import.

Downloaded images and audio are cached in the system temp directory (<tmp>/avianki/media/ by default, or the directory set by --media-dir) so re-runs skip already-fetched files. Re-running the same location only fetches new or missing media. The log is written to <tmp>/avianki/avianki.log.

A birds.json file is also written to <work-dir>/birds.json (override with --json-file) containing the scraped data for every species. Each entry has the common name, scientific name, description, and paths to the cached image and audio files relative to <work-dir>. Audio fields are null when no clip was found. See examples/example-birds.json for a sample.

[
  {
    "name": "American Robin",
    "sci_name": "Turdus migratorius",
    "description": "The quintessential early bird...",
    "images": ["media/bird_American_Robin_img1.jpg", "media/bird_American_Robin_img2.jpg"],
    "call": "media/bird_American_Robin_call.mp3",
    "song": "media/bird_American_Robin_song.mp3"
  }
]

Ephemeral mode

--ephemeral is for one-shot runs where you want no persistent files. Instead of writing to <work-dir> directly, all temporary files (media, log, birds.json) go into <work-dir>/.ephemeral/. That subdirectory is deleted after the .apkg is packaged, leaving the base work directory untouched. The cache is never read or written in this mode.

Notes

  • Audio clips are trimmed to 10 seconds via ffmpeg to keep file sizes small.
  • allaboutbirds.org browse URLs sort species by likelihood score for your location, which gives much better study order than eBird's taxonomic ordering.

Thanks to Cornell Lab of Ornithology

All bird data, photos, audio, and descriptions in AviAnki come from All About Birds, a free resource built and maintained by the Cornell Lab of Ornithology. Their work makes tools like this possible.

Get involved — Cornell Lab runs some of the world's largest citizen science programs. You can contribute bird sightings through eBird, join community science projects like Project FeederWatch and NestWatch, or participate in the annual Christmas Bird Count. Every observation helps researchers track bird populations and protect habitat. Learn more at allaboutbirds.org/news/get-involved.

Donate — If you find All About Birds useful, consider supporting the Cornell Lab directly: give.birds.cornell.edu.

Future Development

If you find AviAnki useful, consider supporting its development at buymeacoffee.com/IanCosta.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

avianki-0.8.2.tar.gz (14.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

avianki-0.8.2-py3-none-any.whl (17.1 kB view details)

Uploaded Python 3

File details

Details for the file avianki-0.8.2.tar.gz.

File metadata

  • Download URL: avianki-0.8.2.tar.gz
  • Upload date:
  • Size: 14.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for avianki-0.8.2.tar.gz
Algorithm Hash digest
SHA256 5d1d5c88323a91d56490da245ea7f9372b4843c467d3ffd78ff49fb88b220b4d
MD5 11e0e27810cb8112dae7ddc97ef5ffca
BLAKE2b-256 b85db62feb50a25d5d2b485fd04e201797f7272a513581853c70a15a6710746b

See more details on using hashes here.

File details

Details for the file avianki-0.8.2-py3-none-any.whl.

File metadata

  • Download URL: avianki-0.8.2-py3-none-any.whl
  • Upload date:
  • Size: 17.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for avianki-0.8.2-py3-none-any.whl
Algorithm Hash digest
SHA256 982d2b40dae07fa03041ab8c849fd769fc0f61e5692999bcd83f32423a738e54
MD5 915f0f3c1a01bed7b2a237a0bca19ef5
BLAKE2b-256 a55142b09b8a97ab95eed27bd07e0d1c4bf7354bddb2ae73862c20a649f07110

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page