AI畫家第三彈——畢業設計大殺器之Flask

僱個城管打天下發表於2019-05-09

AI畫家第三彈——畢業設計大殺器之Flask

上一篇介紹了影像風格遷移的一個最基本實現,雖然在控制檯實現了功能,但是想要實際使用,應用到一個app或者網頁上光靠上一節的內容肯定是不行的。那怎麼樣才可以將風格遷移這個功能變成一個可以實際使用的小程式呢?不著急,在實現上述功能前,我們先來介紹一個小東西,也就是這篇文章的主角,我把他稱為"畢業設計大殺器“的Flask框架

前後端分離

在介紹Flask之前,我們先介紹下什麼是前後端分離。因為如果不介紹前後端分離就不會理解為啥要選擇Flask了。前後端分離是目前網際網路專案開發的標準使用方式,其核心思想簡單理解為是前端頁面(或者app等多端)通過ajax(或者其他請求方式)呼叫後端的restuful api介面並使用json資料進行互動。其目的是為了將專案解耦合,達到**"術業有專攻”**的效果。因為在以往的web專案中,後端人員的工作量非常大,用過jsp的人都知道,那真的是又當爹又當媽,既要會寫後臺邏輯還要會弄樣式。但是採用了前後端分離的架構之後,前後端人員就可以各司其職了。

前端人的追求

前端追求的是:頁面表現,速度流暢,相容性,使用者體驗等等。

把精力放在html5,css3,jquery,angularjs,bootstrap,reactjs,vuejs,webpack,less/sass,gulp,nodejs,Google V8引擎,模組化,設計模式,瀏覽器相容性,效能優化等等。

後端人的追求

後端追求的是:三高(高併發,高可用,高效能),安全,儲存,業務等等。

把精力放在語言基礎,設計模式,底層原理,linux,mysql事務隔離與鎖機制,mongodb,http/tcp,多執行緒,分散式架構,彈性計算架構,微服務架構,效能優化,以及相關的專案管理等等。

應用伺服器、Web伺服器、Restful

應用伺服器:一般指像tomcat,jetty這類的伺服器可以解析動態資源也可以解析靜態資源,但解析靜態資源的能力沒有web伺服器好。

Web伺服器:一般指像nginx,apache這類的伺服器,他們一般只能解析靜態資源。

靜態資源就是類似於html、js、圖片這些多次訪問也不會變化的資源

一般都是隻有web伺服器才能被外網訪問,應用伺服器只能內網訪問。

RESTful

REST的全稱是representational state transfer,即表徵狀態轉移。在理解這個名詞之前我們先來看幾個名詞(感覺需要知道的前置知識好多啊)。

資源(resources)

所謂的資源就是網路上的一個實體,它可以使一個圖片,一個文字,一個服務,你可以用一個URI指向它,每種資源對應一個特定的URI,要獲取這個資源訪問它的URI就行了,所謂的上網,其實就是與網路上的資源進行一系列的互動就是了。

表徵(representation)

怎麼把資源表現出來就是表徵的意義,比如一段文字是txt、html還是json,圖片是jpg還是png,以http協議為例,就是Accept和content-type中的內容,說明了資源的型別。

狀態轉移(state tranfer)

訪問一個網站,就是客戶端和服務端的一個互動過程,客戶端想要操作服務端,就必須通過某種手段讓服務端的狀態發生變化,具體到http協議中就是http的幾種方法:GET用來獲取資源,POST用來新建資源,PUT用來更新資源,DELETE用來刪除資源。

理解RESTful

  1. 使用URI來表示每一個資源
  2. 為每一個資源確定它的表現形式
  3. 使用4個方法來操作這些資源

什麼是Flask?

介紹完前後端分離後,我們就開始介紹下Flask是什麼吧。

Flask是一個使用 Python 編寫的輕量級 Web 應用框架。其 WSGI 工具箱採用 Werkzeug ,模板引擎則使用 Jinja2。Flask也被稱為 “microframework” ,即**"微框架"**,因為它使用簡單的核心,用 extension 增加其他功能。Flask沒有預設使用的資料庫、窗體驗證工具。

理解下"微"

"微"框架中的“微”(micro) 並不表示你需要把整個 Web 應用塞進單個 Python 檔案(雖然確實可以 ),也不意味著 Flask 在功能上有所欠缺。微框架中的“微”意味著 Flask 旨在保持核心簡單而易於擴充套件。Flask 不會替你做出太多決策——比如使用何種資料庫。而那些 Flask 所選擇的——比如使用何種模板引擎——則很容易替換。除此之外的一切都由可由你掌握。預設情況下,Flask 不包含資料庫抽象層、表單驗證,或是其它任何已有多種庫可以勝任的功能。然而,Flask 支援用擴充套件來給應用新增這些功能,如同是 Flask 本身實現的一樣。眾多的擴充套件提供了資料庫整合、表單驗證、上傳處理、各種各樣的開放認證技術等功能。Flask 也許是“微小”的,但它已準備好在需求繁雜的生產環境中投入使用。

