diff --git a/swh/deposit/api/common.py b/swh/deposit/api/common.py --- a/swh/deposit/api/common.py +++ b/swh/deposit/api/common.py @@ -5,7 +5,7 @@ import hashlib -from typing import Any, Tuple +from typing import Sequence, Type from abc import ABCMeta, abstractmethod from django.urls import reverse @@ -13,8 +13,8 @@ from django.shortcuts import render from django.utils import timezone from rest_framework import status -from rest_framework.authentication import BasicAuthentication -from rest_framework.permissions import IsAuthenticated +from rest_framework.authentication import BaseAuthentication, BasicAuthentication +from rest_framework.permissions import BasePermission, IsAuthenticated from rest_framework.views import APIView from swh.model import hashutil @@ -65,8 +65,8 @@ """ - authentication_classes = (BasicAuthentication,) # type: Tuple[Any, ...] - permission_classes = (IsAuthenticated,) + authentication_classes: Sequence[Type[BaseAuthentication]] = (BasicAuthentication,) + permission_classes: Sequence[Type[BasePermission]] = (IsAuthenticated,) class SWHBaseDeposit(SWHDefaultConfig, SWHAPIView, metaclass=ABCMeta): @@ -74,12 +74,12 @@ """ - def _read_headers(self, req): + def _read_headers(self, request): """Read and unify the necessary headers from the request (those are not stored in the same location or not properly formatted). Args: - req (Request): Input request + request (Request): Input request Returns: Dictionary with the following keys (some associated values may be @@ -93,8 +93,8 @@ - on-behalf-of """ - meta = req._request.META - content_type = req.content_type + meta = request._request.META + content_type = request.content_type content_length = meta.get("CONTENT_LENGTH") if content_length and isinstance(content_length, str): content_length = int(content_length) @@ -142,7 +142,9 @@ h.update(chunk) return h.digest() - def _deposit_put(self, req, deposit_id=None, in_progress=False, external_id=None): + def _deposit_put( + self, request, deposit_id=None, in_progress=False, external_id=None + ): """Save/Update a deposit in db. Args: @@ -196,7 +198,7 @@ args = [deposit.collection.name, deposit.id] scheduler = self.scheduler if deposit.status == DEPOSIT_STATUS_DEPOSITED and not deposit.check_task_id: - check_url = req.build_absolute_uri( + check_url = request.build_absolute_uri( reverse(PRIVATE_CHECK_DEPOSIT, args=args) ) task = create_oneshot_task_dict( @@ -351,7 +353,7 @@ def _binary_upload( self, - req, + request, headers, collection_name, deposit_id=None, @@ -363,7 +365,7 @@ Other than such a request, a 415 response is returned. Args: - req (Request): the request holding information to parse + request (Request): the request holding information to parse and inject in db headers (dict): request headers formatted collection_name (str): the associated client @@ -418,7 +420,7 @@ "The packaging provided %s is not supported" % packaging, ) - filehandler = req.FILES["file"] + filehandler = request.FILES["file"] precondition_status_response = self._check_preconditions_on( filehandler, headers["content-md5sum"], content_length @@ -432,7 +434,7 @@ # actual storage of data archive_metadata = filehandler deposit = self._deposit_put( - req, + request, deposit_id=deposit_id, in_progress=headers["in-progress"], external_id=external_id, @@ -462,7 +464,7 @@ def _multipart_upload( self, - req, + request, headers, collection_name, deposit_id=None, @@ -476,7 +478,7 @@ Other than such a request, a 415 response is returned. Args: - req (Request): the request holding information to parse + request (Request): the request holding information to parse and inject in db headers (dict): request headers formatted collection_name (str): the associated client @@ -516,7 +518,7 @@ "application/x-tar": None, # or x-tar "application/atom+xml": None, } - for key, value in req.FILES.items(): + for key, value in request.FILES.items(): fh = value if fh.content_type in content_types_present: return make_error_dict( @@ -566,7 +568,7 @@ # actual storage of data deposit = self._deposit_put( - req, + request, deposit_id=deposit_id, in_progress=headers["in-progress"], external_id=external_id, @@ -589,7 +591,7 @@ def _atom_entry( self, - req, + request, headers, collection_name, deposit_id=None, @@ -599,7 +601,7 @@ """Atom entry deposit. Args: - req (Request): the request holding information to parse + request (Request): the request holding information to parse and inject in db headers (dict): request headers formatted collection_name (str): the associated client @@ -629,7 +631,7 @@ """ try: - raw_metadata, metadata = self._read_metadata(req.data) + raw_metadata, metadata = self._read_metadata(request.data) except ParserError: return make_error_dict( BAD_REQUEST, @@ -649,7 +651,7 @@ external_id = metadata.get("external_identifier", headers["slug"]) deposit = self._deposit_put( - req, + request, deposit_id=deposit_id, in_progress=headers["in-progress"], external_id=external_id, @@ -669,11 +671,11 @@ "status": deposit.status, } - def _empty_post(self, req, headers, collection_name, deposit_id): + def _empty_post(self, request, headers, collection_name, deposit_id): """Empty post to finalize an empty deposit. Args: - req (Request): the request holding information to parse + request (Request): the request holding information to parse and inject in db headers (dict): request headers formatted collection_name (str): the associated client @@ -696,11 +698,11 @@ "archive": None, } - def _make_iris(self, req, collection_name, deposit_id): + def _make_iris(self, request, collection_name, deposit_id): """Define the IRI endpoints Args: - req (Request): The initial request + request (Request): The initial request collection_name (str): client/collection's name deposit_id (id): Deposit identifier @@ -710,11 +712,11 @@ """ args = [collection_name, deposit_id] return { - iri: req.build_absolute_uri(reverse(iri, args=args)) + iri: request.build_absolute_uri(reverse(iri, args=args)) for iri in [EM_IRI, EDIT_SE_IRI, CONT_FILE_IRI, STATE_IRI] } - def additional_checks(self, req, headers, collection_name, deposit_id=None): + def additional_checks(self, request, headers, collection_name, deposit_id=None): """Permit the child class to enrich additional checks. Returns: @@ -723,7 +725,7 @@ """ return {} - def checks(self, req, collection_name, deposit_id=None): + def checks(self, request, collection_name, deposit_id=None): try: self._collection = DepositCollection.objects.get(name=collection_name) except DepositCollection.DoesNotExist: @@ -731,7 +733,7 @@ NOT_FOUND, "Unknown collection name %s" % collection_name ) - username = req.user.username + username = request.user.username if username: # unauthenticated request can have the username empty try: self._client = DepositClient.objects.get(username=username) @@ -753,23 +755,23 @@ NOT_FOUND, "Deposit with id %s does not exist" % deposit_id ) - checks = self.restrict_access(req, deposit) + checks = self.restrict_access(request, deposit) if checks: return checks - headers = self._read_headers(req) + headers = self._read_headers(request) if headers["on-behalf-of"]: return make_error_dict(MEDIATION_NOT_ALLOWED, "Mediation is not supported.") - checks = self.additional_checks(req, headers, collection_name, deposit_id) + checks = self.additional_checks(request, headers, collection_name, deposit_id) if "error" in checks: return checks return {"headers": headers} - def restrict_access(self, req, deposit=None): + def restrict_access(self, request, deposit=None): if deposit: - if req.method != "GET" and deposit.status != DEPOSIT_STATUS_PARTIAL: + if request.method != "GET" and deposit.status != DEPOSIT_STATUS_PARTIAL: summary = "You can only act on deposit with status '%s'" % ( DEPOSIT_STATUS_PARTIAL, ) @@ -778,24 +780,24 @@ BAD_REQUEST, summary=summary, verbose_description=description ) - def _basic_not_allowed_method(self, req, method): + def _basic_not_allowed_method(self, request, method): return make_error_response( - req, + request, METHOD_NOT_ALLOWED, "%s method is not supported on this endpoint" % method, ) - def get(self, req, *args, **kwargs): - return self._basic_not_allowed_method(req, "GET") + def get(self, request, *args, **kwargs): + return self._basic_not_allowed_method(request, "GET") - def post(self, req, *args, **kwargs): - return self._basic_not_allowed_method(req, "POST") + def post(self, request, *args, **kwargs): + return self._basic_not_allowed_method(request, "POST") - def put(self, req, *args, **kwargs): - return self._basic_not_allowed_method(req, "PUT") + def put(self, request, *args, **kwargs): + return self._basic_not_allowed_method(request, "PUT") - def delete(self, req, *args, **kwargs): - return self._basic_not_allowed_method(req, "DELETE") + def delete(self, request, *args, **kwargs): + return self._basic_not_allowed_method(request, "DELETE") class SWHGetDepositAPI(SWHBaseDeposit, metaclass=ABCMeta): @@ -803,7 +805,7 @@ """ - def get(self, req, collection_name, deposit_id, format=None): + def get(self, request, collection_name, deposit_id, format=None): """Endpoint to create/add resources to deposit. Returns: @@ -812,11 +814,11 @@ 404 if the deposit or the collection does not exist """ - checks = self.checks(req, collection_name, deposit_id) + checks = self.checks(request, collection_name, deposit_id) if "error" in checks: - return make_error_response_from_dict(req, checks["error"]) + return make_error_response_from_dict(request, checks["error"]) - r = self.process_get(req, collection_name, deposit_id) + r = self.process_get(request, collection_name, deposit_id) if isinstance(r, tuple): status, content, content_type = r @@ -825,7 +827,7 @@ return r @abstractmethod - def process_get(self, req, collection_name, deposit_id): + def process_get(self, request, collection_name, deposit_id): """Routine to deal with the deposit's get processing. Returns: @@ -840,7 +842,7 @@ """ - def post(self, req, collection_name, deposit_id=None, format=None): + def post(self, request, collection_name, deposit_id=None, format=None): """Endpoint to create/add resources to deposit. Returns: @@ -849,24 +851,24 @@ 404 if the deposit or the collection does not exist """ - checks = self.checks(req, collection_name, deposit_id) + checks = self.checks(request, collection_name, deposit_id) if "error" in checks: - return make_error_response_from_dict(req, checks["error"]) + return make_error_response_from_dict(request, checks["error"]) headers = checks["headers"] _status, _iri_key, data = self.process_post( - req, headers, collection_name, deposit_id + request, headers, collection_name, deposit_id ) error = data.get("error") if error: - return make_error_response_from_dict(req, error) + return make_error_response_from_dict(request, error) data["packagings"] = ACCEPT_PACKAGINGS - iris = self._make_iris(req, collection_name, data["deposit_id"]) + iris = self._make_iris(request, collection_name, data["deposit_id"]) data.update(iris) response = render( - req, + request, "deposit/deposit_receipt.xml", context=data, content_type="application/xml", @@ -876,7 +878,7 @@ return response @abstractmethod - def process_post(self, req, headers, collection_name, deposit_id=None): + def process_post(self, request, headers, collection_name, deposit_id=None): """Routine to deal with the deposit's processing. Returns @@ -894,7 +896,7 @@ """ - def put(self, req, collection_name, deposit_id, format=None): + def put(self, request, collection_name, deposit_id, format=None): """Endpoint to update deposit resources. Returns: @@ -903,21 +905,21 @@ 404 if the deposit or the collection does not exist """ - checks = self.checks(req, collection_name, deposit_id) + checks = self.checks(request, collection_name, deposit_id) if "error" in checks: - return make_error_response_from_dict(req, checks["error"]) + return make_error_response_from_dict(request, checks["error"]) headers = checks["headers"] - data = self.process_put(req, headers, collection_name, deposit_id) + data = self.process_put(request, headers, collection_name, deposit_id) error = data.get("error") if error: - return make_error_response_from_dict(req, error) + return make_error_response_from_dict(request, error) return HttpResponse(status=status.HTTP_204_NO_CONTENT) @abstractmethod - def process_put(self, req, headers, collection_name, deposit_id): + def process_put(self, request, headers, collection_name, deposit_id): """Routine to deal with updating a deposit in some way. Returns @@ -932,7 +934,7 @@ """ - def delete(self, req, collection_name, deposit_id): + def delete(self, request, collection_name, deposit_id): """Endpoint to delete some deposit's resources (archives, deposit). Returns: @@ -941,19 +943,19 @@ 404 if the deposit or the collection does not exist """ - checks = self.checks(req, collection_name, deposit_id) + checks = self.checks(request, collection_name, deposit_id) if "error" in checks: - return make_error_response_from_dict(req, checks["error"]) + return make_error_response_from_dict(request, checks["error"]) - data = self.process_delete(req, collection_name, deposit_id) + data = self.process_delete(request, collection_name, deposit_id) error = data.get("error") if error: - return make_error_response_from_dict(req, error) + return make_error_response_from_dict(request, error) return HttpResponse(status=status.HTTP_204_NO_CONTENT) @abstractmethod - def process_delete(self, req, collection_name, deposit_id): + def process_delete(self, request, collection_name, deposit_id): """Routine to delete a resource. This is mostly not allowed except for the diff --git a/swh/deposit/api/private/__init__.py b/swh/deposit/api/private/__init__.py --- a/swh/deposit/api/private/__init__.py +++ b/swh/deposit/api/private/__init__.py @@ -87,11 +87,23 @@ return {"headers": headers} def get( - self, req, collection_name=None, deposit_id=None, format=None, *args, **kwargs + self, + request, + collection_name=None, + deposit_id=None, + format=None, + *args, + **kwargs ): - return super().get(req, collection_name, deposit_id, format) + return super().get(request, collection_name, deposit_id, format) def put( - self, req, collection_name=None, deposit_id=None, format=None, *args, **kwargs + self, + request, + collection_name=None, + deposit_id=None, + format=None, + *args, + **kwargs ): - return super().put(req, collection_name, deposit_id, format) + return super().put(request, collection_name, deposit_id, format) diff --git a/swh/deposit/api/private/deposit_read.py b/swh/deposit/api/private/deposit_read.py --- a/swh/deposit/api/private/deposit_read.py +++ b/swh/deposit/api/private/deposit_read.py @@ -77,12 +77,12 @@ if not os.path.exists(self.extraction_dir): os.makedirs(self.extraction_dir) - def process_get(self, req, collection_name, deposit_id): + def process_get(self, request, collection_name, deposit_id): """Build a unique tarball from the multiple received and stream that content to the client. Args: - req (Request): + request (Request): collection_name (str): Collection owning the deposit deposit_id (id): Deposit concerned by the reading @@ -221,7 +221,7 @@ return data - def process_get(self, req, collection_name, deposit_id): + def process_get(self, request, collection_name, deposit_id): deposit = Deposit.objects.get(pk=deposit_id) data = self.metadata_read(deposit) d = {} diff --git a/swh/deposit/api/private/deposit_update_status.py b/swh/deposit/api/private/deposit_update_status.py --- a/swh/deposit/api/private/deposit_update_status.py +++ b/swh/deposit/api/private/deposit_update_status.py @@ -23,7 +23,7 @@ parser_classes = (JSONParser,) - def additional_checks(self, req, headers, collection_name, deposit_id=None): + def additional_checks(self, request, headers, collection_name, deposit_id=None): """Enrich existing checks to the default ones. New checks: @@ -31,7 +31,7 @@ - Ensure it exists """ - data = req.data + data = request.data status = data.get("status") if not status: msg = "The status key is mandatory with possible values %s" % list( @@ -51,7 +51,7 @@ return {} - def process_put(self, req, headers, collection_name, deposit_id): + def process_put(self, request, headers, collection_name, deposit_id): """Update the deposit's status Returns: @@ -59,18 +59,18 @@ """ deposit = Deposit.objects.get(pk=deposit_id) - deposit.status = req.data["status"] # checks already done before + deposit.status = request.data["status"] # checks already done before - origin_url = req.data.get("origin_url") + origin_url = request.data.get("origin_url") - dir_id = req.data.get("directory_id") + dir_id = request.data.get("directory_id") if dir_id: deposit.swh_id = persistent_identifier(DIRECTORY, dir_id) deposit.swh_id_context = persistent_identifier( DIRECTORY, dir_id, metadata={"origin": origin_url} ) - rev_id = req.data.get("revision_id") + rev_id = request.data.get("revision_id") if rev_id: deposit.swh_anchor_id = persistent_identifier(REVISION, rev_id) deposit.swh_anchor_id_context = persistent_identifier( diff --git a/tox.ini b/tox.ini --- a/tox.ini +++ b/tox.ini @@ -40,5 +40,6 @@ deps = mypy django-stubs + djangorestframework-stubs commands = mypy swh