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

Feature/streamlined annotations #327

Merged

Conversation

gregorjerse
Copy link
Contributor

No description provided.

@@ -92,6 +98,10 @@ def __init__(self, resolwe, resource, slug_field="slug"):

self.logger = logging.getLogger(__name__)

def _non_string_iterable(self, item) -> bool:
"""Return thur when item is iterable but not string."""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spelling: "thur" should be changed to True, i guess?

Also, could you explain a bit what this function is necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before there were checks where it was expected for resources to be of instance list (_dehydrate_resources, _add_filter). I believe I used them with iterable (dictkeys...) or something like that so I changed it to a more general type.

# Execute the query in a single request.
super()._fetch()

missing = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cold you explain why this scenario happens? Why in some cases self._field is None, while in others it is not None?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only optimization: the annotation fields are fetched in a single query when reading corresponding annotation values.

Maybe this is not necessary. Consider the following use case:

values = res.annotation_values.filter(entity=xxx)
for value in values:
    print(value.field.name, value.field.group.name)

This would query the backend for every field (so it would produce n queries). The "optimized" fetch only produces two queries (one for values and one for fields). One could argue that fields are not always used so the second query is not always necessary.

src/resdk/resolwe.py Outdated Show resolved Hide resolved
src/resdk/resources/__init__.py Show resolved Hide resolved

READ_ONLY_FIELDS = BaseResource.READ_ONLY_FIELDS + ("label",)

UPDATE_PROTECTED_FIELDS = BaseResource.UPDATE_PROTECTED_FIELDS + ("entity", "field")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filed entity is called sample in resdk. Could you enable that users would be able to relate to the sample as AnnotationValue.sample? However, this will only return Sample ID. So maybe it is better to expose this as AnnotationValue.sample_id... We can discuss this live.

@gregorjerse gregorjerse force-pushed the feature/streamlined_annotations branch 2 times, most recently from cf8b1dd to 8b889ec Compare October 24, 2023 12:09
:raises LookupError: when field at the specified path does not exist.
"""
group_name, field_name = full_path.split(".", maxsplit=1)
return self.get(field__name=field_name, field__group__name=group_name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will probably return all AnnotationValues with given field. So it is probably self.filter(...) instead of self.get(...)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, the backend refuses to provide result unless one entity filter is provided. However, my comment is still relevant, consider this filter:
res.annotation_value.filter(entity__collection=<collection>).from_path("general.species")
This will result in many results and AnnotationValueQuery.get fails since it got multiple results.

Please add a comment in docstring that indicates that user needs to provide a sample (entity) filter.

@gregorjerse gregorjerse force-pushed the feature/streamlined_annotations branch 9 times, most recently from e397f55 to caa1269 Compare October 25, 2023 15:06
@gregorjerse gregorjerse force-pushed the feature/streamlined_annotations branch from caa1269 to 0452f17 Compare October 25, 2023 15:34
Copy link
Member

@JureZmrzlikar JureZmrzlikar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very close! :-)
Just a few comments.

"""Get annotation group."""
return self._group

@group.setter
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

group is among READ_ONLY_FIELDS , while it also has a setter method. Isn't this a bit strange? I imagine that group should not be changed one the field is created...

READ_ONLY_FIELDS = BaseResource.READ_ONLY_FIELDS + (
"field",
"entity",
"value",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fields field and value are among other fields already.... Also, why is entity here?

return self._field

@field.setter
def field(self, payload):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider raising error in case _field is not None. This would prevent users from believing they updated the field immediately. I realize that this would raise error during save()

:raises LookupError: when field at the specified path does not exist.
"""
group_name, field_name = full_path.split(".", maxsplit=1)
return self.get(field__name=field_name, field__group__name=group_name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, the backend refuses to provide result unless one entity filter is provided. However, my comment is still relevant, consider this filter:
res.annotation_value.filter(entity__collection=<collection>).from_path("general.species")
This will result in many results and AnnotationValueQuery.get fails since it got multiple results.

Please add a comment in docstring that indicates that user needs to provide a sample (entity) filter.

@gregorjerse gregorjerse force-pushed the feature/streamlined_annotations branch from ecce189 to eac0922 Compare October 26, 2023 15:16
@gregorjerse gregorjerse force-pushed the feature/streamlined_annotations branch from eac0922 to f56898a Compare October 27, 2023 10:39
Copy link
Member

@JureZmrzlikar JureZmrzlikar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks for you effort!

@gregorjerse gregorjerse merged commit f56898a into genialis:master Oct 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants