Skip to content

Commit

Permalink
Merge branch 'master' into explore-and-add-remote
Browse files Browse the repository at this point in the history
  • Loading branch information
markbader authored Mar 4, 2025
2 parents cbe1315 + f2d87e1 commit d488cc8
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 6 deletions.
1 change: 1 addition & 0 deletions webknossos/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ For upgrade instructions, please check the respective _Breaking Changes_ section
### Breaking Changes

### Added
- Added `get_remote_annotations()` to AnnotationInfo class to get a list of all remote Annotations of the current user. [#1262](https://github.com/scalableminds/webknossos-libs/pull/1262)

### Changed

Expand Down

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions webknossos/tests/test_annotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,19 @@ def test_annotation_from_file_with_multi_volume() -> None:
pass


@pytest.mark.use_proxay
def test_remote_annotation_list() -> None:
path = TESTDATA_DIR / "annotations" / "l4_sample__explorational__suser__94b271.zip"
annotation_from_file = wk.Annotation.load(path)
annotation_from_file.organization_id = "Organization_X"
test_token = os.getenv("WK_TOKEN")
with wk.webknossos_context("http://localhost:9000", test_token):
annotation_from_file.upload()
annotations = wk.AnnotationInfo.get_remote_annotations()

assert annotation_from_file.name in [a.name for a in annotations]


@pytest.mark.use_proxay
def test_annotation_upload_download_roundtrip() -> None:
path = TESTDATA_DIR / "annotations" / "l4_sample__explorational__suser__94b271.zip"
Expand Down
20 changes: 19 additions & 1 deletion webknossos/webknossos/annotation/annotation_info.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Optional
from typing import List, Optional

import attr

Expand Down Expand Up @@ -38,3 +38,21 @@ def _from_api_annotation(cls, api_annotation: ApiAnnotation) -> "AnnotationInfo"
else None,
modified=api_annotation.modified,
)

@classmethod
def get_remote_annotations(
cls, is_finished: Optional[bool] = False, owner: Optional[str] = None
) -> List["AnnotationInfo"]:
"""Returns a list of AnnotationInfo objects for all annotations that belong to the current user (if owner is None).
If owner is not None, only annotations of the specified owner are returned."""
from ..client.context import _get_api_client

client = _get_api_client(True)
if owner is None:
owner = client.user_current().id

return [
cls._from_api_annotation(api_annotation)
for api_annotation in client.annotation_list(is_finished)
if api_annotation.owner.id == owner
]
10 changes: 5 additions & 5 deletions webknossos/webknossos/client/api_client/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,11 +261,11 @@ class ApiUser:
@attr.s(auto_attribs=True)
class ApiUserCompact:
id: str
email: str
first_name: str
last_name: str
is_admin: bool
is_dataset_manager: bool
email: Optional[str] = None
is_admin: Optional[bool] = None
is_dataset_manager: Optional[bool] = None


@attr.s(auto_attribs=True)
Expand Down Expand Up @@ -296,9 +296,9 @@ class ApiProject:
name: str
team: str
team_name: str
owner: Optional[ApiUserCompact] # None in case you have no read access on the owner
priority: int
paused: bool
owner: Optional[ApiUserCompact] # None in case you have no read access on the owner
expected_time: Optional[int] = None


Expand All @@ -311,7 +311,7 @@ class ApiAnnotation:
description: str
state: str
modified: int
data_store: ApiDataStore
data_store: Optional[ApiDataStore] = None
tracing_time: Optional[int] = None # millis


Expand Down
10 changes: 10 additions & 0 deletions webknossos/webknossos/client/api_client/wk_api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,16 @@ def dataset_explore_and_add_remote(
dataset,
)

def annotation_list(self, is_finished: Optional[bool]) -> List[ApiAnnotation]:
route = "/annotations/readable"
return self._get_json(
route,
List[ApiAnnotation],
query={
"isFinished": is_finished,
},
)

def datastore_list(self) -> List[ApiDataStore]:
route = "/datastores"
return self._get_json(route, List[ApiDataStore])
Expand Down

0 comments on commit d488cc8

Please sign in to comment.