Hello everyone,
I manage a database in PostGreSQL, and I retrieve my observations via iNaturalist API and a Python script inspired by the remarkable work of @pisum here: https://jumear.github.io/stirpy/lab?path=iNat_APIv1_get_observations.ipynb
(thanks again
)
In order to link to local taxonomic repositories (INPN Taxref in my case), I need to retrieve the link between the taxon_id from iNaturalist and gbif_taxon_id.
I can do this using this script, which uses Wikidata and SPARQL :
import requests
import psycopg2
from psycopg2 import sql
DB_CONFIG = {
"dbname": "inaturalist",
"user": "user",
"host": "host",
"port": "5432"
}
SPARQL_ENDPOINT = "https://query.wikidata.org/sparql"
def get_gbif_id_from_inat_id(inat_id):
query = f"""
SELECT ?gbif_id WHERE {{
?item wdt:P3151 "{inat_id}".
OPTIONAL {{ ?item wdt:P846 ?gbif_id. }}
}}
"""
headers = {
"User-Agent": "iNaturalist-GBIF-Sync/1.0 (mail@mail.fr)"
}
try:
response = requests.get(
SPARQL_ENDPOINT,
params={"query": query, "format": "json"},
headers=headers
)
response.raise_for_status()
data = response.json()
results = data.get("results", {}).get("bindings", [])
if results:
return results[0].get("gbif_id", {}).get("value")
except requests.exceptions.RequestException as e:
print(f"Error for {inat_id}: {e}")
return None
def update_gbif_ids_in_database():
"""Update the database table with GBIF IDs."""
conn = psycopg2.connect(**DB_CONFIG)
cursor = conn.cursor()
cursor.execute("SELECT taxon_id, taxon_name FROM taxo.inat_taxo WHERE gbif_taxon_id IS NULL or gbif_taxon_id = 0")
taxons = cursor.fetchall()
for taxon_id, taxon_name in taxons:
gbif_id = get_gbif_id_from_inat_id(str(taxon_id))
if gbif_id:
cursor.execute(
sql.SQL("""
UPDATE taxo.inat_taxo
SET gbif_taxon_id = %s
WHERE taxon_id = %s
"""),
(gbif_id, taxon_id)
)
print(f"Updated: {taxon_name} (iNaturalist: {taxon_id}) → GBIF: {gbif_id}")
else:
print(f"No GBIF ID found for: {taxon_name} (iNaturalist: {taxon_id})")
conn.commit()
cursor.close()
conn.close()
if __name__ == "__main__":
update_gbif_ids_in_database()
However, I think this is resource-intensive for Wikidata, and I wonder if the global correspondence table might be available somewhere.
Do you have any advice?
