| ページ一覧 | ブログ | twitter |  書式 | 書式(表) |

MyMemoWiki

「Flask」の版間の差分

提供: MyMemoWiki
ナビゲーションに移動 検索に移動
(ページの作成:「==Flask== [Python][Angular] {{amazon|B00XZTYMG6}} *http://flask.pocoo.org/ ==インストール== *http://flask.pocoo.org/docs/0.12/installation/ *Windows , pytho…」)
 
 
(同じ利用者による、間の3版が非表示)
1行目: 1行目:
==Flask==
+
==[[Flask]]==
[Python][Angular]
+
[[Python]] | [[Angular]] |
 
{{amazon|B00XZTYMG6}}
 
{{amazon|B00XZTYMG6}}
 
*http://flask.pocoo.org/
 
*http://flask.pocoo.org/
6行目: 6行目:
 
==インストール==
 
==インストール==
 
*http://flask.pocoo.org/docs/0.12/installation/
 
*http://flask.pocoo.org/docs/0.12/installation/
*Windows , python3
+
*[[Windows]] , python3
  > pythoh -m venv flask
+
  > pythoh -m venv flask
  > cd flask\Scripts
+
  > cd flask\Scripts
  > activate
+
  > activate
  (flask)> pip install Flask
+
  (flask)> pip install [[Flask]]
===Visual Studio Code===
+
===[[Visual Studio Code]]===
 
[[File:0511_flask_vscode_settings.jpg]]
 
[[File:0511_flask_vscode_settings.jpg]]
 
  // 既定の設定とユーザー設定を上書きするには、このファイル内に設定を挿入します
 
  // 既定の設定とユーザー設定を上書きするには、このファイル内に設定を挿入します
22行目: 22行目:
 
  }
 
  }
  
===Git===
+
===[[Git]]===
*Github にリポジトリ作成
+
*[[Git]]hub にリポジトリ作成
 
**https://github.com/pppiroto/flask_sample.git
 
**https://github.com/pppiroto/flask_sample.git
 
=====ローカルリポジトリを初期化=====
 
=====ローカルリポジトリを初期化=====
  > git init
+
  > git init
 
=====ローカルリポジトリにコミット=====
 
=====ローカルリポジトリにコミット=====
  > git add .
+
  > git add .
  > git commit -m "flask lesson init"
+
  > git commit -m "flask lesson init"
  > git branch
+
  > git branch
 
  * master
 
  * master
 
=====リモートリポジトリの設定=====
 
=====リモートリポジトリの設定=====
  > git remote add origin https://github.com/pppiroto/flask_sample.git
+
  > git remote add origin https://github.com/pppiroto/flask_sample.git
 
=====リモートリポジトリにpush=====
 
=====リモートリポジトリにpush=====
  > git push origin master
+
  > git push origin master
 
   
 
   
 
==クイックスタート==
 
==クイックスタート==
 
*http://flask.pocoo.org/docs/0.12/quickstart/
 
*http://flask.pocoo.org/docs/0.12/quickstart/
 
===/hello.py===
 
===/hello.py===
  from flask import Flask
+
  from flask import [[Flask]]
 
   
 
   
  app = Flask(__name__)
+
  app = [[Flask]](__name__)
 
   
 
   
 
  @app.route('/')
 
  @app.route('/')
49行目: 49行目:
  
 
===サーバー起動===
 
===サーバー起動===
*Visual Studio Code、Powershell
+
*[[Visual Studio Code]]、Powershell
  (flask) PS C:\workspaces\vscode\flask_sample> set-item env:FLASK_APP hello.py
+
  (flask) PS C:\workspaces\vscode\flask_sample> set-item env:FLASK_APP hello.py
  (flask) PS C:\workspaces\vscode\flask_sample> python -m flask run
+
  (flask) PS C:\workspaces\vscode\flask_sample> python -m flask run
   * Serving Flask app "hello"
+
   * Serving [[Flask]] app "hello"
   * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
+
   * [[R]]unning on http://127.0.0.1:5000/ (Press CT[[R]]L+C to quit)
 
[[File:0506_flask_run_server.jpg]]
 
[[File:0506_flask_run_server.jpg]]
 
====デバッグモード====
 
====デバッグモード====
  PS> set-item env:FLASK_DEBUG 1
+
  PS> set-item env:FLASK_DEBUG 1
 
===ルーティング===
 
===ルーティング===
  from flask import Flask
+
  from flask import [[Flask]]
 
   
 
   
  app = Flask(__name__)
+
  app = [[Flask]](__name__)
 
   
 
   
 
  @app.route('/')
 
  @app.route('/')
71行目: 71行目:
 
===変数===
 
===変数===
  
  @app.route('/user/<username>/<int:age>')
+
  @app.route('/user/&lt;username&gt;/&lt;int:age&gt;')
 
  def show_user_profile(username, age):
 
  def show_user_profile(username, age):
 
     return 'User {0} {1}'.format(username,age)
 
     return 'User {0} {1}'.format(username,age)
  
=====<コンバーター:変数>=====
+
=====&lt;コンバーター:変数&gt;=====
 
{|class="wikitable"
 
{|class="wikitable"
 
!コンバーター
 
!コンバーター
100行目: 100行目:
 
|}
 
|}
  
===ユニークURL / リダイレクトの振る舞い===
+
===ユニークU[[R]]L / リダイレクトの振る舞い===
 
