deriva 1.7.8__tar.gz → 1.7.10__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.
- {deriva-1.7.8/deriva.egg-info → deriva-1.7.10}/PKG-INFO +17 -4
- {deriva-1.7.8 → deriva-1.7.10}/deriva/config/acl_config.py +2 -1
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/__init__.py +2 -2
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/catalog_cli.py +12 -6
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/datapath.py +57 -8
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/deriva_binding.py +7 -7
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/ermrest_catalog.py +20 -6
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/ermrest_model.py +1 -1
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/utils/core_utils.py +11 -6
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/utils/globus_auth_utils.py +41 -4
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/deriva_export.py +11 -3
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/processors/query/base_query_processor.py +12 -12
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/processors/query/file_download_query_processor.py +2 -2
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/upload/deriva_upload.py +19 -15
- {deriva-1.7.8 → deriva-1.7.10/deriva.egg-info}/PKG-INFO +17 -4
- {deriva-1.7.8 → deriva-1.7.10}/deriva.egg-info/requires.txt +2 -2
- {deriva-1.7.8 → deriva-1.7.10}/setup.py +2 -2
- {deriva-1.7.8 → deriva-1.7.10}/tests/deriva/core/test_datapath.py +37 -3
- {deriva-1.7.8 → deriva-1.7.10}/.gitignore +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/CHANGELOG.md +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/LICENSE +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/README.md +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/__init__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/config/__init__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/config/annotation_config.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/config/annotation_validate.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/config/base_config.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/config/dump_catalog_annotations.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/config/examples/group_owner_policy.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/config/examples/self_serve_policy.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/config/rollback_annotation.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/annotation.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/base_cli.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/deriva_server.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/hatrac_cli.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/hatrac_store.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/mmo.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/polling_ermrest_catalog.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/schemas/app_links.schema.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/schemas/asset.schema.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/schemas/bulk_upload.schema.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/schemas/chaise_config.schema.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/schemas/citation.schema.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/schemas/column_display.schema.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/schemas/display.schema.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/schemas/export.schema.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/schemas/export_2019.schema.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/schemas/foreign_key.schema.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/schemas/generated.schema.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/schemas/immutable.schema.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/schemas/indexing_preferences.schema.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/schemas/key_display.schema.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/schemas/non_deletable.schema.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/schemas/required.schema.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/schemas/source_definitions.schema.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/schemas/table_alternatives.schema.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/schemas/table_display.schema.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/schemas/visible_columns.schema.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/schemas/visible_foreign_keys.schema.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/tests/__init__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/utils/__init__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/utils/hash_utils.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/utils/mime_utils.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/utils/version_utils.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/core/utils/webauthn_utils.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/seo/README.md +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/seo/__init__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/seo/sitemap_builder.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/seo/sitemap_cli.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/__init__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/backup/__init__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/backup/__main__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/backup/deriva_backup.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/backup/deriva_backup_cli.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/__init__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/__main__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/deriva_download.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/deriva_download_cli.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/processors/__init__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/processors/base_processor.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/processors/postprocess/__init__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/processors/postprocess/identifier_post_processor.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/processors/postprocess/transfer_post_processor.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/processors/postprocess/url_post_processor.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/processors/query/__init__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/processors/query/bag_fetch_query_processor.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/processors/transform/__init__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/processors/transform/base_transform_processor.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/processors/transform/column_transform_processor.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/processors/transform/fasta_transform_processor.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/processors/transform/format_transform_processor.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/processors/transform/geo_transform_processor.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/processors/transform/string_transform_processor.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/tests/__init__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/tests/test1.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/tests/test10.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/tests/test11.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/tests/test12.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/tests/test13.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/tests/test14.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/tests/test15.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/tests/test16.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/tests/test19.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/tests/test2.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/tests/test20.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/tests/test3.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/tests/test4.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/tests/test5.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/tests/test6.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/tests/test7.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/tests/test8.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/tests/test9.json +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/restore/__init__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/restore/__main__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/restore/deriva_restore.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/restore/deriva_restore_cli.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/upload/__init__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/upload/__main__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/upload/deriva_upload_cli.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/upload/processors/__init__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/upload/processors/archive_processor.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/upload/processors/base_processor.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/upload/processors/logging_processor.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/upload/processors/metadata_update_processor.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/upload/processors/rename_processor.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/upload/tests/__init__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva/utils/__init__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva.egg-info/SOURCES.txt +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva.egg-info/dependency_links.txt +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva.egg-info/entry_points.txt +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/deriva.egg-info/top_level.txt +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/BUILD.md +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/Makefile +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/README.md +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/_static/README.txt +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/api/deriva.config.rst +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/api/deriva.core.rst +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/api/deriva.core.utils.rst +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/api/deriva.rst +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/api/deriva.seo.rst +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/api/deriva.transfer.backup.rst +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/api/deriva.transfer.download.processors.postprocess.rst +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/api/deriva.transfer.download.processors.query.rst +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/api/deriva.transfer.download.processors.rst +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/api/deriva.transfer.download.processors.transform.rst +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/api/deriva.transfer.download.rst +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/api/deriva.transfer.restore.rst +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/api/deriva.transfer.rst +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/api/deriva.transfer.upload.rst +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/cli/commands.md +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/cli/deriva-acl-config.md +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/cli/deriva-annotation-config.md +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/cli/deriva-annotation-validate.md +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/cli/deriva-backup-cli.md +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/cli/deriva-download-cli.md +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/cli/deriva-hatrac-cli.md +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/cli/deriva-restore-cli.md +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/cli/deriva-sitemap-cli.md +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/conf.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/derivapy-catalog-snapshot.ipynb +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/derivapy-catalog.ipynb +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/derivapy-datapath-example-1.ipynb +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/derivapy-datapath-example-2.ipynb +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/derivapy-datapath-example-3.ipynb +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/derivapy-datapath-example-4.ipynb +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/derivapy-datapath-update.ipynb +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/get-started.ipynb +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/index.rst +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/install.md +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/make.bat +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/project-tutorial.md +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/docs/using-r.md +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/requirements_dev.txt +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/setup.cfg +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/tests/__init__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/tests/deriva/__init__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/tests/deriva/core/__init__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/tests/deriva/core/mmo/__init__.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/tests/deriva/core/mmo/base.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/tests/deriva/core/mmo/test_mmo_drop.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/tests/deriva/core/mmo/test_mmo_find.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/tests/deriva/core/mmo/test_mmo_prune.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/tests/deriva/core/mmo/test_mmo_rename.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/tests/deriva/core/mmo/test_mmo_replace.py +0 -0
- {deriva-1.7.8 → deriva-1.7.10}/tests/deriva/core/test_ermrest_model.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: deriva
|
|
3
|
-
Version: 1.7.
|
|
3
|
+
Version: 1.7.10
|
|
4
4
|
Summary: Python APIs and CLIs (Command-Line Interfaces) for the DERIVA platform.
|
|
5
5
|
Home-page: https://github.com/informatics-isi-edu/deriva-py
|
|
6
6
|
Author: USC Information Sciences Institute, Informatics Systems Research Division
|
|
@@ -26,12 +26,25 @@ License-File: LICENSE
|
|
|
26
26
|
Requires-Dist: packaging
|
|
27
27
|
Requires-Dist: requests
|
|
28
28
|
Requires-Dist: pika
|
|
29
|
-
Requires-Dist: urllib3<3,>=1.26
|
|
29
|
+
Requires-Dist: urllib3<3,>=1.26.20
|
|
30
30
|
Requires-Dist: portalocker>=1.2.1
|
|
31
|
-
Requires-Dist: bdbag>=1.7.
|
|
31
|
+
Requires-Dist: bdbag>=1.7.5
|
|
32
32
|
Requires-Dist: globus_sdk<4,>=3
|
|
33
33
|
Requires-Dist: fair-research-login>=0.3.1
|
|
34
34
|
Requires-Dist: fair-identifiers-client>=0.5.1
|
|
35
35
|
Requires-Dist: jsonschema>=3.1
|
|
36
|
+
Dynamic: author
|
|
37
|
+
Dynamic: author-email
|
|
38
|
+
Dynamic: classifier
|
|
39
|
+
Dynamic: description
|
|
40
|
+
Dynamic: description-content-type
|
|
41
|
+
Dynamic: home-page
|
|
42
|
+
Dynamic: license
|
|
43
|
+
Dynamic: license-file
|
|
44
|
+
Dynamic: maintainer
|
|
45
|
+
Dynamic: maintainer-email
|
|
46
|
+
Dynamic: requires-dist
|
|
47
|
+
Dynamic: requires-python
|
|
48
|
+
Dynamic: summary
|
|
36
49
|
|
|
37
50
|
For further information, visit the project [homepage](https://github.com/informatics-isi-edu/deriva-py).
|
|
@@ -291,7 +291,8 @@ class AclConfig:
|
|
|
291
291
|
elif group.startswith(self.ROBOT_PREFIX_FORMAT.format(server=self.server)):
|
|
292
292
|
self.validate_webauthn_robot(group)
|
|
293
293
|
else:
|
|
294
|
-
|
|
294
|
+
if self.verbose:
|
|
295
|
+
warnings.warn("Can't determine format of group '{g}'".format(g=group))
|
|
295
296
|
|
|
296
297
|
def validate_globus_group(self, group):
|
|
297
298
|
guid = group[len(self.GLOBUS_PREFIX):]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
__version__ = "1.7.
|
|
1
|
+
__version__ = "1.7.10"
|
|
2
2
|
|
|
3
3
|
from deriva.core.utils.core_utils import *
|
|
4
4
|
from deriva.core.base_cli import BaseCLI, KeyValuePairArgs
|
|
@@ -55,7 +55,7 @@ def get_credential(host,
|
|
|
55
55
|
scope_map = globus_client.hosts_to_scope_map(hosts=[host], match_scope_tag=match_scope_tag,
|
|
56
56
|
force_refresh=force_scope_lookup,
|
|
57
57
|
warn_on_discovery_failure=True if not creds else False)
|
|
58
|
-
tokens = globus_client.is_logged_in(exclude_defaults=True)
|
|
58
|
+
tokens = globus_client.is_logged_in(exclude_defaults=True, hosts_to_scope_map=scope_map)
|
|
59
59
|
if tokens:
|
|
60
60
|
# 1. look for the explicitly requested scope in the token store, if specified
|
|
61
61
|
token = globus_client.find_access_token_for_scope(requested_scope, tokens)
|
|
@@ -6,7 +6,7 @@ import traceback
|
|
|
6
6
|
from pprint import pp
|
|
7
7
|
from requests.exceptions import HTTPError, ConnectionError
|
|
8
8
|
from deriva.core import __version__ as VERSION, BaseCLI, KeyValuePairArgs, DerivaServer, DerivaPathError, \
|
|
9
|
-
get_credential, format_credential, format_exception, DEFAULT_HEADERS
|
|
9
|
+
get_credential, format_credential, format_exception, read_config, DEFAULT_SESSION_CONFIG, DEFAULT_HEADERS
|
|
10
10
|
from deriva.core.ermrest_model import nochange
|
|
11
11
|
from deriva.core.utils import eprint
|
|
12
12
|
|
|
@@ -191,6 +191,11 @@ class DerivaCatalogCLI (BaseCLI):
|
|
|
191
191
|
else:
|
|
192
192
|
return get_credential(host_name)
|
|
193
193
|
|
|
194
|
+
@staticmethod
|
|
195
|
+
def _get_session_config():
|
|
196
|
+
config = read_config()
|
|
197
|
+
return config.get("session", DEFAULT_SESSION_CONFIG)
|
|
198
|
+
|
|
194
199
|
def _post_parser_init(self, args):
|
|
195
200
|
"""Shared initialization for all sub-commands.
|
|
196
201
|
"""
|
|
@@ -202,7 +207,8 @@ class DerivaCatalogCLI (BaseCLI):
|
|
|
202
207
|
credentials=DerivaCatalogCLI._get_credential(
|
|
203
208
|
self.host,
|
|
204
209
|
token=args.token,
|
|
205
|
-
oauth2_token=args.oauth2_token)
|
|
210
|
+
oauth2_token=args.oauth2_token),
|
|
211
|
+
session_config=DerivaCatalogCLI._get_session_config())
|
|
206
212
|
|
|
207
213
|
@staticmethod
|
|
208
214
|
def _decorate_headers(headers, file_format, method="get"):
|
|
@@ -279,10 +285,10 @@ class DerivaCatalogCLI (BaseCLI):
|
|
|
279
285
|
catalog = self.server.connect_ermrest(args.id)
|
|
280
286
|
try:
|
|
281
287
|
if args.output_file:
|
|
282
|
-
catalog.
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
288
|
+
catalog.get_as_file(args.path,
|
|
289
|
+
destfilename=args.output_file,
|
|
290
|
+
headers=headers,
|
|
291
|
+
delete_if_empty=args.auto_delete)
|
|
286
292
|
else:
|
|
287
293
|
pp(catalog.get(args.path, headers=headers).json())
|
|
288
294
|
except HTTPError as e:
|
|
@@ -11,7 +11,8 @@ from requests import HTTPError
|
|
|
11
11
|
import warnings
|
|
12
12
|
from . import DEFAULT_HEADERS, ermrest_model as _erm
|
|
13
13
|
|
|
14
|
-
__all__ = ['DataPathException', 'Min', 'Max', 'Sum', 'Avg', 'Cnt', 'CntD', 'Array', 'ArrayD', 'Bin'
|
|
14
|
+
__all__ = ['DataPathException', 'Min', 'Max', 'Sum', 'Avg', 'Cnt', 'CntD', 'Array', 'ArrayD', 'Bin', 'All', 'Any',
|
|
15
|
+
'simple_denormalization', 'simple_denormalization_with_whole_entities']
|
|
15
16
|
|
|
16
17
|
logger = logging.getLogger(__name__)
|
|
17
18
|
"""Logger for this module"""
|
|
@@ -1265,6 +1266,19 @@ class _ColumnWrapper (object):
|
|
|
1265
1266
|
|
|
1266
1267
|
__eq__ = eq
|
|
1267
1268
|
|
|
1269
|
+
def ne(self, other):
|
|
1270
|
+
"""Returns a 'not equal' comparison predicate.
|
|
1271
|
+
|
|
1272
|
+
:param other: `None` or any other literal value.
|
|
1273
|
+
:return: a filter predicate object
|
|
1274
|
+
"""
|
|
1275
|
+
if other is None:
|
|
1276
|
+
return _ComparisonPredicate(self, "::null::", '').negate()
|
|
1277
|
+
else:
|
|
1278
|
+
return _ComparisonPredicate(self, "=", other).negate()
|
|
1279
|
+
|
|
1280
|
+
__ne__ = ne
|
|
1281
|
+
|
|
1268
1282
|
def lt(self, other):
|
|
1269
1283
|
"""Returns a 'less than' comparison predicate.
|
|
1270
1284
|
|
|
@@ -1311,8 +1325,6 @@ class _ColumnWrapper (object):
|
|
|
1311
1325
|
:param other: a _string_ literal value.
|
|
1312
1326
|
:return: a filter predicate object
|
|
1313
1327
|
"""
|
|
1314
|
-
if not isinstance(other, str):
|
|
1315
|
-
logger.warning("'regexp' method comparison only supports string literals.")
|
|
1316
1328
|
return _ComparisonPredicate(self, "::regexp::", other)
|
|
1317
1329
|
|
|
1318
1330
|
def ciregexp(self, other):
|
|
@@ -1321,8 +1333,6 @@ class _ColumnWrapper (object):
|
|
|
1321
1333
|
:param other: a _string_ literal value.
|
|
1322
1334
|
:return: a filter predicate object
|
|
1323
1335
|
"""
|
|
1324
|
-
if not isinstance(other, str):
|
|
1325
|
-
logger.warning("'ciregexp' method comparison only supports string literals.")
|
|
1326
1336
|
return _ComparisonPredicate(self, "::ciregexp::", other)
|
|
1327
1337
|
|
|
1328
1338
|
def ts(self, other):
|
|
@@ -1331,8 +1341,6 @@ class _ColumnWrapper (object):
|
|
|
1331
1341
|
:param other: a _string_ literal value.
|
|
1332
1342
|
:return: a filter predicate object
|
|
1333
1343
|
"""
|
|
1334
|
-
if not isinstance(other, str):
|
|
1335
|
-
logger.warning("'ts' method comparison only supports string literals.")
|
|
1336
1344
|
return _ComparisonPredicate(self, "::ts::", other)
|
|
1337
1345
|
|
|
1338
1346
|
def alias(self, name):
|
|
@@ -1395,6 +1403,16 @@ class _ColumnAlias (object):
|
|
|
1395
1403
|
|
|
1396
1404
|
__eq__ = eq
|
|
1397
1405
|
|
|
1406
|
+
def ne(self, other):
|
|
1407
|
+
"""Returns a 'not equal' comparison predicate.
|
|
1408
|
+
|
|
1409
|
+
:param other: `None` or any other literal value.
|
|
1410
|
+
:return: a filter predicate object
|
|
1411
|
+
"""
|
|
1412
|
+
return self._base_column.ne(other)
|
|
1413
|
+
|
|
1414
|
+
__ne__ = ne
|
|
1415
|
+
|
|
1398
1416
|
def lt(self, other):
|
|
1399
1417
|
"""Returns a 'less than' comparison predicate.
|
|
1400
1418
|
|
|
@@ -1713,7 +1731,7 @@ class _ComparisonPredicate (_Predicate):
|
|
|
1713
1731
|
assert isinstance(lop, _ColumnWrapper)
|
|
1714
1732
|
assert isinstance(rop, _ColumnWrapper) or isinstance(rop, int) or \
|
|
1715
1733
|
isinstance(rop, float) or isinstance(rop, str) or \
|
|
1716
|
-
isinstance(rop, date)
|
|
1734
|
+
isinstance(rop, date) or isinstance(rop, _Quantifier)
|
|
1717
1735
|
assert isinstance(op, str)
|
|
1718
1736
|
self._lop = lop
|
|
1719
1737
|
self._op = op
|
|
@@ -1739,6 +1757,9 @@ class _ComparisonPredicate (_Predicate):
|
|
|
1739
1757
|
if isinstance(self._rop, _ColumnWrapper):
|
|
1740
1758
|
# The only valid circumstance for a _ColumnWrapper rop is in a link 'on' predicate for simple key/fkey joins
|
|
1741
1759
|
return "(%s)=(%s)" % (self._lop._instancename, self._rop._fqname)
|
|
1760
|
+
elif isinstance(self._rop, _Quantifier):
|
|
1761
|
+
# Quantifiers can be trusted to properly urlquote their literals
|
|
1762
|
+
return "%s%s%s" % (self._lop._instancename, self._op, str(self._rop))
|
|
1742
1763
|
else:
|
|
1743
1764
|
# All other comparisons are serialized per the usual form
|
|
1744
1765
|
return "%s%s%s" % (self._lop._instancename, self._op, urlquote(str(self._rop)))
|
|
@@ -1810,6 +1831,34 @@ class _NegationPredicate (_Predicate):
|
|
|
1810
1831
|
return "!(%s)" % self._child
|
|
1811
1832
|
|
|
1812
1833
|
|
|
1834
|
+
class _Quantifier (object):
|
|
1835
|
+
"""Base class of quantifiers."""
|
|
1836
|
+
def __init__(self, quantifier_name, *args):
|
|
1837
|
+
"""Initializes the quantifier object.
|
|
1838
|
+
|
|
1839
|
+
:param quantifier_name: name of the quantifier per ERMrest specification.
|
|
1840
|
+
:param args: arguments of the quantifier per ERMrest specification.
|
|
1841
|
+
"""
|
|
1842
|
+
super(_Quantifier, self).__init__()
|
|
1843
|
+
self._quantifier_name = quantifier_name
|
|
1844
|
+
self._args = args
|
|
1845
|
+
|
|
1846
|
+
def __str__(self):
|
|
1847
|
+
return "%s(%s)" % (self._quantifier_name, ','.join([urlquote(str(arg)) for arg in self._args]))
|
|
1848
|
+
|
|
1849
|
+
|
|
1850
|
+
class All (_Quantifier):
|
|
1851
|
+
"""Universal quantifier."""
|
|
1852
|
+
def __init__(self, *args):
|
|
1853
|
+
super(All, self).__init__('all', *args)
|
|
1854
|
+
|
|
1855
|
+
|
|
1856
|
+
class Any (_Quantifier):
|
|
1857
|
+
"""Existential quantifier."""
|
|
1858
|
+
def __init__(self, *args):
|
|
1859
|
+
super(Any, self).__init__('any', *args)
|
|
1860
|
+
|
|
1861
|
+
|
|
1813
1862
|
class AggregateFunction (object):
|
|
1814
1863
|
"""Base class of all aggregate functions."""
|
|
1815
1864
|
def __init__(self, fn_name, arg):
|
|
@@ -139,9 +139,10 @@ class DerivaBinding (object):
|
|
|
139
139
|
server
|
|
140
140
|
)
|
|
141
141
|
self._server_uri = self._base_server_uri
|
|
142
|
+
self._auth_uri = self._base_server_uri + "/authn/session"
|
|
142
143
|
|
|
143
|
-
self.session_config = DEFAULT_SESSION_CONFIG if not session_config else session_config
|
|
144
144
|
self._session = None
|
|
145
|
+
self.session_config = DEFAULT_SESSION_CONFIG if not session_config else session_config
|
|
145
146
|
self._get_new_session(self.session_config)
|
|
146
147
|
|
|
147
148
|
self._caching = caching
|
|
@@ -160,9 +161,6 @@ class DerivaBinding (object):
|
|
|
160
161
|
self._close_session()
|
|
161
162
|
self._session = get_new_requests_session(self._server_uri + '/',
|
|
162
163
|
session_config if session_config else self.session_config)
|
|
163
|
-
# allow loopback requests to bypass SSL cert verification
|
|
164
|
-
if "https://localhost" in self._server_uri:
|
|
165
|
-
self._session.verify = False
|
|
166
164
|
|
|
167
165
|
def _pre_get(self, path, headers):
|
|
168
166
|
self.check_path(path)
|
|
@@ -222,19 +220,21 @@ class DerivaBinding (object):
|
|
|
222
220
|
self._session.headers.update({'Authorization': 'Bearer {token}'.format(token=credentials['bearer-token'])})
|
|
223
221
|
elif 'cookie' in credentials:
|
|
224
222
|
cname, cval = credentials['cookie'].split('=', 1)
|
|
225
|
-
|
|
223
|
+
# Fix for cookielib domain rewrite to *.local when no "." in hostname. In this case, don't set the domain.
|
|
224
|
+
# Covers "localhost" and other dev/test scenarios. See "https://github.com/psf/requests/issues/5388"
|
|
225
|
+
self._session.cookies.set(cname, cval, domain="" if "." not in server else server, path='/')
|
|
226
226
|
elif 'username' in credentials and 'password' in credentials:
|
|
227
227
|
self.post_authn_session(credentials)
|
|
228
228
|
|
|
229
229
|
def get_authn_session(self):
|
|
230
230
|
headers = { 'deriva-client-context': self.dcctx.encoded() }
|
|
231
|
-
r = self._session.get(self.
|
|
231
|
+
r = self._session.get(self._auth_uri, headers=headers)
|
|
232
232
|
_response_raise_for_status(r)
|
|
233
233
|
return r
|
|
234
234
|
|
|
235
235
|
def post_authn_session(self, credentials):
|
|
236
236
|
headers = { 'deriva-client-context': self.dcctx.encoded() }
|
|
237
|
-
r = self._session.post(self.
|
|
237
|
+
r = self._session.post(self._auth_uri, data=credentials, headers=headers)
|
|
238
238
|
_response_raise_for_status(r)
|
|
239
239
|
return r
|
|
240
240
|
|
|
@@ -481,12 +481,26 @@ class ErmrestCatalog(DerivaBinding):
|
|
|
481
481
|
def getAsFile(self,
|
|
482
482
|
path,
|
|
483
483
|
destfilename,
|
|
484
|
-
headers=DEFAULT_HEADERS,
|
|
485
|
-
callback=None,
|
|
486
|
-
delete_if_empty=False,
|
|
487
|
-
paged=False,
|
|
488
|
-
page_size=DEFAULT_PAGE_SIZE,
|
|
489
|
-
page_sort_columns=frozenset(["RID"])):
|
|
484
|
+
headers = DEFAULT_HEADERS,
|
|
485
|
+
callback = None,
|
|
486
|
+
delete_if_empty = False,
|
|
487
|
+
paged = False,
|
|
488
|
+
page_size = DEFAULT_PAGE_SIZE,
|
|
489
|
+
page_sort_columns = frozenset(["RID"])):
|
|
490
|
+
"""
|
|
491
|
+
Deprecated, call `get_as_file` instead.
|
|
492
|
+
"""
|
|
493
|
+
self.get_as_file(path, destfilename, headers, callback, delete_if_empty, paged, page_size, page_sort_columns)
|
|
494
|
+
|
|
495
|
+
def get_as_file(self,
|
|
496
|
+
path,
|
|
497
|
+
destfilename,
|
|
498
|
+
headers=DEFAULT_HEADERS,
|
|
499
|
+
callback=None,
|
|
500
|
+
delete_if_empty=False,
|
|
501
|
+
paged=False,
|
|
502
|
+
page_size=DEFAULT_PAGE_SIZE,
|
|
503
|
+
page_sort_columns=frozenset(["RID"])):
|
|
490
504
|
"""
|
|
491
505
|
Retrieve catalog data streamed to destination file.
|
|
492
506
|
Caller is responsible to clean up file even on error, when the file may or may not exist.
|
|
@@ -188,7 +188,7 @@ def equivalent(doc1, doc2, method=None):
|
|
|
188
188
|
def canon_cat_acls(d):
|
|
189
189
|
return {
|
|
190
190
|
k: d.get(k, [])
|
|
191
|
-
for k in {'owner', '
|
|
191
|
+
for k in {'owner', 'enumerate', 'write', 'select', 'insert', 'update', 'delete'}
|
|
192
192
|
}
|
|
193
193
|
return equivalent(canon_cat_acls(doc1), canon_cat_acls(doc2), method='acls')
|
|
194
194
|
elif method == 'foreign_key_acls':
|
|
@@ -48,7 +48,8 @@ DEFAULT_SESSION_CONFIG = {
|
|
|
48
48
|
"allow_retry_on_all_methods": False,
|
|
49
49
|
"cookie_jar": DEFAULT_COOKIE_JAR_FILE,
|
|
50
50
|
"max_request_size": DEFAULT_MAX_REQUEST_SIZE,
|
|
51
|
-
"max_chunk_limit": DEFAULT_MAX_CHUNK_LIMIT
|
|
51
|
+
"max_chunk_limit": DEFAULT_MAX_CHUNK_LIMIT,
|
|
52
|
+
"bypass_cert_verify_host_list": []
|
|
52
53
|
}
|
|
53
54
|
OAUTH2_SCOPES_KEY = "oauth2_scopes"
|
|
54
55
|
DEFAULT_CONFIG = {
|
|
@@ -189,11 +190,15 @@ def get_new_requests_session(url=None, session_config=DEFAULT_SESSION_CONFIG):
|
|
|
189
190
|
not session_config.get("allow_retry_on_all_methods", False) else False,
|
|
190
191
|
raise_on_status=True)
|
|
191
192
|
adapter = TimeoutHTTPAdapter(timeout=session_config.get("timeout", DEFAULT_REQUESTS_TIMEOUT), max_retries=retries)
|
|
193
|
+
session.mount('http://', adapter)
|
|
194
|
+
session.mount('https://', adapter)
|
|
195
|
+
|
|
192
196
|
if url:
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
+
# allow whitelisted hosts to bypass SSL cert verification
|
|
198
|
+
upr = urlparse(url)
|
|
199
|
+
bypass_cert_verify_host_list = session_config.get("bypass_cert_verify_host_list", [])
|
|
200
|
+
if upr.scheme == "https" and upr.hostname in bypass_cert_verify_host_list:
|
|
201
|
+
session.verify = False
|
|
197
202
|
|
|
198
203
|
return session
|
|
199
204
|
|
|
@@ -301,7 +306,7 @@ def get_oauth_scopes_for_host(host,
|
|
|
301
306
|
result = scopes
|
|
302
307
|
break
|
|
303
308
|
if not result or force_refresh:
|
|
304
|
-
session = get_new_requests_session(session_config=DEFAULT_SESSION_CONFIG)
|
|
309
|
+
session = get_new_requests_session(url, session_config=config.get("session", DEFAULT_SESSION_CONFIG))
|
|
305
310
|
try:
|
|
306
311
|
r = session.get(url, headers=DEFAULT_HEADERS)
|
|
307
312
|
r.raise_for_status()
|
|
@@ -5,7 +5,7 @@ import json
|
|
|
5
5
|
import logging
|
|
6
6
|
import platform
|
|
7
7
|
import traceback
|
|
8
|
-
import
|
|
8
|
+
import time
|
|
9
9
|
import datetime
|
|
10
10
|
import tzlocal
|
|
11
11
|
import webbrowser
|
|
@@ -15,7 +15,8 @@ from bdbag.fetch.auth import keychain as bdbkc
|
|
|
15
15
|
from deriva.core import __version__ as VERSION, DEFAULT_CONFIG_PATH, DEFAULT_GLOBUS_CREDENTIAL_FILE, urlparse, urljoin,\
|
|
16
16
|
read_config, format_exception, BaseCLI, get_oauth_scopes_for_host, get_new_requests_session
|
|
17
17
|
from deriva.core.utils import eprint
|
|
18
|
-
from globus_sdk import ConfidentialAppAuthClient, AuthClient, AccessTokenAuthorizer,
|
|
18
|
+
from globus_sdk import ConfidentialAppAuthClient, AuthClient, AccessTokenAuthorizer, RefreshTokenAuthorizer, \
|
|
19
|
+
GlobusError, GlobusAPIError, AuthAPIError
|
|
19
20
|
from fair_research_login.client import NativeClient, LoadError, NoSavedTokens, TokensExpired
|
|
20
21
|
|
|
21
22
|
NATIVE_APP_CLIENT_ID = "8ef15ba9-2b4a-469c-a163-7fd910c9d111"
|
|
@@ -586,12 +587,47 @@ class GlobusNativeLogin:
|
|
|
586
587
|
if not scopes:
|
|
587
588
|
return None
|
|
588
589
|
try:
|
|
589
|
-
|
|
590
|
+
tokens = self.client.load_tokens(list(scopes))
|
|
591
|
+
return self.refresh_tokens_preemptively(tokens, time_before_expiry=86400)
|
|
590
592
|
except LoadError as e:
|
|
591
593
|
logging.debug("Unable to load or find tokens for specified scopes [%s]: %s" %
|
|
592
594
|
(scopes, format_exception(e)))
|
|
593
595
|
return None
|
|
594
596
|
|
|
597
|
+
def refresh_tokens_preemptively(self, tokens, time_before_expiry=0):
|
|
598
|
+
needs_refresh = {}
|
|
599
|
+
|
|
600
|
+
for rs, ts in {t: ts for t, ts in tokens.items() if bool(ts['refresh_token'])}.items():
|
|
601
|
+
expiry_threshold = int(time.time()) + time_before_expiry
|
|
602
|
+
if ts['expires_at_seconds'] < expiry_threshold:
|
|
603
|
+
needs_refresh.update({rs:ts})
|
|
604
|
+
|
|
605
|
+
if not needs_refresh:
|
|
606
|
+
return tokens
|
|
607
|
+
|
|
608
|
+
for rs, ts in needs_refresh.items():
|
|
609
|
+
authorizer = RefreshTokenAuthorizer(
|
|
610
|
+
ts['refresh_token'],
|
|
611
|
+
self.client.client,
|
|
612
|
+
access_token=ts['access_token'],
|
|
613
|
+
expires_at=int(time.time()),
|
|
614
|
+
# setting the expires_at to the current time is vicious hack but necessary since the globus_sdk
|
|
615
|
+
# client doesn't allow you to refresh an access token unless it has already expired
|
|
616
|
+
)
|
|
617
|
+
try:
|
|
618
|
+
authorizer.ensure_valid_token()
|
|
619
|
+
ts['access_token'] = authorizer.access_token
|
|
620
|
+
ts['expires_at_seconds'] = authorizer.expires_at
|
|
621
|
+
except AuthAPIError as e:
|
|
622
|
+
if e.message == 'invalid_grant':
|
|
623
|
+
logging.warning('Refresh Token expired for resource server: %s', rs)
|
|
624
|
+
|
|
625
|
+
self.client.save_tokens(needs_refresh)
|
|
626
|
+
result = {rs: ts for rs, ts in tokens.items() if rs not in needs_refresh}
|
|
627
|
+
result.update(needs_refresh)
|
|
628
|
+
|
|
629
|
+
return result
|
|
630
|
+
|
|
595
631
|
def hosts_to_scope_map(self,
|
|
596
632
|
hosts,
|
|
597
633
|
match_scope_tag=None,
|
|
@@ -662,6 +698,7 @@ class GlobusNativeLogin:
|
|
|
662
698
|
access_token = token.get("access_token")
|
|
663
699
|
if (token_scope == scope) and (access_token is not None):
|
|
664
700
|
return access_token
|
|
701
|
+
return None
|
|
665
702
|
|
|
666
703
|
def update_bdbag_keychain(self, token=None, host=None, keychain_file=None, allow_redirects=False, delete=False):
|
|
667
704
|
if (token is None) or (host is None):
|
|
@@ -699,7 +736,7 @@ class GlobusNativeLogin:
|
|
|
699
736
|
prefill_named_grant = self.client.app_name + " with requested scopes [%s] " % ", ".join(scopes)
|
|
700
737
|
tokens = self.client.login(no_local_server=no_local_server,
|
|
701
738
|
no_browser=no_browser,
|
|
702
|
-
requested_scopes=scopes,
|
|
739
|
+
requested_scopes=list(scopes),
|
|
703
740
|
refresh_tokens=refresh_tokens,
|
|
704
741
|
prefill_named_grant=prefill_named_grant,
|
|
705
742
|
query_params=additional_params,
|
|
@@ -45,6 +45,7 @@ class DerivaExport:
|
|
|
45
45
|
self.timeout = kwargs.get("timeout")
|
|
46
46
|
self.export_type = kwargs.get("export_type", "bdbag")
|
|
47
47
|
self.base_server_uri = "https://" + self.host
|
|
48
|
+
self.auth_service_url = self.base_server_uri + "/authn/session"
|
|
48
49
|
self.service_url = self.base_server_uri + EXPORT_SERVICE_PATH % self.export_type
|
|
49
50
|
self.session_config = DEFAULT_SESSION_CONFIG.copy()
|
|
50
51
|
if isinstance(self.timeout, tuple):
|
|
@@ -77,16 +78,23 @@ class DerivaExport:
|
|
|
77
78
|
raise DerivaDownloadAuthenticationError(
|
|
78
79
|
"The requested service requires authentication and a valid login credential could "
|
|
79
80
|
"not be found (or was not provided) for the specified host.")
|
|
81
|
+
|
|
80
82
|
if 'bearer-token' in self.credential:
|
|
81
83
|
self.session.headers.update(
|
|
82
84
|
{'Authorization': 'Bearer {token}'.format(token=self.credential['bearer-token'])})
|
|
83
85
|
elif 'cookie' in self.credential:
|
|
84
86
|
cname, cval = self.credential['cookie'].split('=', 1)
|
|
85
|
-
self.session.cookies.set(cname, cval, domain=self.host, path='/')
|
|
87
|
+
self.session.cookies.set(cname, cval, domain="" if "." not in self.host else self.host, path='/')
|
|
88
|
+
else:
|
|
89
|
+
try:
|
|
90
|
+
r = self.session.post(self.auth_service_url, data=self.credential)
|
|
91
|
+
r.raise_for_status()
|
|
92
|
+
except HTTPError as e:
|
|
93
|
+
raise DerivaDownloadAuthenticationError(
|
|
94
|
+
"Exception during POST authentication flow: %s" % format_exception(e))
|
|
86
95
|
|
|
87
96
|
def validate_authn_session(self):
|
|
88
|
-
|
|
89
|
-
r = self.session.get(url)
|
|
97
|
+
r = self.session.get(self.auth_service_url)
|
|
90
98
|
if r.status_code == requests.codes.not_found or r.status_code == requests.codes.unauthorized:
|
|
91
99
|
logger.warning("Unable to authenticate. Check for missing or expired credentials.")
|
|
92
100
|
r.raise_for_status()
|
{deriva-1.7.8 → deriva-1.7.10}/deriva/transfer/download/processors/query/base_query_processor.py
RENAMED
|
@@ -71,13 +71,13 @@ class BaseQueryProcessor(BaseProcessor):
|
|
|
71
71
|
make_dirs(output_dir)
|
|
72
72
|
try:
|
|
73
73
|
if as_file:
|
|
74
|
-
return self.catalog.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
74
|
+
return self.catalog.get_as_file(self.query, self.output_abspath,
|
|
75
|
+
headers=headers,
|
|
76
|
+
callback=self.callback,
|
|
77
|
+
delete_if_empty=True,
|
|
78
|
+
paged=self.paged_query,
|
|
79
|
+
page_size=self.paged_query_size,
|
|
80
|
+
page_sort_columns=self.paged_query_sort_columns)
|
|
81
81
|
else:
|
|
82
82
|
return self.catalog.get(self.query, headers=headers).json()
|
|
83
83
|
except requests.HTTPError as e:
|
|
@@ -142,21 +142,21 @@ class BaseQueryProcessor(BaseProcessor):
|
|
|
142
142
|
|
|
143
143
|
return url
|
|
144
144
|
|
|
145
|
-
def getExternalSession(self,
|
|
146
|
-
sessions = self.sessions
|
|
145
|
+
def getExternalSession(self, url):
|
|
147
146
|
auth_params = self.kwargs.get("auth_params", dict())
|
|
148
147
|
cookies = auth_params.get("cookies")
|
|
149
148
|
auth_url = auth_params.get("auth_url")
|
|
150
149
|
login_params = auth_params.get("login_params")
|
|
151
150
|
session_config = self.kwargs.get("session_config")
|
|
152
151
|
|
|
153
|
-
|
|
152
|
+
host = urlsplit(url).hostname
|
|
153
|
+
session = self.sessions.get(host)
|
|
154
154
|
if session is not None:
|
|
155
155
|
return session
|
|
156
156
|
|
|
157
157
|
if not session_config:
|
|
158
158
|
session_config = DEFAULT_SESSION_CONFIG
|
|
159
|
-
session = get_new_requests_session(session_config=session_config)
|
|
159
|
+
session = get_new_requests_session(url, session_config=session_config)
|
|
160
160
|
|
|
161
161
|
if cookies:
|
|
162
162
|
session.cookies.update(cookies)
|
|
@@ -166,7 +166,7 @@ class BaseQueryProcessor(BaseProcessor):
|
|
|
166
166
|
raise DerivaDownloadError(
|
|
167
167
|
'GetExternalSession Failed with Status Code: %s\n%s\n' % (r.status_code, r.text))
|
|
168
168
|
|
|
169
|
-
sessions[host] = session
|
|
169
|
+
self.sessions[host] = session
|
|
170
170
|
return session
|
|
171
171
|
|
|
172
172
|
def create_default_paths(self):
|
|
@@ -31,13 +31,12 @@ class FileDownloadQueryProcessor(BaseQueryProcessor):
|
|
|
31
31
|
return self.outputs
|
|
32
32
|
|
|
33
33
|
def getExternalFile(self, url, output_path, headers=None):
|
|
34
|
-
host = urlsplit(url).netloc
|
|
35
34
|
if output_path:
|
|
36
35
|
if not headers:
|
|
37
36
|
headers = self.HEADERS.copy()
|
|
38
37
|
else:
|
|
39
38
|
headers.update(self.HEADERS)
|
|
40
|
-
session = self.getExternalSession(
|
|
39
|
+
session = self.getExternalSession(url)
|
|
41
40
|
with session.get(url, headers=headers, stream=True) as r:
|
|
42
41
|
if r.status_code != 200:
|
|
43
42
|
file_error = "File [%s] transfer failed." % output_path
|
|
@@ -58,6 +57,7 @@ class FileDownloadQueryProcessor(BaseQueryProcessor):
|
|
|
58
57
|
length = int(r.headers.get('Content-Length'))
|
|
59
58
|
content_type = r.headers.get("Content-Type")
|
|
60
59
|
return output_path, length, content_type
|
|
60
|
+
return None
|
|
61
61
|
|
|
62
62
|
def downloadFiles(self, input_manifest):
|
|
63
63
|
logging.info("Attempting to download file(s) based on the results of query: %s" % self.query)
|