1. 程式人生 > >一起學FLask -第一章,基礎入門

一起學FLask -第一章,基礎入門

本來想學習使用mock, 發現API server一般使用的flask框架。。簡單學習一下flask框架。

推薦一個版本的pycharm  下載地址:https://pan.baidu.com/s/13qD_sMZiEttyjphad-zqmQ

我覺得這個版本的pycharm 對python web框架還是比較友好的。

下面這個連結,是本人寫的django 的入門。。

https://blog.csdn.net/qq_39208536/article/details/81540605    

flask 的安裝pip install flask 。

pycham 可以建立flask專案,(個人感覺通過pycharm來建立web專案還湊合,不是很好用)

1.程式的基本結構

1.初始化

所有 Flask 程式都必須建立一個程式例項。Web 伺服器使用一種名為 Web 伺服器閘道器介面 (Web Server Gateway Interface,WSGI)的協議,把接收自客戶端的所有請求都轉交給這 個物件處理。程式例項是 Flask 類的物件,經常使用下述程式碼建立:

from flask import Flask

app = Flask(__name__)

Flask 類的建構函式只有一個必須指定的引數,即程式主模組或包的名字。在大多數程式 中,Python 的 __name__ 變數就是所需的值。

1.2 路由和檢視函式

客戶端(例如 Web 瀏覽器)把請求傳送給 Web 伺服器,Web 伺服器再把請求傳送給 Flask 程式例項。需要知道對每個 URL 請求執行哪些程式碼,所以儲存了一個 URL 到 Python 函式的對映關係。處理 URL 和函式之間關係的程式稱為路由。

在 Flask 程式中定義路由的最簡便方式,是使用程式例項提供的 app.route 修飾器,把修 飾的函式註冊為路由。下面的例子說明了如何使用這個修飾器宣告路由:

在 Flask 程式中定義路由的最簡便方式,是使用程式例項提供的 app.route 修飾器,把修 飾的函式註冊為路由。下面的例子說明了如何使用這個修飾器宣告路由:

@app.route('/') 
def index(): 
    return 'Hello World!'

(修飾器是 Python 語言的標準特性,可以使用不同的方式修改函式的行為。慣 常用法是使用修飾器把函式註冊為事件的處理程式。)

 

前例把 index() 函式註冊為程式根地址的處理程式。如果部署程式的伺服器域名為 www. example.com,在瀏覽器中訪問 http://www.example.com 後,會觸發伺服器執行 index() 函 數。這個函式的返回值稱為響應,是客戶端接收到的內容。如果客戶端是 Web 瀏覽器,響 應就是顯示給使用者檢視的文件。 像 index() 這樣的函式稱為檢視函式(view function)。檢視函式返回的響應可以是包含 HTML 的簡單字串,也可以是複雜的表單。

如果你仔細觀察日常所用服務的某些 URL 格式,會發現很多地址中都包含可變部分。例 如, 你 的 Facebook 資 料 頁 面 的 地 址 是

http://www.facebook.com/<your-name>

 用 戶 名 (your-name)是地址的一部分。Flask 支援這種形式的 URL,只需在 route 修飾器中使用特 殊的句法即可。下例定義的路由中就有一部分是動態名字:

@app.route('/user/<name>')
def user(name):
     return '<h1>Hello, %s!</h1>' % name

尖括號中的內容就是動態部分,任何能匹配靜態部分的 URL 都會對映到這個路由上。調 用檢視函式時,Flask 會將動態部分作為引數傳入函式。在這個檢視函式中,引數用於生 成針對個人的歡迎訊息。

路由中的動態部分預設使用字串,不過也可使用型別定義。例如,路由 /user/ 只會匹配動態片段 id 為整數的 URL。Flask 支援在路由中使用 int、float 和 path 型別。 path 型別也是字串,但不把斜線視作分隔符,而將其當作動態片段的一部分。

1.3 啟動伺服器

程式例項用 run 方法啟動 Flask 整合的開發 Web 伺服器:

if __name__ == '__main__': 
     app.run(debug=True)

 __name__=='__main__' 是 Python 的慣常用法,在這裡確保直接執行這個指令碼時才啟動開發 Web 伺服器。如果這個指令碼由其他指令碼引入,程式假定父級指令碼會啟動不同的伺服器,因 此不會執行 app.run()。

伺服器啟動後,會進入輪詢,等待並處理請求。輪詢會一直執行,直到程式停止,比如按 Ctrl-C 鍵。

有一些選項引數可被 app.run() 函式接受用於設定 Web 伺服器的操作模式。在開發過程中 啟用除錯模式會帶來一些便利,比如說啟用偵錯程式和過載程式。要想啟用除錯模式,我們 可以把 debug 引數設為 True。 Flask 提供的 Web 伺服器不適合在生產環境中使用。

1.4 一個完整的程式

 一個完整的 Flask 程式如下:Hello.py

from flask import Flask

app = Flask(__name__)


@app.route('/')
def index():
    return '<h1>Hello World!</h1>'


if __name__ == '__main__':
    app.run(debug=True)

點選執行該程式(點選run  Hello.py)

如下示例,添加了一個動態路由。訪問這個地址時,你會看到一則針 對個人的歡迎訊息。

from flask import Flask
app = Flask(__name__)

# @app.route('/')
# def index():
#     return '<h1>Hello World!</h1>'

@app.route('/user/<name>')
def user(name):
    return '<h1>Hello, %s!</h1>' % name

if __name__ == '__main__':
 app.run(debug=True)

測試動態路由前,你要確保伺服器正在執行中,然後訪問 http://localhost:5000/user/Dave。 程式會顯示一個使用 name 動態引數生成的歡迎訊息。請嘗試使用不同的名字,可以看到視 圖函式總是使用指定的名字生成響應。

1.5 請求-響應迴圈

介紹flask框架的一些設計理念

1.5.1 程式和請求上下文

Flask 從客戶端收到請求時,要讓檢視函式能訪問一些物件,這樣才能處理請求。請求對 象就是一個很好的例子,它封裝了客戶端傳送的 HTTP 請求。 要想讓檢視函式能夠訪問請求物件,一個顯而易見的方式是將其作為引數傳入檢視函式, 不過這會導致程式中的每個檢視函式都增加一個引數。除了訪問請求物件,如果檢視函式在處理請求時還要訪問其他物件,情況會變得更糟。 為了避免大量可有可無的引數把檢視函式弄得一團糟,Flask 使用上下文臨時把某些物件 變為全域性可訪問。有了上下文,就可以寫出下面的檢視函式:

from flask import request
from flask import Flask
app = Flask(__name__)

@app.route('/')
def index():
    user_agent = request.headers.get('User-Agent')
    return '<p>Your browser is %s </p>' % user_agent


if __name__ == '__main__':
 app.run(debug=True)

注意在這個檢視函式中我們如何把 request 當作全域性變數使用。事實上,request 不可能是 全域性變數。試想,在多執行緒伺服器中,多個執行緒同時處理不同客戶端傳送的不同請求時, 每個執行緒看到的 request 物件必然不同。Falsk 使用上下文讓特定的變數在一個執行緒中全域性 可訪問,與此同時卻不會干擾其他執行緒。

執行緒是可單獨管理的最小指令集。程序經常使用多個活動執行緒,有時還會共 享記憶體或檔案控制代碼等資源。多執行緒 Web 伺服器會建立一個執行緒池,再從線 程池中選擇一個執行緒用於處理接收到的請求。

1.5.2 請求排程

程式收到客戶端發來的請求時,要找到處理該請求的檢視函式。為了完成這個任務,Flask 會在程式的 URL 對映中查詢請求的 URL。URL 對映是 URL 和檢視函式之間的對應關係。

Flask 使用 app.route 修飾器或者非修飾器形式的 app.add_url_rule() 生成對映。

URL 對映中的 HEAD、Options、GET 是請求方法,由路由進行處理。Flask 為每個路由都指 定了請求方法,這樣不同的請求方法傳送到相同的 URL 上時,會使用不同的檢視函式進 行處理。HEAD 和 OPTIONS 方法由 Flask 自動處理。

2.5.3 請求鉤子

有時在處理請求之前或之後執行程式碼會很有用。例如,在請求開始時,我們可能需要創 建資料庫連線或者認證發起請求的使用者。為了避免在每個檢視函式中都使用重複的程式碼, Flask 提供了註冊通用函式的功能,註冊的函式可在請求被分發到檢視函式之前或之後 呼叫。 請求鉤子使用修飾器實現。Flask 支援以下 4 種鉤子。

• before_first_request:註冊一個函式,在處理第一個請求之前執行。

• before_request:註冊一個函式,在每次請求之前執行。

• after_request:註冊一個函式,如果沒有未處理的異常丟擲,在每次請求之後執行。

• teardown_request:註冊一個函式,即使有未處理的異常丟擲,也在每次請求之後執行。

在請求鉤子函式和檢視函式之間共享資料一般使用上下文全域性變數 g。例如,before_ request 處理程式可以從資料庫中載入已登入使用者,並將其儲存到 g.user 中。隨後呼叫視 圖函式時,檢視函式再使用 g.user 獲取使用者。

 

1.5.4 響應

