synapseclient 4.4.1__tar.gz → 4.5.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.
- {synapseclient-4.4.1/synapseclient.egg-info → synapseclient-4.5.0}/PKG-INFO +5 -4
- {synapseclient-4.4.1 → synapseclient-4.5.0}/setup.cfg +4 -3
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/client.py +15 -10
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/download/__init__.py +2 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/download/download_async.py +6 -1
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/download/download_functions.py +79 -15
- synapseclient-4.5.0/synapseclient/core/dozer.py +44 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/retry.py +2 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/synapsePythonClient +1 -1
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/table.py +43 -4
- {synapseclient-4.4.1 → synapseclient-4.5.0/synapseclient.egg-info}/PKG-INFO +5 -4
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient.egg-info/requires.txt +4 -3
- synapseclient-4.4.1/synapseclient/core/dozer.py +0 -28
- {synapseclient-4.4.1 → synapseclient-4.5.0}/MANIFEST.in +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/README.md +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/pyproject.toml +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/setup.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/.synapseConfig +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/__init__.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/__main__.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/activity.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/annotations.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/api/__init__.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/api/annotations.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/api/configuration_services.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/api/entity_bundle_services_v2.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/api/entity_factory.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/api/entity_services.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/api/file_services.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/__init__.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/async_utils.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/cache.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/config.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/constants/__init__.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/constants/concrete_types.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/constants/config_file_constants.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/constants/limits.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/constants/method_flags.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/credentials/__init__.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/credentials/cred_data.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/credentials/credential_provider.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/cumulative_transfer_progress.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/exceptions.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/lock.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/logging_setup.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/models/__init__.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/models/custom_json.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/models/dict_object.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/models/permission.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/multithread_download/__init__.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/multithread_download/download_threads.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/pool_provider.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/remote_file_storage_wrappers.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/sts_transfer.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/transfer_bar.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/upload/__init__.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/upload/multipart_upload.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/upload/multipart_upload_async.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/upload/upload_functions.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/upload/upload_functions_async.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/upload/upload_utils.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/utils.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/version_check.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/entity.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/evaluation.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/__init__.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/activity.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/annotations.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/evaluation.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/file.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/folder.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/mixins/__init__.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/mixins/access_control.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/mixins/storable_container.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/project.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/protocols/__init__.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/protocols/access_control_protocol.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/protocols/activity_protocol.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/protocols/annotations_protocol.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/protocols/file_protocol.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/protocols/folder_protocol.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/protocols/project_protocol.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/protocols/storable_container_protocol.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/protocols/table_protocol.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/protocols/team_protocol.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/protocols/user_protocol.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/services/__init__.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/services/search.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/services/storable_entity.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/services/storable_entity_components.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/table.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/team.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/user.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/wiki.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/services/__init__.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/services/json_schema.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/team.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/wiki.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient.egg-info/SOURCES.txt +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient.egg-info/dependency_links.txt +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient.egg-info/entry_points.txt +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient.egg-info/not-zip-safe +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient.egg-info/top_level.txt +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseutils/__init__.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseutils/copy_functions.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseutils/describe_functions.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseutils/migrate_functions.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseutils/monitor.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseutils/sync.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/synapseutils/walk_functions.py +0 -0
- {synapseclient-4.4.1 → synapseclient-4.5.0}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: synapseclient
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.5.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
|
|
@@ -32,9 +32,9 @@ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
|
32
32
|
Requires-Dist: requests<3.0,>=2.22.0
|
|
33
33
|
Requires-Dist: urllib3<2,>=1.26.18
|
|
34
34
|
Requires-Dist: deprecated<2.0,>=1.2.4
|
|
35
|
-
Requires-Dist: opentelemetry-api
|
|
36
|
-
Requires-Dist: opentelemetry-sdk
|
|
37
|
-
Requires-Dist: opentelemetry-exporter-otlp-proto-http
|
|
35
|
+
Requires-Dist: opentelemetry-api>=1.21.0
|
|
36
|
+
Requires-Dist: opentelemetry-sdk>=1.21.0
|
|
37
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.21.0
|
|
38
38
|
Requires-Dist: nest-asyncio~=1.6.0
|
|
39
39
|
Requires-Dist: asyncio-atexit~=1.0.1
|
|
40
40
|
Requires-Dist: httpx~=0.27.0
|
|
@@ -67,6 +67,7 @@ Requires-Dist: pytest-cov~=4.1.0; extra == "tests"
|
|
|
67
67
|
Requires-Dist: pandas<3.0,>=1.5; extra == "tests"
|
|
68
68
|
Provides-Extra: pandas
|
|
69
69
|
Requires-Dist: pandas<3.0,>=1.5; extra == "pandas"
|
|
70
|
+
Requires-Dist: numpy<2.0.0; extra == "pandas"
|
|
70
71
|
Provides-Extra: pysftp
|
|
71
72
|
Requires-Dist: pysftp<0.3,>=0.2.8; extra == "pysftp"
|
|
72
73
|
Provides-Extra: boto3
|
|
@@ -41,9 +41,9 @@ install_requires =
|
|
|
41
41
|
requests>=2.22.0,<3.0
|
|
42
42
|
urllib3>=1.26.18,<2
|
|
43
43
|
deprecated>=1.2.4,<2.0
|
|
44
|
-
opentelemetry-api
|
|
45
|
-
opentelemetry-sdk
|
|
46
|
-
opentelemetry-exporter-otlp-proto-http
|
|
44
|
+
opentelemetry-api>=1.21.0
|
|
45
|
+
opentelemetry-sdk>=1.21.0
|
|
46
|
+
opentelemetry-exporter-otlp-proto-http>=1.21.0
|
|
47
47
|
nest-asyncio~=1.6.0
|
|
48
48
|
asyncio-atexit~=1.0.1
|
|
49
49
|
httpx~=0.27.0
|
|
@@ -89,6 +89,7 @@ tests =
|
|
|
89
89
|
pandas>=1.5,<3.0
|
|
90
90
|
pandas =
|
|
91
91
|
pandas>=1.5,<3.0
|
|
92
|
+
numpy<2.0.0
|
|
92
93
|
pysftp =
|
|
93
94
|
pysftp>=0.2.8,<0.3
|
|
94
95
|
boto3 =
|
|
@@ -380,6 +380,10 @@ class Synapse(object):
|
|
|
380
380
|
if debug is None:
|
|
381
381
|
debug = config_debug if config_debug is not None else DEBUG_DEFAULT
|
|
382
382
|
|
|
383
|
+
if not isinstance(debug, bool):
|
|
384
|
+
raise ValueError("debug must be set to a bool (either True or False)")
|
|
385
|
+
self.debug = debug
|
|
386
|
+
|
|
383
387
|
self.cache = cache.Cache(cache_root_dir)
|
|
384
388
|
self._sts_token_store = sts_transfer.StsTokenStore()
|
|
385
389
|
|
|
@@ -393,16 +397,12 @@ class Synapse(object):
|
|
|
393
397
|
}
|
|
394
398
|
self.credentials = None
|
|
395
399
|
|
|
396
|
-
if not isinstance(debug, bool):
|
|
397
|
-
raise ValueError("debug must be set to a bool (either True or False)")
|
|
398
|
-
self.debug = debug
|
|
399
|
-
|
|
400
400
|
self.silent = silent
|
|
401
401
|
self._init_logger() # initializes self.logger
|
|
402
402
|
|
|
403
403
|
self.skip_checks = skip_checks
|
|
404
404
|
|
|
405
|
-
self.table_query_sleep = 2
|
|
405
|
+
self.table_query_sleep = 0.2 # Sleep for 200ms between table query retries
|
|
406
406
|
self.table_query_backoff = 1.1
|
|
407
407
|
self.table_query_max_sleep = 20
|
|
408
408
|
self.table_query_timeout = 600 # in seconds
|
|
@@ -696,10 +696,14 @@ class Synapse(object):
|
|
|
696
696
|
|
|
697
697
|
# Update endpoints if we get redirected
|
|
698
698
|
if not skip_checks:
|
|
699
|
-
response =
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
699
|
+
response = with_retry(
|
|
700
|
+
lambda point=point: self._requests_session.get(
|
|
701
|
+
endpoints[point],
|
|
702
|
+
allow_redirects=False,
|
|
703
|
+
headers=synapseclient.USER_AGENT,
|
|
704
|
+
),
|
|
705
|
+
verbose=self.debug,
|
|
706
|
+
**STANDARD_RETRY_PARAMS,
|
|
703
707
|
)
|
|
704
708
|
if response.status_code == 301:
|
|
705
709
|
endpoints[point] = response.headers["location"]
|
|
@@ -5041,6 +5045,7 @@ class Synapse(object):
|
|
|
5041
5045
|
# Tables #
|
|
5042
5046
|
############################################################
|
|
5043
5047
|
|
|
5048
|
+
@tracer.start_as_current_span("Synapse::_waitForAsync")
|
|
5044
5049
|
def _waitForAsync(self, uri, request, endpoint=None):
|
|
5045
5050
|
if endpoint is None:
|
|
5046
5051
|
endpoint = self.repoEndpoint
|
|
@@ -5072,7 +5077,7 @@ class Synapse(object):
|
|
|
5072
5077
|
sleep = min(
|
|
5073
5078
|
self.table_query_max_sleep, sleep * self.table_query_backoff
|
|
5074
5079
|
)
|
|
5075
|
-
doze(sleep)
|
|
5080
|
+
doze(sleep, trace_span_name="Synapse::doze_for_async")
|
|
5076
5081
|
else:
|
|
5077
5082
|
break
|
|
5078
5083
|
else:
|
|
@@ -6,6 +6,7 @@ from .download_async import (
|
|
|
6
6
|
PresignedUrlInfo,
|
|
7
7
|
PresignedUrlProvider,
|
|
8
8
|
_MultithreadedDownloader,
|
|
9
|
+
_pre_signed_url_expiration_time,
|
|
9
10
|
download_file,
|
|
10
11
|
)
|
|
11
12
|
from .download_functions import (
|
|
@@ -32,4 +33,5 @@ __all__ = [
|
|
|
32
33
|
"PresignedUrlInfo",
|
|
33
34
|
"PresignedUrlProvider",
|
|
34
35
|
"_MultithreadedDownloader",
|
|
36
|
+
"_pre_signed_url_expiration_time",
|
|
35
37
|
]
|
|
@@ -274,7 +274,12 @@ def _get_file_size(
|
|
|
274
274
|
if otel_context:
|
|
275
275
|
context.attach(otel_context)
|
|
276
276
|
with syn._requests_session_storage.stream("GET", url) as response:
|
|
277
|
-
_raise_for_status_httpx(
|
|
277
|
+
_raise_for_status_httpx(
|
|
278
|
+
response=response,
|
|
279
|
+
logger=syn.logger,
|
|
280
|
+
verbose=debug,
|
|
281
|
+
read_response_content=False,
|
|
282
|
+
)
|
|
278
283
|
return int(response.headers["Content-Length"])
|
|
279
284
|
|
|
280
285
|
|
{synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/download/download_functions.py
RENAMED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""This module handles the various ways that a user can download a file to Synapse."""
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
|
+
import datetime
|
|
4
5
|
import errno
|
|
5
6
|
import hashlib
|
|
6
7
|
import os
|
|
@@ -14,7 +15,10 @@ from tqdm import tqdm
|
|
|
14
15
|
from tqdm.contrib.logging import logging_redirect_tqdm
|
|
15
16
|
|
|
16
17
|
from synapseclient.api.configuration_services import get_client_authenticated_s3_profile
|
|
17
|
-
from synapseclient.api.file_services import
|
|
18
|
+
from synapseclient.api.file_services import (
|
|
19
|
+
get_file_handle_for_download,
|
|
20
|
+
get_file_handle_for_download_async,
|
|
21
|
+
)
|
|
18
22
|
from synapseclient.core import exceptions, sts_transfer, utils
|
|
19
23
|
from synapseclient.core.constants import concrete_types
|
|
20
24
|
from synapseclient.core.constants.method_flags import (
|
|
@@ -25,6 +29,8 @@ from synapseclient.core.constants.method_flags import (
|
|
|
25
29
|
from synapseclient.core.download import (
|
|
26
30
|
SYNAPSE_DEFAULT_DOWNLOAD_PART_SIZE,
|
|
27
31
|
DownloadRequest,
|
|
32
|
+
PresignedUrlProvider,
|
|
33
|
+
_pre_signed_url_expiration_time,
|
|
28
34
|
download_file,
|
|
29
35
|
)
|
|
30
36
|
from synapseclient.core.exceptions import (
|
|
@@ -500,11 +506,14 @@ async def download_by_file_handle(
|
|
|
500
506
|
progress_bar = get_or_create_download_progress_bar(
|
|
501
507
|
file_size=1, postfix=synapse_id, synapse_client=syn
|
|
502
508
|
)
|
|
509
|
+
|
|
503
510
|
downloaded_path = await loop.run_in_executor(
|
|
504
511
|
syn._get_thread_pool_executor(asyncio_event_loop=loop),
|
|
505
512
|
lambda: download_from_url(
|
|
506
513
|
url=file_handle_result["preSignedURL"],
|
|
507
514
|
destination=destination,
|
|
515
|
+
entity_id=synapse_id,
|
|
516
|
+
file_handle_associate_type=entity_type,
|
|
508
517
|
file_handle_id=file_handle["id"],
|
|
509
518
|
expected_md5=file_handle.get("contentMd5"),
|
|
510
519
|
progress_bar=progress_bar,
|
|
@@ -610,6 +619,8 @@ async def download_from_url_multi_threaded(
|
|
|
610
619
|
def download_from_url(
|
|
611
620
|
url: str,
|
|
612
621
|
destination: str,
|
|
622
|
+
entity_id: Optional[str],
|
|
623
|
+
file_handle_associate_type: Optional[str],
|
|
613
624
|
file_handle_id: Optional[str] = None,
|
|
614
625
|
expected_md5: Optional[str] = None,
|
|
615
626
|
progress_bar: Optional[tqdm] = None,
|
|
@@ -622,6 +633,11 @@ def download_from_url(
|
|
|
622
633
|
Arguments:
|
|
623
634
|
url: The source of download
|
|
624
635
|
destination: The destination on local file system
|
|
636
|
+
entity_id: The id of the Synapse object that uses the FileHandle
|
|
637
|
+
e.g. "syn123"
|
|
638
|
+
file_handle_associate_type: The type of the Synapse object that uses the
|
|
639
|
+
FileHandle e.g. "FileEntity". Any of
|
|
640
|
+
<https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/file/FileHandleAssociateType.html>
|
|
625
641
|
file_handle_id: Optional. If given, the file will be given a temporary name that includes the file
|
|
626
642
|
handle id which allows resuming partial downloads of the same file from previous
|
|
627
643
|
sessions
|
|
@@ -719,21 +735,69 @@ def download_from_url(
|
|
|
719
735
|
else None
|
|
720
736
|
)
|
|
721
737
|
|
|
722
|
-
response = with_retry(
|
|
723
|
-
lambda url=url, range_header=range_header, auth=auth: client._requests_session.get(
|
|
724
|
-
url=url,
|
|
725
|
-
headers=client._generate_headers(range_header),
|
|
726
|
-
stream=True,
|
|
727
|
-
allow_redirects=False,
|
|
728
|
-
auth=auth,
|
|
729
|
-
),
|
|
730
|
-
verbose=client.debug,
|
|
731
|
-
**STANDARD_RETRY_PARAMS,
|
|
732
|
-
)
|
|
733
738
|
try:
|
|
739
|
+
url_has_expiration = "Expires" in urllib_urlparse.urlparse(url).query
|
|
740
|
+
url_is_expired = False
|
|
741
|
+
if url_has_expiration:
|
|
742
|
+
url_is_expired = datetime.datetime.now(
|
|
743
|
+
tz=datetime.timezone.utc
|
|
744
|
+
) + PresignedUrlProvider._TIME_BUFFER >= _pre_signed_url_expiration_time(
|
|
745
|
+
url
|
|
746
|
+
)
|
|
747
|
+
if url_is_expired:
|
|
748
|
+
response = get_file_handle_for_download(
|
|
749
|
+
file_handle_id=file_handle_id,
|
|
750
|
+
synapse_id=entity_id,
|
|
751
|
+
entity_type=file_handle_associate_type,
|
|
752
|
+
synapse_client=client,
|
|
753
|
+
)
|
|
754
|
+
url = response["preSignedURL"]
|
|
755
|
+
response = with_retry(
|
|
756
|
+
lambda url=url, range_header=range_header, auth=auth: client._requests_session.get(
|
|
757
|
+
url=url,
|
|
758
|
+
headers=client._generate_headers(range_header),
|
|
759
|
+
stream=True,
|
|
760
|
+
allow_redirects=False,
|
|
761
|
+
auth=auth,
|
|
762
|
+
),
|
|
763
|
+
verbose=client.debug,
|
|
764
|
+
**STANDARD_RETRY_PARAMS,
|
|
765
|
+
)
|
|
734
766
|
exceptions._raise_for_status(response, verbose=client.debug)
|
|
735
767
|
except SynapseHTTPError as err:
|
|
736
|
-
if err.response.status_code ==
|
|
768
|
+
if err.response.status_code == 403:
|
|
769
|
+
url_has_expiration = (
|
|
770
|
+
"Expires" in urllib_urlparse.urlparse(url).query
|
|
771
|
+
)
|
|
772
|
+
url_is_expired = False
|
|
773
|
+
if url_has_expiration:
|
|
774
|
+
url_is_expired = datetime.datetime.now(
|
|
775
|
+
tz=datetime.timezone.utc
|
|
776
|
+
) + PresignedUrlProvider._TIME_BUFFER >= _pre_signed_url_expiration_time(
|
|
777
|
+
url
|
|
778
|
+
)
|
|
779
|
+
if url_is_expired:
|
|
780
|
+
response = get_file_handle_for_download(
|
|
781
|
+
file_handle_id=file_handle_id,
|
|
782
|
+
synapse_id=entity_id,
|
|
783
|
+
entity_type=file_handle_associate_type,
|
|
784
|
+
synapse_client=client,
|
|
785
|
+
)
|
|
786
|
+
refreshed_url = response["preSignedURL"]
|
|
787
|
+
response = with_retry(
|
|
788
|
+
lambda url=refreshed_url, range_header=range_header, auth=auth: client._requests_session.get(
|
|
789
|
+
url=url,
|
|
790
|
+
headers=client._generate_headers(range_header),
|
|
791
|
+
stream=True,
|
|
792
|
+
allow_redirects=False,
|
|
793
|
+
auth=auth,
|
|
794
|
+
),
|
|
795
|
+
verbose=client.debug,
|
|
796
|
+
**STANDARD_RETRY_PARAMS,
|
|
797
|
+
)
|
|
798
|
+
else:
|
|
799
|
+
raise
|
|
800
|
+
elif err.response.status_code == 404:
|
|
737
801
|
raise SynapseError(f"Could not download the file at {url}") from err
|
|
738
802
|
elif (
|
|
739
803
|
err.response.status_code == 416
|
|
@@ -745,8 +809,8 @@ def download_from_url(
|
|
|
745
809
|
# If it fails the user can retry with another download.
|
|
746
810
|
shutil.move(temp_destination, destination)
|
|
747
811
|
break
|
|
748
|
-
|
|
749
|
-
|
|
812
|
+
else:
|
|
813
|
+
raise
|
|
750
814
|
# handle redirects
|
|
751
815
|
if response.status_code in [301, 302, 303, 307, 308]:
|
|
752
816
|
url = response.headers["location"]
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Created on Sep 21, 2017
|
|
3
|
+
|
|
4
|
+
@author: bhoff
|
|
5
|
+
|
|
6
|
+
sleep while checking registered _listeners
|
|
7
|
+
"""
|
|
8
|
+
import time
|
|
9
|
+
|
|
10
|
+
from opentelemetry import trace
|
|
11
|
+
|
|
12
|
+
tracer = trace.get_tracer("synapseclient")
|
|
13
|
+
|
|
14
|
+
_listeners = []
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def add_listener(listener):
|
|
18
|
+
if not callable(listener):
|
|
19
|
+
raise ValueError("listener is not callable")
|
|
20
|
+
_listeners.append(listener)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def clear_listeners():
|
|
24
|
+
del _listeners[:]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def doze(
|
|
28
|
+
secs: float,
|
|
29
|
+
listener_check_interval_secs: float = 0.1,
|
|
30
|
+
trace_span_name: str = "doze",
|
|
31
|
+
) -> None:
|
|
32
|
+
"""Sleep for a given number of seconds while checking registered listeners.
|
|
33
|
+
|
|
34
|
+
Arguments:
|
|
35
|
+
secs: the number of seconds to sleep
|
|
36
|
+
listener_check_interval_secs: the interval at which to check the listeners
|
|
37
|
+
trace_span_name: the name of the trace span
|
|
38
|
+
"""
|
|
39
|
+
with tracer.start_as_current_span(name=trace_span_name):
|
|
40
|
+
end_time = time.time() + secs
|
|
41
|
+
while time.time() < end_time:
|
|
42
|
+
for listener in _listeners:
|
|
43
|
+
listener()
|
|
44
|
+
time.sleep(listener_check_interval_secs)
|
|
@@ -407,7 +407,34 @@ def _csv_to_pandas_df(
|
|
|
407
407
|
list_columns=None,
|
|
408
408
|
rowIdAndVersionInIndex=True,
|
|
409
409
|
dtype=None,
|
|
410
|
+
**kwargs,
|
|
410
411
|
):
|
|
412
|
+
"""
|
|
413
|
+
Convert a csv file to a pandas dataframe
|
|
414
|
+
|
|
415
|
+
Arguments:
|
|
416
|
+
filepath: The path to the file.
|
|
417
|
+
separator: The separator for the file, Defaults to `DEFAULT_SEPARATOR`.
|
|
418
|
+
quote_char: The quote character for the file,
|
|
419
|
+
Defaults to `DEFAULT_QUOTE_CHARACTER`.
|
|
420
|
+
escape_char: The escape character for the file,
|
|
421
|
+
Defaults to `DEFAULT_ESCAPSE_CHAR`.
|
|
422
|
+
contain_headers: Whether the file contains headers,
|
|
423
|
+
Defaults to `True`.
|
|
424
|
+
lines_to_skip: The number of lines to skip at the beginning of the file,
|
|
425
|
+
Defaults to `0`.
|
|
426
|
+
date_columns: The names of the date columns in the file
|
|
427
|
+
list_columns: The names of the list columns in the file
|
|
428
|
+
rowIdAndVersionInIndex: Whether the file contains rowId and
|
|
429
|
+
version in the index, Defaults to `True`.
|
|
430
|
+
dtype: The data type for the file, Defaults to `None`.
|
|
431
|
+
**kwargs: Additional keyword arguments to pass to pandas.read_csv. See
|
|
432
|
+
https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html
|
|
433
|
+
for complete list of supported arguments.
|
|
434
|
+
|
|
435
|
+
Returns:
|
|
436
|
+
A pandas dataframe
|
|
437
|
+
"""
|
|
411
438
|
test_import_pandas()
|
|
412
439
|
import pandas as pd
|
|
413
440
|
|
|
@@ -426,6 +453,7 @@ def _csv_to_pandas_df(
|
|
|
426
453
|
escapechar=escape_char,
|
|
427
454
|
header=0 if contain_headers else None,
|
|
428
455
|
skiprows=lines_to_skip,
|
|
456
|
+
**kwargs,
|
|
429
457
|
)
|
|
430
458
|
# parse date columns if exists
|
|
431
459
|
if date_columns:
|
|
@@ -2445,14 +2473,23 @@ class CsvFileTable(TableAbstractBaseClass):
|
|
|
2445
2473
|
self.etag = upload_to_table_result["etag"]
|
|
2446
2474
|
return self
|
|
2447
2475
|
|
|
2448
|
-
def asDataFrame(
|
|
2476
|
+
def asDataFrame(
|
|
2477
|
+
self,
|
|
2478
|
+
rowIdAndVersionInIndex: bool = True,
|
|
2479
|
+
convert_to_datetime: bool = False,
|
|
2480
|
+
**kwargs,
|
|
2481
|
+
):
|
|
2449
2482
|
"""Convert query result to a Pandas DataFrame.
|
|
2450
2483
|
|
|
2451
2484
|
Arguments:
|
|
2452
|
-
rowIdAndVersionInIndex: Make the dataframe index consist of the
|
|
2453
|
-
(and row_etag if it exists)
|
|
2485
|
+
rowIdAndVersionInIndex: Make the dataframe index consist of the
|
|
2486
|
+
row_id and row_version (and row_etag if it exists)
|
|
2454
2487
|
convert_to_datetime: If set to True, will convert all Synapse DATE columns from UNIX timestamp
|
|
2455
2488
|
integers into UTC datetime objects
|
|
2489
|
+
kwargs: Additional keyword arguments to pass to
|
|
2490
|
+
pandas.read_csv via _csv_to_pandas_df. See
|
|
2491
|
+
https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html
|
|
2492
|
+
for complete list of supported arguments.
|
|
2456
2493
|
|
|
2457
2494
|
Returns:
|
|
2458
2495
|
A Pandas dataframe with results
|
|
@@ -2491,8 +2528,10 @@ class CsvFileTable(TableAbstractBaseClass):
|
|
|
2491
2528
|
list_columns=list_columns,
|
|
2492
2529
|
rowIdAndVersionInIndex=rowIdAndVersionInIndex,
|
|
2493
2530
|
dtype=dtype,
|
|
2531
|
+
**kwargs,
|
|
2494
2532
|
)
|
|
2495
|
-
|
|
2533
|
+
|
|
2534
|
+
except pd.errors.ParserError:
|
|
2496
2535
|
return pd.DataFrame()
|
|
2497
2536
|
|
|
2498
2537
|
def asRowSet(self):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: synapseclient
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.5.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
|
|
@@ -32,9 +32,9 @@ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
|
32
32
|
Requires-Dist: requests<3.0,>=2.22.0
|
|
33
33
|
Requires-Dist: urllib3<2,>=1.26.18
|
|
34
34
|
Requires-Dist: deprecated<2.0,>=1.2.4
|
|
35
|
-
Requires-Dist: opentelemetry-api
|
|
36
|
-
Requires-Dist: opentelemetry-sdk
|
|
37
|
-
Requires-Dist: opentelemetry-exporter-otlp-proto-http
|
|
35
|
+
Requires-Dist: opentelemetry-api>=1.21.0
|
|
36
|
+
Requires-Dist: opentelemetry-sdk>=1.21.0
|
|
37
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.21.0
|
|
38
38
|
Requires-Dist: nest-asyncio~=1.6.0
|
|
39
39
|
Requires-Dist: asyncio-atexit~=1.0.1
|
|
40
40
|
Requires-Dist: httpx~=0.27.0
|
|
@@ -67,6 +67,7 @@ Requires-Dist: pytest-cov~=4.1.0; extra == "tests"
|
|
|
67
67
|
Requires-Dist: pandas<3.0,>=1.5; extra == "tests"
|
|
68
68
|
Provides-Extra: pandas
|
|
69
69
|
Requires-Dist: pandas<3.0,>=1.5; extra == "pandas"
|
|
70
|
+
Requires-Dist: numpy<2.0.0; extra == "pandas"
|
|
70
71
|
Provides-Extra: pysftp
|
|
71
72
|
Requires-Dist: pysftp<0.3,>=0.2.8; extra == "pysftp"
|
|
72
73
|
Provides-Extra: boto3
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
requests<3.0,>=2.22.0
|
|
2
2
|
urllib3<2,>=1.26.18
|
|
3
3
|
deprecated<2.0,>=1.2.4
|
|
4
|
-
opentelemetry-api
|
|
5
|
-
opentelemetry-sdk
|
|
6
|
-
opentelemetry-exporter-otlp-proto-http
|
|
4
|
+
opentelemetry-api>=1.21.0
|
|
5
|
+
opentelemetry-sdk>=1.21.0
|
|
6
|
+
opentelemetry-exporter-otlp-proto-http>=1.21.0
|
|
7
7
|
nest-asyncio~=1.6.0
|
|
8
8
|
asyncio-atexit~=1.0.1
|
|
9
9
|
httpx~=0.27.0
|
|
@@ -39,6 +39,7 @@ markdown-include~=0.8.1
|
|
|
39
39
|
|
|
40
40
|
[pandas]
|
|
41
41
|
pandas<3.0,>=1.5
|
|
42
|
+
numpy<2.0.0
|
|
42
43
|
|
|
43
44
|
[pysftp]
|
|
44
45
|
pysftp<0.3,>=0.2.8
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Created on Sep 21, 2017
|
|
3
|
-
|
|
4
|
-
@author: bhoff
|
|
5
|
-
|
|
6
|
-
sleep while checking registered _listeners
|
|
7
|
-
"""
|
|
8
|
-
import time
|
|
9
|
-
|
|
10
|
-
_listeners = []
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def add_listener(listener):
|
|
14
|
-
if not callable(listener):
|
|
15
|
-
raise ValueError("listener is not callable")
|
|
16
|
-
_listeners.append(listener)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def clear_listeners():
|
|
20
|
-
del _listeners[:]
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def doze(secs, listener_check_interval_secs=0.1):
|
|
24
|
-
end_time = time.time() + secs
|
|
25
|
-
while time.time() < end_time:
|
|
26
|
-
for listener in _listeners:
|
|
27
|
-
listener()
|
|
28
|
-
time.sleep(listener_check_interval_secs)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/constants/config_file_constants.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/credentials/credential_provider.py
RENAMED
|
File without changes
|
{synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/cumulative_transfer_progress.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/multithread_download/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/remote_file_storage_wrappers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/upload/multipart_upload_async.py
RENAMED
|
File without changes
|
|
File without changes
|
{synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/core/upload/upload_functions_async.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/mixins/storable_container.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/protocols/activity_protocol.py
RENAMED
|
File without changes
|
{synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/protocols/annotations_protocol.py
RENAMED
|
File without changes
|
|
File without changes
|
{synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/protocols/folder_protocol.py
RENAMED
|
File without changes
|
{synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/protocols/project_protocol.py
RENAMED
|
File without changes
|
|
File without changes
|
{synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/protocols/table_protocol.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{synapseclient-4.4.1 → synapseclient-4.5.0}/synapseclient/models/services/storable_entity.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|