pyinaturalist
Python client for iNaturalist, a community science platform that helps people get involved in the natural world by observing and identifying the living things around them.
https://github.com/pyinat/pyinaturalist
Category: Biosphere
Sub Category: Biodiversity Citizen Science
Keywords
api api-client biodiversity biodiversity-data biodiversity-informatics citizen-science inaturalist python
Keywords from Contributors
birding dwc taxonomy ebird climate sustainability gbif invasive-species biodiversity-standards oscibio
Last synced: about 9 hours ago
JSON representation
Repository metadata
Python client for iNaturalist
- Host: GitHub
- URL: https://github.com/pyinat/pyinaturalist
- Owner: pyinat
- License: mit
- Created: 2018-10-10T08:34:57.000Z (over 7 years ago)
- Default Branch: main
- Last Pushed: 2026-05-11T17:44:34.000Z (10 days ago)
- Last Synced: 2026-05-11T19:05:41.243Z (10 days ago)
- Topics: api, api-client, biodiversity, biodiversity-data, biodiversity-informatics, citizen-science, inaturalist, python
- Language: Python
- Homepage: https://pyinaturalist.readthedocs.io
- Size: 15.7 MB
- Stars: 174
- Watchers: 10
- Forks: 20
- Open Issues: 11
- Releases: 13
-
Metadata Files:
- Readme: README.md
- Changelog: HISTORY.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: docs/code_of_conduct.md
README.md
pyinaturalist
Introduction
iNaturalist is a community science platform that helps people
get involved in the natural world by observing and identifying the living things around them.
Collectively, the community produces a rich source of global biodiversity data that can be valuable
to anyone from hobbyists to scientists.
pyinaturalist is a client for the iNaturalist API that makes
these data easily accessible in the python programming language.
Features
- β‘οΈ Easier requests: Simplified request formats, easy pagination, and complete request
parameter type annotations for better IDE integration - β¬
οΈ Convenient responses: Type conversions to the things you would expect in python, and
typed model objects (Observation,Taxon, etc.) with full IDE autocompletion - π Security: Keyring integration for secure credential storage
- π Docs: Example requests, responses, scripts, and Jupyter notebooks to help get you started
- π§ͺ Testing: A dry-run testing mode to preview your requests before potentially modifying data
- π Responsible use: Follows the
API Recommended Practices without extra configuration;
caching and rate-limiting features reduce bandwidth usage, errors, and unexpected throttling
Supported Endpoints
Many of the most relevant API endpoints are supported, including:
- π Annotations and observation fields
- π Identifications
- π¬ Messages
- π Observations (multiple formats)
- π· Observation photos + sounds
- π Observation histograms, observers, identifiers, life lists, and species counts
- π Places
- π₯ Projects
- π¦ Species
- π€ Users
Quickstart
Here are usage examples for some of the most commonly used features.
First, install with pip:
pip install pyinaturalist
Then, import and create a client object. This will be our main interface to the API:
from pyinaturalist import *
client = iNatClient()
Note: If you are looking for the lower-level API functions (without the client class), see
this page
Search observations
Let's start by searching for all your own observations. There are
numerous fields you can search on, but we'll just use user_id for now:
>>> results = client.observations.search(user_id='my_username')
The full response consists of Observation objects with numerous attributes, but we can use pyinaturalist.pprint() to print
out a condensed summary:
>>> pprint(results)
ID Taxon Observed on User Location
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
117585709 Genus: Hyoscyamus (henbanes) May 18, 2022 niconoe Calvi, France
117464920 Genus: Omophlus May 17, 2022 niconoe GalΓ©ria, France
117464393 Genus: Briza (Rattlesnake Grasses) May 17, 2022 niconoe GalΓ©ria, France
...
You can also get
observation counts by species.
On iNaturalist.org, this information can be found on the 'Species' tab of search results.
For example, to get species counts of all your own research-grade observations:
>>> counts = client.observations.species_counts(user_id='my_username', quality_grade='research')
>>> pprint(counts)
ID Rank Scientific name Common name Count
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
47934 species π Libellula luctuosa Widow Skimmer 7
48627 species π» Echinacea purpurea Purple Coneflower 6
504060 species π Pleurotus citrinopileatus Golden Oyster Mushroom 6
...
The data will be in the form of
TaxonCount
objects:
>>> counts[0]
TaxonCount(
id=48662,
name='Danaus plexippus',
preferred_common_name='Monarch',
rank='species',
count=13,
observations_count=458712,
...
)
Another useful format is the
observation histogram,
which shows the number of observations over a given time interval. The default is month_of_year:
>>> histogram = client.observations.histogram(user_id='my_username')
>>> pprint(histogram)
Month Count
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Jan 8 ββββ
Feb 1 β
Mar 20 ββββββββββ
The raw data will be a dict, with either int or datetime keys, depending on the interval:
>>> print(histogram.raw)
{
1: 8, # January
2: 1, # February
3: 19, # March
..., # etc.
}
Create and update observations: authentication
To create or modify observations, you will first need to log in.
This requires creating an iNaturalist app,
which will be used to get an access token.
creds = {
'username': 'my_username',
'password': 'my_password',
'app_id': 'my_app_id',
'app_secret': 'my_app_secret',
}
client = iNatClient(creds=creds)
See Authentication
for more options including environment variables, keyrings, and password managers.
A keyring is recommended, which does not require passing credentials directly:
client = iNatClient()
# Creds will be requested from the keyring when an authenticated request is made
client.observations.create(...)
Create and update observations
Now we can create a new observation:
from datetime import datetime
new_obs = client.observations.create(
taxon_id=54327, # Vespa Crabro
observed_on_string=datetime.now(),
time_zone='Brussels',
description='This is a free text comment for the observation',
tag_list='wasp, Belgium',
latitude=50.647143,
longitude=4.360216,
positional_accuracy=50, # GPS accuracy in meters
photos=['~/observations/wasp1.jpg', '~/observations/wasp2.jpg'],
sounds=['~/observations/recording.wav'],
)
We can then update the observation information, photos, or sounds:
client.observations.update(
new_obs.id, # Use the observation ID from the result above
access_token=token,
description='updated description !',
photos='~/observations/wasp_nest.jpg',
sounds='~/observations/wasp_nest.mp3',
)
Search species
There are many more resource types available besides observations. Taxonomy is another useful one.
Let's say you partially remember either a genus or family name that started with 'vespi'-something.
The taxon search
can be used to search by name, rank, and several other criteria:
>>> results = client.taxa.search(q='vespi', rank=['genus', 'family'])
As with observations, there is a lot of information available in the response (Taxon objects), but we'll print just a few basic details:
>>> pprint(results)
ID Rank Scientific name Common name
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
52747 family π Vespidae Hornets, Paper Wasps, Potter Wasps, and Allies
84737 genus π¦ Vespina
646195 genus πͺ° Vespiodes
...
Next Steps
For more information, see:
- User Guide:
introduction and general features that apply to most endpoints - Endpoint Summary:
a complete list of endpoints wrapped by pyinaturalist - Examples:
data visualizations and other examples of things to do with iNaturalist data - Reference: Detailed API documentation
- Contributing Guide:
development details for anyone interested in contributing to pyinaturalist - History:
details on past and current releases - Issues: planned & proposed features
Feedback
If you have any problems, suggestions, or questions about pyinaturalist, you are welcome to create an issue or discussion. Also, PRs are welcome!
Note: pyinaturalist is developed by members of the iNaturalist community, and is not endorsed by
iNaturalist.org or the California Academy of Sciences. If you have non-python-specific questions
about the iNaturalist API or iNaturalist in general, the
iNaturalist Community Forum is the best place to start.
Related Projects
Other python projects related to iNaturalist:
- naturtag: A desktop application for tagging image files with iNaturalist taxonomy & observation metadata
- pyinaturalist-convert: Tools to convert observation data to and from a variety of useful formats
- pyinaturalist-notebook: Jupyter notebook Docker image for pyinaturalist
- dronefly: A Discord bot with iNaturalist integration, used by the iNaturalist Discord server.
Owner metadata
- Name: pyinat
- Login: pyinat
- Email:
- Kind: organization
- Description: Python tools for interacting with iNaturalist
- Website: https://pyinaturalist.readthedocs.io
- Location: United States of America
- Twitter:
- Company:
- Icon url: https://avatars.githubusercontent.com/u/105503620?v=4
- Repositories: 6
- Last ynced at: 2024-05-12T00:45:45.872Z
- Profile URL: https://github.com/pyinat
GitHub Events
Total
- Release event: 1
- Delete event: 53
- Pull request event: 100
- Fork event: 3
- Issues event: 43
- Watch event: 18
- Issue comment event: 70
- Push event: 143
- Pull request review event: 2
- Create event: 49
Last Year
- Delete event: 39
- Pull request event: 72
- Fork event: 1
- Issues event: 32
- Watch event: 11
- Issue comment event: 45
- Push event: 102
- Pull request review event: 2
- Create event: 38
Committers metadata
Last synced: 5 days ago
Total Commits: 1,061
Total Committers: 15
Avg Commits per committer: 70.733
Development Distribution Score (DDS): 0.1
Commits in past year: 150
Committers in past year: 5
Avg Commits per committer in past year: 30.0
Development Distribution Score (DDS) in past year: 0.093
| Name | Commits | |
|---|---|---|
| Jordan Cook | j****k@p****m | 955 |
| Nicolas NoΓ© | n****s@n****u | 52 |
| dependabot[bot] | 4****] | 19 |
| LarytheLord | l****m@g****m | 10 |
| Nicolas NoΓ© | n****e@i****e | 6 |
| Will Kuhn | k****l@g****m | 4 |
| Darren Kirby | b****r@g****m | 4 |
| Peter Desmet | p****k@g****m | 3 |
| Oleksii Brodnikov | o****v@2****m | 2 |
| stuckvgn | s****n | 1 |
| Richard Littauer | r****r@g****m | 1 |
| Eduardo RamΓrez | e****0@g****m | 1 |
| Ben Armstrong | s****g@d****g | 1 |
| Stijn Van Hoey | s****y@i****e | 1 |
| Eduardo | e****z@a****m | 1 |
Committer domains:
- inbo.be: 2
- adevinta.com: 1
- debian.org: 1
- 2xideas.com: 1
- niconoe.eu: 1
- pioneer.com: 1
Issue and Pull Request metadata
Last synced: 10 days ago
Total issues: 223
Total pull requests: 457
Average time to close issues: 3 months
Average time to close pull requests: 6 days
Total issue authors: 30
Total pull request authors: 9
Average comments per issue: 2.0
Average comments per pull request: 0.76
Merged pull request: 326
Bot issues: 1
Bot pull requests: 199
Past year issues: 7
Past year pull requests: 28
Past year average time to close issues: 8 days
Past year average time to close pull requests: 4 days
Past year issue authors: 3
Past year pull request authors: 3
Past year average comments per issue: 1.43
Past year average comments per pull request: 0.5
Past year merged pull request: 9
Past year bot issues: 0
Past year bot pull requests: 19
Top Issue Authors
- JWCook (160)
- synrg (11)
- arky (10)
- niconoe (9)
- nigelcharman (4)
- abubelinha (3)
- svshepherd (2)
- AugustT (2)
- aubreymoore (1)
- peterdesmet (1)
- FelipeSBarros (1)
- nleguillarme (1)
- jhuus (1)
- jwidness (1)
- dependabot[bot] (1)
Top Pull Request Authors
- JWCook (241)
- dependabot[bot] (199)
- DarrenKirby (6)
- alterionisto (3)
- eduramirezh (2)
- LucaCappelletti94 (2)
- willkuhn (2)
- RichardLitt (1)
- synrg (1)
Top Issue Labels
- enhancement (88)
- new endpoint (42)
- bug (36)
- docs (27)
- logistics (23)
- question (12)
- examples (11)
- refactoring (3)
- good first issue (2)
- endpoint (2)
- wontfix (2)
- dependencies (1)
- github_actions (1)
- tests (1)
Top Pull Request Labels
- dependencies (112)
- enhancement (112)
- python (86)
- docs (44)
- bug (32)
- new endpoint (32)
- logistics (26)
- github_actions (20)
- examples (7)
- python:uv (6)
- refactoring (6)
- tests (3)
Package metadata
- Total packages: 3
-
Total downloads:
- pypi: 16,140 last-month
- Total dependent packages: 5 (may contain duplicates)
- Total dependent repositories: 16 (may contain duplicates)
- Total versions: 109
- Total maintainers: 2
proxy.golang.org: github.com/pyinat/pyinaturalist
- Homepage:
- Documentation: https://pkg.go.dev/github.com/pyinat/pyinaturalist#section-documentation
- Licenses: mit
- Latest release: v0.21.1 (published 3 months ago)
- Last Synced: 2026-05-15T21:05:20.494Z (5 days ago)
- Versions: 28
- Dependent Packages: 0
- Dependent Repositories: 0
-
Rankings:
- Dependent packages count: 5.395%
- Average: 5.576%
- Dependent repos count: 5.758%
pypi.org: pyinaturalist
iNaturalist API client for python
- Homepage:
- Documentation: https://pyinaturalist.readthedocs.io/
- Licenses: MIT
- Latest release: 0.21.1 (published 3 months ago)
- Last Synced: 2026-05-15T21:05:25.983Z (5 days ago)
- Versions: 75
- Dependent Packages: 4
- Dependent Repositories: 15
- Downloads: 16,140 Last month
-
Rankings:
- Dependent packages count: 1.611%
- Dependent repos count: 3.79%
- Stargazers count: 6.884%
- Average: 7.278%
- Forks count: 10.557%
- Downloads: 13.549%
- Maintainers (2)
conda-forge.org: pyinaturalist
- Homepage: https://github.com/pyinat/pyinaturalist
- Licenses: MIT
- Latest release: 0.16.0 (published about 4 years ago)
- Last Synced: 2026-04-01T02:00:11.345Z (about 2 months ago)
- Versions: 6
- Dependent Packages: 1
- Dependent Repositories: 1
-
Rankings:
- Dependent repos count: 24.348%
- Dependent packages count: 28.978%
- Average: 33.37%
- Stargazers count: 35.211%
- Forks count: 44.942%
Dependencies
- 130 dependencies
- coverage >=6.3 develop
- nox ^2022.1.7 develop
- nox-poetry ^1.0.0 develop
- pre-commit ^2.19 develop
- pretty-errors ^1.2.23 develop
- pytest ^7.0 develop
- pytest-asyncio ^0.18.1 develop
- pytest-cov >=3.0 develop
- pytest-xdist >=2.2 develop
- requests-mock ^1.8 develop
- sphinx-autobuild >=2021.3.14 develop
- attrs >=21.2
- furo ^2022.2.14.1
- ipython ^7.25.0
- keyring >=22.3
- linkify-it-py ^1.0.1
- myst-parser ^0.17.0
- nbsphinx ^0.8.5
- platformdirs >=2.5
- python ^3.7
- python-dateutil >=2.0
- python-forge >=18.6
- requests >=2.22
- requests-cache >=1.0.0a1
- requests-ratelimiter >=0.3.2
- rich >=10.9
- sphinx ^4.2.0
- sphinx-autodoc-typehints ^1.17
- sphinx-automodapi ^0.14
- sphinx-copybutton >=0.5
- sphinx-inline-tabs ^2022.1.2b11
- sphinx-panels ^0.6.0
- sphinxcontrib-apidoc ^0.3
- actions/cache v3 composite
- actions/checkout v3 composite
- actions/setup-python v4 composite
- codecov/codecov-action v3 composite
- pre-commit/action v3.0.0 composite
- snok/install-poetry v1.3 composite
- actions/checkout v3 composite
- actions/setup-python v4 composite
- snok/install-poetry v1.3 composite
- jxcook/pyinaturalist-notebook 0.14 build
- jxcook/pyinaturalist-notebook latest
Score: 17.618885984590342
