When using flask I try to send a patch request to update user data but get a TypeError message instead which I cant seem to figure out why.
Here’s the relevant part of my code…
class UpdateUser(Resource):
def token_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
token = request.headers.get('Authorization')
if not token:
return jsonify({'error': 'Token is missing!'}), 403
try:
token = token.split(" ")[1] # Assuming 'Bearer <token>'
data = jwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])
return f(*args, **kwargs, current_user_id=data['sub'])
except jwt.ExpiredSignatureError:
return jsonify({'error': 'Token has expired!'}), 403
except jwt.InvalidTokenError:
return jsonify({'error': 'Invalid Token!'}), 403
return decorated_function
@token_required
def patch(self, id, current_user_id):
if id != current_user_id:
return jsonify({'error': 'Unauthorized'}), 401
user = User.query.filter_by(id=id).first()
if not user:
return jsonify({'error': 'User not found'}), 404
data = request.get_json()
if '_password_hash' in data:
hashed_password = bcrypt.hashpw(data['_password_hash'].encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
user._password_hash = hashed_password
for field in ['fname', 'lname', 'email', 'user_role']:
if field in data:
setattr(user, field, data[field])
try:
db.session.commit()
user_dict = user.to_dict()
return jsonify({'user': user_dict}), 200
except Exception as e:
db.session.rollback()
app.logger.error(f"Error during updating user: {e}")
return jsonify({'error': 'Internal Server Error'}), 500
api.add_resource(UpdateUser, '/user/<int:id>')
and i guess my model for good measure
class User(db.Model, SerializerMixin):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
fname = db.Column(db.String, nullable=False)
lname = db.Column(db.String, nullable=False)
email = db.Column(db.String, nullable=False, unique=True)
user_role = db.Column(db.String, nullable=False)
phone_number = db.Column(db.String, nullable=False)
_password_hash = db.Column(db.String, nullable=False)
reset_password_token = db.Column(db.String)
reset_password_token_expiration = db.Column(db.DateTime)
created_at = db.Column(db.DateTime, server_default=db.func.now())
updated_at = db.Column(db.DateTime, onupdate=db.func.now())
libraries = db.relationship('Library', backref='user')
product_metrics = db.relationship('ProductMetric', backref='user')
@property
def password(self):
return self._password_hash
@password.setter
def password(self, password):
self._password_hash = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
def authenticate(self, password):
return bcrypt.checkpw(password.encode('utf-8'), self._password_hash.encode('utf-8'))
@validates('email')
def validate_email(self, key, email):
assert '@' in email, 'Invalid email address'
return email
def __repr__(self):
return f"<User(id={self.id}, email='{self.email}')>"
serialize_rules = ('-created_at', '-updated_at', '-libraries', '-product_metrics')
Edit: Here’s my full traceback error message
127.0.0.1 - - [19/Aug/2024 09:35:25] "OPTIONS /user/1 HTTP/1.1" 200 -
[2024-08-19 09:35:27,293] ERROR in app: Exception on /user/1 [PATCH]
Traceback (most recent call last):
File "/home/chernandez148/.pyenv/versions/3.8.13/lib/python3.8/site-packages/flask/app.py", line 880, in full_dispatch_request
rv = self.dispatch_request()
File "/home/chernandez148/.pyenv/versions/3.8.13/lib/python3.8/site-packages/flask/app.py", line 865, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
File "/home/chernandez148/.pyenv/versions/3.8.13/lib/python3.8/site-packages/flask_restful/__init__.py", line 493, in wrapper
return self.make_response(data, code, headers=headers)
File "/home/chernandez148/.pyenv/versions/3.8.13/lib/python3.8/site-packages/flask_restful/__init__.py", line 522, in make_response
resp = self.representations[mediatype](data, *args, **kwargs)
File "/home/chernandez148/.pyenv/versions/3.8.13/lib/python3.8/site-packages/flask_restful/representations/json.py", line 21, in output_json
dumped = dumps(data, **settings) + "n"
File "/home/chernandez148/.pyenv/versions/3.8.13/lib/python3.8/json/__init__.py", line 231, in dumps
return _default_encoder.encode(obj)
File "/home/chernandez148/.pyenv/versions/3.8.13/lib/python3.8/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/home/chernandez148/.pyenv/versions/3.8.13/lib/python3.8/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/home/chernandez148/.pyenv/versions/3.8.13/lib/python3.8/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Response is not JSON serializable
127.0.0.1 - - [19/Aug/2024 09:35:27] "PATCH /user/1 HTTP/1.1" 500 -
I’m not sure why im getting the error, even when it’s actually updating my database, Whelp anyone can give is greatly appreciated, thank you!
1