Restful API with Flask and MySQL database with Raspberry Pi - python

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.

Related

Python Flask - Session Not Being Set with Waitress

I am using waitress on IIS with Flask.
I have a route that sets a session as follows
#gp_clinicals_bp.route("/setting", methods=["POST","GET"])
def gp_clinicals():
session["gp_clinicals_meds_repeat"] = "123456"
return session["gp_clinicals_meds_repeat"]
This returns, unsurprisingly:
123456
I have another route as follows:
#gp_clinicals_bp.route("/testing", methods=["POST","GET"])
def gp_clinicals_test():
return session["gp_clinicals_meds_repeat"]
Now, I get nothing back and the following in the error log
2022-08-02 20:03:51,126 - ERROR - app.py - log_exception - 1455 - Exception on /gp-clinicals/medication-repeat [GET]
Traceback (most recent call last):
File "C:\Python310\lib\site-packages\flask\app.py", line 2077, in wsgi_app
response = self.full_dispatch_request()
File "C:\Python310\lib\site-packages\flask\app.py", line 1525, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Python310\lib\site-packages\flask\app.py", line 1523, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Python310\lib\site-packages\flask\app.py", line 1509, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "E:\Apps\dev\digital\gp_clinicals\gp_clinicals.py", line 158, in gp_clinicals_medication_repeat
return str(session["gp_clinicals_meds_repeat"])
KeyError: 'gp_clinicals_meds_repeat'
2022-08-02 20:03:51,128 - ERROR - __init__.py - handle_error_500 - 92 - 500 Internal Server Error: The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.
I'm the only one on the server. Below is a snippet from my initilisation file:
"""Initialize Flask app."""
import logging
import os
from logging.handlers import RotatingFileHandler
from flask import Flask, render_template, flash,request
from flask_session import Session
from flask_assets import Environment
from config import Config
if Config.FLASK_ENV == "development" and Config.DD_SERVICE:
patch_all()
sess = Session()
def init_app():
"""Create Flask application."""
app = Flask(__name__, instance_relative_config=False)
app.config["CACHE_TYPE"] = "null"
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
app.config['TEMPLATES_AUTO_RELOAD'] = True
app.config["SESSION_TYPE"] = "filesystem"
app.config.from_object("config.Config")
assets = Environment()
assets.init_app(app)
sess.init_app(app)
What's going wrong? In the flask_session folder I am seeing files being created
Any advice? I tried using single apostophes instead of quotes but no go there either
The site in IIS is running through a reverse proxy in IIS - could that be doing it?

Flask app NameError: name 'Markup' is not defined

