API using Python and Flask with JWT Authentication

Packages used

Let’s Start by building API first

from flask import Flask, render_template, request, jsonify, make_response
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
import mysql.connector
from authentication import check_for_token

Moving on to the next part

app = Flask(__name__)app.config['SQLALCHEMY_DATABASE_URI'] = ('mysql://<username>:<password>@<host>/database_name')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

Now in this sections we’ll see how to create model for API.

db = SQLAlchemy(app)
ma = Marshmallow(app)
class upload_file(db.Model):
id = db.Column(db.Integer, primary_key = True, nullable = False)
description = db.Column(db.String(200), unique = True, nullable = False)
file = db.Column(db.LargeBinary(length = 4294967295), nullable = False)
def __init__(self, description, file):
self.description = description
self.file = file
class upload_schema(ma.SQLAlchemyAutoSchema):
class Meta:
model = upload_file
db.create_all()

Now we provide route

@app.route('/')
@check_for_token
def index():
return render_template('index.html')
@app.route('/upload', methods = ['POST'])
def upload():
description = request.form.get('description')
file = request.files['inputFile']
new_file = upload_file(description = description, file= file.read())
db.session.add(new_file)
db.session.commit()
return 'file ' +file.filename+ ' uploaded successfully'
if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>File Upload</title>
</head>
<body>
<form
style="display: flex; flex-direction: column; width: 20%;"
method="POST"
action="/upload"
enctype="multipart/form-data"
>
<input type="file" name="inputFile" />
<textarea
placeholder=""
name="description"
rows="4"
col="1"
placeholder="description..."
></textarea>
<button type="submit">Submit</button>
</form>
</body>
</html>

JWT Authentication

from flask import Flask, jsonify, request, make_response
from functools import wraps
import jwt
import datetime
app = Flask(__name__)
app.config['SECRET_KEY'] = 'thisissecret'
def check_for_token(f):
@wraps(f)
def decorated(*args, **kwargs):
token = request.args.get('token')
if not token:
return jsonify({'message' : 'Token missing'}), 403
try:
data = jwt.decode(token, app.config['SECRET_KEY'])
except:
return jsonify({'message' : 'Invalid token'}), 403
return f(*args, **kwargs)
return decorated
@app.route('/login')
def login():
auth = request.authorization
if auth and auth.password == 'password':
token = jwt.encode({'user' : auth.username, 'exp' : datetime.datetime.utcnow() + datetime.timedelta(minutes=20)}, app.config['SECRET_KEY'])
return jsonify({'token' : token.decode('UTF-8')})
else:
return make_response('Unable to verify'), 403
if __name__ == '__main__':
app.run(debug=True)

Demo

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store