Home > database >  Django - PUT endpoint authenticator error "wrapped_view() missing 1 required positional argumen
Django - PUT endpoint authenticator error "wrapped_view() missing 1 required positional argumen

Time:09-21

So I'm trying to create a PUT endpoint for editing post data. In the endpoint the post id is given in the URL then the new post dated is inserted into the entity. The issue I'm running into is that request isn't coming through on the authenticator (I'm using Cognito to authenticate, not super important for the error). So even though you can see I'm clearly passing in data, the request isn't coming through on the wrapped_view in the cognito_authenticator function. Why is this happening? The error I'm getting is:

"wrapped_view() missing 1 required positional argument: 'request'"

Test.py

def test_edit(self):
    response = self.client.put(reverse('edit_post_by_id', kwargs={'post_id': str(self.post.uuid)}),
                               data={'body': 'updated text #update'},
                               content_type='application/json',
                               **{'HTTP_AUTHORIZATION': f'bearer {self.cognito.access_token}'})
    self.assertEqual(response.status_code, status.HTTP_200_OK)

View.py

@api_view(['PUT'])
@method_decorator(cognito_authenticator)

def edit_post(request, post_id):
    try:
        post = Post.objects.get(pk=post_id)
    except Post.DoesNotExist:
        return JsonResponse(dict(error=f'Post id: {post_id} does not exists'), status=status.HTTP_400_BAD_REQUEST)

authenticator

def cognito_authenticator(view_func=None):
    if view_func is None:
        return partial(cognito_authenticator)

    @wraps(view_func)
    def wrapped_view(request, *args, **kwargs):
        # Check the cognito token from the request.
        auth = request.headers.get("Authorization", None)
        if not auth:
            return Response(dict(error='Authorization header expected'), status=status.HTTP_401_UNAUTHORIZED)

        parts = auth.split()

        if parts[0].lower() != "bearer":
            return Response(dict(error='Authorization header must start with bearer'),
                            status=status.HTTP_401_UNAUTHORIZED)
        elif len(parts) == 1:
            return Response(dict(error='Token not found'), status=status.HTTP_401_UNAUTHORIZED)
        elif len(parts) > 2:
            return Response(dict(error='Authorization header must be Bearer token'),
                            status=status.HTTP_401_UNAUTHORIZED)

        token = parts[1]
        try:
            res = decode_cognito_jwt(token)
        except Exception:
            # Fail if invalid
            return Response("Invalid JWT", status=status.HTTP_401_UNAUTHORIZED)  # Or HttpResponseForbidden()
        else:
            # Proceed with the view if valid
            return view_func(request, *args, **kwargs)

    return wrapped_view

CodePudding user response:

With function-based views, you don't need to use method_decorator so:

@api_view(['PUT'])
@cognito_authenticator
def edit_post(request, post_id):
    ...
  • Related