
深度定制Python的Flask框架開發(fā)環(huán)境的一些技巧總結(jié)
現(xiàn)在越來越多的人使用virtualenv虛擬環(huán)境部署Python項目,包括針對框架的實例文件夾與版本控制布置,這里我們就來整理關于深度定制Python的Flask框架開發(fā)環(huán)境的一些技巧總結(jié)
Flask 環(huán)境配置
你的應用程序可能需要大量的軟件包才能正常的工作。如果都不需要 Flask 包的話,你有可能讀錯了教程。當應用程序運行的時候,你的應用程序的 環(huán)境 基本上是所有一切事情的根基。我們是幸運的,因為有許多方式使得我們能夠輕松地管理我們的環(huán)境。
使用 virtualenv 管理你的環(huán)境
virtualenv 是用于在所謂 虛擬環(huán)境 中隔離你的應用程序的一個工具。一個虛擬環(huán)境是包含了你的應用依賴的軟件的一個目錄。一個虛擬環(huán)境也能夠改變你的環(huán)境變量以維持你的開發(fā)環(huán)境包含的環(huán)境變量。不用下載包,像 Flask, 到你系統(tǒng)級或者用戶級的包目錄,我們可以下載它們到一個獨立的并且只為我們應用使用的目錄。這就可以很容易地指定使用的 Python 的版本以及每一個項目依賴的包。
Virtualenv 也可以讓你在不同的項目中使用相同的包的不同版本。這種靈活性可能是十分重要的,如果你正使用一個舊的系統(tǒng)并且它的上面有幾個項目需要不同的版本。
當使用 virtualenv 的時候,你通常只需要安裝幾個的 Python 包在你的系統(tǒng)上。其中一個就是 virtualenv 本身。你可以使用 Pip 來安裝 virtualenv 包。
一旦在你的系統(tǒng)上安裝了 virtualenv,你可以開始創(chuàng)建虛擬環(huán)境。前往你項目所在的目錄并且運行 virtualenv 命令。它需要一個參數(shù),這個參數(shù)就是虛擬環(huán)境的目標目錄。下面展示了它大概的樣子。
$ virtualenv venv
New python executable in venv/bin/python
Installing Setuptools...........[...].....done.
Installing Pip..................[...].....done.
virtualenv 創(chuàng)建一個新的目錄,依賴包將會安裝到這個目錄中。
一旦新的虛擬環(huán)境已經(jīng)創(chuàng)建,你必須激活它,通過發(fā)動創(chuàng)建在虛擬環(huán)境里的 bin/activate 腳本。
$ which python
/usr/local/bin/python
$ source venv/bin/activate
(venv)$ which python
/Users/robert/Code/myapp/venv/bin/python
bin/activate 腳本對你的 shell 環(huán)境變量進行一些改變以致一切都指向新的虛擬環(huán)境而不是全局系統(tǒng)。你可以在上面的代碼塊中看到效果。激活后,python 命令指向虛擬環(huán)境的中 Python 的 bin 目錄。當虛擬環(huán)境激活后,使用 Pip 安裝的依賴包會被下載到虛擬環(huán)境中而不是全局系統(tǒng)。
你可能會注意到 shell 中的提示符也已經(jīng)改變了。virtualenv 預先設定目前激活虛擬環(huán)境的名稱,因此你會知道你不是在全局系統(tǒng)上工作。
你可以通過運行 deactivate 命令停用你的虛擬環(huán)境。
(venv)$ deactivate
virtualenvwrapper
virtualenvwrapper 是一個用于管理 virtualenv 創(chuàng)建的虛擬環(huán)境的軟件包。我不想提到這個工具,直到你看到了 virtualenv 的基礎知識以便你理解它改善了什么以及為什么我們應該使用它。
上一部分創(chuàng)建的虛擬環(huán)境目錄會給你的項目庫帶來一些混亂。你只需要激活虛擬環(huán)境和它進行交互,但是它不應該出現(xiàn)在版本控制中,因此這個虛擬環(huán)境目錄就不應該在這里。解決方案就是使用 virtualenvwrapper。這個軟件包會把所有你的虛擬環(huán)境放在一個目錄的方式,通常默認是在 ~/.virtualenvs/。
要安裝 virtualenvwrapper,請按照文檔中的說明,文檔位于 http://virtualenvwrapper.readthedocs.org/en/latest/install.html 。
請確保在安裝 virtualenvwrapper 之前你已經(jīng)停用所有的虛擬環(huán)境。你需要把它安裝在全局系統(tǒng)中,而不是虛擬環(huán)境中。
現(xiàn)在,不用運行 virtualenv 來創(chuàng)建一個環(huán)境,你需要運行 mkvirtualenv:
$ mkvirtualenv rocket
New python executable in rocket/bin/python
Installing setuptools...........[...].....done.
Installing pip..................[...].....done.
(rocket)$
mkvirtualenv 在你虛擬環(huán)境目錄中創(chuàng)建一個文件夾并且為你激活虛擬環(huán)境。就像上面的 virtualenv 一樣,python 以及 pip 指向虛擬環(huán)境中而不是全局系統(tǒng)的二進制文件。要激活一個特定的環(huán)境,使用命令:workon [environment name]。deactivate 仍然會停用虛擬環(huán)境。
安裝依賴包
隨著項目的發(fā)展,你會發(fā)現(xiàn)依賴包的列表會增大。需要幾十個 Python 包來運行一個 Flask 應用程序的情況并不少見。管理這些最簡單的方法是用一個簡單的文本文件。Pip 能夠生成一個列出所有已安裝的包的文本文件。在一個新的系統(tǒng)上,或者在一個新的剛創(chuàng)建的環(huán)境上也能讀取文件中的列表并且安裝它們中每一個。
pip freeze:
requirements.txt 是一個文本文件,它被許多 Flask 應用程序用來列出運行應用所有需要的包。這個代碼塊用來說明如何創(chuàng)建這個文件接著下一個代碼塊用來說明在一個新環(huán)境中如果使用這個文件來安裝依賴包。
(rocket)$ pip freeze > requirements.txt
$ workon fresh-env
(fresh-env)$ pip install -r requirements.txt
[...]
Successfully installed flask Werkzeug Jinja2 itsdangerous markupsafe
Cleaning up...
(fresh-env)$
人工管理依賴包
隨著項目的發(fā)展,你可能會發(fā)現(xiàn) pip freeze 列出的某些包實際上并不是運行應用必須的。你安裝這些包僅僅為開發(fā)用的。pip freeze 并不能區(qū)分,它僅僅列出目前已經(jīng)安裝的包。因此,你可能要手動地管理這些依賴包。你可以分別把那些運行應用必須的包放入 require\_run.txt 以及那些開發(fā)應用程序需要的包放入 require\_dev.txt 。
版本控制
選擇一個版本控制系統(tǒng)并且使用它。我推薦 Git。從我所看到的,Git 是這些天來新項目最流行的選擇。能夠刪除代碼而不必擔心犯了一個不可逆轉(zhuǎn)的錯誤是非常寶貴的。你也可以讓你的項目擺脫大量注釋掉的代碼的困擾,因為你可以刪除它們,以后如有需要可以恢復它們。另外,你可以在 GitHub,Bitbucket 或者你自己的 Gitolite 服務器上備份整個項目。
置身版本控制之外的文件
我通常會讓一個文件置身版本控制之外有兩個原因:要么就是它會讓整個項目顯得混亂,要么它就是一個很隱私的密鑰/證書。編譯的 .pyc 文件和虛擬環(huán)境 — 如果由于某些原因你沒有使用 virtualenvwrapper — 就是讓項目顯得很混亂的例子。它們不需要在版本控制之中因為它們能夠分別地從 .py 文件和你的 requirements.txt 文件重新創(chuàng)建。
API 秘鑰,應用程序秘鑰以及數(shù)據(jù)庫證書是很隱私的密鑰/證書的示例。它們不應該出現(xiàn)在版本控制中因為它們的曝光將是一個巨大的安全漏洞。
當做跟安全有關的決定的時候,我總是喜歡假設我的版本庫將在某個時候變成公開的。這就意味著要保守秘密并且從不假設一個安全漏洞不會被發(fā)現(xiàn),“誰來猜猜他們能做到”這類型的假設被稱為通過隱匿來實現(xiàn)安全,這是十分槽糕的策略。
當使用 Git 的時候,你可以在你的版本庫中創(chuàng)建名為 .gitignore 的一個特殊文件。在這個文件里,使用列表通配符來匹配文件名。任何匹配其中一個模式的文件名都會被 Git 給忽略掉。我推薦使用 .gitignore 來控制不需要版本控制的文件。例如:
*.pyc
instance/
Instance 文件夾是用于以一種更安全地方式提供給你的應用程序敏感配置變量。我將會在后面更多地談到它。
調(diào)試
1.調(diào)試模式
Flask 有一個稱為調(diào)試模式方便的功能。要打開調(diào)試功能的話,你只必須在你的開發(fā)配置中設置 debug = True。當它打開的時候,服務器在代碼變化的時候自動加載并且出錯的時候會伴隨著一個堆棧跟蹤和一個交互式控制臺。
小心!不要在生產(chǎn)環(huán)境中使用調(diào)試模式。交互式控制臺允許執(zhí)行任意代碼并會是一個巨大的安全漏洞。
2.Flask-DebugToolbar
Flask-DebugToolbar 是另一個非常了不起的工具,它可以幫助在你的應用程序中調(diào)試問題。在調(diào)試模式下,它會把一個側(cè)邊欄置于你的應用程序的每一頁上。側(cè)邊欄提供了有關 SQL 查詢,日志記錄,版本,模板,配置和其它有趣的信息,使得更容易地跟蹤問題。
看看快速入門中的 調(diào)試模式。在 Flask 官方文檔 中有一些關于錯誤處理,日志記錄以及使用調(diào)試器等不錯的信息。
Flask 工程配置
當你學習 Flask 的時候,配置看起來很簡單。你只要在 config.py 中定義一些變量接著一切就能工作了。當你開始必須要管理生產(chǎn)應用的配置的時候,這些簡單性開始消失了。你可能需要保護 API 密鑰以及為不同的環(huán)境使用不同的配置(例如,開發(fā)和生產(chǎn)環(huán)境)。在本章節(jié)中我們會介紹 Flask 一些先進的功能,它可以使得管理配置容易些。
簡單的例子
一個簡單的應用程序可能不會需要任何這些復雜的功能。你可能只需要把 config.py 放在你的倉庫/版本庫的根目錄并且在 app.py 或者 yourapp/\\_init\\_.py 中加載它。
config.py 文件中應該每行包含一個配置變量賦值。當你的應用程序初始化的時候,在 config.py 中的配置變量用于配置 Flask 和它的擴展并且它們能夠通過 app.config 字典訪問到 – 例如,app.config["DEBUG"]。
DEBUG = True # Turns on debugging features in Flask
BCRYPT_LEVEL = 12 # Configuration for the Flask-Bcrypt extension
MAIL_FROM_EMAIL = "robert@example.com" # For use in application emails
配置的變量可以被 Flask,它的擴展或者你來使用。這個例子中, 每當我們在一封事務性郵件中需要默認的 “發(fā)件人” 的時候,我們可以使用 app.config["MAIL_FROM_EMAIL"] – 例如,密碼重置。把這些信息放置于一個配置變量中使得以后能夠容易地修改它。
# app.py or app/__init__.pyfrom flask import Flask
app = Flask(__name__)
app.config.from_object('config')
# Now we can access the configuration variables via app.config["VAR_NAME"].
DEBUG: 為你提供了調(diào)試錯誤的一些方便的工具。 這包括一個基于 Web 的堆棧跟蹤和交互式的 Python 控制臺。在開發(fā)環(huán)境中設置成 True; 生產(chǎn)環(huán)境中設置成 False。
SECRET\_KEY:這是 Flask 用來為 cookies 簽名的密鑰。 它也能被像 Flask-Bcrypt 類的擴展使用。 你應該在你的實例文件夾中定義它, 這樣可以遠離版本控制。 你可以在下一個章節(jié)中閱讀更多關于示例文件夾的內(nèi)容。一般情況下這應該是一個復雜的隨機值。
BCRYPT\_LEVEL:如果你使用 Flask-Bcrypt 來散列用戶密碼的話, 你需要指定一個“循環(huán)”數(shù),這個數(shù)是在執(zhí)行散列密碼的 算法需要的。如果你不使用 Flask-Bcrypt,你可以 忽略這里。用于散列密碼的循環(huán)數(shù)越大,攻擊者猜測密碼 的時間會越長。同時,循環(huán)數(shù)越大會增加散列密碼的時間。后面我們會給出在 Flask 應用中 使用 Bcrypt 的一些最佳實踐。
確保在生產(chǎn)環(huán)境中 DEBUG 設置成 False。如果保留 DEBUG 為 True,它允許用戶在你的服務器上執(zhí)行任意的 Python。
實例文件夾
有時候你需要定義包含敏感信息的配置變量。我們想要從 config.py 中分離這些變量并且讓它們保留在倉庫/版本庫之外。你可能會隱藏像數(shù)據(jù)庫密碼以及 API 密鑰的一些敏感信息,或者定義于特定于指定機器的配置變量。為讓實現(xiàn)這些要求更加容易些,F(xiàn)lask 提供了一個叫做 instance folders 的功能。實例文件夾是倉庫/版本庫下的一個子目錄并且包含專門為這個應用程序的實例的一個配置文件。我們不希望它提交到版本控制。
config.py
requirements.txt
run.py
instance/
config.py
yourapp/
__init__.py
models.py
views.py
templates/
static/
使用實例文件夾
我們使用 app.config.from_pyfile() 來從一個實例文件夾中加載配置變量。當我們調(diào)用 Flask() 來創(chuàng)建我們的應用的時候,如果我們設置了 instance_relative_config=True, app.config.from_pyfile() 將會從 instance/ 目錄加載指定文件。
# app.py or app/__init__.py
app = Flask(__name__, instance_relative_config=True)
app.config.from_object('config')
app.config.from_pyfile('config.py')
現(xiàn)在我們可以像在 config.py 中那樣在 instance/config.py 中定義配置變量。你也應該把你的實例文件夾加入到版本控制系統(tǒng)的忽略列表中。要使用 Git 做到這一點的話,你需要在 .gitignore 新的一行中添加 instance/ 。
密鑰
實例文件夾的隱私性成為在其里面定義不想暴露到版本控制的密鑰的最佳候選。這些密鑰可能包含了你的應用的密鑰或者第三方 API 密鑰。如果你的應用是開源的或者以后可能會公開的話,這一點特別重要。我們通常要求其他用戶或者貢獻者使用自己的密鑰。
# instance/config.py
SECRET_KEY = 'Sm9obiBTY2hyb20ga2lja3MgYXNz'
STRIPE_API_KEY = 'SmFjb2IgS2FwbGFuLU1vc3MgaXMgYSBoZXJv'
SQLALCHEMY_DATABASE_URI= \\"postgresql://user:TWljaGHFgiBCYXJ0b3N6a2lld2ljeiEh@localhost/databasename"
基于環(huán)境的配置
如果在你的生產(chǎn)環(huán)境和開發(fā)環(huán)境中的差異非常小的話,你可能想要使用實例文件夾來處理配置的變化。定義在 'instance/config.py' 文件中的配置變量能夠覆蓋 'config.py' 中的值。你只需要在 'app.config.from_object()' 后調(diào)用 'app.config.from_pyfile()'。這樣用法的好處之一就是在不同的機器上修改你的應用的配置。
# config.py
DEBUG = False
SQLALCHEMY_ECHO = False
# instance/config.py
DEBUG = True
SQLALCHEMY_ECHO = True
在生產(chǎn)環(huán)境上,我們略去上面 'instance/-config.py' 中的配置變量,它會退回到定義在 'config.py' 中的值。
基于環(huán)境變量配置
實例文件夾不應該出現(xiàn)在版本控制中。這就意味著你將無法跟蹤你的實例配置的變化。如果只是一、兩個變量這可能不是什么問題,但是如果你在不同的環(huán)境上(生產(chǎn),預升級,開發(fā),等等)配置都有些微調(diào)話,你就不會想要存在丟失它們的風險。
Flask 給我們選擇配置文件的能力,它可以基于一個環(huán)境變量的值來加載不同的配置文件。這就意味著在我們的倉庫/版本庫里,我們可以有多個配置文件并且總會加載正確的那一個。一旦我們有多個配置文件的話,我可以把它們移入它們自己 config 文件夾中。
requirements.txt
run.py
config/
__init__.py # Empty, just here to tell Python that it's a package.
default.py
production.py
development.py
staging.py
instance/
config.py
yourapp/
__init__.py
models.py
views.py
static/
templates/
在上面的文件列表中我們有多個不同的配置文件。
config/default.py: 默認的配置值,可用于所有的環(huán)境或者被個人的環(huán)境給覆蓋。
config/development.py: 用于開發(fā)環(huán)境的配置值。這里你可能會指定本地數(shù)據(jù)庫的 URI。
config/production.py: 用于生產(chǎn)環(huán)境的配置值。在這里 DEBUG 一定要設置成 False。
config/staging.py: 根據(jù)開發(fā)進度,你可能會有一個模擬生產(chǎn)環(huán)境,這個文件主要用于這種場景。
為了決定要加載哪個配置文件,我們會調(diào)用 'app.config.from_envvar()'。
# yourapp/\\_\\_init\\_\\_.py
app = Flask(__name__, instance_relative_config=True)
# Load the default configuration
app.config.from_object('config.default')
# Load the configuration from the instance folder
app.config.from_pyfile('config.py')
# Load the file specified by the APP\\_CONFIG\\_FILE environment variable# Variables defined here will override those in the default configuration
app.config.from_envvar('APP_CONFIG_FILE')
環(huán)境變量的值應該是配置文件的絕對路徑。
我們?nèi)绾卧O置這個環(huán)境變量取決于我們運行應用所在的平臺。如果我們運行在一個普通的 Linux 服務器上,我們可以編寫一個設置環(huán)境變量的 shell 腳本并且運行 run.py。
# start.sh
APP\\_CONFIG\\_FILE=/var/www/yourapp/config/production.py
python run.py
start.sh 對于每一個環(huán)境都是獨一無二的,因此它應該被排除在版本控制之外。在 Heroku 上,我們需要使用 Heroku 工具來設置環(huán)境變量。這種設置方式也適用于其它的 PaaS 平臺。
數(shù)據(jù)分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
SQL Server 中 CONVERT 函數(shù)的日期轉(zhuǎn)換:從基礎用法到實戰(zhàn)優(yōu)化 在 SQL Server 的數(shù)據(jù)處理中,日期格式轉(zhuǎn)換是高頻需求 —— 無論 ...
2025-09-18MySQL 大表拆分與關聯(lián)查詢效率:打破 “拆分必慢” 的認知誤區(qū) 在 MySQL 數(shù)據(jù)庫管理中,“大表” 始終是性能優(yōu)化繞不開的話題。 ...
2025-09-18CDA 數(shù)據(jù)分析師:表結(jié)構(gòu)數(shù)據(jù) “獲取 - 加工 - 使用” 全流程的賦能者 表結(jié)構(gòu)數(shù)據(jù)(如數(shù)據(jù)庫表、Excel 表、CSV 文件)是企業(yè)數(shù)字 ...
2025-09-18DSGE 模型中的 Et:理性預期算子的內(nèi)涵、作用與應用解析 動態(tài)隨機一般均衡(Dynamic Stochastic General Equilibrium, DSGE)模 ...
2025-09-17Python 提取 TIF 中地名的完整指南 一、先明確:TIF 中的地名有哪兩種存在形式? 在開始提取前,需先判斷 TIF 文件的類型 —— ...
2025-09-17CDA 數(shù)據(jù)分析師:解鎖表結(jié)構(gòu)數(shù)據(jù)特征價值的專業(yè)核心 表結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 規(guī)范存儲的結(jié)構(gòu)化數(shù)據(jù),如數(shù)據(jù)庫表、Excel 表、 ...
2025-09-17Excel 導入數(shù)據(jù)含缺失值?詳解 dropna 函數(shù)的功能與實戰(zhàn)應用 在用 Python(如 pandas 庫)處理 Excel 數(shù)據(jù)時,“缺失值” 是高頻 ...
2025-09-16深入解析卡方檢驗與 t 檢驗:差異、適用場景與實踐應用 在數(shù)據(jù)分析與統(tǒng)計學領域,假設檢驗是驗證研究假設、判斷數(shù)據(jù)差異是否 “ ...
2025-09-16CDA 數(shù)據(jù)分析師:掌控表格結(jié)構(gòu)數(shù)據(jù)全功能周期的專業(yè)操盤手 表格結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 存儲的結(jié)構(gòu)化數(shù)據(jù),如 Excel 表、數(shù)據(jù) ...
2025-09-16MySQL 執(zhí)行計劃中 rows 數(shù)量的準確性解析:原理、影響因素與優(yōu)化 在 MySQL SQL 調(diào)優(yōu)中,EXPLAIN執(zhí)行計劃是核心工具,而其中的row ...
2025-09-15解析 Python 中 Response 對象的 text 與 content:區(qū)別、場景與實踐指南 在 Python 進行 HTTP 網(wǎng)絡請求開發(fā)時(如使用requests ...
2025-09-15CDA 數(shù)據(jù)分析師:激活表格結(jié)構(gòu)數(shù)據(jù)價值的核心操盤手 表格結(jié)構(gòu)數(shù)據(jù)(如 Excel 表格、數(shù)據(jù)庫表)是企業(yè)最基礎、最核心的數(shù)據(jù)形態(tài) ...
2025-09-15Python HTTP 請求工具對比:urllib.request 與 requests 的核心差異與選擇指南 在 Python 處理 HTTP 請求(如接口調(diào)用、數(shù)據(jù)爬取 ...
2025-09-12解決 pd.read_csv 讀取長浮點數(shù)據(jù)的科學計數(shù)法問題 為幫助 Python 數(shù)據(jù)從業(yè)者解決pd.read_csv讀取長浮點數(shù)據(jù)時的科學計數(shù)法問題 ...
2025-09-12CDA 數(shù)據(jù)分析師:業(yè)務數(shù)據(jù)分析步驟的落地者與價值優(yōu)化者 業(yè)務數(shù)據(jù)分析是企業(yè)解決日常運營問題、提升執(zhí)行效率的核心手段,其價值 ...
2025-09-12用 SQL 驗證業(yè)務邏輯:從規(guī)則拆解到數(shù)據(jù)把關的實戰(zhàn)指南 在業(yè)務系統(tǒng)落地過程中,“業(yè)務邏輯” 是連接 “需求設計” 與 “用戶體驗 ...
2025-09-11塔吉特百貨孕婦營銷案例:數(shù)據(jù)驅(qū)動下的精準零售革命與啟示 在零售行業(yè) “流量紅利見頂” 的當下,精準營銷成為企業(yè)突圍的核心方 ...
2025-09-11CDA 數(shù)據(jù)分析師與戰(zhàn)略 / 業(yè)務數(shù)據(jù)分析:概念辨析與協(xié)同價值 在數(shù)據(jù)驅(qū)動決策的體系中,“戰(zhàn)略數(shù)據(jù)分析”“業(yè)務數(shù)據(jù)分析” 是企業(yè) ...
2025-09-11Excel 數(shù)據(jù)聚類分析:從操作實踐到業(yè)務價值挖掘 在數(shù)據(jù)分析場景中,聚類分析作為 “無監(jiān)督分組” 的核心工具,能從雜亂數(shù)據(jù)中挖 ...
2025-09-10統(tǒng)計模型的核心目的:從數(shù)據(jù)解讀到?jīng)Q策支撐的價值導向 統(tǒng)計模型作為數(shù)據(jù)分析的核心工具,并非簡單的 “公式堆砌”,而是圍繞特定 ...
2025-09-10