Skip to content

Commit 88e5182

Browse files
committed
enh: return private basin URL creation and expiration time
1 parent d76ff24 commit 88e5182

4 files changed

Lines changed: 70 additions & 2 deletions

File tree

CHANGELOG

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
0.17.3
2+
- enh: return private basin URL creation and expiration time
3+
- setup: bump dcor_shared to 0.13.1
14
0.17.2
25
- enh: add basin features to served basin information (#4)
36
- enh: internally cache resource metadata

ckanext/dc_serve/serve.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import copy
33
import functools
44
import logging
5+
import time
56

67
import ckan.logic as logic
78
import ckan.model as model
@@ -158,13 +159,21 @@ def get_resource_basins_dicts_private(resource_id):
158159
"""
159160
basin_dicts = []
160161
for artifact in ["condensed", "resource"]:
161-
signed_url = s3cc.create_presigned_url(resource_id, artifact=artifact)
162+
time_request = time.time()
163+
signed_url, expires_at = s3cc.create_presigned_url(
164+
resource_id,
165+
artifact=artifact,
166+
expiration=3600,
167+
ret_expiration=True
168+
)
162169
basin_dicts.append({
163170
"name": f"{artifact}-{resource_id[:5]}",
164171
"format": "http",
165172
"type": "remote",
166173
"mapping": "same",
167174
"perishable": True,
175+
"time_request": time_request,
176+
"time_expiration": expires_at,
168177
"key": f"dcor-presigned-{artifact}-{resource_id}",
169178
"urls": [signed_url],
170179
})

ckanext/dc_serve/tests/test_serve.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import pathlib
44
from unittest import mock
55
import shutil
6+
import time
67
import uuid
78

89
import ckan.tests.factories as factories
@@ -378,6 +379,61 @@ def test_api_dcserv_basin_v2_private_presigned(enqueue_job_mock, app):
378379
assert "volume" in bn_cond["features"]
379380

380381

382+
@pytest.mark.ckan_config('ckan.plugins', 'dcor_schemas dc_serve')
383+
@pytest.mark.usefixtures('clean_db')
384+
@mock.patch('ckan.plugins.toolkit.enqueue_job',
385+
side_effect=synchronous_enqueue_job)
386+
def test_api_dcserv_basin_v2_private_presigned_expiration_time(
387+
enqueue_job_mock, app):
388+
user = factories.UserWithToken()
389+
create_context = {'ignore_auth': False,
390+
'user': user['name'],
391+
'api_version': 3}
392+
393+
_, res_dict = make_dataset_via_s3(
394+
create_context=copy.deepcopy(create_context),
395+
resource_path=data_path / "calibration_beads_47.rtdc",
396+
private=True,
397+
activate=True)
398+
rid = res_dict["id"]
399+
400+
# Version two API serves basins
401+
resp = app.get(
402+
"/api/3/action/dcserv",
403+
params={"id": rid,
404+
"query": "basins",
405+
"version": "2",
406+
},
407+
headers={"Authorization": user["token"]},
408+
status=200
409+
)
410+
jres = json.loads(resp.body)
411+
assert jres["success"]
412+
basins = jres["result"]
413+
414+
for bn in basins:
415+
assert bn["type"] == "remote"
416+
assert bn["format"] == "http"
417+
assert bn["perishable"]
418+
assert bn["time_request"] < time.time()
419+
assert bn["time_expiration"] > time.time() + 3000
420+
for url in bn["urls"]:
421+
assert url.lower().count("expires")
422+
423+
bn_cond = basins[0]
424+
bn_res = basins[1]
425+
426+
assert bn_res["name"] == f"resource-{rid[:5]}"
427+
assert "deform" in bn_res["features"]
428+
assert "image" in bn_res["features"]
429+
assert len(bn_res["features"]) == 34
430+
431+
assert bn_cond["name"] == f"condensed-{rid[:5]}"
432+
assert "deform" in bn_cond["features"]
433+
assert "image" not in bn_cond["features"]
434+
assert "volume" in bn_cond["features"]
435+
436+
381437
@pytest.mark.ckan_config('ckan.plugins', 'dcor_schemas dc_serve')
382438
@pytest.mark.usefixtures('clean_db')
383439
@mock.patch('ckan.plugins.toolkit.enqueue_job',

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ license = {text = "GNU Affero General Public License v3 or later (AGPLv3+)"}
2929
dependencies = [
3030
"ckan>=2.10.4, <3",
3131
"dclab>=0.60.9",
32-
"dcor_shared>=0.10.0",
32+
"dcor_shared>=0.13.1",
3333
]
3434
dynamic = ["version"]
3535

0 commit comments

Comments
 (0)