Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Labels not returned for Plant Phenology annotation #433

Closed
nigelcharman opened this issue Nov 21, 2022 · 6 comments · Fixed by #434
Closed

Labels not returned for Plant Phenology annotation #433

nigelcharman opened this issue Nov 21, 2022 · 6 comments · Fixed by #434
Labels
bug Something isn't working enhancement New feature or request
Milestone

Comments

@nigelcharman
Copy link

The problem

I'm hoping to get the labels for annotations, but am only seeing the IDs

Expected behavior

I can see the labels Plant Phenology and No Evidence of Flowering rather than just 12 and 21

Steps to reproduce the behavior

observation_in_json = get_observation(141964204)
observation = Observation.from_json(observation_in_json)
print(f'Term: {observation.annotations[0].term_label}, Value: {observation.annotations[0].value_label}')

is returning:
Term: 12, Value: 21

I've checked that these ids map to the labels Plant Phenology and No Evidence of Flowering at https://api.inaturalist.org/v1/docs/#!/Controlled_Terms/get_controlled_terms

Workarounds

Not that I know of

Environment

MacOS 12.6.1
Python 3.9.13
Pyinaturalist latest as at 21 Nov 2022 (pip install -U --pre pyinaturalist)

  • OS & version: [e.g. Debian 10]
  • Python version: [e.g. 3.9]
  • Pyinaturalist version or branch: [e.g. 0.13 or main branch]
@nigelcharman nigelcharman added the bug Something isn't working label Nov 21, 2022
@JWCook JWCook added the enhancement New feature or request label Nov 21, 2022
@JWCook JWCook added this to the v0.18 milestone Nov 21, 2022
@JWCook
Copy link
Member

JWCook commented Nov 21, 2022

Interesting, it looks like the response format has changed within the last year or so. Previously, GET /observations/{id} would return only attribute and value IDs for annotations, like in this sample response:

"annotations": [
{
"user_id": 2115051,
"concatenated_attr_val": "1|2",
"controlled_attribute_id": 1,
"votes": [],
"uuid": "65ce57cc-5e00-45ba-83d3-de9b0ee05c24",
"vote_score": 0,
"controlled_value_id": 2,
"user": {

But I just checked that same observation, and it looks like it now contains labels and other details you could previously only get from GET /controlled_terms: https://api.inaturalist.org/v1/observations/70963477

It would be fairly simple to include that info in Observation.annotations. I'll get that added soon.

@JWCook
Copy link
Member

JWCook commented Nov 27, 2022

This is mostly done, but a few more changes are needed. I noticed that these annotation details are available from GET /observations/{id}, but not GET /observations?id={id}.

@JWCook
Copy link
Member

JWCook commented Nov 27, 2022

@nigelcharman I ended up adding a separate function for this, get_observations_by_id(), instead of making breaking changes to get_observation() (See #435).

Changes for this are available in the latest pre-release. Usage example:

>>> from pyinaturalist import *

>>> observation_json = get_observations_by_id(141964204)
>>> observation = Observation.from_json(observation_json['results'][0])

>>> a = observation.annotations[0]
>>> a
Annotation(term='Plant Phenology', value='No Evidence of Flowering')

I added some less verbose properties to get labels only:

>>> a.term
'Plant Phenology'

>>> a.value
'No Evidence of Flowering',

To see full controlled term details:

>>> a.controlled_attribute
ControlledTerm(
    id=12,
    is_value=False,
    multivalued=True,
    label='Plant Phenology',
    ontology_uri='',
    uri='',
    uuid='e997f5f1-1e22-4f1e-bb51-425d70d07b1a',
    taxon_ids=[47126],
    values=[
        ControlledTermValue(id=13),
        ControlledTermValue(id=14),
        ControlledTermValue(id=15),
        ControlledTermValue(id=21),
    ],
)

>>> a.controlled_value
ControlledTermValue(
    id=21,
    blocking=True,
    label='No Evidence of Flowering',
    ontology_uri='',
    uri='',
    uuid='943f8dac-764a-4736-86b5-2f419bbd368b',
    taxon_ids=[47125],
)

@JWCook
Copy link
Member

JWCook commented Nov 27, 2022

By the way, if you mainly want to work with model objects instead of JSON, you may want to give the API client class a try (#217). It's not fully documented yet, but will be soon.

Here's an example of getting an observation by ID:

from pyinaturalist import *
client = iNatClient()

observation = client.observations.from_ids(141964204).one()

# Shorter syntax for getting a single record by ID:
observation = client.observations(141964204)

Or multiple observations by ID:

observations = client.observations.from_ids(141964204, 12345).all()

Or by other search criteria:

observations = client.observations.search(user_login='my_username', taxon_name='Danaus plexippus').all()

@nigelcharman
Copy link
Author

Thanks for the changes @JWCook!

I do normally want to search for observations (by taxon and place) rather than getting them by id. With the get_observations_by_id() approach, I think I would need to first do the search and then assemble a list of ids to pass to get_observations_by_id(). Let me know if there is a search based equivalent to get_observations_by_id()?

I'm not tied to JSON, so could definitely try out the model object approach and see if it gives us what we need.

@JWCook
Copy link
Member

JWCook commented Nov 27, 2022

Let me know if there is a search based equivalent to get_observations_by_id()?

Not yet, but that would be doable. I could add an option to use the main observation search endpoint, and make a separate request to fill in the missing annotation details using the controlled terms endpoint.

Generally I'd like the basic API functions (like get_observations()) to behave similarly to the iNaturalist API, and put higher-level features in the API client class. So this could be added as a keyword argument for iNatClient.observations.search().

I'll make a separate issue for that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants