synapseclient 4.1.0__tar.gz → 4.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. {synapseclient-4.1.0/synapseclient.egg-info → synapseclient-4.2.0}/PKG-INFO +7 -1
  2. {synapseclient-4.1.0 → synapseclient-4.2.0}/setup.cfg +6 -0
  3. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/__main__.py +12 -7
  4. synapseclient-4.2.0/synapseclient/api/__init__.py +54 -0
  5. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/api/annotations.py +12 -5
  6. synapseclient-4.2.0/synapseclient/api/entity_bundle_services_v2.py +146 -0
  7. synapseclient-4.2.0/synapseclient/api/entity_services.py +177 -0
  8. synapseclient-4.2.0/synapseclient/api/file_services.py +365 -0
  9. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/client.py +734 -242
  10. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/async_utils.py +55 -10
  11. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/cache.py +5 -1
  12. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/credentials/credential_provider.py +1 -4
  13. synapseclient-4.2.0/synapseclient/core/exceptions.py +274 -0
  14. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/multithread_download/download_threads.py +23 -12
  15. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/remote_file_storage_wrappers.py +56 -28
  16. synapseclient-4.2.0/synapseclient/core/retry.py +610 -0
  17. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/sts_transfer.py +38 -2
  18. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/upload/multipart_upload.py +40 -63
  19. synapseclient-4.2.0/synapseclient/core/upload/multipart_upload_async.py +871 -0
  20. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/upload/upload_functions.py +0 -3
  21. synapseclient-4.2.0/synapseclient/core/upload/upload_functions_async.py +424 -0
  22. synapseclient-4.2.0/synapseclient/core/upload/upload_utils.py +70 -0
  23. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/utils.py +83 -14
  24. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/annotations.py +32 -16
  25. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/file.py +508 -161
  26. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/folder.py +24 -10
  27. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/mixins/access_control.py +1 -3
  28. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/mixins/storable_container.py +5 -6
  29. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/project.py +27 -11
  30. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/services/__init__.py +2 -1
  31. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/services/search.py +3 -5
  32. synapseclient-4.2.0/synapseclient/models/services/storable_entity.py +101 -0
  33. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/services/storable_entity_components.py +1 -1
  34. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/table.py +31 -29
  35. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/team.py +6 -2
  36. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/user.py +1 -3
  37. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/synapsePythonClient +1 -1
  38. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/table.py +0 -4
  39. {synapseclient-4.1.0 → synapseclient-4.2.0/synapseclient.egg-info}/PKG-INFO +7 -1
  40. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient.egg-info/SOURCES.txt +7 -0
  41. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient.egg-info/requires.txt +6 -0
  42. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseutils/copy_functions.py +31 -1
  43. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseutils/sync.py +8 -11
  44. synapseclient-4.1.0/synapseclient/api/__init__.py +0 -7
  45. synapseclient-4.1.0/synapseclient/core/exceptions.py +0 -159
  46. synapseclient-4.1.0/synapseclient/core/retry.py +0 -197
  47. {synapseclient-4.1.0 → synapseclient-4.2.0}/MANIFEST.in +0 -0
  48. {synapseclient-4.1.0 → synapseclient-4.2.0}/README.md +0 -0
  49. {synapseclient-4.1.0 → synapseclient-4.2.0}/pyproject.toml +0 -0
  50. {synapseclient-4.1.0 → synapseclient-4.2.0}/setup.py +0 -0
  51. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/.synapseConfig +0 -0
  52. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/__init__.py +0 -0
  53. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/activity.py +0 -0
  54. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/annotations.py +0 -0
  55. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/__init__.py +0 -0
  56. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/config.py +0 -0
  57. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/constants/__init__.py +0 -0
  58. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/constants/concrete_types.py +0 -0
  59. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/constants/config_file_constants.py +0 -0
  60. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/constants/limits.py +0 -0
  61. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/constants/method_flags.py +0 -0
  62. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/credentials/__init__.py +0 -0
  63. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/credentials/cred_data.py +0 -0
  64. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/cumulative_transfer_progress.py +0 -0
  65. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/dozer.py +0 -0
  66. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/lock.py +0 -0
  67. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/logging_setup.py +0 -0
  68. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/models/__init__.py +0 -0
  69. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/models/custom_json.py +0 -0
  70. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/models/dict_object.py +0 -0
  71. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/models/permission.py +0 -0
  72. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/multithread_download/__init__.py +0 -0
  73. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/pool_provider.py +0 -0
  74. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/upload/__init__.py +0 -0
  75. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/core/version_check.py +0 -0
  76. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/entity.py +0 -0
  77. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/evaluation.py +0 -0
  78. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/__init__.py +0 -0
  79. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/activity.py +0 -0
  80. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/evaluation.py +0 -0
  81. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/mixins/__init__.py +0 -0
  82. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/protocols/__init__.py +0 -0
  83. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/protocols/access_control_protocol.py +0 -0
  84. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/protocols/activity_protocol.py +0 -0
  85. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/protocols/annotations_protocol.py +0 -0
  86. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/protocols/file_protocol.py +0 -0
  87. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/protocols/folder_protocol.py +0 -0
  88. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/protocols/project_protocol.py +0 -0
  89. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/protocols/storable_container_protocol.py +0 -0
  90. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/protocols/table_protocol.py +0 -0
  91. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/protocols/team_protocol.py +0 -0
  92. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/protocols/user_protocol.py +0 -0
  93. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/models/wiki.py +0 -0
  94. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/services/__init__.py +0 -0
  95. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/services/json_schema.py +0 -0
  96. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/team.py +0 -0
  97. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient/wiki.py +0 -0
  98. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient.egg-info/dependency_links.txt +0 -0
  99. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient.egg-info/entry_points.txt +0 -0
  100. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient.egg-info/not-zip-safe +0 -0
  101. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseclient.egg-info/top_level.txt +0 -0
  102. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseutils/__init__.py +0 -0
  103. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseutils/describe_functions.py +0 -0
  104. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseutils/migrate_functions.py +0 -0
  105. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseutils/monitor.py +0 -0
  106. {synapseclient-4.1.0 → synapseclient-4.2.0}/synapseutils/walk_functions.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: synapseclient
3
- Version: 4.1.0
3
+ Version: 4.2.0
4
4
  Summary: A client for Synapse, a collaborative, open-source research platform that allows teams to share data, track analyses, and collaborate.
5
5
  Home-page: https://www.synapse.org
6
6
  Author: The Synapse Engineering Team
@@ -36,6 +36,12 @@ Requires-Dist: opentelemetry-api~=1.21.0
36
36
  Requires-Dist: opentelemetry-sdk~=1.21.0
37
37
  Requires-Dist: opentelemetry-exporter-otlp-proto-http~=1.21.0
38
38
  Requires-Dist: nest-asyncio~=1.6.0
39
+ Requires-Dist: asyncio-atexit~=1.0.1
40
+ Requires-Dist: httpx~=0.27.0
41
+ Requires-Dist: tqdm<5.0,>=4.66.2
42
+ Requires-Dist: loky~=3.0.0
43
+ Requires-Dist: async-lru~=2.0.4
44
+ Requires-Dist: psutil~=5.9.8
39
45
  Provides-Extra: dev
40
46
  Requires-Dist: pytest<7.0,>=6.0.0; extra == "dev"
41
47
  Requires-Dist: pytest-mock<4.0,>=3.0; extra == "dev"
@@ -45,6 +45,12 @@ install_requires =
45
45
  opentelemetry-sdk~=1.21.0
46
46
  opentelemetry-exporter-otlp-proto-http~=1.21.0
47
47
  nest-asyncio~=1.6.0
48
+ asyncio-atexit~=1.0.1
49
+ httpx~=0.27.0
50
+ tqdm>=4.66.2,<5.0
51
+ loky~=3.0.0
52
+ async-lru~=2.0.4
53
+ psutil~=5.9.8
48
54
  tests_require =
49
55
  pytest>=6.0.0,<7.0
50
56
  pytest-mock>=3.0,<4.0
@@ -4,6 +4,7 @@ The Synapse command line client.
4
4
  For a description of its usage and parameters, see its documentation:
5
5
  https://python-docs.synapse.org/build/html/CommandLineClient.html