I have been really stumped on this, been out of this game of web dev/python for a bit. I had a previously working Azure app service running this website, we did a minor HTML spelling change and re deployed. I am assuming some dependency got updated and now its broken. I don't know if this is a packaging version issue or if I have a missing import for my flask app.
I am getting a NameError: name 'Markup' is not defined error when trying to load a static html page. My app starts up just fine but I can't load the actual web pages.
Full Traceback
Traceback (most recent call last):
File "C:\Users\St**\PythonProjects\**Site-Portfolio\lib\site-packages\flask\app.py", line 2095, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Users\St**\PythonProjects\**Site-Portfolio\lib\site-packages\flask\app.py", line 2080, in wsgi_app
response = self.handle_exception(e)
File "C:\Users\St**\PythonProjects\**Site-Portfolio\lib\site-packages\flask_cors\extension.py", line 165, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "C:\Users\St**\PythonProjects\**Site-Portfolio\lib\site-packages\flask\app.py", line 2077, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\St**\PythonProjects\**Site-Portfolio\lib\site-packages\flask\app.py", line 1525, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\St**\PythonProjects\**Site-Portfolio\lib\site-packages\flask_cors\extension.py", line 165, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "C:\Users\St**\PythonProjects\**Site-Portfolio\lib\site-packages\flask\app.py", line 1523, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\St**\PythonProjects\**Site-Portfolio\lib\site-packages\flask\app.py", line 1509, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "C:\Users\St**\PycharmProjects\**Site-portfolio\application.py", line 32, in index
return render_template("//index.html")
File "C:\Users\St**\PythonProjects\**Site-Portfolio\lib\site-packages\flask\templating.py", line 147, in render_template
ctx.app.update_template_context(context)
File "C:\Users\St**\PythonProjects\**Site-Portfolio\lib\site-packages\flask\app.py", line 756, in update_template_context
context.update(func())
File "C:\Users\St**\PythonProjects\**Site-Portfolio\lib\site-packages\flask_recaptcha.py", line 59, in get_code
return dict(recaptcha=Markup(self.get_code()))
NameError: name 'Markup' is not defined
127.0.0.1 - - [08/Apr/2022 17:02:51] "GET /?__debugger__=yes&cmd=resource&f=style.css HTTP/1.1" 304 -
127.0.0.1 - - [08/Apr/2022 17:02:51] "GET /?__debugger__=yes&cmd=resource&f=debugger.js HTTP/1.1" 304 -
127.0.0.1 - - [08/Apr/2022 17:02:51] "GET /?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 304 -
Process finished with exit code 0
Here is my code:
from flask import Flask, request, render_template, flash
from flask_mail import Mail, Message
from flask_cors import CORS, cross_origin
from flask_recaptcha import ReCaptcha
import requests
import json
import os
app = Flask(__name__, static_folder='static', static_url_path='')
recaptcha = ReCaptcha(app=app)
app.config['RECAPTCHA_ENABLED'] = True
app.config['RECAPTCHA_PUBLIC_KEY'] = '***********************'
app.config['RECAPTCHA_PRIVATE_KEY'] = '****************************'
#app.route('/', methods=['GET'])
def index():
return render_template("//index.html")
#app.route('/contact-us', methods=['GET'])
#app.route('/contact', methods=['GET', 'POST'])
def contact():
if request.method == 'POST':
r = requests.post('https://www.google.com/recaptcha/api/siteverify',
data={'secret': '***********',
'response': request.form['g-recaptcha-response']})
google_response = json.loads(r.text)
if google_response['success']:
contact_form = {'name': request.form['name'],
'email': request.form['email'],
'message': request.form['message']}
msg = Message(subject='Contact from website',
sender=contact_form['email'],
recipients=['*************'],
body=contact_form['message'])
mail.send(msg)
flash('Success, we will respond within at least 24 hours.')
return render_template('contact.html')
else:
flash('failed to submit, please retry or contact us at ************')
return render_template('contact.html')
return render_template('contact.html')
if __name__ == '__main__':
app.run()
My requirements.txt for package version
Flask>=1.0.2
jinja2>=2.11.3
Flask-Mail>=0.9.1
Flask-Cors>=3.0.9
Flask-Admin>=1.5.2
Flask-ReCaptcha>=0.4.2
Flask-SQLAlchemy>=2.3.2
Flask-WTF>=0.14.2
SQLAlchemy>=1.3.0
requests>=2.20.0
Flask-Login>=0.4.1
Werkzeug>=0.15.3
Flask-ReCaptcha is a very old project. The last update of Flask-ReCaptcha is on 2016. You'd better not use it.
Back to the error log itself, Flask-ReCaptcha has code like from jinja2 import Markup. But, since jinja2==3.1.0, Markup's position has changed. Try pip install jinja2==3.0.0`.
You will probably meet other problems as Flask-ReCaptcha is really old.
Go to Python installation folder
Go to Lib > site-packages
Open flask_recaptcha.py
You'll see something like this:
try:
from flask import request
from jinja2 import Markup
import requests
except ImportError as ex:
print("Missing dependencies")
Change it to:
try:
from flask import request
from markupsafe import Markup
import requests
except ImportError as ex:
print("Missing dependencies")

How to filter a SQL query on columns in SQLAlchemy?

