dcor-shared 0.9.0__tar.gz → 0.9.1__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 (30) hide show
  1. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/CHANGELOG +2 -0
  2. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/PKG-INFO +1 -1
  3. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/dcor_shared/_version_save.py +1 -1
  4. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/dcor_shared/s3cc.py +75 -0
  5. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/dcor_shared.egg-info/PKG-INFO +1 -1
  6. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/tests/test_s3cc.py +19 -0
  7. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/LICENSE +0 -0
  8. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/MANIFEST.in +0 -0
  9. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/README.rst +0 -0
  10. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/dcor_shared/__init__.py +0 -0
  11. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/dcor_shared/_version.py +0 -0
  12. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/dcor_shared/ckan.py +0 -0
  13. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/dcor_shared/data.py +0 -0
  14. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/dcor_shared/dcinst.py +0 -0
  15. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/dcor_shared/mime.py +0 -0
  16. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/dcor_shared/parse.py +0 -0
  17. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/dcor_shared/paths.py +0 -0
  18. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/dcor_shared/s3.py +0 -0
  19. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/dcor_shared/testing.py +0 -0
  20. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/dcor_shared.egg-info/SOURCES.txt +0 -0
  21. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/dcor_shared.egg-info/dependency_links.txt +0 -0
  22. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/dcor_shared.egg-info/requires.txt +0 -0
  23. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/dcor_shared.egg-info/top_level.txt +0 -0
  24. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/setup.cfg +0 -0
  25. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/setup.py +0 -0
  26. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/tests/test_basic.py +0 -0
  27. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/tests/test_ckan.py +0 -0
  28. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/tests/test_data.py +0 -0
  29. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/tests/test_s3.py +0 -0
  30. {dcor_shared-0.9.0 → dcor_shared-0.9.1}/tests/test_testing.py +0 -0
@@ -1,3 +1,5 @@
1
+ 0.9.1
2
+ - feat: add convenience method `get_s3_attributes_for_artifact`
1
3
  0.9.0
2
4
  - feat: introduce `testing.make_dataset_via_s3` and
3
5
  `testing.make_resource_via_s3` which uploads resources via S3
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dcor_shared
3
- Version: 0.9.0
3
+ Version: 0.9.1
4
4
  Summary: Functionalities shared by the DCOR CKAN extensions
5
5
  Home-page: https://github.com/DCOR-dev/dcor_shared
6
6
  Author: Paul Müller
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env python
2
2
  # This file was created automatically
3
- longversion = '0.9.0'
3
+ longversion = '0.9.1'
@@ -61,6 +61,81 @@ def create_presigned_url(
61
61
  filename=filename)
62
62
 
63
63
 