6
6
  """
7
+
7
8
  import argparse
8
9
  import collections.abc
9
10
  import logging
@@ -221,9 +222,11 @@ def store(args, syn):
221
222
  else:
222
223
  entity = {
223
224
  "concreteType": "org.sagebionetworks.repo.model.%s" % args.type,
224
- "name": utils.guess_file_name(args.file)
225
- if args.file and not args.name
226
- else None,
225
+ "name": (
226
+ utils.guess_file_name(args.file)
227
+ if args.file and not args.name
228
+ else None
229
+ ),
227
230
  "parentId": None,
228
231
  }
229
232
  # Overide setting for parameters included in args
@@ -644,7 +647,7 @@ def submit(args, syn):
644
647
  )
645
648
 
646
649
 
647
- def get_download_list(args, syn):
650
+ def get_download_list(args, syn: synapseclient.Synapse) -> None:
648
651
  """Download files from the Synapse download cart"""
649
652
  manifest_path = syn.get_download_list(downloadLocation=args.downloadLocation)
650
653
  syn.logger.info(f"Manifest file: {manifest_path}")
@@ -676,9 +679,11 @@ def test_encoding() -> None:
676
679
  print("python version = ", platform.python_version())
677
680
  print(
678
681
  "sys.stdout.encoding = ",
679
- sys.stdout.encoding
680
- if hasattr(sys.stdout, "encoding")
681
- else "no encoding attribute",
682
+ (
683
+ sys.stdout.encoding
684
+ if hasattr(sys.stdout, "encoding")
685
+ else "no encoding attribute"
686
+ ),
682
687
  )
683
688
  print("sys.stdout.isatty() = ", sys.stdout.isatty())
684
689
  print("locale.getpreferredencoding() =", locale.getpreferredencoding())
@@ -0,0 +1,54 @@
1
+ # These are all of the models that are used by the Synapse client.
2
+ from .annotations import set_annotations
3
+ from .entity_bundle_services_v2 import (
4
+ get_entity_id_bundle2,
5
+ get_entity_id_version_bundle2,
6
+ post_entity_bundle2_create,
7
+ put_entity_id_bundle2,
8
+ )
9
+ from .entity_services import (
10
+ get_entity,
11
+ get_upload_destination,
12
+ get_upload_destination_location,
13
+ post_entity,
14
+ put_entity,
15
+ create_access_requirements_if_none,
16
+ )
17
+ from .file_services import (
18
+ get_file_handle,
19
+ post_external_filehandle,
20
+ post_external_object_store_filehandle,
21
+ post_external_s3_file_handle,
22
+ post_file_multipart,
23
+ put_file_multipart_complete,
24
+ post_file_multipart_presigned_urls,
25
+ put_file_multipart_add,
26
+ AddPartResponse,
27
+ )
28
+
29
+ __all__ = [
30
+ # annotations
31
+ "set_annotations",
32
+ "get_entity_id_bundle2",
33
+ "get_entity_id_version_bundle2",
34
+ "post_entity_bundle2_create",
35
+ "put_entity_id_bundle2",
36
+ # file_services
37
+ "post_file_multipart",
38
+ "put_file_multipart_add",
39
+ "put_file_multipart_complete",
40
+ "post_external_object_store_filehandle",
41
+ "post_external_s3_file_handle",
42
+ "get_file_handle",
43
+ "post_external_filehandle",
44
+ "post_file_multipart_presigned_urls",
45
+ "put_file_multipart_add",
46
+ "AddPartResponse",
47
+ # entity_services
48
+ "get_entity",
49
+ "put_entity",
50
+ "post_entity",
51
+ "get_upload_destination",
52
+ "get_upload_destination_location",
53
+ "create_access_requirements_if_none",
54
+ ]
@@ -2,33 +2,40 @@
2
2
  The purpose of this module is to provide any functions that are needed to interact with
3
3
  annotations that are not cleanly provided by the synapseclient library.
4
4
  """
5
+
5
6
  import json
6
7
 
7
8
  from dataclasses import asdict
8
9
 
9
10
  from typing import TYPE_CHECKING, Optional
10
- from synapseclient import Synapse
11
+
11
12
  from synapseclient.annotations import _convert_to_annotations_list
12
13
 
13
14
  if TYPE_CHECKING:
14
15
  from synapseclient.models import Annotations
16
+ from synapseclient import Synapse
15
17
 
16
18
 
17
19
  def set_annotations(
18
20
  annotations: "Annotations",
19
- synapse_client: Optional[Synapse] = None,
21
+ synapse_client: Optional["Synapse"] = None,
20
22
  ):