I am new to flask-alchemy. I want to filter a SQL query on the values of a LOC_CODE column. I made db.session.query(schools).filter_by(LOC_CODE='X270').first(). But the compiler returns:
(base) C:\Users\antoi\Documents\Programming\musicaltroupefinder>python hello_world.py
C:\ProgramData\Anaconda3\lib\site-packages\flask_sqlalchemy\__init__.py:835: 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 '
* Serving Flask app "hello_world" (lazy loading)
* 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
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
the total number of school is 3281
[2019-12-18 11:08:31,831] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\util\_collections.py", line 210, in __getattr__
return self._data[key]
KeyError: 'LOC_CODE'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\orm\base.py", line 399, in _entity_descriptor
return getattr(entity, key)
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\util\_collections.py", line 212, in __getattr__
raise AttributeError(key)
AttributeError: LOC_CODE
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 2446, in wsgi_app
response = self.full_dispatch_request()
File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 1951, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 1820, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\ProgramData\Anaconda3\lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 1949, in full_dispatch_request
rv = self.dispatch_request()
File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 1935, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "hello_world.py", line 37, in index
school = db.session.query(schools).filter_by(LOC_CODE='X270').first()
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\orm\query.py", line 1800, in filter_by
for key, value in kwargs.items()
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\orm\query.py", line 1800, in <listcomp>
for key, value in kwargs.items()
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\orm\base.py", line 402, in _entity_descriptor
"Entity '%s' has no property '%s'" % (description, key)
sqlalchemy.exc.InvalidRequestError: Entity 'schools' has no property 'LOC_CODE'
127.0.0.1 - - [18/Dec/2019 11:08:31] "[1m[35mGET / HTTP/1.1[0m" 500 -
However, I have this column in the database:
sqlite> SELECT * FROM SCHOOLS ORDER BY ROWID ASC LIMIT 1
...>
...> ;
0,,O,0,OAQK,"Victory Schools, DBA The Charter School of Excelle",Elementary,2,0,0,260 WARBURTON AVE,NY,10701,,,,"0K,01,02,03,04",YONKERS,260 WARBURTON AVE,1006,YONKERS,"-73.897156,40.94465",119,"260 WARBURTON AVE, YONKERS, NY, 10701",0,Exact,Match,40.94465,-73.897156,"260 WARBURTON AVE, YONKERS, NY, 10701",R,NY,36,139742928,402,10701
sqlite> PRAGMA table_info(schools);
0|,ATS_CODE,BORO,BORONUM,LOC_CODE,SCHOOLNAME,SCH_TYPE,MANAGED_BY,GEO_DISTRI,ADMIN_DIST,ADDRESS,STATE_CODE,ZIP,PRINCIPAL,PRIN_PH,FAX,GRADES,City,address2,block,city2,coordinates,county_fips,geocoded_address,id,is_exact,is_match,latitude,longitude,returned_address,side,state,state_fips,tiger_line,tract,zipcode|TEXT|0||0
Here's my entire code:
from flask import Flask # pip install flask
from flask import render_template
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import create_engine, MetaData, Table
from sqlalchemy.orm import mapper, sessionmaker
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydb.db'
db = SQLAlchemy(app)
schools = db.Table("schools",db.metadata, autoload = True, autoload_with = db.engine)
#app.route("/")
def index():
results = db.session.query(schools).count()
print("the total number of school is ", db.session.query(schools).count())
school = db.session.query(schools).filter_by(LOC_CODE='X270').first()
print("School's name is", school.SCHOOLNAME)
return render_template("index.html")
#app.route("/map")
def shoelaces():
return "This works now!"
#app.route("/about")
def about():
return "All about my website"
if __name__ == "__main__":
app.run()
But I couldn't tell SQLAlchemy that we are lazy and that he should learn on his own about the database, we use this line:
I based it on this tutorial but I couldn't tell SQLAlchemy that he was lazy and that he should learn on his own about the database with a line db.Model.metadata.reflect(db.engine).
With classes
I also tried with a class:
(base) C:\Users\antoi\Documents\Programming\musicaltroupefinder>python hello_world.py
C:\ProgramData\Anaconda3\lib\site-packages\flask_sqlalchemy\__init__.py:835: 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 '
* Serving Flask app "hello_world" (lazy loading)
* 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
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
[2019-12-20 13:03:58,460] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1249, in _execute_context
cursor, statement, parameters, context
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\default.py", line 580, in do_execute
cursor.execute(statement, parameters)
sqlite3.OperationalError: no such column: schools.LOC_CODE
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 2446, in wsgi_app
response = self.full_dispatch_request()
File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 1951, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 1820, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\ProgramData\Anaconda3\lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 1949, in full_dispatch_request
rv = self.dispatch_request()
File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 1935, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "hello_world.py", line 32, in index
school = School.query.filter(School.LOC_CODE == 'X270').all()
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\orm\query.py", line 3186, in all
return list(self)
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\orm\query.py", line 3342, in __iter__
return self._execute_and_instances(context)
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\orm\query.py", line 3367, in _execute_and_instances
result = conn.execute(querycontext.statement, self._params)
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 988, in execute
return meth(self, multiparams, params)
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\sql\elements.py", line 287, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1107, in _execute_clauseelement
distilled_params,
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1253, in _execute_context
e, statement, parameters, cursor, context
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1473, in _handle_dbapi_exception
util.raise_from_cause(sqlalchemy_exception, exc_info)
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\util\compat.py", line 398, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb, cause=cause)
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\util\compat.py", line 152, in reraise
raise value.with_traceback(tb)
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1249, in _execute_context
cursor, statement, parameters, context
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\default.py", line 580, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such column: schools.LOC_CODE
[SQL: SELECT schools."LOC_CODE" AS "schools_LOC_CODE"
FROM schools
WHERE schools."LOC_CODE" = ?]
[parameters: ('X270',)]
(Background on this error at: http://sqlalche.me/e/e3q8)
127.0.0.1 - - [20/Dec/2019 13:03:58] "[1m[35mGET / HTTP/1.1[0m" 500 -
Here is the code
from flask import Flask # pip install flask
from flask import render_template
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import create_engine, MetaData, Table
from sqlalchemy.orm import mapper, sessionmaker
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydb.db'
db = SQLAlchemy(app)
class School(db.Model):
__tablename__ = 'schools'
# __table_args__ = { 'extend_existing': True }
LOC_CODE = db.Column(db.Text, primary_key=True)
#app.route("/")
def index():
school = School.query.filter(School.LOC_CODE == 'X270').first()
print("School's name is", school.SCHOOLNAME)
return render_template("index.html")
The error has to do with how you utilize db or session. In your third code snippet, the configuration is handled by the School class, and your hashed out line is important to the subsequent queries through it. It is also important for utilizing the reflect method on the db.engine configuration. Switching filter() to filter_by() will also yield the result. I've split my .py files into two, one to create the sqlite db and another for the Flask session. Minimal changes were required to get no error and expected result, tested on both scripts' ending lines.
#create_db.py
from sqlalchemy import create_engine, MetaData, Table, Column, String
from sqlalchemy.orm import mapper, sessionmaker
engine= create_engine('sqlite:///example.db')
metadata = MetaData(engine)
table = Table('schools', metadata,
Column('name', String),
Column('LOC_CODE', String))
metadata.create_all()
ins = table.insert().values(name = 'Victory',
LOC_CODE = 'X270'
)
conn = engine.connect()
conn.execute(ins)
Session = sessionmaker(bind=engine)
session = Session()
schools = table
# Test session below
results = session.query(schools).count()
filt = session.query(schools).filter_by(LOC_CODE='X270').first()
print(results)
print(filt)
#filter_by_test.py
from flask import Flask
from flask import render_template
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import create_engine, MetaData, Table, Column, String
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.db'
db = SQLAlchemy(app)
db.Model.metadata.reflect(db.engine)
class School(db.Model):
__tablename__ = 'schools'
__table_args__ = {'extend_existing': True}
LOC_CODE = db.Column(db.Text, primary_key = True)
#app.route("/")
def hello():
print("Total number of schools is", School.query.count())
school = School.query.filter_by(LOC_CODE='X270').first()
print(school.name)
hello()
#combined.py
from flask import Flask
from flask import render_template
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import create_engine, MetaData, Table, Column, String
import sqlite3
import pandas as pd
#data = 'schools-geocoded - schools-geocoded.csv'
#df = pd.read_csv(data)
#con = sqlite3.connect('example2.db')
#df.to_sql("schools", con)
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example2.db'
db = SQLAlchemy(app)
db.Model.metadata.reflect(db.engine)
class School(db.Model):
__tablename__ = 'schools'
__table_args__ = {'extend_existing': True}
LOC_CODE = db.Column(db.Text, primary_key = True)
#app.route("/")
def hello():
print("Total number of schools is", School.query.count())
school = School.query.filter_by(LOC_CODE='X270').first()
print(school.SCHOOLNAME)
hello()
I was able to get past your first error by running these commands from the python console first, then starting up the flask application. This creates the database that is used by your code in the given example. If you have an existing database you will need to change the URI to where it is at. The URI you are using is the one that will be created by using this command. I would look over the Flask-SQLAlchemy documentation to see how to connect to an existing database if desired.
from yourapplication import db
db.create_all()
Source:
https://flask-sqlalchemy.palletsprojects.com/en/2.x/quickstart/

error with flask session during youtube api v3 authentication [duplicate]

This question already has answers here:
demystify Flask app.secret_key
(2 answers)
Closed 7 years ago.
I'm developing an app in python that uses YT API. I decided to move it to the web and i'm using Flask. I took the auth example from Google guides. For testing purposes i'm trying to create a playlist after authentication. It looks like this:
#app.route('/')
def index():
if 'credentials' not in flask.session:
return flask.redirect(flask.url_for('oauth2callback'))
credentials = client.OAuth2Credentials.from_json(flask.session['credentials'])
if credentials.access_token_expired:
return flask.redirect(flask.url_for('oauth2callback'))
else:
http_auth = credentials.authorize(httplib2.Http())
yt_service = discovery.build('youtube', 'v3', http_auth)
playlists_insert_response = yt_service.playlists().insert(
part="snippet,status",
body=dict(
snippet=dict(
title="Test Playlist",
description="A private playlist created with the YouTube API v3"
),
status=dict(
privacyStatus="private"
)
)
).execute()
return playlists_insert_response["id"]
#app.route('/oauth2callback')
def oauth2callback():
flow = client.flow_from_clientsecrets('youtube/client_secret.json',scope='https://www.googleapis.com/auth/youtube',redirect_uri=flask.url_for('oauth2callback', _external=True))
if 'code' not in flask.request.args:
auth_uri = flow.step1_get_authorize_url()
return flask.redirect(auth_uri)
else:
auth_code = flask.request.args.get('code')
credentials = flow.step2_exchange(auth_code)
flask.session['credentials'] = credentials.to_json()
return flask.redirect(flask.url_for('index'))
So in browser I authenticate, accept app's permisions and then I see 500 internal error with ouath2callback URI and code parameter. In the error log I see this:
2015-09-07 10:23:08,319 :Successfully retrieved access token
2015-09-07 10:23:08,330 :Exception on /oauth2callback [GET]
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1687, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1360, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1358, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1344, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/Kraxi/youtube/playlist.py", line 63, in oauth2callback
flask.session['credentials'] = credentials.to_json()
File "/usr/local/lib/python2.7/dist-packages/werkzeug/local.py", line 339, in __setitem__
self._get_current_object()[key] = value
File "/usr/local/lib/python2.7/dist-packages/flask/sessions.py", line 57, in _fail
raise RuntimeError('the session is unavailable because no secret '
RuntimeError: the session is unavailable because no secret key was set. Set the secret_key on the application to something unique and secret.
I tihnk it might be something wrong with Flask session - maybe seassion type?
Using Flask 0.10
Any ideas, please?
In order to use sessions you need to set a SECRET_KEY.
Extracted from the docs:
# set the secret key. keep this really secret:
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'

Python Flask: Getting an 'OperationalError' object is not callable when inserting to database

I'm trying to create a python flask script that will add a row to a database. Here's my code:
main.py:
import json
import sys
from flask import Flask, request
from app.config import DB
from app.items.items import ItemsAPI
from app.users.accounts import AccountsAPI
from app.users.customers import CustomersAPI
app = Flask(__name__)
db = DB()
app.register_blueprint(ItemsAPI)
app.register_blueprint(CustomersAPI)
app.register_blueprint(AccountsAPI)
#app.route('/home')
def hello_world():
return "Welcome to Omnimoda."
#app.route('/dbtest', methods=['GET'])
def hello_database():
q_sql = "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = %s"
a_sql = ("omnimoda",)
test_request = db.query(q_sql, a_sql)
result_request = test_request.fetchall()
if (result_request is None):
return "Database does not exist."
else:
return "Database exists."
if __name__ == '__main__':
app.run(host = '0.0.0.0', debug=True)
customers.py:
from flask import Flask, request, jsonify, json, Blueprint
#from time import mktime
from json import dumps
from datetime import datetime
from app.config import DB
CustomersAPI = Blueprint('CustomersAPI', __name__)
db = DB()
#CustomersAPI.route('/customers/addtest', methods=['POST'])
def add_test():
first_name = request.form['first_name']
last_name = request.form['last_name']
birthdate = request.form['birthdate']
email = request.form['email']
gender = request.form['gender']
occupation = request.form['occupation']
address = request.form['address']
others = request.form['others']
q_add_one = "INSERT INTO `customer_info` (`first_name`, `last_name`, `birthdate`, `init_email`, `gender`, `occupation`, `address`, `others`) VALUES (%s,%s,%s,%s,%s,%s,%s,%s)"
a_add_one = (first_name, last_name, birthdate, email, gender, occupation, address, others)
items_add = db.commit_ret_lastrow(q_add_one, a_add_one)
return items_add
And finally, my config.py:
from flask import Flask
import MySQLdb
class DB:
conn = None
def connect(self):
self.conn = MySQLdb.connect(host="localhost", user="lance", passwd="lance", db="omnimoda")
self.conn.autocommit(True)
def query(self, sql, values):
try:
print values
self.connect()
cursor = self.conn.cursor()
cursor.execute(sql, values)
return cursor
except Exception, e:
return e
def commit_ret_lastrow(self, sql, values):
try:
self.connect()
cursor = self.conn.cursor()
cursor.execute(sql, values)
return cursor.lastrowid
except Exception, e:
return e
Unfortunately, upon testing it in CocoaRestClient, via http://127.0.0.1:5000/customers/addtest:
I get the following unhelpful error:
127.0.0.1 - - [30/Jun/2015 22:04:22] "POST /customers/addtest HTTP/1.1" 500 -
Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/Library/Python/2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/Library/Python/2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Library/Python/2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/Library/Python/2.7/site-packages/flask/app.py", line 1478, in full_dispatch_request
response = self.make_response(rv)
File "/Library/Python/2.7/site-packages/flask/app.py", line 1577, in make_response
rv = self.response_class.force_type(rv, request.environ)
File "/Library/Python/2.7/site-packages/werkzeug/wrappers.py", line 841, in force_type
response = BaseResponse(*_run_wsgi_app(response, environ))
File "/Library/Python/2.7/site-packages/werkzeug/test.py", line 867, in run_wsgi_app
app_iter = app(environ, start_response)
TypeError: 'OperationalError' object is not callable
And I have no idea what's wrong. Can I have some help, please?
The last two lines of your query and commit_ret_lastrow methods don't make any sense. If there's an exception, you catch it, and then return it. So Flask tries to serve it as your actual app, which it obviously can't do.
Drop those lines, and the try/except completely. You shouldn't be catching all exceptions anyway; maybe, if you're sure, you could catch a specific database exception - eg IntegrityError - but usually you should only catch the ones you know that you can deal with. Otherwise, simply let the exception bubble up, and the framework can log or display it.

Categories