Trouble with iNat API - update observation info

Platform Android, iOS, WEB

Hello!
From the beginning: I am a student of biological sciences at the federal university of uberlândia. I’m currently working on arthropod identification in the city of Uberlândia, more specifically on the glória campus (experimental farm).

The idea of the work is to survey the arthropod fauna in the region. To do this, I set up traps in various locations around the farm (I have the coordinates of the regions).

Sorting process: identification of the arthropod, weighing, size measurement.

The problem: Hundreds of different animals are collected every day. During the sorting process, we upload photos of the animals to inaturalist, both to have photos attached and to help identify the species. As this process is done in the laboratory, the latitude, longitude and place_guess fields were automatically entered as if the animal had been collected in the laboratory.

As we have more than 300 observations and changing the coordinates of each observation is unfeasible, I thought I’d develop a code using the inaturalist api with application authentication to be able to make mass changes to the ids of the photos I need to change.

We still have more than 500 observations to place in iNaturalist, making the bulk change option unfeasible as well.

The problem encountered: For some reason that even the inaturalist developers couldn’t tell me, when the script is run it takes a list of observation ids and changes the coordinates one by one. When it makes the change, the photo of the observation is deleted (the coordinates and place_guess are changed without problems).

Alternatives tried: make the script save the photo of the observation before changing the coordinates and place_guess, make these changes and send the photo to the observation again → I couldn’t identify why it didn’t work.

Here’s the code for the script I’m trying to set up:

import requests 

 

# Credenciais do app inat 

CLIENT_ID = '' 

CLIENT_SECRET = '' 

USERNAME = 'email' 

PASSWORD = 'passwd' 

 

# ID obs. 

observation_id = [ids] 

 

# coordinates + place_guess 

new_latitude = -20.0 

new_longitude = -50.0 

new_place_guess = "test place" 

 

# Endpoint 

update_observation_url = f'https://api.inaturalist.org/v1/observations/{observation_id}' 

 

# access token 

token_url = 'https://www.inaturalist.org/oauth/token' 

data = { 

    'client_id': CLIENT_ID, 

    'client_secret': CLIENT_SECRET, 

    'grant_type': 'password', 

    'username': USERNAME, 

    'password': PASSWORD 

} 

 

response = requests.post(token_url, data=data) 

access_token = response.json().get('access_token') 

 

# Verifique se o token de acesso foi obtido com sucesso 

if not access_token: 

    print('Falha ao obter o token de acesso. Verifique suas credenciais.') 

    exit() 

 

# Obtenha a observação existente para preservar as fotos 

get_observation_url = f'https://api.inaturalist.org/v1/observations/{observation_id}' 

headers = {'Authorization': f'Bearer {access_token}'} 

existing_observation = requests.get(get_observation_url, headers=headers).json() 

 

# Construa os dados de atualização, incluindo fotos existentes e novo local 

update_data = { 

    'observation': { 

        'latitude': new_latitude, 

        'longitude': new_longitude, 

        'place_guess': new_place_guess, 

        'observation_photos_attributes': [{'photo_id': photo['photo']['id']} for photo in existing_observation.get('observation_photos', [])] 

    } 

} 

 

# Faça a solicitação de atualização usando o método PUT 

response = requests.put(update_observation_url, json=update_data, headers=headers) 

 

# Verifique o status da resposta 

if response.status_code == 200: 

    print(f'A observação {observation_id} foi atualizada com sucesso!') 

else: 

    print(f'Erro ao atualizar a observação {observation_id}. Status code: {response.status_code}') 

    try: 

        print(response.json()) 

    except: 

        print(f'Resposta não válida: {response.text}') 

Did you try with the parameter ignore_photos set to true?

(Related discussion here)

3 Likes

Sounds like a cool project! Not related to the API issue, but just to clarify your use case:

Are you taking photos in the lab via a device which has some type of automatic geolocation that adds the lab as the location when the observation coordinates should be for the trapping site?

And then you are looking to change the coordinates from the lab to the trap site after initially posting the observations? Are you also changing the date/time to that of trapping?

One workaround/alternative workflow could just be to “cut out the middleman” and upload with the correct trap location/date/time all at once. This might be longer as a step, but could simplify the process overall.

I would also recommend adding some standard text in the notes to your observations describing that you are giving the trap location (if that’s what you are doing) so that IDers know not to mark the observations as “not wild”.

Hey! Thank you :)

First question: Yes, it’s an Android phone that automatically sets the coordinates for the location of the laboratory.

Second question: Exactly, except the date/time because we don’t have that kind of control (we use fall traps and check them twice a week).

One workaround/alternative workflow could just be to “cut out the middleman” and upload with the correct trap location/date/time all at once. This might be longer as a step, but could simplify the process overall.

I’m not the only one who works with these arthropods, so I can’t say that everyone knows and uses this app. Unfortunately, some people don’t know how to use (don’t try to learn) the iNat app, so it’s confusing for them

I would also recommend adding some standard text in the notes to your observations describing that you are giving the trap location (if that’s what you are doing) so that IDers know not to mark the observations as “not wild”.

I hadn’t thought of that, thanks, I will

1 Like

Thanks for the clarification! For the date, time, if it’s a 3-4 day trapping period, and you pick one of the days in the middle of the trapping period, this is probably reasonable, as the observation would mostly like be off by a day, max of two.

1 Like

That was amazing!

Thank you so much!!!

1 Like