21
23
  """Call to synapse and set the annotations for the given input.
22
24
 
23
25
  Arguments:
24
- annotations: The annotations to set. This is expected to have the id, etag, and annotations filled in.
25
- synapse_client: If not passed in or None this will use the last client from the `.login()` method.
26
+ annotations: The annotations to set. This is expected to have the id, etag,
27
+ and annotations filled in.
28
+ synapse_client: If not passed in or None this will use the last client from
29
+ the `.login()` method.
26
30
 
27
31
  Returns: The annotations set in Synapse.
28
32
  """
29
33
  annotations_dict = asdict(annotations)
30
34
 
31
- synapse_annotations = _convert_to_annotations_list(annotations_dict["annotations"])
35
+ synapse_annotations = _convert_to_annotations_list(
36
+ annotations_dict["annotations"] or {}
37
+ )
38
+ from synapseclient import Synapse
32
39
 
33
40
  return Synapse.get_client(synapse_client=synapse_client).restPUT(
34
41
  f"/entity/{annotations.id}/annotations2",
@@ -0,0 +1,146 @@
1
+ """This module is responsible for exposing the services defined at:
2
+ <https://rest-docs.synapse.org/rest/#org.sagebionetworks.repo.web.controller.EntityBundleV2Controller>
3
+ """
4
+
5
+ import json
6
+ from typing import Any, Dict, Optional, TYPE_CHECKING
7
+
8
+ if TYPE_CHECKING:
9
+ from synapseclient import Synapse
10
+
11
+
12
+ async def get_entity_id_bundle2(
13
+ entity_id: str,
14
+ request: Optional[Dict[str, bool]] = None,
15
+ synapse_client: Optional["Synapse"] = None,
16
+ ) -> Dict[str, Any]:
17
+ """
18
+ Arguments:
19
+ entity_id: The ID of the entity to which the bundle belongs
20
+ request: The request for the bundle matching
21
+ <https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/entitybundle/v2/EntityBundleRequest.html>.
22
+ If not passed in or None, the default request will be used:
23
+
24
+ - includeEntity: True
25
+ - includeAnnotations: True
26
+ - includeFileHandles: True
27
+ - includeRestrictionInformation: True
28
+ synapse_client: If not passed in or None this will use the last client from
29
+ the `.login()` method.
30
+
31
+ Returns:
32
+ The requested entity bundle matching
33
+ <https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/entitybundle/v2/EntityBundle.html>
34
+ """
35
+ from synapseclient import Synapse
36
+
37
+ if not request:
38
+ request = {
39
+ "includeEntity": True,
40
+ "includeAnnotations": True,
41
+ "includeFileHandles": True,
42
+ "includeRestrictionInformation": True,
43
+ }
44
+
45
+ client = Synapse.get_client(synapse_client=synapse_client)
46
+ return await client.rest_post_async(
47
+ uri=f"/entity/{entity_id}/bundle2",
48
+ body=json.dumps(request),
49
+ )
50
+
51
+
52
+ async def get_entity_id_version_bundle2(
53
+ entity_id: str,
54
+ version: int,
55
+ request: Optional[Dict[str, bool]] = None,
56
+ synapse_client: Optional["Synapse"] = None,
57
+ ) -> Dict[str, Any]:
58
+ """
59
+ Arguments:
60
+ entity_id: The ID of the entity to which the bundle belongs
61
+ version: The version of the entity to which the bundle belongs
62
+ request: The request for the bundle matching
63
+ <https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/entitybundle/v2/EntityBundleRequest.html>.
64
+ If not passed in or None, the default request will be used:
65
+
66
+ - includeEntity: True
67
+ - includeAnnotations: True
68
+ - includeFileHandles: True
69
+ - includeRestrictionInformation: True
70
+ synapse_client: If not passed in or None this will use the last client from
71
+ the `.login()` method.
72
+
73
+ Returns:
74
+ The requested entity bundle matching
75
+ <https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/entitybundle/v2/EntityBundle.html>
76
+ """
77
+ from synapseclient import Synapse
78
+
79
+ if not request:
80
+ request = {
81
+ "includeEntity": True,
82
+ "includeAnnotations": True,
83
+ "includeFileHandles": True,
84
+ "includeRestrictionInformation": True,
85
+ }
86
+ client = Synapse.get_client(synapse_client=synapse_client)
87
+ return await client.rest_post_async(
88
+ uri=f"/entity/{entity_id}/version/{version}/bundle2",
89
+ body=json.dumps(request),
90
+ )
91
+
92
+
93
+ async def post_entity_bundle2_create(
94
+ request: Dict[str, Any],
95
+ generated_by: Optional[str] = None,
96
+ synapse_client: Optional["Synapse"] = None,
97
+ ) -> Dict[str, Any]:
98
+ """
99
+ Arguments:
100
+ request: The request for the bundle matching
101
+ <https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/entitybundle/v2/EntityBundleCreate.html>
102
+ generated_by: The ID of the activity to associate with the entity.
103
+ synapse_client: If not passed in or None this will use the last client from
104
+ the `.login()` method.
105
+
106
+ Returns:
107
+ The requested entity bundle matching
108
+ <https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/entitybundle/v2/EntityBundle.html>
109
+ """
110
+ from synapseclient import Synapse
111
+
112
+ client = Synapse.get_client(synapse_client=synapse_client)
113
+ return await client.rest_post_async(
114
+ uri="/entity/bundle2/create"
115
+ + (f"?generatedBy={generated_by}" if generated_by else ""),
116
+ body=json.dumps(request),
117
+ )
118
+
119
+
120
+ async def put_entity_id_bundle2(
121
+ entity_id: str,
122
+ request: Dict[str, Any],
123
+ generated_by: Optional[str] = None,
124
+ synapse_client: Optional["Synapse"] = None,
125
+ ) -> Dict[str, Any]:
126
+ """
127
+ Arguments:
128
+ entity_id: The ID of the entity to which the bundle belongs.
129
+ request: The request for the bundle matching
130
+ <https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/entitybundle/v2/EntityBundleCreate.html>
131
+ generated_by: The ID of the activity to associate with the entity.
132
+ synapse_client: If not passed in or None this will use the last client from
133
+ the `.login()` method.
134
+
135
+ Returns:
136
+ The requested entity bundle matching
137
+ <https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/entitybundle/v2/EntityBundle.html>
138
+ """
139
+ from synapseclient import Synapse
140
+
141
+ client = Synapse.get_client(synapse_client=synapse_client)
142
+ return await client.rest_put_async(
143
+ uri=f"/entity/{entity_id}/bundle2"
144
+ + (f"?generatedBy={generated_by}" if generated_by else ""),
145
+ body=json.dumps(request),
146
+ )
@@ -0,0 +1,177 @@
1
+ """This module is responsible for exposing the services defined at:
2
+ <https://rest-docs.synapse.org/rest/#org.sagebionetworks.repo.web.controller.EntityController>
3
+ """
4
+
5
+ import json
6
+ from typing import Any, Dict, Optional, Union, TYPE_CHECKING
7
+ from async_lru import alru_cache
8
+
9
+ if TYPE_CHECKING:
10
+ from synapseclient import Synapse
11
+
12
+
13
+ async def post_entity(
14
+ request: Dict[str, Any],
15
+ generated_by: Optional[str] = None,
16
+ synapse_client: Optional["Synapse"] = None,
17
+ ) -> Dict[str, Any]:
18
+ """
19
+ Arguments:
20
+ request: The request for the entity matching
21
+ <https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/Entity.html>
22
+ generated_by: The ID of the activity to associate with the entity.
23
+ synapse_client: If not passed in or None this will use the last client from
24
+ the `.login()` method.
25
+
26
+ Returns:
27
+ The requested entity matching
28
+ <https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/Entity.html>
29
+ """
30
+ from synapseclient import Synapse
31
+
32
+ client = Synapse.get_client(synapse_client=synapse_client)
33
+ params = {}
34
+ if generated_by:
35
+ params["generatedBy"] = generated_by
36
+ return await client.rest_post_async(
37
+ uri="/entity", body=json.dumps(request), params=params
38
+ )
39
+
40
+
41
+ async def put_entity(
42
+ entity_id: str,
43
+ request: Dict[str, Any],
44
+ new_version: bool = False,
45
+ generated_by: Optional[str] = None,
46
+ synapse_client: Optional["Synapse"] = None,
47
+ ) -> Dict[str, Any]:
48
+ """
49
+ Arguments:
50
+ entity_id: The ID of the entity to update.
51
+ request: The request for the entity matching
52
+ <https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/Entity.html>
53
+ new_version: If true, a new version of the entity will be created.
54
+ generated_by: The ID of the activity to associate with the entity.
55
+ synapse_client: If not passed in or None this will use the last client from
56
+ the `.login()` method.
57
+
58
+ Returns:
59
+ The requested entity bundle matching
60
+ <https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/Entity.html>
61
+ """
62
+ from synapseclient import Synapse
63
+
64
+ client = Synapse.get_client(synapse_client=synapse_client)
65
+ params = {}
66
+ if generated_by:
67
+ params["generatedBy"] = generated_by
68
+ if new_version:
69
+ params["newVersion"] = "true"
70
+ return await client.rest_put_async(
71
+ uri=f"/entity/{entity_id}", body=json.dumps(request), params=params
72
+ )
73
+
74
+
75
+ async def get_entity(
76
+ entity_id: str,
77
+ synapse_client: Optional["Synapse"] = None,
78
+ ) -> Dict[str, Any]:
79
+ """
80
+ Arguments:
81
+ entity_id: The ID of the entity.
82
+ synapse_client: If not passed in or None this will use the last client from
83
+ the `.login()` method.
84
+
85
+ Returns:
86
+ The requested entity bundle matching
87
+ <https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/Entity.html>
88
+ """
89
+ from synapseclient import Synapse
90
+
91
+ client = Synapse.get_client(synapse_client=synapse_client)
92
+ return await client.rest_get_async(
93
+ uri=f"/entity/{entity_id}",
94
+ )
95
+
96
+
97
+ @alru_cache(ttl=60)
98
+ async def get_upload_destination(
99
+ entity_id: str, synapse_client: Optional["Synapse"] = None
100
+ ) -> Dict[str, Union[str, int]]:
101
+ """
102
+ <https://rest-docs.synapse.org/rest/GET/entity/id/uploadDestination.html>
103
+
104
+ Arguments:
105
+ entity_id: The ID of the entity.
106
+ synapse_client: If not passed in or None this will use the last client from
107
+ the `.login()` method.
108
+
109
+ Returns:
110
+ The upload destination.
111
+ <https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/file/UploadDestination.html>
112
+ """
113
+ from synapseclient import Synapse
114
+
115
+ client = Synapse.get_client(synapse_client=synapse_client)
116
+ return await client.rest_get_async(
117
+ uri=f"/entity/{entity_id}/uploadDestination",
118
+ endpoint=client.fileHandleEndpoint,
119
+ )
120
+
121
+
122
+ async def get_upload_destination_location(
123
+ entity_id: str, location: str, synapse_client: Optional["Synapse"] = None
124
+ ) -> Dict[str, Union[str, int]]:
125
+ """
126
+ <https://rest-docs.synapse.org/rest/GET/entity/id/uploadDestination/storageLocationId.html>
127
+
128
+ Arguments:
129
+ entity_id: The ID of the entity.
130
+ location: A storage location ID of the upload destination.
131
+ synapse_client: If not passed in or None this will use the last client from
132
+ the `.login()` method.
133
+
134
+ Returns:
135
+ The upload destination.
136
+ <https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/file/UploadDestination.html>
137
+ """
138
+ from synapseclient import Synapse
139
+
140
+ client = Synapse.get_client(synapse_client=synapse_client)
141
+ return await client.rest_get_async(
142
+ uri=f"/entity/{entity_id}/uploadDestination/{location}",
143
+ endpoint=client.fileHandleEndpoint,
144
+ )
145
+
146
+
147
+ async def create_access_requirements_if_none(
148
+ entity_id: str, synapse_client: Optional["Synapse"] = None
149
+ ) -> None:
150
+ """
151
+ Checks to see if the given entity has access requirements. If not, then one is added
152
+
153
+ Arguments:
154
+ entity_id: The ID of the entity.
155
+ synapse_client: If not passed in or None this will use the last client from
156
+ the `.login()` method.
157
+ """
158
+ from synapseclient import Synapse
159
+
160
+ client = Synapse.get_client(synapse_client=synapse_client)
161
+ existing_restrictions = await client.rest_get_async(
162
+ f"/entity/{entity_id}/accessRequirement?offset=0&limit=1"
163
+ )
164
+ if (
165
+ existing_restrictions is None
166
+ or not hasattr(existing_restrictions, "results")
167
+ or len(existing_restrictions["results"]) == 0
168
+ ):
169
+ access_requirements = await client.rest_post_async(
170
+ f"/entity/{entity_id}/lockAccessRequirement"
171
+ )
172
+ client.logger.info(
173
+ "Created an access requirements request for "
174
+ f"{entity_id}: {access_requirements['jiraKey']}. An email will be sent to "
175
+ "the Synapse access control team to start the process of adding "
176
+ "terms-of-use or review board approval for this entity."
177
+ )