Skip to content

Commit abc7551

Browse files
Merge pull request #136 from keshavsingh4522/keshav
flask api with JWT security
2 parents b0df579 + 9454f68 commit abc7551

File tree

2 files changed

+314
-0
lines changed

2 files changed

+314
-0
lines changed

Flask/API/app.py

+263
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
from flask import Flask,jsonify,request
2+
from flask_sqlalchemy import SQLAlchemy
3+
from sqlalchemy import Column,Integer,Float,String
4+
import os
5+
from flask_marshmallow import Marshmallow
6+
from flask_jwt_extended import JWTManager,jwt_required,create_access_token
7+
from flask_mail import Mail,Message
8+
9+
app=Flask(__name__)
10+
basedir = os.path.abspath(os.path.dirname(__file__))
11+
12+
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///'+os.path.join(basedir,"planets.db")
13+
app.config['JWT_SECRET_KEY']='super secret' # chenge this in real life
14+
15+
app.config['MAIL_SERVER']='smtp.mailtrap.io'
16+
app.config['MAIL_PORT'] = 2525
17+
app.config['MAIL_USERNAME'] = ''
18+
# app.config['MAIL_USERNAME'] = os.environ['MAIL_USERNAME']
19+
app.config['MAIL_PASSWORD'] = ''
20+
# app.config['MAIL_PASSWORD'] = os.environ['MAIL_PASSWORD']
21+
app.config['MAIL_USE_TLS'] = True
22+
app.config['MAIL_USE_SSL'] = False
23+
24+
db = SQLAlchemy(app)
25+
ma = Marshmallow(app)
26+
jwt = JWTManager(app)
27+
mail=Mail(app)
28+
29+
# Start
30+
@app.cli.command("db_create")
31+
def db_create():
32+
db.create_all()
33+
print("databse created")
34+
35+
@app.cli.command("db_drop")
36+
def db_drop():
37+
db.drop_all()
38+
print("databse droped")
39+
40+
'''
41+
seeding databse
42+
'''
43+
@app.cli.command("db_seed")
44+
def db_seed():
45+
mercury = Planet(
46+
planet_name='Mercury',
47+
planet_type='Class D',
48+
home_star='Sol',
49+
mass=2.258e23,
50+
radius=1516,
51+
distance=35.98e6)
52+
venus = Planet(
53+
planet_name='Venus',
54+
planet_type='Class K',
55+
home_star='Sol',
56+
mass=4.867e24,
57+
radius=3760,
58+
distance=67.24e6)
59+
earth = Planet(
60+
planet_name='Earth',
61+
planet_type='Class M',
62+
home_star='Sol',
63+
mass=5.972e24,
64+
radius=3959,
65+
distance=92.96e6)
66+
db.session.add(mercury)
67+
db.session.add(venus)
68+
db.session.add(earth)
69+
70+
test_user = User(first_name='William',
71+
last_name='Herschel',
72+
73+
password='P@ssw0rd')
74+
db.session.add(test_user)
75+
db.session.commit()
76+
print("databse seeded!")
77+
78+
# End
79+
80+
81+
82+
@app.route("/",methods=["GET"])
83+
def hello_world():
84+
return jsonify( message ="hi this is looking awesome"),200
85+
86+
@app.route("/<int:id>",methods=["GET"])
87+
def hello(id):
88+
return jsonify(message=f"hi you entered the number is {id}"),400
89+
90+
91+
@app.route("/parameters")
92+
def parameters():
93+
name=request.args.get("name")
94+
age=int(request.args.get("age"))
95+
if age<18:
96+
return jsonify(message="hi "+name+ ', you are not old,hence you are not able to accesss this page'),401
97+
# by default status code is 200 or ok
98+
return jsonify(message="hello "+name+" you are old.")
99+
100+
101+
@app.route("/url_parameter/<string:name>/<int:age>")
102+
# def url_parameter(name,age): same work as below
103+
def url_parameter(name:str,age:int):
104+
if age<18:
105+
return jsonify(message="hi "+name+ ', you are not old,hence you are not able to accesss this page'),401
106+
# by default status code is 200 or ok
107+
return jsonify(message="hello "+name+" you are old.")
108+
109+
110+
111+
##
112+
@app.route("/planets",methods=["GET"])
113+
def planets():
114+
planet_list=Planet.query.all()
115+
result = planets_schema.dump(planet_list)
116+
return jsonify(result)
117+
# return jsonify(data=planet_list)
118+
119+
@app.route("/register",methods=["POST"])
120+
def register():
121+
email=request.form['email']
122+
test=User.query.filter_by(email=email).first()
123+
if test:
124+
return jsonify(message="email is already exist!"),409
125+
126+
first_name=request.form['first_name']
127+
last_name=request.form['last_name']
128+
password=request.form['password']
129+
db.session.add(User(first_name=first_name,last_name=last_name,email=email,password=password))
130+
db.session.commit()
131+
return jsonify(message="user Created Successfully!"),201
132+
133+
134+
@app.route("/login",methods=["POST"])
135+
def login():
136+
# api==json, or form
137+
if request.is_json:
138+
# if user is trying to login via api
139+
email=request.json['email']
140+
password=request.json['password']
141+
else:
142+
# if user is logging via form
143+
email=request.form['email']
144+
password=request.form['password']
145+
test=User.query.filter_by(email=email,password=password).first()
146+
if test:
147+
# create token
148+
access_token=create_access_token(identity=email)
149+
return jsonify(message="login Successfully!",access_token=access_token)
150+
else:
151+
return jsonify(message="bad password or email"),401
152+
153+
154+
@app.route("/retrieve_password/<string:email>",methods=["GET"])
155+
def retrieve_password(email:str):
156+
user = User.query.filter_by(email=email).first()
157+
if user:
158+
msg = Message(
159+
"Your planetry api password is "+user.password,
160+
161+
recipients=[email])
162+
mail.send(msg)
163+
return jsonify(message="password sent to "+email)
164+
else:
165+
return jsonify(message=email+" email doesn't exist!"),401
166+
167+
168+
@app.route("/planet_details/<int:planet_id>",methods=["GET"])
169+
def planet_details(planet_id:int):
170+
planet = Planet.query.filter_by(planet_id=planet_id).first()
171+
if planet:
172+
result = planet_schema.dump(planet)
173+
return jsonify(result)
174+
else:
175+
return jsonify(message="that planet does not exist!"),404
176+
177+
178+
@app.route("/add_planet",methods=["POST"])
179+
@jwt_required()
180+
def add_planet():
181+
planet_name= request.form['planet_name']
182+
planet = Planet.query.filter_by(planet_name=planet_name).first()
183+
if planet:
184+
return jsonify(message="the planet is exists already!"),409
185+
else:
186+
planet_type=request.form['planet_type']
187+
home_star=request.form['home_star']
188+
mass=request.form['mass']
189+
radius=request.form["radius"]
190+
distance=request.form["distance"]
191+
db.session.add(Planet(planet_name=planet_name,planet_type=planet_type,home_star=home_star,mass=mass,radius=radius,distance=distance))
192+
db.session.commit()
193+
return jsonify(message="You added a planet Successfully!"),201
194+
195+
196+
@app.route("/update_planet",methods=["PUT"])
197+
@jwt_required()
198+
def update_planet():
199+
planet_id= request.form['planet_id']
200+
planet = Planet.query.filter_by(planet_id=planet_id).first()
201+
if planet:
202+
planet.planet_name=request.form['planet_name']
203+
planet.planet_type=request.form['planet_type']
204+
planet.home_star=request.form['home_star']
205+
planet.mass=request.form['mass']
206+
planet.radius=request.form["radius"]
207+
planet.distance=request.form["distance"]
208+
db.session.commit()
209+
return jsonify(message="You updated a planet Successfully!"),202
210+
else:
211+
return jsonify(message="the planet does not exists!"),404
212+
213+
214+
215+
@app.route("/remove_planet/<int:planet_id>",methods=["DELETE"])
216+
@jwt_required()
217+
def remove_planet(planet_id:int):
218+
planet = Planet.query.filter_by(planet_id=planet_id).first()
219+
if planet:
220+
db.session.delete(planet)
221+
db.session.commit()
222+
return jsonify(message="You deleted a planet Successfully!"),202
223+
else:
224+
return jsonify(message="the planet does not exists!"),404
225+
226+
# Databse Models
227+
class User(db.Model):
228+
__tablename__="User"
229+
id=Column(Integer,primary_key=True)
230+
first_name=Column(String)
231+
last_name=Column(String)
232+
email=Column(String,unique=True)
233+
password=Column(String)
234+
235+
class Planet(db.Model):
236+
planet_id = Column(Integer,primary_key=True)
237+
planet_type=Column(String)
238+
planet_name=Column(String)
239+
home_star=Column(String)
240+
mass=Column(Float)
241+
radius=Column(Float)
242+
distance=Column(Float)
243+
244+
class UserSchema(ma.Schema):
245+
class Meta:
246+
fields=("id","first_name","last_name","email","password")
247+
248+
class PlanetSchema(ma.Schema):
249+
class Meta:
250+
fields=("planet_id","planet_type","planet_name","home_star","mass","radius","distance")
251+
252+
user_schema = UserSchema()
253+
users_schema = UserSchema(many=True)
254+
255+
planet_schema = PlanetSchema()
256+
planets_schema = PlanetSchema(many=True)
257+
258+
259+
260+
261+
262+
if __name__=="__main__":
263+
app.run(debug=True)