*FlaskのURLルールは、[http://werkzeug.pocoo.org/ Werkzeug]のルーティングモジュールに基づく
 
*FlaskのURLルールは、[http://werkzeug.pocoo.org/ Werkzeug]のルーティングモジュールに基づく
*このモジュールの背後にあるアイディアは、Apacheなど過去のHTTPサーバーの先例にもとづいた、美しくユニークなURLをを保証すること。
+
*このモジュールの背後にあるアイディアは、[[Apache]]など過去のHTTPサーバーの先例にもとづいた、美しくユニークなURLをを保証すること。
 
  @app.route('/projects/')
 
  @app.route('/projects/')
 
  def projects():
 
  def projects():
111行目: 111行目:
 
     return 'The about page'
 
     return 'The about page'
 
*これらは同じように見えるが、末尾の/の扱いが異なる。
 
*これらは同じように見えるが、末尾の/の扱いが異なる。
*projectsエンドポイントのための正統なURLは末尾に/を伴う。ファイルシステムのフォルダと同様
+
*projectsエンドポイントのための正統なU[[R]]Lは末尾に/を伴う。ファイルシステムのフォルダと同様
*末尾の/がない状態で、アクセスした場合、Flaskは末尾に/がある正統なURLにリダイレクトする
+
*末尾の/がない状態で、アクセスした場合、[[Flask]]は末尾に/がある正統なURLにリダイレクトする
 
*末尾の/ない例は、ファイルシステムのファイルと同様、末尾に/を伴ってアクセスされた場合、404 Not Foundエラーとなる
 
*末尾の/ない例は、ファイルシステムのファイルと同様、末尾に/を伴ってアクセスされた場合、404 Not Foundエラーとなる
===URL 生成===
+
===U[[R]]L 生成===
*url_for()関数は、関数名を最初の、関数の引数を以降の引数としてとり、URLを生成する
+
*url_for()関数は、関数名を最初の、関数の引数を以降の引数としてとり、U[[R]]Lを生成する
  from flask import Flask,url_for
+
  from flask import [[Flask]],url_for
 
   
 
   
  app = Flask(__name__)
+
  app = [[Flask]](__name__)
 
   
 
   
 
  @app.route('/')
 
  @app.route('/')
128行目: 128行目:
 
     return 'Hello world!'
 
     return 'Hello world!'
 
   
 
   
  @app.route('/user/<username>/<int:age>')
+
  @app.route('/user/&lt;username&gt;/&lt;int:age&gt;')
 
  def show_user_profile(username, age):
 
  def show_user_profile(username, age):
 
     return 'User {0} {1}'.format(username,age)
 
     return 'User {0} {1}'.format(username,age)
135行目: 135行目:
 
  def print_urls():
 
  def print_urls():
 
     return '''
 
     return '''
         <ol>
+
         &lt;ol&gt;
         <li>index() = {0}
+
         &lt;li&gt;index() = {0}
         <li>hello_world() = {1}
+
         &lt;li&gt;hello_world() = {1}
         <li>show_user_profile('piroto',46) = {2}
+
         &lt;li&gt;show_user_profile('piroto',46) = {2}
         </ol>
+
         &lt;/ol&gt;
 
     '''.format(
 
     '''.format(
 
         url_for('index'),
 
         url_for('index'),
145行目: 145行目:
 
         url_for('show_user_profile',username='piroto',age=46))
 
         url_for('show_user_profile',username='piroto',age=46))
 
[[File:0510_flask_url_for.jpg]]
 
[[File:0510_flask_url_for.jpg]]
===HTTP メソッド===
+
===[[HTTP]] メソッド===
 
*
 
*
 
  from flask import request
 
  from flask import request
152行目: 152行目:
 
  def method_check():
 
  def method_check():
 
     if request.method == 'GET':
 
     if request.method == 'GET':
         return "HTTP METHOD GET"
+
         return "[[HTTP]] METHOD GET"
     return "HTTP METHOD {0}".format(request.method)
+
     return "[[HTTP]] METHOD {0}".format(request.method)
 
   
 
   
 
===静的ファイル===
 
===静的ファイル===
174行目: 174行目:
  
 
=====テンプレート利用=====
 
=====テンプレート利用=====
  from flask import Flask, render_template
+
  from flask import [[Flask]], render_template
  @app.route('/render_sample/<param>')
+
  @app.route('/render_sample/&lt;param&gt;')
 
  def render_sample(param=None):
 
  def render_sample(param=None):
 
     return render_template('render_sample.html',param=param)
 
     return render_template('render_sample.html',param=param)
 
=====テンプレート=====
 
=====テンプレート=====
  <!doctype html>
+
  &lt;!doctype html&gt;
  <title>Rendering Sample</title>
+
  &lt;title&gt;[[R]]endering Sample&lt;/title&gt;
 
  {% if param %}
 
  {% if param %}
   <h1>Parameter : {{ param }}!</h1>
+
   &lt;h1&gt;Parameter : {{ param }}!&lt;/h1&gt;
 
  {% else %}
 
  {% else %}
   <h1>No parameter found.</h1>
+
   &lt;h1&gt;No parameter found.&lt;/h1&gt;
 
  {% endif %}
 
  {% endif %}
  
198行目: 198行目:
 
*安全と確信できる場合、Markupクラスもしくは、 |safeフィルターを使用する
 
*安全と確信できる場合、Markupクラスもしくは、 |safeフィルターを使用する
 
=====テンプレート=====
 
=====テンプレート=====
  <!doctype html>
+
  &lt;!doctype html&gt;
  <title>Safe Rendering Sample</title>
+
  &lt;title&gt;Safe [[R]]endering Sample&lt;/title&gt;
  <p>{{ param1 }}</p>
+
  &lt;p&gt;{{ param1 }}&lt;/p&gt;
  <p>{{ param2 }}</p>
+
  &lt;p&gt;{{ param2 }}&lt;/p&gt;
  <p>{{ param3 | safe}}</p>
+
  &lt;p&gt;{{ param3 | safe}}&lt;/p&gt;
 
==========
 
==========
 
  from flask import Markup
 
  from flask import Markup
208行目: 208行目:
 
  def render_safe_var(param=None):
 
  def render_safe_var(param=None):
 
     return render_template('render_safe_var.html',  
 
     return render_template('render_safe_var.html',  
         param1="<h2>Sub title</h2>",
+
         param1="&lt;h2&gt;Sub title&lt;/h2&gt;",
         param2=Markup("<h2>Mark up Sub title</h2>"),
+
         param2=Markup("&lt;h2&gt;Mark up Sub title&lt;/h2&gt;"),
         param3="<h2>Safe filtered Sub title</h2>")
+
         param3="&lt;h2&gt;Safe filtered Sub title&lt;/h2&gt;")
 
{{ref_image flask_safe_var.jpg.jpg}}
 
{{ref_image flask_safe_var.jpg.jpg}}
 
===リクエストデータへのアクセス===
 
===リクエストデータへのアクセス===
216行目: 216行目:
 
*context locals により、グローバルオブジェクトをどうやってスレッドセーフにし管理している
 
*context locals により、グローバルオブジェクトをどうやってスレッドセーフにし管理している
 
====Context Locals====
 
====Context Locals====
*Flaskのグローバルオブジェクトは実際には特定コンテキストローカルオブジェクトのプロキシ
+
*[[Flask]]のグローバルオブジェクトは実際には特定コンテキストローカルオブジェクトのプロキシ
==Tips==
+
==[[Tips]]==
 
===Session===
 
===Session===
 
*http://flask.pocoo.org/docs/0.12/quickstart/#sessions
 
*http://flask.pocoo.org/docs/0.12/quickstart/#sessions
  
  from flask import Flask, session
+
  from flask import [[Flask]], session
  app = Flask(__name__, static_folder='app')
+
  app = [[Flask]](__name__, static_folder='app')
 
  app.secret_key = "hoge"
 
  app.secret_key = "hoge"
 
   
 
   
228行目: 228行目:
 
     sessio["foo"] = "bar"
 
     sessio["foo"] = "bar"
  
===CRSF===
+
===C[[R]]SF===
 
*http://flask.pocoo.org/snippets/3/
 
*http://flask.pocoo.org/snippets/3/
 
*[http://typea.info/blg/glob/2018/01/angular-httpclientxsrfmodule-flask-csrf.html Angular + HttpClientXsrfModule + Flask で CSRF]
 
*[http://typea.info/blg/glob/2018/01/angular-httpclientxsrfmodule-flask-csrf.html Angular + HttpClientXsrfModule + Flask で CSRF]
===Cookie===
+
===[[Cookie]]===
 
*http://flask.pocoo.org/snippets/30/
 
*http://flask.pocoo.org/snippets/30/
 
*https://stackoverflow.com/questions/37068604/flask-sessions-where-are-the-cookies-stored
 
*https://stackoverflow.com/questions/37068604/flask-sessions-where-are-the-cookies-stored

2020年2月16日 (日) 04:25時点における最新版

Flask

Python | Angular |

インストール

> pythoh -m venv flask
> cd flask\Scripts
> activate
(flask)> pip install Flask

Visual Studio Code

0511 flask vscode settings.jpg

// 既定の設定とユーザー設定を上書きするには、このファイル内に設定を挿入します
{
    "python.pythonPath": "C:\\workspaces\\venv\\flask\\Scripts\\python",
        "python.autoComplete.extraPaths": [
        "C:\\workspaces\\venv\\flask\\Lib\\site-packages"
    ],
    "python.linting.enabled": false,
}

Git

ローカルリポジトリを初期化
> git init
ローカルリポジトリにコミット
> git add .
> git commit -m "flask lesson init"
> git branch
* master
リモートリポジトリの設定
> git remote add origin https://github.com/pppiroto/flask_sample.git
リモートリポジトリにpush
> git push origin master

クイックスタート

/hello.py

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    return "Hello world!"

サーバー起動

(flask) PS C:\workspaces\vscode\flask_sample> set-item env:FLASK_APP hello.py
(flask) PS C:\workspaces\vscode\flask_sample> python -m flask run
 * Serving Flask app "hello"
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

0506 flask run server.jpg

デバッグモード

PS> set-item env:FLASK_DEBUG 1

ルーティング

from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return 'Index Page'

@app.route('/hello')
def hello_world():
    return 'Hello world!'

変数

@app.route('/user/<username>/<int:age>')
def show_user_profile(username, age):
    return 'User {0} {1}'.format(username,age)
<コンバーター:変数>
コンバーター 説明
string '/'以外のすべてのテキスト(デフォルト)
int 整数
float 浮動小数点数
path '/'を受け付ける
any 与えられるアイテムの一つに一致
uuid UUID文字列

ユニークURL / リダイレクトの振る舞い

  • FlaskのURLルールは、Werkzeugのルーティングモジュールに基づく
  • このモジュールの背後にあるアイディアは、Apacheなど過去のHTTPサーバーの先例にもとづいた、美しくユニークなURLをを保証すること。
@app.route('/projects/')
def projects():
    return 'The project page'
@app.route('/about')
def about():
    return 'The about page'
  • これらは同じように見えるが、末尾の/の扱いが異なる。
  • projectsエンドポイントのための正統なURLは末尾に/を伴う。ファイルシステムのフォルダと同様
  • 末尾の/がない状態で、アクセスした場合、Flaskは末尾に/がある正統なURLにリダイレクトする
  • 末尾の/ない例は、ファイルシステムのファイルと同様、末尾に/を伴ってアクセスされた場合、404 Not Foundエラーとなる

URL 生成

  • url_for()関数は、関数名を最初の、関数の引数を以降の引数としてとり、URLを生成する
from flask import Flask,url_for

app = Flask(__name__)

@app.route('/')
def index():
    return 'Index Page'

@app.route('/hello')
def hello_world():
    return 'Hello world!'

@app.route('/user/<username>/<int:age>')
def show_user_profile(username, age):
    return 'User {0} {1}'.format(username,age)

@app.route('/urls')
def print_urls():
    return 
        <ol>
        <li>index() = {0}
        <li>hello_world() = {1}
        <li>show_user_profile('piroto',46) = {2}
        </ol>
    .format(
        url_for('index'),
        url_for('hello_world'),
        url_for('show_user_profile',username='piroto',age=46))

0510 flask url for.jpg

HTTP メソッド

from flask import request
 
@app.route('/method_check', methods=['GET','POST','HEAD'])
def method_check():
    if request.method == 'GET':
        return "HTTP METHOD GET"
    return "HTTP METHOD {0}".format(request.method)

静的ファイル

@app.route('/static_path')
def print_static_file_url():
    return url_for('static', filename='style.css')

0508 flask static.jpg

テンプレート

  • Flaskでは、Jinja2テンプレートエンジンが自動で設定される
  • アプリケーションがモジュールか、パッケージ化によって、以下の構成のtempletesフォルダに配置する
モジュール
/アプリケーション.py
/templates
    /テンプレート.html
パッケージ
/アプリケーション
    /__init__.py
    /templates
        /テンプレート.html
テンプレート利用
from flask import Flask, render_template
@app.route('/render_sample/<param>')
def render_sample(param=None):
    return render_template('render_sample.html',param=param)
テンプレート
<!doctype html>
<title>Rendering Sample</title>
{% if param %}
  <h1>Parameter : テンプレート:Param!</h1>
{% else %}
  <h1>No parameter found.</h1>
{% endif %}

0509 flask template.jpg

自動エスケープ

  • 自動エスケープは有効
  • 安全と確信できる場合、Markupクラスもしくは、 |safeフィルターを使用する
テンプレート
<!doctype html>
<title>Safe Rendering Sample</title>
<p>テンプレート:Param1</p>
<p>テンプレート:Param2</p>
<p>テンプレート:Param3</p>

==

from flask import Markup
@app.route('/render_safe_var')
def render_safe_var(param=None):
    return render_template('render_safe_var.html', 
        param1="<h2>Sub title</h2>",
        param2=Markup("<h2>Mark up Sub title</h2>"),
        param3="<h2>Safe filtered Sub title</h2>")

テンプレート:Ref image flask safe var.jpg.jpg

リクエストデータへのアクセス

  • クライアントが送信したリクエストデータは、request グローバルオブジェクトにより提供される
  • context locals により、グローバルオブジェクトをどうやってスレッドセーフにし管理している

Context Locals

  • Flaskのグローバルオブジェクトは実際には特定コンテキストローカルオブジェクトのプロキシ

Tips

Session

from flask import Flask, session
app = Flask(__name__, static_folder='app')
app.secret_key = "hoge"

def use_session:
    sessio["foo"] = "bar"

CRSF

Cookie

テンプレート

ディレクトリを変える