Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
1
resposta

TypeError: create_product() missing 1 required positional argument: 'token'

Olá, pessoal! Estou enfrentando a seguinte dificuldade:

Após adicionar o decorator @token_required na função create_product, adicionando o token como parâmetro, conforme código do professor, recebo o erro "TypeError: create_product() missing 1 required positional argument: 'token&#39" como retorno no Postman após acessar o http://127.0.0.1:5000/products com o método POST, mesmo adicionando o Auth Type "Bearer Token" e colando no campo "Token" o token obtido em http://127.0.0.1:5000/login.

Abaixo segue o código do módulo decorators.py e o da função create_product no módulo main.py:

Código módulo decorators.py:

from functools import wraps
from flask import request, jsonify, current_app
import jwt

def token_required(f):
    @wraps
    def decorated(*args, **kwargs):

        token = None
        if 'Authorization' in request.headers:
            auth_header = request.headers['Authorization']
            try:
                token = auth_header.split(' ')[1]
            except IndexError:
                return jsonify({'message': 'Token mal formado.'})
        if not token:
            return jsonify({'error': 'Token não encontrado.'}), 401
        
        try:
            data = jwt.decode(token, current_app.config['SECRET_KEY'], algorithms=['HS256'])
        except jwt.ExpiredSignatureError:
            return jsonify({'error': 'Token expirado.'}), 401
        except jwt.InvalidTokenError:
            return jsonify({'error': 'Token inválido.'}), 401
        
        return f(data, *args, **kwargs)
            
    return decorated

Código da função create_product no módulo main.py:

@token_required
@main_bp.route('/products', methods=['POST'])
def create_product(token):
    try:
        product = Product(**request.get_json())
    except ValidationError as e:
        return jsonify({'error': e.errors()})
    
    result = db.products.insert_one(product.model_dump())

    return jsonify({'message': 'Produto adicionado com sucesso.',
                    'id': str(result.inserted_id)}), 201

Abaixo estão prints do Postman.

Print post rota /products

Print Postman rota /login

Desde já, grato pela ajuda!

1 resposta
solução!

Consegui resolver o problema! rs

Além de alterar a ordem dos decorators, de forma que o decorator referente à rota seja o mais externo e o @token_required venha abaixo dele (o que eu já tinha tentado, mas apenas essa alteração não tinha dado resultado), faltou adicionar o parâmetro f dentro do decorator wrap da função token required, conforme abaixo:

def token_required(f):
    @wraps(f)
    def decorated(*args, **kwargs):

        token = None
        ...

O professor não colocou na aula e funcionou normalmente. Mas para mim só funcionou com esse ajuste.
Fica a dica caso alguém esteja passando pela mesma situação.