I am trying to test Restful API with Flask and MySQL database with Raspberry Pi. Found a interesting article Tutorial My Full Code is below,
from flask import Flask, request, jsonify, make_response
from flask_sqlalchemy import SQLAlchemy
from marshmallow import fields
from marshmallow_sqlalchemy import SQLAlchemySchema
import json
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:root@localhost:3306/todo'
db = SQLAlchemy(app)
# Model
class Todo(db.Model):
__tablename__ = "todos"
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(20))
todo_description = db.Column(db.String(100))
def create(self):
db.session.add(self)
db.session.commit()
return self
def __init__(self, title, todo_description):
self.title = title
self.todo_description = todo_description
def __repr__(self):
return f"{self.id}"
db.create_all()
class TodoSchema(SQLAlchemySchema):
class Meta(SQLAlchemySchema.Meta):
model = Todo
sqla_session = db.session
id = fields.Number(dump_only=True)
title = fields.String(required=True)
todo_description = fields.String(required=True)
@app.route('/api/v1/todo', methods=['POST'])
def create_todo():
data = request.get_json()
print(data)
todo_schema = TodoSchema()
todo = todo_schema.load(data)
result = todo_schema.dump(todo.create())
return make_response(jsonify({"todo": result}), 200)
# return 'This works',200
@app.route('/api/v1/todo', methods=['GET'])
def index():
get_todos = Todo.query.all()
todo_schema = TodoSchema(many=True)
todos = todo_schema.dump(get_todos)
return make_response(jsonify({"todos": todos}))
@app.route('/api/v1/todo/<id>', methods=['GET'])
def get_todo_by_id(id):
get_todo = Todo.query.get(id)
todo_schema = TodoSchema()
todo = todo_schema.dump(get_todo)
return make_response(jsonify({"todo": todo}))
But when I send Rest POST request through Postman I am getting following error,
Error:
(venv) root@raspberrypi:~/password_db_test1# flask run -h 0.0.0.0
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
/root/password_db_test1/venv/lib/python3.7/site-packages/flask_sqlalchemy/__init__.py:873: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future. Set it to True or False to suppress this warning.
'SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and '
* Running on all addresses.
WARNING: This is a development server. Do not use it in a production deployment.
* Running on http://192.168.8.182:5000/ (Press CTRL+C to quit)
{'title': 'test title', 'todo_description': 'test'}
[2021-09-19 07:58:10,883] ERROR in app: Exception on /api/v1/todo [POST]
Traceback (most recent call last):
File "/root/password_db_test1/venv/lib/python3.7/site-packages/flask/app.py", line 2070, in wsgi_app
response = self.full_dispatch_request()
File "/root/password_db_test1/venv/lib/python3.7/site-packages/flask/app.py", line 1515, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/root/password_db_test1/venv/lib/python3.7/site-packages/flask/app.py", line 1513, in full_dispatch_request
rv = self.dispatch_request()
File "/root/password_db_test1/venv/lib/python3.7/site-packages/flask/app.py", line 1499, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "/root/password_db_test1/app.py", line 48, in create_todo
result = todo_schema.dump(todo.create())
AttributeError: 'dict' object has no attribute 'create'
192.168.8.228 - - [19/Sep/2021 07:58:10] "POST /api/v1/todo HTTP/1.1" 500 -
I have done playing with the code and change the below
From:
result = todo_schema.dump(todo.create())
To:
result = todo_schema.dump(todo.create())
Since method is Todo
After that I am getting,
Error:
{'title': 'test title', 'todo_description': 'test'}
[2021-09-19 08:02:29,147] ERROR in app: Exception on /api/v1/todo [POST]
Traceback (most recent call last):
File "/root/password_db_test1/venv/lib/python3.7/site-packages/flask/app.py", line 2070, in wsgi_app
response = self.full_dispatch_request()
File "/root/password_db_test1/venv/lib/python3.7/site-packages/flask/app.py", line 1515, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/root/password_db_test1/venv/lib/python3.7/site-packages/flask/app.py", line 1513, in full_dispatch_request
rv = self.dispatch_request()
File "/root/password_db_test1/venv/lib/python3.7/site-packages/flask/app.py", line 1499, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "/root/password_db_test1/app.py", line 48, in create_todo
result = todo_schema.dump(Todo.create())
TypeError: create() missing 1 required positional argument: 'self'
192.168.8.228 - - [19/Sep/2021 08:02:29] "POST /api/v1/todo HTTP/1.1" 500 -
I changed some codes due to testing and changes in marshmallow_sqlalchemy import ModelSchema to SQLAlchemySchema as per the ModelSchema_Change
My Sample JSON POST Request from Postman is below
{
"title": "test title",
"todo_description": "test"
}
Please help me to sort this issue, I am doing a project to encrypted user date in mariaDB for a project using Raspberry Pi which will be this be a sample.