Flask Extensions

Flask core functionality includes WSGI(Suggest to use bjoern)
Routing(URL rules) based on Werkzeug
Template engine based on Jinja2
support cookie、sessions、web helpers like JSON, static files etc
and other extensions.

pip install <Flask-Ext>

#import Flask extensions(Flask 0.8 and after):
from flask.ext import foo

Some ext introducing:

Flask-Admin: admin interface framework
Flask-Babel: Adds i18n/l10n support to Flask applications
Flask-Bcrypt: bcrypt hashing(password) utilities
Flask-Blogging: Markdown blog support
Flask-Cache: cache support
Flask-Captain: Handle webhooks with Flask

Flask-CDN:
Serve the static files in your Flask app from a CDN
Flask-FileUpload: easy file upload and management
Flask-Gravatar: integration gravatar
Flask-Login: User session management
Flask-Locale: i18n/l10n support(CSV or db)
Flask-Mail: sending email
Flask-PageDown: StackOverflow's "PageDown" markdown editor for Flask-WTF
Flask-Principal: Identity management
Flask-Script: Scripting support
Flask-Security: security features
Flask-SQLAlchemy: SQLAlchemy support
Flask-Themes: infrastructure for theming Flask ap
Flask-Uploads: upload handling
Flask-User: Customizable User Account Management
Flask-WTF: Simple integration of Flask and WTForms

Flask-API: Browsable web APIs
Flask-Assets: to compress and merge CSS and Javascript files
Flask-RESTful: framework for creating REST APIs
Flask-Sijax: Sijax interface - Python/jQuery library for AJAX


==

#Before Flask 0.8 need activated compatibility module first
download
flaskext_compat:
https://github.com/McStasMcXtrace/McCode/blob/master/tools/Python/www/www-flask/flaskext_compat.py

import flaskext_compat
flaskext_compat.activate()
from flask.ext import foo



Flask File Uploading

an HTML form with its enctype attribute set to 'multipart/form-data'
request.files[]: fetches file and saves it to the desired location
secure_filename(): read the file name with a more secure method

app.config[‘UPLOAD_FOLDER’]: Defines path for upload folder
app.config[‘MAX_CONTENT_LENGTH’]: Specifies maximum size of file yo be uploaded – in bytes

example:

mkdir uploadfd

vi templates/upload.html

<html>
  <body>

    <form action = "/uploadfd" method = "POST"
      enctype = "multipart/form-data">
      <input type = "file" name = "file" />
      <input type = "submit" value="upload"/>
    </form>

  </body>
</html>

vi upload.py
from flask import Flask, render_template, request
from werkzeug import secure_filename
ap = Flask(__name__)

@ap.route('/upload')
def upload():
  return render_template('upload.html')

@ap.route('/uploadfd', methods = ['GET', 'POST'])
def upload_file():
  if request.method == 'POST':
    f = request.files['file']
    f.save('uploadfd/' + secure_filename(f.filename))
    return 'file uploaded successfully'

if __name__ == '__main__':
  ap.run(host='0.0.0.0')

python upload.py

#opengttp://<ip/url>:5000/upload

secure_filename can't save not ASCII file name, must do some modify,
but how to do?...



Flask Message Flashing

flash(): to pass a message to the next request, which generally is a template

flash(message, category)

message: The actual message you want to be flashed.
category: 'message'、'info'、'warning' or '
error', optional.

get_flashed_messages(): to remove(take out) message from session

get_flashed_messages(with_categories, category_filter):

with_categories: a tuple if received messages are having category,
optional
category_filter: to display only specific messages,
optional

a template block of a flashes received message:
{% with messages = get_flashed_messages() %}
   {% if messages %}
      {% for message in messages %}
         {{ message }}
      {% endfor %}
   {% endif %}
{% endwith %}

example:

vi templates/flash.html

<!doctype html>
<html>

  <head>
    <title>Flask Message flashing</title>
  </head>

  <body>

    <h2>Flask Message Flashing below</h2>

    {% with messages = get_flashed_messages() %}
      {% if messages %}
        <ul>
          {% for message in messages %}
          <li>{{ message }}</li>
          {% endfor %}
        </ul>
      {% endif %}
    {% endwith %}

    <h2>Flask Message Flashing above</h2>


    <p>Do you want to <a href = "{{ url_for('login') }}">
      <b>log in?</b></a></p>

  </body>
</html>
vi templates/flash_login.html
<!doctype html>
<html>
  <body>

    <h1>Login</h1>

    {% if error %}
    <p><strong>Error:</strong> {{ error }}
    {% endif %}

    <form action = "/flash_login" method = "post">
      <dl>
        <dt>Username:</dt>
        <dd>
          <input type = "text" name = "username"
            value = "{{request.form.username }}">
        </dd>

        <dt>Password:</dt>
        <dd><input type = "password" name = "password"></dd>
      </dl>
     
      <p><input type = "submit" value = "Login"></p>
     
    </form>

  </body>
</html>

vi flash.py
from flask import Flask, redirect, render_template, request, url_for, flash
ap = Flask(__name__)
ap.secret_key = '<random string>'

@ap.route('/flash')
def flashing():
   return render_template('flash.html')

@ap.route('/flash_login', methods = ['GET', 'POST'])
def login():
   error = None

   if request.method == 'POST':
      if (request.form['username'] != 'admin' or
          request.form['password'] != 'admin'
         ):
         error = 'Invalid username or password. Please try again!'
      else:
         flash('Hi, Admin!')
         return redirect(url_for('flashing'))

   return render_template('flash_login.html', error = error)

if __name__ == "__main__":
   ap.run(host='0.0.0.0')

python flash.py

#open http://<ip/url>:5000/flash



Flask Redirect & Errors

redirect(): returns a response object and
  redirects the user to another target location with specified status code
  (must import redirect from flask)

redirect(location, statuscode, response)

location: URL be redirected
statuscode: default is 302
response: used to instantiate response

standardized status code−
    HTTP_300_MULTIPLE_CHOICES
    HTTP_301_MOVED_PERMANENTLY
    HTTP_302_FOUND
    HTTP_303_SEE_OTHER
    HTTP_304_NOT_MODIFIED
    HTTP_305_USE_PROXY
    HTTP_306_RESERVED
    HTTP_307_TEMPORARY_REDIRECT

example1:

vi templates/login2.html
<html>
  <body>

    <form action = "/check" method = "POST">

      <p>User Name <input type = "text" name = "Name"/></p>
      <p><input type = "submit" value = "Login"/></p>

    </form>

  </body>
</html>
vi login2.py
from flask import Flask, redirect, url_for, render_template, request

ap = Flask(__name__)

@ap.route('/login')
def login():
  return render_template('login2.html')

@ap.route('/check', methods = ['POST', 'GET'])
def check():

  if request.method == 'POST' and request.form['Name'] == 'admin':
    return redirect(url_for('success'))

  return redirect(url_for('login'), 301) #care this line when you login fail

@ap.route('/success')
def success():
  return 'logged in successfully'

if __name__ == '__main__':
  ap.run(host='0.0.0.0')
python login2.py

Error: error code in abort()
(must import abort from flask)

abort(code)

Code parameter values-
    400 − for Bad Request
    401 − for Unauthenticated
    403 − for Forbidden
    404 − for Not Found
    406 − for Not Acceptable
    415 − for Unsupported Media Type
    429 − Too Many Requests

example2:

#to modify login2.py
cp login2.py login2_2.py
vi
login2_2.py
from flask import Flask, redirect, url_for, render_template, request, abort #add abort

@ap.route('/check', methods = ['POST', 'GET'])
def check():

   if request.method == 'POST':
      if request.form['Name'] == 'admin' :
         return redirect(url_for('success'))
      else: #care the else statement
         abort(401)

   return redirect(url_for('login'), 301)
python login2_2.py


Flask Sessions

Session: a dictionary object containing session variables and associated values stored on server.
it's a time interval from login until logout


Session ID: stored in top of cookie
secret_key: to encrypt the session id
session.pop(): to cancel a session id

example:

vi templates/sessionlogin.html

<form action = "" method = "POST">
  <p><input type = "text" name = "username"/></p>
  <p<<input type = "submit" value = "Login"/></p>
</form>


vi session.py
from flask import Flask, session, redirect, url_for, escape, request, render_template
ap = Flask(__name__)


@ap.route('/sessions')

def sessions():
   if 'username' in session:
      username = session['username']
      return 'Logged in as ' + username + '<br>' + \
         "<b><a href = '/logout'>click here to log out</a></b>"
   return "You are not logged in <br><a href = '/login'></b>" + \
      "click here to log in</b></a>"

@ap.route('/login', methods = ['GET', 'POST'])
def login():
   if request.method == 'POST':
      session['username'] = request.form['username']
      return redirect(url_for('sessions'))
   return
render_template("sessionlogin.html")
     
@ap.route('/logout')
def logout():
   # remove the username from the session if it is there
   session.pop('username', None)
   return redirect(url_for('sessions'))

ap.secret_key = '<input any string>'

if __name__ == '__main__':
   ap.run(host= '0.0.0.0')

python session.py

#open http://<ip/url>:5000/sessions

==

Common Flask Errors And Their Solutions:
https://www.jjude.com/flask-errors/


Flask Request Object III - Cookies

Cookies:

def setcookie(): define a cookie created and stored function
make_response(): get response object from return value of a view function
set(): from response object to store a cookie

def getcookie(): define a read cookie function
get(): from request.cookies to read a cookie

example:

vi templates/cookie.html

<html>
   <body>
     
<!--
         <form action = "http://<ip/url>/setcookie" method = "POST">
      -->
      <form action = "/setcookie" method = "POST">
         <p><h3>Enter
User Name</h3></p>
         <p><input type = 'text' name = 'Name'/></p>
         <p><input type = 'submit' value = 'Login'/></p>
      </form>

   </body>
</html>
vi cookie.py
from flask import Flask, render_template, request, make_response
ap = Flask(__name__)

@ap.route('/')
def cookie():
   return render_template('cookie.html')

@ap.route('/setcookie', methods = ['POST', 'GET'])
def setcookie():
   if request.method == 'POST':
       user = request.form['Name']

   resp = make_response(render_template('readcookie.html'))
   resp.set_cookie('UserName', user)

   return resp