Flask/API/readme.md

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
```python
2+
from flask import Flask,jsonify,request
3+
```
4+
- return result as in form of json
5+
```py
6+
return jsonify(message="great work",name="_name_here_")
7+
```
8+
- by default status code is 200 ok, above code will work same as below
9+
```py
10+
return jsonify(message="great work",name="_name_here_"),200
11+
```
12+
- catch the data wwhich is passed along with url
13+
```py
14+
app.route("/parameters")
15+
def parameters():
16+
name=request.args.get("name")
17+
age=int(request.args.get("age"))
18+
if age<18:
19+
return jsonify(message="hi "+name+ ', you are not old,hence you are not able to accesss this page'),401
20+
# by default status code is 200 or ok
21+
return jsonify(message="hello "+name+" you are old.")
22+
```
23+
- url parameters
24+
```py
25+
@app.route("/url_parameter/<string:name>/<int:age>")
26+
# def url_parameter(name,age): same work as below
27+
def url_parameter(name:str,age:int):
28+
if age<18:
29+
return jsonify(message="hi "+name+ ', you are not old,hence you are not able to accesss this page'),401
30+
# by default status code is 200 or ok
31+
return jsonify(message="hello "+name+" you are old.")
32+
```
33+
- [Flask + marshmallow for beautiful APIs(if jsonify will not work then use one more this)](https://flask-marshmallow.readthedocs.io/en/latest/)
34+
```py
35+
36+
```
37+
38+
## Securing your web api with JWT(JSON Web Tokens)
39+
```py
40+
- pip3 install Flask-Login
41+
- pip3 install Flask-User # role based
42+
43+
--- i used below
44+
pip3 install flask-jwt-extended
45+
46+
```
47+
-- for mail
48+
```py
49+
pip3 install Flask-Mail
50+
51+
```

0 commit comments

Comments
 (0)