I have a issue about execute in python flask - python

I am new in build python api. I want to get the data depend on date.
https://programminghistorian.org/en/lessons/creating-apis-with-python-and-flask#what-is-an-api
I am following this link to code my api but I don't know what can I do in execute.
This is my python code:
# -*- coding: utf-8 -*-
from flask import Flask, render_template, request
from flask_mysqldb import MySQL
app = Flask(__name__)
app.config["DEBUG"] = True
app.config['MYSQL_HOST'] = 'localhost'
app.config['MYSQL_USER'] = 'root'
app.config['MYSQL_PASSWORD'] = 'root'
app.config['MYSQL_DB'] = 'MyDB'
app.config['MYSQL_charset'] ='utf8'
mysql = MySQL(app)
#app.route('/',methods = ['GET','POST'])
def index():
if request.method == "POST":
details = request.form
firstday = details['firstday']
lastday = details['lastday']
cur = mysql.connection.cursor()
cur.execute("select * from transaction join transaction_item on transaction.id = transaction_item.transaction_id join customer on customer.id = transaction.customer_id where transaction_datetime <= lastday and transaction_datetime >= firstday VALUES (%s, %s)", (firstday, lastday))
mysql.connection.commit()
cur.close()
return 'success'
return render_template('index.html')
if __name__ == '__main__':
app.run()
This is my HTML code:
<HTML>
<BODY bgcolor="cyan">
<form method="POST" action="">
<center>
<H1>Enter your details </H1> <br>
first_transaction_datetime <input type = "text" name= "firstday" /> <br>
last_transaction_datetime <input type = "text" name= "lastday" /> <br>
<input type = "submit">
</center>
</form>
</BODY>
</HTML>

When you are sending requests to a back-end it does not fill out the form an easy way to do it would be to add the query values in the URL
http://127.0.0.1:5000/?firstName=<firstName>&lastName=<lastName>
then your python code would look something like this.
#app.route('/',methods = ['GET','POST'])
def index():
firstName = request.args.get('firstName')
lastName = request.args.get('lastName')
if request.method == "POST":
# Do stuff here

Related

Flask SQLAlchemy Add Images

I want to add into a sqlalchemy database an image where a user uploads one. I tried to do it with this StackOverFlow [post].(Serve image stored in SQLAlchemy LargeBinary column)
Here is the flask code:
from flask import Flask,render_template,request
from flask_sqlalchemy import SQLAlchemy
from base64 import b64encode
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users1.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class Images(db.Model):
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(200))
img = db.Column(db.LargeBinary)
db.create_all()
mylist = []
#app.route('/',methods=['POST','GET'])
def home():
if request.method == 'POST':
img1 = request.files['ab']
imager = Images(name='abc',img=img1)
db.session.add(imager)
db.session.commit()
return render_template('other.html')
#app.route('/allimg',methods=['POST','GET'])
def home1():
mylist1 = Images.query.filter_by(name='abc').all()
event = Images.query.get_or_404(id)
image = b64encode(event.img)
return render_template('new.html',posts=image)
if __name__ == '__main__':
app.run(debug=True)
Other.html
<form action='' method='post' enctype="multipart/form-data">
<button><input type='file' name='ab' id='file-input' multiple></button>
</form>
New.html
<html>
<body>
{%for i in posts%}
<img src="data:;base64,{{ logo }}"/>
{%endfor%}
</body>
</html>
When I go to allimg (The page that I show all images) I get
sqlalchemy.exc.InterfaceError
sqlalchemy.exc.InterfaceError: (sqlite3.InterfaceError) Error binding parameter 0 - probably unsupported type.
[SQL: SELECT images.id AS images_id, images.name AS images_name, images.img AS images_img
FROM images
WHERE images.id = ?]
[parameters: (<built-in function id>,)]
(Background on this error at: https://sqlalche.me/e/14/rvf5)
Please answer.
Thanks.
Serve image stored in SQLAlchemy LargeBinary
column
#app.route('/event/<int:id>/logo')
def event_logo(id):
event = Event.query.get_or_404(id)
image = b64encode(event.logo)
return render_template('event.html', event=event, logo=image)
id in this context is comming in as an int parameter
your passing in id as (<built-in function id>,)
from here https://docs.python.org/3/library/functions.html#id

I want to update a database by loading a file into an already existing field, but an error occurs

My code:
from flask import Flask, render_template, url_for, request, redirect, send_file
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
from io import BytesIO
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///filestorage.db'
db = SQLAlchemy(app)
class FileContents(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(300))
date = db.Column(db.String(300), default=datetime.utcnow)
content = db.Column(db.LargeBinary)
def __repr__(self):
return '<File %r>' % self.id
#app.route('/')
def index():
files = FileContents.query.filter(FileContents.content == None).all()
return render_template('index.html', files=files)
#app.route('/upload/<int:id>', methods=['GET','POST'])
def upload(id):
file = FileContents.query.get_or_404(id)
if request.method == 'POST':
file.content = request.files['content']
db.session.commit()
return redirect('/')
if __name__ == "__main__":
app.run(debug=True)
Html:
<form action="/upload/{{file.id}}" method="POST" enctype="multipart/form-data">
<input type="file" name="content" id="content" value="{{file.content}}">
<br>
<input type="image" src="static/css/upload.png" name="submit" width="50" height="50" alt="submit"/>
</form>
An error:
sqlalchemy.exc.StatementError
sqlalchemy.exc.StatementError: (builtins.TypeError) memoryview: a bytes-like object is required, not 'FileStorage'
[SQL: UPDATE file_contents SET content=? WHERE file_contents.id = ?]
[parameters: [{'content': <FileStorage: 'randomfile.docx' ('application/vnd.openxmlformats-officedocument.wordprocessingml.document')>, 'file_contents_id': 1}]]
the problem appears to be in this line:
file.content = request.files['content']
Is there any way to pass a "bytes-like object" so that it could be uploaded?
Figured it out! Had to put .read() after the problematic line.
file.content = request.files['content'].read()

Uploading .xlsx file and processing it with .py file when we click submit button and store data to mysql

I am developing program where I can upload excel invoice .xlsx file using Flask and then store that file to mysql when user click submit button. There are total three files involved. getFile.py which is Flask to upload file using index.html. exlTomySQL.py store data to mysql from file received by index.html. I am new to Flask and don't know how to process data after clicking submit button on index.html to process .xlsx file and return response for user.
getFile.py
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
fileDetails = request.form
myFile = fileDetails['myfile']
return myFile
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True)
Index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>File Page</title>
</head>
<body>
<form method="POST" action="">
<label for="myfile">Select a file:</label>
<br>
<input type="file" id="myfile" name="myfile">
<br>
<input type="submit">
</form>
</body>
</html>
exlToSQL.py
import openpyxl
import math
import datetime
import mysql.connector
wb = openpyxl.load_workbook('myFile')
sheet = wb.active
# count rows of data for column 2 as it represent description
def countRows():
count = 0
for i in range(1, 100, 1):
if sheet.cell(row=i, column=2).value != None:
count = i
return count
# list each row description, (not counting quantity), gst amount and last column(total excluding GST)
def readRows():
description = []
# quantity = []
amount = []
gstAmount = []
for i in range(3, countRows() + 1, 1):
description.append(sheet.cell(row=i, column=2).value)
# quantity.append(sheet.cell(row=i, column=5).value)
gstAmount.append(sheet.cell(row=i, column=10).value)
amount.append(sheet.cell(row=i, column=11).value)
uperCaseDescription = [desc.upper()
for desc in description]
return uperCaseDescription, gstAmount, amount
# count all list totals for GST and Amount
def countTotals():
uperCaseDescription, gstAmount, amount = readRows()
totalGST = round(sum(gstAmount), 2)
subTotalAmount = round(sum(amount), 2)
totalAmountOfInvoice = round((totalGST + subTotalAmount), 2)
return totalGST, subTotalAmount, totalAmountOfInvoice
# get static data of invoice e.g. invoice number,
# invoice date, sub total, total gst, total inc gst
print(countRows())
print(countTotals())
invoice_number = sheet.cell(row=1, column=1).value
print("Invoice Number:", invoice_number)
invoice_date = sheet.cell(row=1, column=2).value
print("Invoice Date:", invoice_date)
sun_offset = (invoice_date.weekday() - 6) % 7
weekEnd = invoice_date - datetime.timedelta(days=sun_offset)
print("Week End Date:", weekEnd)
print(readRows())
# merge all list into tuple
def mergeList():
uperCaseDescription, gstAmount, amount = readRows()
mergeTuple = tuple(zip(uperCaseDescription, gstAmount, amount))
return mergeTuple
# MySql connection and transfer data to mysql
mydb = mysql.connector.connect(
host="localhost",
user="root",
password="Vrishab2145",
database="testdbOne"
)
# creating database_cursor to perform SQL operation
mycursor = mydb.cursor()
sqlFormula = "INSERT INTO invoice (description, gstAmount, totalExGst) VALUES (%s,%s,%s)"
mycursor.executemany(sqlFormula, mergeList())
mydb.commit()
You can save the file being uploaded by making some changes in your code as shown below.
Once you have saved the file, you can deal with the file processing to store the data to MySQL. You can also delete the file previously saved once the processing is done.
getFile.py
from flask import Flask, render_template, request
import os
app = Flask(__name__)
app.config["UPLOADS"] = "C:/FlaskSandbox/uploads" # path where uploads are saved. Can also be UNIX path
#app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
userfile = request.files['myfile']
userfile.save(os.path.join(app.config["UPLOADS"], userfile.filename))
print('File Saved!')
# call your file processing functions below
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>File Page</title>
</head>
<body>
<form method="POST" action="" enctype=multipart/form-data>
<label for="myfile">Select a file:</label>
<br>
<input type="file" id="myfile" name="myfile">
<br>
<input type="submit">
</form>
</body>
</html>
Bellow Code working perfectly fine. After spending so many days finally worked out.
from flask import Flask, render_template, request
from werkzeug.utils import secure_filename
import os
import openpyxl
import math
import datetime
import mysql.connector
app = Flask(__name__)
# path where uploads are saved. Can also be UNIX path
app.config["UPLOADS"] = "/Users/vrishabpatel/Desktop/PythonPrep/FlaskApp/uploads"
#app.route('/', methods=['GET', 'POST'])
def index():
mydb = mysql.connector.connect(
host="localhost",
user="root",
password="Vrishab2145",
database="testdbOne"
)
if request.method == 'POST':
userfile = request.files['myfile']
userfile.save(os.path.join(app.config["UPLOADS"], userfile.filename))
print('File Saved!')
# call your file processing functions below
wb = openpyxl.load_workbook(userfile)
sheet = wb.active
mycursor = mydb.cursor()
sqlFormula = "INSERT INTO invoice (description, gstAmount, totalExGst) VALUES (%s,%s,%s)"
mycursor.executemany(sqlFormula, mergeList(sheet))
mycursor.close()
mydb.commit()
return render_template('index.html')
# creating database_cursor to perform SQL operation
# countRows()
# readRows()
# countTotals()
def countRows(sheet):
count = 0
for i in range(1, 100, 1):
if sheet.cell(row=i, column=2).value != None:
count = i
return count
def readRows(sheet):
description = []
# quantity = []
amount = []
gstAmount = []
for i in range(3, countRows(sheet) + 1, 1):
description.append(sheet.cell(row=i, column=2).value)
# quantity.append(sheet.cell(row=i, column=5).value)
gstAmount.append(sheet.cell(row=i, column=10).value)
amount.append(sheet.cell(row=i, column=11).value)
uperCaseDescription = [desc.upper()
for desc in description]
return uperCaseDescription, gstAmount, amount
def countTotals(sheet):
uperCaseDescription, gstAmount, amount = readRows(sheet)
totalGST = round(sum(gstAmount), 2)
subTotalAmount = round(sum(amount), 2)
totalAmountOfInvoice = round((totalGST + subTotalAmount), 2)
return totalGST, subTotalAmount, totalAmountOfInvoice
def mergeList(sheet):
uperCaseDescription, gstAmount, amount = readRows(sheet)
mergeTuple = tuple(zip(uperCaseDescription, gstAmount, amount))
return mergeTuple
if __name__ == "__main__":
app.run(debug=True)

single entry SQL/python

im trying to do a blog post simple app in witch you can write and than edit or delete a post.
I got so far that i can show post but i can not edit them
i did a /edit.html page on witch i would like to have a single blog post and than edit it. The problem is that the post does not appear
app.py
from flask import Flask, render_template, request
from flask_mysqldb import MySQL
import yaml
from flask_bootstrap import Bootstrap
app=Flask(__name__)
bootstrap = Bootstrap(app)
db = yaml.load(open('db.yaml'))
app.config['MYSQL_HOST'] = db['mysql_host']
app.config['MYSQL_USER'] = db['mysql_user']
app.config['MYSQL_PASSWORD'] = db['mysql_password']
app.config['MYSQL_DB'] = db['mysql_db']
mysql = MySQL(app)
#app.route('/', methods=['GET','POST'])
def index():
if request.method == 'POST':
form = request.form
user_name = form['user_name']
besedilo = form['besedilo']
cur = mysql.connection.cursor()
cur.execute("INSERT INTO post(user_name, besedilo) VALUES(%s, %s)", (user_name, besedilo))
mysql.connection.commit()
return render_template('index.html')
#app.route('/post/')
def post():
cur = mysql.connection.cursor()
result_value = cur.execute("SELECT * FROM post")
if result_value > 0:
posts = cur.fetchall()
return render_template('post.html',posts = posts)
#app.route('/edit/<int:id>/', methods=['GET','POST'])
def edit(id):
cur = mysql.connection.cursor()
result_value = cur.execute("SELECT * FROM post WHERE post_id = {}".format(id))
if result_value > 0:
post = cur.fetchone()
return render_template('edit.html', post = post)
## here i would like to single out one entry and show it on
#app.route('/delete/')
def delete():
return render_template('delete.html')
if __name__ == '__main__':
app.run(debug=True)
edit.html
{% extends 'base.html' %}
{% block sub_content %}
<h1>{{post['user_name']}}</h1>
<h1>{{post['besedilo']}}</h1>
{% if posts %}
{% for post in posts %}
<h3> {{edit['title']}}</h3>
{%endfor%}
{% endblock %}
this should show single entry
You may need to pass a properly prepared sql query not dynamic.
Try modifying your view like:
#app.route('/edit/<int:id>/', methods=['GET','POST'])
def edit(id):
cur = mysql.connection.cursor()
query = "SELECT * FROM post WHERE post_id = {}".format(id)
result_value = cur.execute(query)
if result_value > 0:
post = cur.fetchone()
return render_template('edit.html', post = post)
Alternatively;
result_value = cur.execute("SELECT * FROM post WHERE post_id = %s", (id,))

