Flask
- 輕量化 Web 框架
- MVC架構(Model–view–controller)
控制器(Controller): 對 Request/Response 進行處理並透過 Controller 把 Model 的資料串接到 View(Templates)
視圖(View):連接前端網頁
模型(Model):連接 database
- Flask 的 MVC
Flask Hello World 兩步驟
第一步:安裝 Flask
$ pip install flask# 查看 flask 版本
$ python
>>> import flask
>>> print(flask.__version__)
第二步:flask 最簡易的 Hello World (只需 7 行 code)
# hello.py# one
from flask import Flask
app = Flask(__name__)
# two
@app.route('/')
def hello_world():
return 'Hello World!'
# three
if __name__ == '__main__':
app.run()# 默認 port 5000
運行python hello.py
第一:
from flask import Flask
- 從 flask 套件導入 Flask 類別
app = Flask(__name__)
- 創建 Flask() 建構子 -> 回傳一個 Flask 物件(application instance)用 app 變數接收
- 用途:程式執行路口;例如: C 語言的 main(){}
- 進階:找到根目錄,來獲取靜態文件和模板文件的目錄路徑
第二:
@app.route('/')
def hello_world():
return 'Hello World!'
- 使用 route 裝飾器 @ (decorator)
(前端 Web URL<=> 後端觸發函數)
第三:
if __name__ == '__main__':
app.run()
- if __name__ == ‘__main__’: -> 確保 Web Server 只在運行此腳本(python xxx.py)時才會啟動,避免被 import 匯入時就啟動。
- run()函數,啟動內建Web Server
Docker
第一步:Pull image(from Docker Hub)
# 從 Docker Hub 找尋一個 flask 的 image
$ Docker search Flask
- 我從 github 尋找 docker, flask 相關的專案找到了:python-flask-docker
$ docker pull lvthillo/python-flask-docker
第二步:Run image
# -p 冒號前是本地 port 冒號後是 Container port(flask裡的 port)
$ docker run --name=flask_dlspm_t -i -t -p 8787:8888 lvthillo/python-flask-docke# 掛載目錄
$ docker run --name=flask_dlspm_t -v <本地目錄路徑>:<Container 路徑>-i -t -p 2151:8888 lvthillo/python-flask-docke /bin/bash# 如何查看路徑(先 cd 到你的專案目錄底下)
$ pwd # Container 路徑會自行新增沒有的資料夾所以不用擔心
- 這邊要注意 image 的 python 版本!
Error:socket.error: [Errno 98] Address already in use
— 這是python 版本不符的 Error
# run 起來後會自行產生一個 container
# 有些 image 的 Dockerfil 會自動切換目錄且運行檔案,如果有的話可以先:Control+C 離開# 查詢所有 docker container(找到剛剛的 NAMES->把 CONTAINER ID 複製起來)
$ docker ps -a
第三步:Run Container
# 啟動容器
$ docker start <貼上CONTAINER ID># 進入容器
$ docker exec -it <貼上CONTAINER ID> /bin/bash# 進到我們的專案裡面三種辦法
# 放到 github 上 git clone 下來
# 掛載目錄方法
# 從寫一個
在 run flask 之前需先修改 host, port:
一定要加上 host=‘0.0.0.0’ ,不然可能會連不上
if __name__ == '__main__':
app.run(host='0.0.0.0', port = 8888)
運行 flask 檔案 👍 👏 👌 🤙 🙌🏻
$ python XX.py# 開啟連結後記得更改 0.0.0.0:XXXX => 127.0.0.1:XXXX
# XXXX是本地端的 port
那如果從 Docker Hub 都找不到相符的 iamge 該怎麼辦?
那就自己弄一個 image!
New Files(requirements.txt、Dockerfile)
- Dockerfile
📌鏡像(image)配置,用來快速建立鏡像
# vim Dockerfile
FROM python:3.7
COPY . /
WORKDIR /app
RUN apt-get install vim
RUN pip install -r requirements.txt
RUN ["/bin/bash"]
EXPOSE 8888
ENTRYPOINT ["python"]
CMD ["/bin/bash"]
解析:
#版本
FROM python:3.7#複製當前目錄所有檔案到 Container 根目錄底下的 app 資料夾
(會在 Container 根目錄底下 new 名為 'app' 的資料夾)
COPY . /app# 切換工作目錄(沒有也可;那進入 Container 後就會在根目錄)
WORKDIR /app# install requirements.txt 裡的所有套件
RUN pip install -r requirements.txt# Container 的 port
EXPOSE 8888# 使用 python 語言
ENTRYPOINT ["python"]# CMD <指令> = docker run -it <指令>
# 啟用此 image 時默認 shell 設置為 bash
# 如果沒有 CMD ["/bin/bash"] 這樣 docker run 後面就不用接 /bin/bash
CMD ["/bin/bash"]
Shell
可以參考我寫的思維導圖:https://app.gitmind.com/doc/947161738
官網規範:
參數介紹:
- requirements.txt
📌專案所需的套件以及版本(範例我們使用 flask 即可)
flask==1.1.1
- 若需生成整個專案所需套件 $ pip freeze > requirements.txt
第一步:Build(透過 Dockerfile 創建自己的 image)
$ docker build -t <REPOSITORY_name>:<TAG> .
# 默認為 <none>
# TAG 做為標示版本號或是重大資訊的標註
官網說明:
更改 image REPOSITORY、TAG
$ docker tag [IMAGE ID] [new_REPOSITORY]:[new_TAG]
# TAG 默認是 latest
第二步:Run image
# -p 冒號前是本地 port 冒號後是 Container port(flask裡的 port)
$ docker run --name=flask_dlspm_t -i -t -p 8787:8888 <image_REPOSITORY># run 會運行 [REPOSITORY]:[TAG],TAG 默認是 latest
# 所以 TAG 是 latest 以外的值在 run 時都要補上 TAG 參數
# -i 設置為 Interactive shell(交互式shel)
# -t 為容器重新分配一個偽輸入終端,通常與 -i 同時使用;可以合併使用:-it
# -p 設置 port
# -d 背景執行
Docker run 參數介紹:
檢查 Container:
第三步:Run Container(每 run 一個 image docker 都會自動 new 一個 container)
# 會自動進入容器(上方紅色框框就是 CONTAINER ID)
運行 flask 檔案 👍 👏 👌 🤙 🙌🏻
$ python flask_hello_world.py# 開啟連結後記得更改 0.0.0.0:XXXX => 127.0.0.1:XXXX
# XXXX是本地端的 port
# 我的範例是改為:http://127.0.0.1:8787/ 在瀏覽器上預覽
Error:
Docker failed to find anaconda-client:
ERROR: Could not find a version that satisfies the requirement anaconda-client==1.7.2 (from -r requirements.txt (line 2)) (from versions: 1.1.1, 1.2.2)
ERROR: No matching distribution found for anaconda-client==1.7.2 (from -r requirements.txt (line 2))
# 我覺得起因是 anaconda-client 版本不相符
$ pip list | grep anaconda-client
anaconda-client==1.7.2
- python 的 anaconda-client只到 1.2.2,但anaconda 的 anaconda-client 有到 1.7.2
解決:降低 anaconda-client 版本
$ pip install anaconda-client==1.2.2
Flask with WSGI
- Flask 以 WSGI 介面與 Jinja2 模板為基礎,內建一個實作 WSGI 伺服器與路由功能的 Werkzeug
- WSGI 是 Python 標準的網頁伺服器介面協定
- Flask 雖是 HTTP 的 Web 伺服器,但其效能只能做為開發使用,實際大型專案還是要透過 Ex: Nginx 或 Apache 等伺服器(支援 WSGI 介面)
文獻參考: