iNaturalist API with Python : get family name from observations?

this is my relevant code from https://github.com/jumear/stirpy/blob/main/content/iNat_APIv1_get_observations.ipynb (which can also be viewed as a web-based Jupyter workbook from https://jumear.github.io/stirpy/lab/index.html?path=iNat_APIv1_get_observations.ipynb):

def add_obs_taxon_ancestors(r):
    """Intended to be used as pre-parse function in parse_results when parsing observations.
    The observation taxon itself has an ancestor list but no detailed ancestor information; however, the taxon fields in the identiifcations do have ancestor details.
    So this adds ancestor details to the observation taxon, based on the ancestor details in the identifications (since the observation taxon should always be included in the indentification taxa or their ancestors).
    """
    ancestors = []
    rank_level_kingdom = 70 # this is the highest-level taxon stored in identification[i].ancestors
    if (rt := r.get('taxon')) and (taxon_id := rt.get('id')) is not None and (rank_level := rt.get('rank_level')) < rank_level_kingdom:
        for id in r.get('identifications',[]):
            if (idt := id.get('taxon')):
                if idt['id'] == taxon_id:
                    ancestors = list(idt['ancestors'])
                    break
                if (idta := idt['ancestors']):
                    for i, atid in enumerate([a['id'] for a in idta]):
                        if atid == taxon_id:
                            ancestors = idta[0:i] # add everything above this taxon (will add this taxon later below)
                            break
                if ancestors:
                    break
    if rt and rank_level <= rank_level_kingdom:
        ancestors.append(rt.copy())
        rt['ancestors'] = ancestors

when you run this for each observation in your result set, this function effectively adds detailed ancestors information from identifications[i].taxon.ancestors to the existing taxon object.

this eliminates the need to make all the extra API requests to /v1/taxon/{id} (which you’re making from get_taxon_info).

so then after that, i didn’t check the code below, but getting ancestor should be something like:

ancestors = result.get["taxon"],{}).get("ancestors",[])

… and getting the family name should be something like:

family_name = ancestor[0]['name'] for ancestor in result.get["taxon"],{}).get("ancestors",[]) if (ancestor["rank"]=='family')
2 Likes