64
+ def get_s3_attributes_for_artifact(
65
+ resource_id: str,
66
+ artifact: Literal["condensed", "preview", "resource"] = "resource"):
67
+ """Return all attribute for an artifact in the S3 object store
68
+
69
+ Returns
70
+ -------
71
+ meta: dict
72
+ Metadata dictionary with the keys "etag", "server", "size",
73
+ and "success".
74
+ """
75
+ bucket_name, object_name = get_s3_bucket_object_for_artifact(
76
+ resource_id=resource_id, artifact=artifact)
77
+ s3_client, _, _ = s3.get_s3()
78
+ attr_info = s3_client.head_object(Bucket=bucket_name, Key=object_name)
79
+ # Example output from MinIO::
80
+ #
81
+ # {'AcceptRanges': 'bytes',
82
+ # 'ContentLength': 904729,
83
+ # 'ContentType': 'application/octet-stream',
84
+ # 'ETag': '"108d47e80f3e5f35110493b1fdcd30d5"',
85
+ # 'LastModified': datetime.datetime(2024, 3, 7, 8, 15,
86
+ # tzinfo=tzutc()),
87
+ # 'Metadata': {},
88
+ # 'ResponseMetadata': {
89
+ # 'HTTPHeaders': {
90
+ # 'accept-ranges': 'bytes',
91
+ # 'content-length': '904729',
92
+ # 'content-type': 'application/octet-stream',
93
+ # 'date': 'Thu, 07 Mar 2024 08:15:02 GMT',
94
+ # 'etag': '"108d47e80f3e5f35110493b1fdcd30d5"',
95
+ # 'last-modified': 'Thu, 07 Mar 2024 '
96
+ # '08:15:00 GMT',
97
+ # 'server': 'MinIO',
98
+ # 'strict-transport-security': 'max-age=31536000; '
99
+ # 'includeSubDomains',
100
+ # 'vary': 'Origin, Accept-Encoding',
101
+ # 'x-amz-id-2': 'dd9025bab4ad464b049177c95eb6e...',
102
+ # 'x-amz-request-id': '17BA6D680CB67A2C',
103
+ # 'x-amz-tagging-count': '1',
104
+ # 'x-content-type-options': 'nosniff',
105
+ # 'x-xss-protection': '1; mode=block'},
106
+ # 'HTTPStatusCode': 200,
107
+ # 'HostId': 'dd9025bab4ad464b049177c95eb6ebf3...',
108
+ # 'RequestId': '17BA6D680CB67A2C',
109
+ # 'RetryAttempts': 0}
110
+ # }
111
+ meta = {}
112
+ for key, funcs in [
113
+ ("etag", [lambda m: m.get("ETag"),
114
+ lambda m: m.get("ResponseMetadata",
115
+ {}).get("HTTPHeaders",
116
+ {}).get("etag"),
117
+ ]),
118
+ ("server", [lambda m: m.get("ResponseMetadata",
119
+ {}).get("HTTPHeaders",
120
+ {}).get("server", "unknown")
121
+ ]),
122
+ ("size", [lambda m: m.get("ContentLength"),
123
+ lambda m: m.get("ResponseMetadata",
124
+ {}).get("HTTPHeaders",
125
+ {}).get("content-length"),
126
+ ]),
127
+ ("success", [lambda m: m.get("ResponseMetadata",
128
+ {}).get("HTTPStatusCode", 404) == 200
129
+ ]),
130
+ ]:
131
+ for fn in funcs:
132
+ val = fn(attr_info)
133
+ if val is not None:
134
+ meta[key] = val
135
+ break
136
+ return meta
137
+
138
+
64
139
  def get_s3_bucket_object_for_artifact(
65
140
  resource_id: str,
66
141
  artifact: Literal["condensed", "preview", "resource"] = "resource"):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dcor-shared
3
- Version: 0.9.0
3
+ Version: 0.9.1
4
4
  Summary: Functionalities shared by the DCOR CKAN extensions
5
5
  Home-page: https://github.com/DCOR-dev/dcor_shared
6
6
  Author: Paul Müller
@@ -115,6 +115,25 @@ def test_create_presigned_url(enqueue_job_mock, tmp_path):
115
115
  "490efdf5d9bb4cd4b2a6bcf2fe54d4dc201c38530140bcb168980bf8bf846c73"
116
116
 
117
117
 
118
+ @pytest.mark.ckan_config('ckan.plugins', 'dcor_schemas')
119
+ @pytest.mark.usefixtures('clean_db', 'with_request_context')
120
+ @mock.patch('ckan.plugins.toolkit.enqueue_job',
121
+ side_effect=synchronous_enqueue_job)
122
+ def test_get_s3_attributes_for_artifact(enqueue_job_mock):
123
+ rid, _, _, org_dict = setup_s3_resource_on_ckan()
124
+
125
+ # Make sure the resource exists
126
+ res_dict = helpers.call_action("resource_show", id=rid)
127
+ assert res_dict["id"] == rid, "sanity check"
128
+
129
+ # get the size
130
+ meta = s3cc.get_s3_attributes_for_artifact(rid)
131
+ assert meta["size"] == 904729
132
+ assert meta["success"]
133
+ assert meta["etag"]
134
+ assert meta["server"]
135
+
136
+
118
137
  @pytest.mark.ckan_config('ckan.plugins', 'dcor_schemas')
119
138
  @pytest.mark.usefixtures('clean_db', 'with_request_context')
120
139
  @mock.patch('ckan.plugins.toolkit.enqueue_job',
File without changes
File without changes
File without changes
File without changes
File without changes