什麼是wsgi?

全名Web Server Gateway Interface,即伺服器閘道器介面,是應用程式和Web伺服器之間的一種介面。可以理解為是伺服器程式和應用程式的一個約定,規定了各自使用的介面和功能,以便二和互相配合。

這裡因為篇幅原因就不給出詳細解釋了,推薦兩片文章,講的挺詳細的。

  1. www.jianshu.com/p/29f66eb4e…
  2. www.liaoxuefeng.com/wiki/897692…

為什麼選Flask?

我把Flask稱為畢業設計大殺器自然是有他的道理的,接下來我們看看他的幾大優點:

  1. 外掛多。查詢資料方便
  2. 沒有太多繁瑣的配置步驟
  3. 各種中文資料、網友的受虐後的心得文章,查詢方便
  4. 部署也非常方便
  5. 社群非常活躍

例項

上面說了那麼多,你們肯定還是不會理解為啥要使用Flask,別急,我們用例子說話。

安裝

這裡就不多說了,直接pip install flask即可。(官方文件是推薦建立一個虛擬環境的,這裡為了方便起見,省略了這一步)。

最小的應用

一個最小的 Flask 應用看起來會是這樣:

from flask import Flask
app = Flask(__name__)

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

if __name__ == '__main__':
    app.run()
複製程式碼

把它儲存為 hello.py (或是類似的),然後啟動terminal(powershell)來執行這個檔案。 確保你的應用檔名不是 flask.py ,因為這將與 Flask物件本身衝突。

python hello.py
複製程式碼

現在訪問 http://127.0.0.1:5000/ ,你會看見 Hello World 早已等候多時。

AI畫家第三彈——畢業設計大殺器之Flask

一旦部署到遠端伺服器上之後,這就是一個可以用GET請求訪問的介面了,是不是很方便呢?如果想更改請求方法也很簡單,只需要在@app.route()裝飾器第二個引數填入想要支援的請求方法就可以了,如下:

@app.route('/login', methods=['GET', 'POST'])
複製程式碼

這樣,login這個路由就可以支援get和post兩種請求方式了。

路由

所謂 路由,即URL 繫結 Flask 使用 route()裝飾器把一個函式綁於一個URL上, 如下:

這裡是一些基本的例子:

@app.route('/hello')
def hello_world():
    return 'Hello World!'
複製程式碼

我們便可以在本地通過localhost:xxxx/hello,來獲取到hello函式中的內容。

同時,我們還可以使用add_url_rule()方法來實現路由的註冊

from flask import Flask

app = Flask(__name__)   
 
def hello():
    return 'Hello ,world!'

app.add_url_rule('/hello', viewfunc=hello)
app.run()
複製程式碼

其實add_url_rule@app.route()裝飾器內部封裝的一個方法,兩者的本質是相同的。不信我們們看原始碼:

Carbonize 2019-05-09 at 3.10.23 PM

藍圖(blueprint)

雖然說flask想實現一個路由非常簡單,但是在實際的專案中我們肯定是不能把所有的路由都放在初始檔案中啊,檔案變大不說,還不方便管理,完全不符合模組化開發的思想。不過不用擔心,flask早就幫我們想好了應對的辦法了。這就是藍圖。

為了在一個或多個應用中,使應用模組化並且支援常用方案,Flask 引入了藍圖概念。藍圖可以極大地簡化大型應用併為擴充套件提供集中的註冊入口。

接下來則是藍圖的使用(一般位於API級的__init__.py檔案中):

from flask import Flask

def create_app():
    app = Flask(__name__)

    register_blueprint(app)   # 完成藍圖註冊
    init_db(app)
    return app

def register_blueprint(app):  # 註冊藍圖
    from app.api.v1 import v1
    from app.api.v1.img import img

    app.register_blueprint(v1, url_prefix='/api/v1')  
    # url_prefix新增了這個引數後,所有藍圖路由前面機會自動新增這個引數
    # PS:這個引數必須是一個字串,而且要以' / '開頭
    app.register_blueprint(img, url_prefix='/api/v1/img')
複製程式碼

之後我們就可以在另一個檔案(需要使用app物件的檔案,也就是存放路由函式的檔案)中將它初始化

from flask import Blueprint  # 藍圖引入
 
