Skip to content

Commit 87ab0c5

Browse files
committed
deposit: change /deposits/{pid}/files endpoints
* download a file on /deposits/{pid}/files/{file_key} [GET] * add POST, PUT, DELETE Signed-off-by: Anna Trzcinska <[email protected]>
1 parent e8a6880 commit 87ab0c5

File tree

7 files changed

+231
-341
lines changed

7 files changed

+231
-341
lines changed

cap/config.py

-3
Original file line numberDiff line numberDiff line change
@@ -536,9 +536,6 @@ def _(x):
536536
'search_class': 'cap.modules.deposit.search:CAPDepositSearch',
537537
'search_factory_imp': 'cap.modules.search.query:cap_search_factory',
538538
'item_route': '/deposits/<{0}:pid_value>'.format(_PID),
539-
'file_list_route': '/deposits/<{0}:pid_value>/files'.format(_PID),
540-
'file_item_route': '/deposits/<{0}:pid_value>/files/<path:key>'.format(
541-
_PID),
542539
'create_permission_factory_imp': check_oauth2_scope(
543540
lambda record: CreateDepositPermission(record).can(), write_scope.id),
544541
'read_permission_factory_imp': check_oauth2_scope(

cap/modules/deposit/ext.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
"""Initialize extension."""
22

33
from __future__ import absolute_import, print_function
4-
from cap.modules.schemas.models import Schema
4+
55
from invenio_search import current_search
66

7+
from cap.modules.schemas.models import Schema
8+
9+
from .views import create_deposit_files_blueprint
10+
711

812
class CAPDeposit(object):
913
"""CAPDeposit extension."""
10-
1114
def __init__(self, app=None):
1215
"""Extension initialization."""
1316
if app:
@@ -16,3 +19,4 @@ def __init__(self, app=None):
1619
def init_app(self, app):
1720
"""Flask application initialization."""
1821
app.extensions['cap_deposit'] = self
22+
app.register_blueprint(create_deposit_files_blueprint(app))

cap/modules/deposit/serializers/__init__.py

+1-6
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,11 @@
2525

2626
from __future__ import absolute_import, print_function
2727

28-
from invenio_deposit.serializers import json_file_response
2928
from invenio_records_rest.serializers.response import (record_responsify,
3029
search_responsify)
3130

3231
from .json import DepositSerializer
33-
from .schemas.json import DepositSchema, DepositFormSchema
32+
from .schemas.json import DepositFormSchema, DepositSchema
3433

3534
# Serializers
3635
# ===========
@@ -46,7 +45,3 @@
4645
deposit_form_json_v1_response = record_responsify(deposit_form_json_v1,
4746
'application/json')
4847
deposit_json_v1_search = search_responsify(deposit_json_v1, 'application/json')
49-
50-
# Files-REST serializers
51-
# JSON Files serializers for deposit files
52-
files_response = json_file_response

cap/modules/deposit/views.py

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# This file is part of CERN Analysis Preservation Framework.
4+
# Copyright (C) 2016 CERN.
5+
#
6+
# CERN Analysis Preservation Framework is free software; you can redistribute
7+
# it and/or modify it under the terms of the GNU General Public License as
8+
# published by the Free Software Foundation; either version 2 of the
9+
# License, or (at your option) any later version.
10+
#
11+
# CERN Analysis Preservation Framework is distributed in the hope that it will
12+
# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
# General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU General Public License
17+
# along with CERN Analysis Preservation Framework; if not, write to the
18+
# Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19+
# MA 02111-1307, USA.
20+
#
21+
# In applying this license, CERN does not
22+
# waive the privileges and immunities granted to it by virtue of its status
23+
# as an Intergovernmental Organization or submit itself to any jurisdiction.
24+
"""Extra deposit views."""
25+
26+
from __future__ import absolute_import, print_function
27+
28+
from flask import Blueprint, g
29+
from invenio_files_rest.views import bucket_view, object_view
30+
from sqlalchemy.orm.exc import NoResultFound
31+
32+
from .api import CAPDeposit
33+
34+
35+
def create_deposit_files_blueprint(app):
36+
"""Create blueprint from a Flask application.
37+
:params app: A Flask application.
38+
:returns: Configured blueprint.
39+
"""
40+
cap_deposit_files_bp = Blueprint('cap_deposit_files',
41+
__name__,
42+
url_prefix='')
43+
44+
deposit_item_path = app.config['DEPOSIT_REST_ENDPOINTS']['depid'][
45+
'item_route']
46+
cap_deposit_files_bp.add_url_rule('{}/files'.format(deposit_item_path),
47+
view_func=bucket_view)
48+
cap_deposit_files_bp.add_url_rule(
49+
'{}/files/<path:key>'.format(deposit_item_path), view_func=object_view)
50+
51+
@cap_deposit_files_bp.url_value_preprocessor
52+
def resolve_pid_to_bucket_id(endpoint, values):
53+
"""Flask URL preprocessor to resolve pid to Bucket ID.
54+
In the ``cap_deposit_bp`` we are gluing together Records-REST
55+
and Files-REST APIs. Records-REST knows about PIDs but Files-REST does
56+
not, this function will pre-process the URL so the PID is removed from
57+
the URL and resolved to bucket ID which is injected into Files-REST
58+
view calls:
59+
``/api/<record_type>/<pid_value>/files/<key>`` ->
60+
``/files/<bucket>/<key>``.
61+
"""
62+
# Remove the 'pid_value' in order to match the Files-REST bucket view
63+
# signature. Store the value in Flask global request object for later
64+
# usage.
65+
g.pid = values.pop('pid_value')
66+
pid, _ = g.pid.data
67+
68+
try:
69+
deposit = CAPDeposit.get_record(pid.object_uuid)
70+
values['bucket_id'] = str(deposit.files.bucket)
71+
except (AttributeError, NoResultFound):
72+
# Hack, to make invenio_files_rest.views.as_uuid throw a
73+
# ValueError instead of a TypeError if we set the value to None.
74+
values['bucket_id'] = ''
75+
76+
@cap_deposit_files_bp.url_defaults
77+
def restore_pid_to_url(endpoint, values):
78+
"""Put ``pid_value`` back to the URL after matching Files-REST views.
79+
Since we are computing the URL more than one times, we need the
80+
original values of the request to be unchanged so that it can be
81+
reproduced.
82+
"""
83+
# Value here has been saved in above method (resolve_pid_to_bucket_id)
84+
values['pid_value'] = g.pid
85+
86+
return cap_deposit_files_bp

setup.py

+6-10
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
DATABASE = "postgresql"
1717
ELASTICSEARCH = "elasticsearch5"
18-
INVENIO_VERSION = '3.0.0' # "3.0.0rc2"
18+
INVENIO_VERSION = '3.0.0' # "3.0.0rc2"
1919

2020
tests_require = [
2121
'check-manifest>=0.35',
@@ -44,9 +44,7 @@
4444
for reqs in extras_require.values():
4545
extras_require['all'].extend(reqs)
4646

47-
extras_require['ldap'] = [
48-
'python-ldap>=2.4.39'
49-
]
47+
extras_require['ldap'] = ['python-ldap>=2.4.39']
5048

5149
# Do not include in all requirement
5250
extras_require['xrootd'] = [
@@ -72,7 +70,7 @@
7270
'cachetools==3.1.0',
7371

7472
# Pinned libraries
75-
'celery==4.1.1', # temporary fix
73+
'celery==4.1.1', # temporary fix
7674
# temporary pinned since there are 'connection closed' issues
7775
# on production server
7876
'urllib3[secure]==1.22',
@@ -95,19 +93,17 @@
9593
# "raven" versions needed till we FIX dependecies on installation
9694
'raven[flask]>=5.0.0,<5.5',
9795
'invenio-logging[sentry]>=1.0.0b1',
98-
9996
'uWSGI==2.0.17',
10097
'uwsgi-tools==1.1.1',
10198
'uwsgitop==0.10',
10299
]
103100

104101
packages = find_packages()
105102

106-
107103
# Get the version string. Cannot be done with import!
108104
g = {}
109105
with open(os.path.join('cap', 'version.py'), 'rt') as fp:
110-
exec(fp.read(), g)
106+
exec (fp.read(), g)
111107
version = g['__version__']
112108

113109
setup(
@@ -119,7 +115,8 @@
119115
license='MIT',
120116
author='CERN',
121117
author_email='[email protected]',
122-
url='https://github.com/cernanalysispreservation/analysispreservation.cern.ch', # noqa
118+
url=
119+
'https://github.com/cernanalysispreservation/analysispreservation.cern.ch', # noqa
123120
packages=packages,
124121
zip_safe=False,
125122
include_package_data=True,
@@ -175,7 +172,6 @@
175172
'cap.modules.records.minters:cap_record_minter',
176173
'cap_deposit_minter = '
177174
'cap.modules.deposit.minters:cap_deposit_minter',
178-
179175
],
180176
'invenio_pidstore.fetchers': [
181177
'cap_record_fetcher = '

0 commit comments

Comments
 (0)