|
3 | 3 | """
|
4 | 4 |
|
5 | 5 | import json
|
| 6 | +from dataclasses import dataclass |
6 | 7 | from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
|
7 | 8 |
|
8 | 9 | from async_lru import alru_cache
|
|
13 | 14 | from synapseclient import Synapse
|
14 | 15 |
|
15 | 16 |
|
| 17 | +@dataclass |
| 18 | +class EntityHeader: |
| 19 | + """ |
| 20 | + JSON schema for EntityHeader POJO. This represents metadata about a Synapse entity. |
| 21 | +
|
| 22 | + Attributes: |
| 23 | + name: The name of the entity |
| 24 | + id: The id of the entity |
| 25 | + type: The type of the entity |
| 26 | + version_number: The version number of the entity |
| 27 | + version_label: The user defined version label of the entity |
| 28 | + is_latest_version: If this version is the latest version of the entity |
| 29 | + benefactor_id: The ID of the entity that this Entity's ACL is inherited from |
| 30 | + created_on: The date this entity was created |
| 31 | + modified_on: The date this entity was last modified |
| 32 | + created_by: The ID of the user that created this entity |
| 33 | + modified_by: The ID of the user that last modified this entity |
| 34 | + """ |
| 35 | + |
| 36 | + name: Optional[str] = None |
| 37 | + """The name of the entity""" |
| 38 | + |
| 39 | + id: Optional[str] = None |
| 40 | + """The id of the entity""" |
| 41 | + |
| 42 | + type: Optional[str] = None |
| 43 | + """The type of the entity""" |
| 44 | + |
| 45 | + version_number: Optional[int] = None |
| 46 | + """The version number of the entity""" |
| 47 | + |
| 48 | + version_label: Optional[str] = None |
| 49 | + """The user defined version label of the entity""" |
| 50 | + |
| 51 | + is_latest_version: Optional[bool] = None |
| 52 | + """If this version is the latest version of the entity""" |
| 53 | + |
| 54 | + benefactor_id: Optional[int] = None |
| 55 | + """The ID of the entity that this Entity's ACL is inherited from""" |
| 56 | + |
| 57 | + created_on: Optional[str] = None |
| 58 | + """The date this entity was created""" |
| 59 | + |
| 60 | + modified_on: Optional[str] = None |
| 61 | + """The date this entity was last modified""" |
| 62 | + |
| 63 | + created_by: Optional[str] = None |
| 64 | + """The ID of the user that created this entity""" |
| 65 | + |
| 66 | + modified_by: Optional[str] = None |
| 67 | + """The ID of the user that last modified this entity""" |
| 68 | + |
| 69 | + def fill_from_dict(self, synapse_response: Dict[str, Any]) -> "EntityHeader": |
| 70 | + """Converts a response from the REST API into this dataclass.""" |
| 71 | + self.name = synapse_response.get("name", None) |
| 72 | + self.id = synapse_response.get("id", None) |
| 73 | + self.type = synapse_response.get("type", None) |
| 74 | + self.version_number = synapse_response.get("versionNumber", None) |
| 75 | + self.version_label = synapse_response.get("versionLabel", None) |
| 76 | + self.is_latest_version = synapse_response.get("isLatestVersion", None) |
| 77 | + self.benefactor_id = synapse_response.get("benefactorId", None) |
| 78 | + self.created_on = synapse_response.get("createdOn", None) |
| 79 | + self.modified_on = synapse_response.get("modifiedOn", None) |
| 80 | + self.created_by = synapse_response.get("createdBy", None) |
| 81 | + self.modified_by = synapse_response.get("modifiedBy", None) |
| 82 | + return self |
| 83 | + |
| 84 | + |
16 | 85 | async def post_entity(
|
17 | 86 | request: Dict[str, Any],
|
18 | 87 | generated_by: Optional[str] = None,
|
@@ -345,6 +414,81 @@ async def main():
|
345 | 414 | )
|
346 | 415 |
|
347 | 416 |
|
| 417 | +async def get_entity_acl( |
| 418 | + entity_id: str, |
| 419 | + *, |
| 420 | + synapse_client: Optional["Synapse"] = None, |
| 421 | +): |
| 422 | + """ |
| 423 | + Get the Access Control List (ACL) for an entity. |
| 424 | +
|
| 425 | + Note: If this method is called on an Entity that is inheriting its permission |
| 426 | + from another Entity a NOT_FOUND (404) response will be generated. The error |
| 427 | + response message will include the Entity's benefactor ID. |
| 428 | +
|
| 429 | + Arguments: |
| 430 | + entity_id: The ID of the entity. |
| 431 | + synapse_client: If not passed in and caching was not disabled by |
| 432 | + `Synapse.allow_client_caching(False)` this will use the last created |
| 433 | + instance from the Synapse class constructor. |
| 434 | + """ |
| 435 | + from synapseclient import Synapse |
| 436 | + |
| 437 | + client = Synapse.get_client(synapse_client=synapse_client) |
| 438 | + return await client.rest_get_async( |
| 439 | + uri=f"/entity/{entity_id}/acl", |
| 440 | + ) |
| 441 | + |
| 442 | + |
| 443 | +async def get_entity_benefactor( |
| 444 | + entity_id: str, |
| 445 | + *, |
| 446 | + synapse_client: Optional["Synapse"] = None, |
| 447 | +) -> EntityHeader: |
| 448 | + """ |
| 449 | + Get an Entity's benefactor. An Entity gets its ACL from its benefactor. |
| 450 | +
|
| 451 | + Implements: |
| 452 | + <https://rest-docs.synapse.org/rest/GET/entity/id/benefactor.html> |
| 453 | +
|
| 454 | + Arguments: |
| 455 | + entity_id: The ID of the entity. |
| 456 | + synapse_client: If not passed in and caching was not disabled by |
| 457 | + `Synapse.allow_client_caching(False)` this will use the last created |
| 458 | + instance from the Synapse class constructor. |
| 459 | +
|
| 460 | + Returns: |
| 461 | + The EntityHeader of the entity's benefactor (the entity from which it inherits its ACL). |
| 462 | +
|
| 463 | + Example: Get the benefactor of an entity |
| 464 | + Get the benefactor entity header for entity `syn123`. |
| 465 | +
|
| 466 | + ```python |
| 467 | + import asyncio |
| 468 | + from synapseclient import Synapse |
| 469 | + from synapseclient.api import get_entity_benefactor |
| 470 | +
|
| 471 | + syn = Synapse() |
| 472 | + syn.login() |
| 473 | +
|
| 474 | + async def main(): |
| 475 | + benefactor = await get_entity_benefactor(entity_id="syn123") |
| 476 | + print(f"Entity benefactor: {benefactor.name} (ID: {benefactor.id})") |
| 477 | +
|
| 478 | + asyncio.run(main()) |
| 479 | + ``` |
| 480 | + """ |
| 481 | + from synapseclient import Synapse |
| 482 | + |
| 483 | + client = Synapse.get_client(synapse_client=synapse_client) |
| 484 | + response = await client.rest_get_async( |
| 485 | + uri=f"/entity/{entity_id}/benefactor", |
| 486 | + ) |
| 487 | + |
| 488 | + entity_header = EntityHeader() |
| 489 | + return entity_header.fill_from_dict(response) |
| 490 | + |
| 491 | + |
348 | 492 | async def get_entity_path(
|
349 | 493 | entity_id: str,
|
350 | 494 | *,
|
|
0 commit comments