Flask 呼叫檢視函式後,會將其返回值作為響應的內容。大多數情況下,響應就是一個簡 單的字串,作為 HTML 頁面回送客戶端。 但 HTTP 協議需要的不僅是作為請求響應的字串。HTTP 響應中一個很重要的部分是狀 態碼,Flask 預設設為 200,這個程式碼表明請求已經被成功處理。 如果檢視函式返回的響應需要使用不同的狀態碼,那麼可以把數字程式碼作為第二個返回 值,新增到響應文字之後。例如,下述檢視函式返回一個 400 狀態碼,表示請求無效:


from flask import Flask
app = Flask(__name__)

@app.route('/')
def index():
    return '<h1>Bad Request</h1>', 400

if __name__ == '__main__':
 app.run(debug=True)

 檢視函式返回的響應還可接受第三個引數,這是一個由首部(header)組成的字典,可以 新增到 HTTP 響應中。一般情況下並不需要這麼做。

 如果不想返回由 1 個、2 個或 3 個值組成的元組,Flask 檢視函式還可以返回 Response 對 象。make_response() 函式可接受 1 個、2 個或 3 個引數(和檢視函式的返回值一樣),並 返回一個 Response 物件。有時我們需要在檢視函式中進行這種轉換,然後在響應物件上調 用各種方法,進一步設定響應。下例建立了一個響應物件,然後設定了 cookie:

from flask import make_response
from flask import Flask
app = Flask(__name__)


@app.route('/')
def index():
 response = make_response('<h1>This document carries a cookie!</h1>')
 response.set_cookie('answer', '42')
 return response



if __name__ == '__main__':
 app.run(debug=True)

有一種名為重定向的特殊響應型別。這種響應沒有頁面文件,只告訴瀏覽器一個新地址用 以載入新頁面。重定向經常在 Web 表單中使用。

重定向經常使用 302 狀態碼錶示,指向的地址由 Location 首部提供。重定向響應可以使用 3 個值形式的返回值生成,也可在 Response 物件中設定。不過,由於使用頻繁,Flask 提 供了 redirect() 輔助函式,用於生成這種響應:

from flask import redirect


@app.route('/')
def index():
 return redirect('http://www.example.com')

還有一種特殊的響應由 abort 函式生成,用於處理錯誤。在下面這個例子中,如果 URL 中 動態引數 id 對應的使用者不存在,就返回狀態碼 404:

from flask import abort


@app.route('/user/<id>')
def get_user(id):
     user = load_user(id)
     if not user:
         abort(404)
     return '<h1>Hello, %s</h1>' % user.name

注意,abort 不會把控制權交還給呼叫它的函式,而是丟擲異常把控制權交給 Web 服 務器。

2.5 Flask擴充套件

Flask 被設計為可擴充套件形式,故而沒有提供一些重要的功能,例如資料庫和使用者認證,所 以開發者可以自由選擇最適合程式的包,或者按需求自行開發。 社群成員開發了大量不同用途的擴充套件,如果這還不能滿足需求,你還可使用所有 Python 標 準包或程式碼庫。為了讓你知道如何把擴充套件整合到程式中,接下來我們將在 hello.py 中新增 一個擴充套件,使用命令列引數增強程式的功能。

使用Flask-Script支援命令列選項

Flask 的開發 Web 伺服器支援很多啟動設定選項,但只能在指令碼中作為引數傳給 app.run() 函式。這種方式並不十分方便,傳遞設定選項的理想方式是使用命令列引數。 Flask-Script 是一個 Flask 擴充套件,為 Flask 程式添加了一個命令列解析器。Flask-Script 自帶 了一組常用選項,而且還支援自定義命令。

Flask-Script 擴充套件使用 pip 安裝:

(venv) $ pip install flask-script

示例 1-1 顯示了把命令列解析功能新增到 hello.py 程式中時需要修改的地方。

示例 1-1 hello.py:使用 Flask-Script
 

from flask import Flask
from flask_script import Manager

app = Flask(__name__)
manager = Manager(app)




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


if __name__ == '__main__':
    manager.run()

專為 Flask 開發的擴充套件都暴漏在 flask_script 名稱空間下。flask_script 輸出了一個名為 Manager 的類,可從 flask_script 中引入。

這個擴充套件的初始化方法也適用於其他很多擴充套件:把程式例項作為引數傳給建構函式,初始 化主類的例項。建立的物件可以在各個擴充套件中使用。在這裡,伺服器由 manager.run() 啟 動,啟動後就能解析命令行了。

這樣修改之後,程式可以使用一組基本命令列選項。現在執行 hello.py,會顯示一個用法 訊息:

 

D:\python3\python.exe C:/Users/Administrator/PycharmProjects/Flask/Hello.py
usage: Hello.py [-?] {shell,runserver} ...

positional arguments:
  {shell,runserver}
    shell            Runs a Python shell inside Flask application context.
    runserver        Runs the Flask development server i.e. app.run()

optional arguments:
  -?, --help         show this help message and exit

Process finished with exit code 2