Flask
Flask: (web development, one drop at a time)
- microframework
- minimal features
- minimal code
Why Choose Flask:
- clean and simple: small app in a single python file
- un-opinionated: flexible, choose the components you need
- well-documented
- popular
Included with Flask:
- Jinja 2 - Templates
- Werkzeug - HTTP & routing
- Development Server and Debugger
- Unit testing support
Install Flask:
=========================================================
flashcards.py
=========================================================
from flask import Flask, render_template, abort, jsonfy, request, redirect, url_for # app object represents as web app
from datetime import datetime
from model import db
app = Flask(__name__) # flask constructor, creates: global flask application object,
# name is special variable which is the python file name
@app.route('/') #decorator called View Function
def welcome():
return 'Welcome to flask'
return render_template('welcome.html', msg='msg from view', name='boss', age=1000)
-------------------------------------------------------------------------------------
@app.route('/card') #connecting database data
def card_view():
card = db[0]
return render_template('card.html', card=card)
-------------------------------------------------------------------------------------
@app.route('/card/<int:index>') # parameter url
def card_view(index):
try:
card = db[index]
return render_template('card.html', card=card, index=index, max_index=len(db)-1)
except IndexError:
abort(404)
-------------------------------------------------------------------------------------
@app.route('/date')
def date():
return 'Page serverd at' + str(datetime.now())
#exercise: pages shows how many time it has visited
counter = 0
@app.route('/count_views')
def count_views():
global counter
counter += 1
return 'Page visited' + str(counter) + 'times'
/static
/flasklogo.png
/templates
/welcome.html Notes:
Running Flask Application: [NO SPACE at all]
=========================================================
# location of module containing our application, enable dev feature like debugging
export FLASK_APP=flashcards.py #for windows, use 'set'
export FLASK_ENV=development #for windows, use 'set'
flask run
python -m flask run # if app is not running by the previous line
# Ctrl + C to stop the server
python # see all app url, open terminal as python interpreter
import flashcards
flashcards.app.url_map
=========================================================- python -m pip install flask
=========================================================
flashcards.py
=========================================================
from flask import Flask, render_template, abort, jsonfy, request, redirect, url_for # app object represents as web app
from datetime import datetime
from model import db
app = Flask(__name__) # flask constructor, creates: global flask application object,
# name is special variable which is the python file name
@app.route('/') #decorator called View Function
def welcome():
return 'Welcome to flask'
return render_template('welcome.html', msg='msg from view', name='boss', age=1000)
-------------------------------------------------------------------------------------
@app.route('/card') #connecting database data
def card_view():
card = db[0]
return render_template('card.html', card=card)
-------------------------------------------------------------------------------------
@app.route('/card/<int:index>') # parameter url
def card_view(index):
try:
card = db[index]
return render_template('card.html', card=card, index=index, max_index=len(db)-1)
except IndexError:
abort(404)
-------------------------------------------------------------------------------------
@app.route('/date')
def date():
return 'Page serverd at' + str(datetime.now())
#exercise: pages shows how many time it has visited
counter = 0
@app.route('/count_views')
def count_views():
global counter
counter += 1
return 'Page visited' + str(counter) + 'times'
/static
/flasklogo.png
/templates
/welcome.html Notes:
- control flow is dictated by incoming HTTP Requests
- a view function is only called if its URL is requested (visited in browser)
Running Flask Application: [NO SPACE at all]
=========================================================
# location of module containing our application, enable dev feature like debugging
export FLASK_APP=flashcards.py #for windows, use 'set'
export FLASK_ENV=development #for windows, use 'set'
flask run
python -m flask run # if app is not running by the previous line
# Ctrl + C to stop the server
python # see all app url, open terminal as python interpreter
import flashcards
flashcards.app.url_map
Jinja templates:
=========================================================
- displaying data to the user
- generating HTML
- calling templates from view
- passing data from view to template
- Jinja variables
- Templates: components that display data to the user
- Jinja templates generate text files: we use it to create HTML
- Templates are text files: with placeholders for variables, and logic: if/for/filters etc
- render_template: first arg is name of the template file. other arguments are data passed to the template context. and template should be in folder /tamplages
Jinja Variable:
- {{ msg }}
- Q {{ card.q }}. Ans {{ card.a }}. #card.html
- <button><a href="/card/{{ index+1 }}">NEXT</a></button> # link of next card
- <a href="{{ url_for('card_view', index= index+1) }}">NEXT</a> best (viewName, params on view method)
- if template. [in view function: max_index=len(db)-1]
<a href="{{ url_for('card_view', index= index+1) }}">Next</a>
{ % else %}
<a href="{{ url_for('card_view', index= 0) }}">Start Over </a>
{ % endif %}
Serving REST API:
flashcards_db.json
[
{"q":"name1", "ans":"10"},
{"q":"name2", "ans":"20"}
]
{% for card in cards %}
<a href="{{ url_for('card_view', index=loop.index0) }}">{{ card.q }}</a>
{% endfor %}
- for template: [in view function: cards=db]
{% for card in cards %}
<a href="{{ url_for('card_view', index=loop.index0) }}">{{ card.q }}</a>
{% endfor %}
=========================================================
Model:
=========================================================
model.py
import json
def load_db():
with open('flashcards_db.json') as f:
return json.load(f)
def save_db():
with open('flashcards_db.json', 'w') as f:
return json.dump(db, f)
db = load_db()
def save_db():
with open('flashcards_db.json', 'w') as f:
return json.dump(db, f)
db = load_db()
Model-Template-View:
Serving REST API:
@app.route('/api/card')
def api_card_list():
return jsonfy(db)
@app.route('/api/card/<int:index>')
def api_card_detail():
try:
return db[index]
except IndexError:
abort(404)
Add new card:
@app.route('/add_card', method=['GET','POST'])
def add_card():
if request.method == 'POST':
card = {"question": request.form['question'], "answer": request.form['answer']}
db.append(card)
return redirect(url_for('card_view', index=len(db)-1))
else:
return render_tempalte('add_card.html')
add_card.html
<form method="post">
<p>Question:<input type="text" name="question"></p>
<p>Answer:<input type="text" name="answer"></p>
<button type="submit"> Create </button>
</form>
def api_card_list():
return jsonfy(db)
@app.route('/api/card/<int:index>')
def api_card_detail():
try:
return db[index]
except IndexError:
abort(404)
Add new card:
@app.route('/add_card', method=['GET','POST'])
def add_card():
if request.method == 'POST':
card = {"question": request.form['question'], "answer": request.form['answer']}
db.append(card)
return redirect(url_for('card_view', index=len(db)-1))
else:
return render_tempalte('add_card.html')
add_card.html
<form method="post">
<p>Question:<input type="text" name="question"></p>
<p>Answer:<input type="text" name="answer"></p>
<button type="submit"> Create </button>
</form>