Mysql wont load user data of application

I just copied an application from my local dev env to prod env, and my data is not loading for my flask app instead its showing no blog posts right now...
I've verified the following:
db user has permission to table.
mysql is running
verified query again (works fine)
tried messing with MYSQL_DATABASE_HOST set to localhost and xx.xxx.xxx.xxx to no avail.
verified my import (from flask_mysqldb import MySQL is working fine for mysql) - it is
app.py:
from flask_mysqldb import MySQL
app = Flask(__name__)
app.secret_key = 'mysecret'
# mail server config
app.config['MAIL_SERVER'] = 'mailserver.net'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_USERNAME'] = 'contact#mysite.com'
app.config['MAIL_PASSWORD'] = 'mypass'
# mysql config
app.config['MYSQL_HOST'] = 'localhost'
app.config['MYSQL_PORT'] = '3306'
app.config['MYSQL_DB'] = 'mydb'
app.config['MYSQL_USER'] = 'myusr'
app.config['MYSQL_PASSWORD'] = 'mypass'
mysql = MySQL()
mysql.init_app(app)
c = mysql.connect().cursor()
#app.route('/', methods=('GET', 'POST'))
def email():
form = EmailForm()
c.execute("SELECT post_title, post_name, YEAR(post_date) as YEAR, MONTH(post_date) as MONTH FROM mydb.wp_posts WHERE post_status='publish' ORDER BY RAND() LIMIT 3")
blogposts = c.fetchall()
print(blogposts)
if request.method == 'POST':
if form.validate() == False:
return 'Please fill in all fields <p>Try Again</p>'
else:
msg = Message("Message from your visitor",
sender='contact#mysite.com',
recipients=['contact#mysite.com'])
msg.body = """
From: %s
""" % (form.email.data)
mail.send(msg)
return render_template('email_submit_thankyou.html')
elif request.method == 'GET':
return render_template('index.html', form=form, blogposts=blogposts)
if __name__ == '__main__':
app.run()
templates/index.html contains:
<ul>
{% for blogpost in blogposts %}
<li>{{blogpost[0]}}</li>
{% else %}
<li>no blog posts right now...</li>
{% endfor %}
<div class="clearL"> </div>
</ul>
I found a "slow" query in /var/log/mysql/mysql-slow.log:
# Time: 170101 16:34:32
# User#Host: myuser[myuser] # localhost [127.0.0.1]
# Query_time: 0.004649 Lock_time: 0.001712 Rows_sent: 3 Rows_examined: 53
SET timestamp=1483306472;
SELECT
post_title, post_name, YEAR(post_date) as YEAR, MONTH(post_date) as MONTH
FROM mydb.wp_posts WHERE post_status='publish' ORDER BY RAND() LIMIT 3;
Thus, What is going wrong here?

Categories

Resources