@ap.route('/getcookie')
def getcookie():
   name = request.cookies.get('
UserName')
   return '<h1>Hello '+name+'</h1>'

if __name__ == '__main__':
   ap.run(host= '0.0.0.0')
vi templates/readcookie.html
<html>
  <body>

    <a href="http://<ip/url>:5000/getcookie">Enter</a>
   
<!--
     
<a href="/getcookie">Enter</a>
     -->
  </body>
</html>
python cookie.py

#open http://<ip/url>:5000


Flask Request Object II - Form

Form:

example:

vi templates/record.html

<!doctype html>
<html>
  <body>
    <table border = 1>
      {% for key, value in input.iteritems() %}

        <tr>
          <th> {{ key }} </th>
          <td> {{ value }} </td>
        </tr>

      {% endfor %}
    </table>

  </body>
</html>
vi templates/friend.html
<html>
  <body>

    <form action = "http://<ip/url>:5000/record" method = "POST">
       <p>Name <input type = "text" name = "name" /></p>
       <p>Age <input type = "text" name = "age" /></p>
       <p>Higher <input type = "text" name = "higher" /></p>
       <p>Weight <input type ="text" name = "weight" /></p>
       <p><input type = "submit" value = "submit" /></p>
    </form>

  </body>
</html>
vi friend_rec.py
from flask import Flask, render_template, request
ap = Flask(__name__)

@ap.route('/')
def friend():
  return render_template('friend.html')

@ap.route('/record',methods = ['POST', 'GET'])
def record():
  if request.method == 'POST':
    input = request.form
    return render_template("record.html",input = input)

if __name__ == '__main__':
  ap.run(host= '0.0.0.0')
python friend_rec.py

#open
http://<ip/url>:5000


Flask Template II - Static Files

#mkdir static file dir and store static files in it
mkdir
static

vi static/hello2.js

function sayHello() {
  alert("Hello. :)")
}
vi templates/hello2.html
<html>
  <head>
    <script type = "text/javascript"
       src = "{{ url_for('static', filename = 'hello2.js') }}" ></script>
  </head>

  <body>
    <input type = "button" onclick = "sayHello()" value = "Say: Hello" />
  </body>
</html>
vi hello2.py
from flask import Flask, render_template
ap = Flask(__name__)

@ap.route("/hello")
def index():
  return render_template("hello2.html")

if __name__ == '__main__':
  ap.run(host='0.0.0.0')



Flask Template I - Jinga2

pwd

#you should here
/home/pyenv/versions/2.7.13/envs/flask_test

mkdir templates

example1:

vi templates/hello.html

<!doctype html>
<html>
   <body>

      <h1>Hello,{{ name }}!</h1>

   </body>
</html>
vi hello.py
from flask import Flask, render_template
ap = Flask(__name__)

@ap.route('/<who>')
def hello(who):
   return render_template('hello.html', name=who)

if __name__ == '__main__':
   ap.run(host = '0.0.0.0')
python hello.py

example2:

vi templates/allpeople.html
<!doctype html>
<html>
  <body>
    <table border = 1>
        {% for key, value in people.iteritems() %}
        
            <tr>
               <th> {{ key }} </th>
               <td> {{ value }} </td>
            </tr>
           
        {% endfor %}
    </table>
  </body>
</html>
vi allpeople.py
from flask import Flask, render_template
ap = Flask(__name__)

@ap.route('/allpeople')
def result():
   dict = {'phoebe':1,'range':2}
   return render_template('allpeople.html', people = dict)

if __name__ == '__main__':
   ap.run(host = '0.0.0.0')

python allpeople.py

#now, let's modify our previous example at Http mothods

cp login.html templates/
cp login.py login1.py


vi hello1.py

#must remember import render_template from flask
#add below into file under @app.route('/login', methods = ['POST', 'GET'])
@app.route('/')
def who():
    return render_template('login.html')
python hello1.py

#open browser with http://<ip/url>:5000


===


Jinga2 delimiters:


1.{{ Expressions to print to the template output }}

  variable、python basic type、op expression、filter(|)&tester(is)、string connector(~)、inline express(if)
  Escaping(ignore templates syntax): {{ '{{' }}

2.{% Statements %}
  2.1.
    {% if ... %}
      ...
    {% elif ... %}
      ...
    {% else %}
      ...
    {% endif %}

  2.2.
    {% for ... %}
      ...
    (% endfor %)

  2.3.
Escaping(ignore templates syntax)
    {% raw %}
      ...
    {% endraw %}

  2.4.
Escaping(ignore html syntax)
    {% autoescape false %}
      ...
    {% endautoescape $}


  2.5.assignment
    {% set <var> = <value> %}

  space control: {%+ %}、{% -%}、{%- -%}


3.# Statements
  # for ...
    ...
  # endfor

4.Comments not included in the template output
  4.1.
    {# ...
      ...
    #}

  4.2.
    ## comment

Template Designer Documentation:
http://jinja.pocoo.org/docs/2.10/templates/



Flask Request Object I - method

Client send the data to server as a global request object(must import request from FLASK)

some important attributes are below:
method − current request method
Form − dictionary object form parameters and their values
Cookies − dictionary object holding Cookie names and values
files − data pertaining to uploaded file
args − parsed contents of query string which is part of URL after a ? charter

method:

GET: get the information stored on that page and send it
HEAD: get only interested in the headers, not the content of the page
POST: post information to that URL and that the server must ensure the data is stored and only stored once
PUT: server might trigger the store procedure multiple times by overwriting the old values more than once
PATCH: used to update partial resources(e.g. update one field)
DELETE: remove the information from the given location
OPTIONS: provides a quick way for a client to figure out which methods are supported by this URL

In HTML4 and XHTML1, the only methods a form can submit to the server are GET and POST,
but with JavaScript and future HTML standards you can use the other methods as well.

example:

login.html

<html>
  <body>
    <form action = "http://<ip/url>:5000/login" method = "post">

      <p>Enter Name:</p>
      <p><input type = "text" name = "nm" /></p>
      <p><input type = "submit" value = "submit" /></p>

    </form>
  </body>

</html>
login.py
from flask import Flask, redirect, url_for, request
app = Flask(__name__)

@app.route('/success/<
name_input>')
def success(
name_input):
    return 'Welcome %s.' %
name_input

@app.route('/login', methods = ['POST', 'GET'])
def login():
    if request.method == 'POST':
       user = request.form['nm']
       return redirect(url_for('success', name_input=user))
    else:
       user = request.args.get('nm')
       return redirect(url_for('success',
name_input=user))

if __name__ == '__main__':
    app.run(host='0.0.0.0')
python login.py

#use your browser open the login.html(must use general http since it's a text file with no route)
#or maybe save it at client and open it at local


Flask Blueprint(views)

Func style:

    templates/
        home/
        control_panel/
        admin/

    views/
        __init__.py
        home.py
        control_panel.py
        admin.py

Zone Style:

    admin/
        __init__.py
        views.py
        static/
        templates/

    home/
        __init__.py
        views.py
        static/
        templates/

    control_panel/
        __init__.py
        views.py
        static/
        templates/

Example:

ap/views/profile.py

from flask import Blueprint, render_template
profile = Blueprint('profile', __name__,
                    template_folder='templates', #Blueprint with self template
                    static_folder='static') #Blueprint with self static

@profile.route('/<user_url>')
def timeline(user_url):
    ...
    return render_template('profile/timeline.html')

@profile.route('/<user_url>/photos')
def photos(user_url):
    ...
    return render_template('profile/photos.html')

@profile.route('/<user_url>/about')
def about(user_url):
    ...
    return render_template('profile/about.html')

ap/__init__.py

from flask import Flask
from .views.profile import profile

app = Flask(__name__)
app.register_blueprint(profile)

Dynamic Url Prefix

instance:

ap/views/profile.py

from flask import Blueprint, render_template
profile = Blueprint('profile', __name__, url_prefix='/<user_url>')

register:

ap/__init__.py

from flask import Flask
from .views.profile import profile

app = Flask(__name__)
app.register_blueprint(profile, url_prefix='/<user_url>')


example:

ap/views/profile.py

from flask import Blueprint, render_template, g
from ..models import User

# The prefix is defined in ap/__init__.py.
profile = Blueprint('profile', __name__)

@profile.url_value_preprocessor
def get_profile_owner(endpoint, values):
    query = User.query.filter_by(url=values.pop('user_url'))
    g.profile_owner = query.first_or_404()

@profile.route('/')
def timeline():
    return render_template('profile/timeline.html')

@profile.route('/photos')
def photos():
    return render_template('profile/photos.html')

@profile.route('/about')
def about():
    return render_template('profile/about.html')

Dynamic SubDomain

ap.com:

ap/__init__.py

from flask import Flask
from .site import site

app = Flask(__name__)
app.register_blueprint(site, subdomain='<site_subdomain>')

subdn.ap.com:

ap/site1/__init__.py

from flask import Blueprint
from ..models import Site

# Site is module, site is Blueprint
site = Blueprint('site', __name__)

@site.url_value_preprocessor
def get_site(endpoint, values):
    query = Site.query.filter_by(subdomain=values.pop('site_subdn'))
    g.site = query.first_or_404()

#View module need import 'site', so def site before import views.
from . import views

#modify var SERVER_NAME
config.py

SERVER_NAME = 'ap.com'

 



Flask dir config

<pyenv / dir>

    requirements.txt

pip install <pkg> >> requirements.txt

    main.py

from flask import Flask
app = Flask(__name__)

    config.py

app.config.from_object('config')

    instance/config.py

app = Flask(__name__, instance_relative_config=True)
app.config.from_pyfile('config.py')

 #SECRET_KEY in onfig.py

    SECRET_KEY =
    STRIPE_API_KEY =
    SQLALCHEMY_DATABASE_URI=

    ap_home/

                  __init__.py
                  models.py
                  views.py
                  templates/
                  static/ 

    config/<configname>.py

 app.config.from_envvar(‘ap_config_file’) #abs path of config file

#start ap from hosting
start.sh
ap_config_file=/<path>/<configname>.py
python main.py


Flask Route

service firewalld status
#if Firewalld not running
service firewalld start
firewall-cmd --zone=public --permanent --add-port=5000/tcp
firewall-cmd --zone=public --list-all

#mkdir <flask_root> and into flask_root dir
mkdir /home/pyenv/versions/2.7.13/envs/flask_test
cd
/home/pyenv/versions/2.7.13/envs/flask_test
pyenv activate

#pip upgrade all pkg/moule
pip list -o | awk '{ print $1 }' | xargs pip install -U

pip install flask

#mkdir <ap_dir> for flask web use then into ap dir
mkdir www
cd www

vi hello.py

from flask import Flask
app = Flask(__name__)

@app.route("/")
def index():
     return "It's Flask!"

@app.route("/<name>")
def hello(name):
     return "Hello, %s! :)" %name

if __name__ == "__main__":
    app.run(host='0.0.0.0')

python hello.py

#Open web browser with http://<ip>:5000

===

1.
@app.route('<route>', options)
def func():
    ....

above is the same as below

def func():
    ....
app.add_url_rule('<route>', 'func', func, options)

2.
@app.route("/xxx/") -> <url>/xxx == <url>/xxx/ (like to a dir)
@app.route("/xxx") -> <url>/xxx/ -> 404 Not Found (like to a file)

3.
@app
.route('/<name>')
@app
.route('/<path/<int:var>') #type(var) == type(int)
@app
.route('/hello/<float:var>') #type(var) == type(float)

The variable rules of route():
http://flask.pocoo.org/docs/0.12/quickstart/#variable-rules

4.
url_for():

from flask import Flask, redirect, url_for

#static route(url path):

app.route('/admin')
def
hello_admin():

   
return 'Hello, Admin.'


@app
.route('/<guest>')

def
hello_guest(guest):

   
return 'Hello,
%s.' % guest

#dynamic route(url path):

app.route('/user/<name>')
def
hello(name):
   
if name =='admin':
       
return redirect(url_for('hello_admin.'))
   
else:
       
return redirect(url_for('hello_guest', guest=name)) #using keyword assign parameter into func()

5.
app.run(host, port, debug, **options)

The options of run():
http://werkzeug.pocoo.org/docs/0.14/serving/#werkzeug.serving.run_simple



pyenv on RHEL/CentOS 7

git clone https://github.com/yyuu/pyenv.git /home/pyenv
git clone https://github.com/yyuu/pyenv-virtualenv.git /home/pyenv/plugins/pyenv-virtualenv

vi ~/.bashrc

alias ...
##
#pyenv
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
##
source ...

source ~/.bashrc

yum install readline readline-devel readline-static -y
yum install openssl openssl-devel openssl-static -y
yum install sqlite-devel -y
yum install bzip2-devel bzip2-libs -y

cd /home/pyenv/versions
pyenv versions
pyenv install 2.7.13
pyenv versions
pyenv rehash
pyenv virtualenv 2.7.13 <vdir>
pyenv virtualenvs

#pyenv global, pyenv local, pyenv shell

cd <vdir>
pyenv activate
pyenv deactivate



I would like to learn to code

 Since I am a third-rate U*ix system admin,

I would like to try to trace Fabric code.

but where to start?

 you can read all the code on github at https://github.com/fabric/fabric.

ok...I try to start from any file of them.




Copyright(c) 2017 - PythonBlogs.com
By using this website, you signify your acceptance of Terms and Conditions and Privacy Policy
All rights reserved