img = Blueprint('img', __name__)  # 藍圖初始化
複製程式碼

其實我們可以理解為就是把主頁面的app物件傳遞到了不同的路由檔案中了,方便了模組化的開發。

這裡如果沒有例項展示的話可能不是很容易理解,下一篇文章我們將會延續上一篇,講一下如何利用Flask將影像風格遷移的功能變成一個可用的restful api,例項我已經上傳了,大家可以先在微信公眾號「01二進位制」後臺回覆「風格遷移API」把程式碼下載下來,體驗下flask專案如何分層才不會導致混亂。

flask與資料庫

作為一個後臺框架,不可缺少的就是如何與資料庫打交道,flask_sqlalchemy很好的幫我們解決了這個問題。

在瞭解flask_sqlalchemy是什麼之前先看下sqlalchemy是什麼,我這裡直接引用下廖雪峰大神的介紹:

AI畫家第三彈——畢業設計大殺器之Flask

直接我們也提過,flask是一個微框架,通過外掛來增加功能的,flask_sqlalchemy就是sqlalchemy的一個flask框架,目的就是為了更加方便的使用ORM技術運算元據庫。

接下來簡單介紹下他的使用方法。

先安裝:pip install flask_sqlalchemy

然後在初始檔案中新增如下程式碼以配置資料庫連線:

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy() # 例項化
複製程式碼

然後在啟動檔案中新增如下程式碼將flask_sqlalchemy配置到flask物件中:

def init_db(app):
    # 註冊db
    db.init_app(app)
    # 將程式碼對映到資料庫中
    with app.app_context():
        db.create_all(app=app)
複製程式碼

這時候別忘了兩件事:資料庫的連線配置資訊和資料表的定義

  • 資料庫的連線配置資訊

我們在專案中新建一個secure.py檔案(專門用於記錄敏感資訊),並在其中新增如下欄位

DIALECT = 'mysql'  # 要用的什麼資料庫
DRIVER = 'pymysql'  # 連線資料庫驅動
USERNAME = 'xxx'  # 使用者名稱
PASSWORD = 'xxx'  # 密碼
HOST = 'localhost'  # 伺服器
PORT = '3306'  # 埠
DATABASE = 'xxx'  # 資料庫名

SQLALCHEMY_DATABASE_URI = "{}+{}://{}:{}@{}:{}/{}?charset=utf8".format(DIALECT, DRIVER, USERNAME, PASSWORD, HOST, PORT,
                                                                       DATABASE)
SQLALCHEMY_TRACK_MODIFICATIONS = False
複製程式碼

建立flask物件的時候別忘了新增下這個配置檔案:

app = Flask(__name__)
app.config.from_object('app.secure')
複製程式碼
  • 資料表的定義

以反饋(feedback)為例,如下程式碼就構建了一個非常簡單的資料庫模型了

from sqlalchemy import Column, Integer, String

from app.model import db
from app.utils import common_utils

class FeedBack(db.Model):
    # 反饋記錄的id
    id = Column(Integer, primary_key=True, autoincrement=True)
    # 反饋人的uid
    uid = Column(String(50), nullable=False)
    # 反饋的內容
    content = Column(String(50), nullable=False)
    # 反饋人的聯絡方式
    contact = Column(String(50), nullable=False)
    # 反饋的來源
    origin = Column(Integer, nullable=False)
    # 反饋的時間
    created_time = Column(String(50), nullable=False)

    def __init__(self, uid, content, contact, origin):
        self.uid = uid
        self.content = content
        self.contact = contact
        self.origin = origin
        self.created_time = common_utils.get_date_now()
複製程式碼

然後開啟資料庫服務,啟動flask專案,沒有報錯就說明成功了。

最後

我們總結下,這篇文章的主角是flask,但是想要理解為啥要使用flask的話我們必須要有前後端分離的概念,不然我們是不會體會到flask的便捷之處的。然後緊接著介紹了我認為剛開始使用flask時的幾個比較重要的東西:路由、藍圖和ORM外掛。因為篇幅原因,沒有非常詳細的介紹使用方法,但是事實上只要會了這三個應付畢業設計是綽綽有餘的,這也就是我將其稱為畢業設計大殺器的原因。那麼在哪可以學到flask呢?

AI畫家第三彈——畢業設計大殺器之Flask

在微信公眾號「01二進位制」後臺回覆「flask視訊」即可獲得一份非常非常優質的flask視訊

下一篇將會介紹如何用flask結合風格遷移模型給你的應用程式提供一個可用的RESTful API,喜歡的小夥伴可以微信掃一掃關注轉發和支援,謝謝?

AI畫家第三彈——畢業設計大殺器之Flask

相關文章