深度定制Python的Flask框架開發(fā)環(huán)境的一些技巧總結
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 命令。它需要一個參數,這個參數就是虛擬環(huán)境的目標目錄。下面展示了它大概的樣子。
$ virtualenv venv New python executable in venv/bin/python Installing Setuptools...........[...].....done. Installing Pip..................[...].....done.
virtualenv 創(chuàng)建一個新的目錄,依賴包將會安裝到這個目錄中。
一旦新的虛擬環(huán)境已經創(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 中的提示符也已經改變了。virtualenv 預先設定目前激活虛擬環(huán)境的名稱,因此你會知道你不是在全局系統(tǒng)上工作。
你可以通過運行 deactivate 命令停用你的虛擬環(huán)境。
(venv)$ deactivate
virtualenvwrapper
virtualenvwrapper 是一個用于管理 virtualenv 創(chuàng)建的虛擬環(huán)境的軟件包。我不想提到這個工具,直到你看到了 virtualenv 的基礎知識以便你理解它改善了什么以及為什么我們應該使用它。
上一部分創(chuàng)建的虛擬環(huán)境目錄會給你的項目庫帶來一些混亂。你只需要激活虛擬環(huán)境和它進行交互,但是它不應該出現在版本控制中,因此這個虛擬環(huán)境目錄就不應該在這里。解決方案就是使用 virtualenvwrapper。這個軟件包會把所有你的虛擬環(huán)境放在一個目錄的方式,通常默認是在 ~/.virtualenvs/。
要安裝 virtualenvwrapper,請按照文檔中的說明,文檔位于 http://virtualenvwrapper.readthedocs.org/en/latest/install.html 。
請確保在安裝 virtualenvwrapper 之前你已經停用所有的虛擬環(huán)境。你需要把它安裝在全局系統(tǒng)中,而不是虛擬環(huán)境中。
現在,不用運行 virtualenv 來創(chuàng)建一個環(huán)境,你需要運行 mkvirtualenv:
$ mkvirtualenv rocket New python executable in rocket/bin/python Installing setuptools...........[...].....done. Installing pip..................[...].....done. (rocket)$
安裝依賴包
隨著項目的發(fā)展,你會發(fā)現依賴包的列表會增大。需要幾十個 Python 包來運行一個 Flask 應用程序的情況并不少見。管理這些最簡單的方法是用一個簡單的文本文件。Pip 能夠生成一個列出所有已安裝的包的文本文件。在一個新的系統(tǒng)上,或者在一個新的剛創(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ā)現 pip freeze 列出的某些包實際上并不是運行應用必須的。你安裝這些包僅僅為開發(fā)用的。pip freeze 并不能區(qū)分,它僅僅列出目前已經安裝的包。因此,你可能要手動地管理這些依賴包。你可以分別把那些運行應用必須的包放入 require\_run.txt 以及那些開發(fā)應用程序需要的包放入 require\_dev.txt 。
版本控制
選擇一個版本控制系統(tǒng)并且使用它。我推薦 Git。從我所看到的,Git 是這些天來新項目最流行的選擇。能夠刪除代碼而不必擔心犯了一個不可逆轉的錯誤是非常寶貴的。你也可以讓你的項目擺脫大量注釋掉的代碼的困擾,因為你可以刪除它們,以后如有需要可以恢復它們。另外,你可以在 GitHub,Bitbucket 或者你自己的 Gitolite 服務器上備份整個項目。
置身版本控制之外的文件
我通常會讓一個文件置身版本控制之外有兩個原因:要么就是它會讓整個項目顯得混亂,要么它就是一個很隱私的密鑰/證書。編譯的 .pyc 文件和虛擬環(huán)境 — 如果由于某些原因你沒有使用 virtualenvwrapper — 就是讓項目顯得很混亂的例子。它們不需要在版本控制之中因為它們能夠分別地從 .py 文件和你的 requirements.txt 文件重新創(chuàng)建。
API 秘鑰,應用程序秘鑰以及數據庫證書是很隱私的密鑰/證書的示例。它們不應該出現在版本控制中因為它們的曝光將是一個巨大的安全漏洞。
當做跟安全有關的決定的時候,我總是喜歡假設我的版本庫將在某個時候變成公開的。這就意味著要保守秘密并且從不假設一個安全漏洞不會被發(fā)現,“誰來猜猜他們能做到”這類型的假設被稱為通過隱匿來實現安全,這是十分槽糕的策略。
當使用 Git 的時候,你可以在你的版本庫中創(chuàng)建名為 .gitignore 的一個特殊文件。在這個文件里,使用列表通配符來匹配文件名。任何匹配其中一個模式的文件名都會被 Git 給忽略掉。我推薦使用 .gitignore 來控制不需要版本控制的文件。例如:
*.pyc instance/
你可以閱讀更多的關于 .gitignore 的內容從這里: http://git-scm.com/docs/gitignore
調試
1.調試模式
Flask 有一個稱為調試模式方便的功能。要打開調試功能的話,你只必須在你的開發(fā)配置中設置 debug = True。當它打開的時候,服務器會在代碼變化的時候自動加載并且出錯的時候會伴隨著一個堆棧跟蹤和一個交互式控制臺。
小心!不要在生產環(huán)境中使用調試模式。交互式控制臺允許執(zhí)行任意代碼并會是一個巨大的安全漏洞。
2.Flask-DebugToolbar
Flask-DebugToolbar 是另一個非常了不起的工具,它可以幫助在你的應用程序中調試問題。在調試模式下,它會把一個側邊欄置于你的應用程序的每一頁上。側邊欄提供了有關 SQL 查詢,日志記錄,版本,模板,配置和其它有趣的信息,使得更容易地跟蹤問題。
看看快速入門中的 調試模式。在 Flask 官方文檔 中有一些關于錯誤處理,日志記錄以及使用調試器等不錯的信息。
Flask 工程配置
當你學習 Flask 的時候,配置看起來很簡單。你只要在 config.py 中定義一些變量接著一切就能工作了。當你開始必須要管理生產應用的配置的時候,這些簡單性開始消失了。你可能需要保護 API 密鑰以及為不同的環(huán)境使用不同的配置(例如,開發(fā)和生產環(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: 為你提供了調試錯誤的一些方便的工具。 這包括一個基于 Web 的堆棧跟蹤和交互式的 Python 控制臺。在開發(fā)環(huán)境中設置成 True; 生產環(huán)境中設置成 False。
- SECRET\_KEY:這是 Flask 用來為 cookies 簽名的密鑰。 它也能被像 Flask-Bcrypt 類的擴展使用。 你應該在你的實例文件夾中定義它, 這樣可以遠離版本控制。 你可以在下一個章節(jié)中閱讀更多關于示例文件夾的內容。一般情況下這應該是一個復雜的隨機值。
- BCRYPT\_LEVEL:如果你使用 Flask-Bcrypt 來散列用戶密碼的話, 你需要指定一個“循環(huán)”數,這個數是在執(zhí)行散列密碼的 算法需要的。如果你不使用 Flask-Bcrypt,你可以 忽略這里。用于散列密碼的循環(huán)數越大,攻擊者猜測密碼 的時間會越長。同時,循環(huán)數越大會增加散列密碼的時間。后面我們會給出在 Flask 應用中 使用 Bcrypt 的一些最佳實踐。
確保在生產環(huán)境中 DEBUG 設置成 False。如果保留 DEBUG 為 True,它允許用戶在你的服務器上執(zhí)行任意的 Python。
實例文件夾
有時候你需要定義包含敏感信息的配置變量。我們想要從 config.py 中分離這些變量并且讓它們保留在倉庫/版本庫之外。你可能會隱藏像數據庫密碼以及 API 密鑰的一些敏感信息,或者定義于特定于指定機器的配置變量。為讓實現這些要求更加容易些,Flask 提供了一個叫做 instance folders 的功能。實例文件夾是倉庫/版本庫下的一個子目錄并且包含專門為這個應用程序的實例的一個配置文件。我們不希望它提交到版本控制。
config.py requirements.txt run.py instance/ config.py yourapp/ __init__.py models.py views.py templates/ static/
使用實例文件夾
我們使用 app.config.from_pyfile() 來從一個實例文件夾中加載配置變量。當我們調用 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')
現在我們可以像在 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)境的配置
如果在你的生產環(huán)境和開發(fā)環(huán)境中的差異非常小的話,你可能想要使用實例文件夾來處理配置的變化。定義在 'instance/config.py' 文件中的配置變量能夠覆蓋 'config.py' 中的值。你只需要在 'app.config.from_object()' 后調用 'app.config.from_pyfile()'。這樣用法的好處之一就是在不同的機器上修改你的應用的配置。
# config.py DEBUG = False SQLALCHEMY_ECHO = False # instance/config.py DEBUG = True SQLALCHEMY_ECHO = True
在生產環(huán)境上,我們略去上面 'instance/-config.py' 中的配置變量,它會退回到定義在 'config.py' 中的值。
了解更多關于 Flask-SQLAlchemy 的 配置項。(中文版的位于:http://www.pythondoc.com/flask-sqlalchemy/config.html#configuration-keys)
基于環(huán)境變量配置
實例文件夾不應該出現在版本控制中。這就意味著你將無法跟蹤你的實例配置的變化。如果只是一、兩個變量這可能不是什么問題,但是如果你在不同的環(huán)境上(生產,預升級,開發(fā),等等)配置都有些微調話,你就不會想要存在丟失它們的風險。
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)境的配置值。這里你可能會指定本地數據庫的 URI。
- config/production.py: 用于生產環(huán)境的配置值。在這里 DEBUG 一定要設置成 False。
- config/staging.py: 根據開發(fā)進度,你可能會有一個模擬生產環(huán)境,這個文件主要用于這種場景。
為了決定要加載哪個配置文件,我們會調用 '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)境變量的值應該是配置文件的絕對路徑。
我們如何設置這個環(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 平臺。
相關文章
Python實現Mysql數據統(tǒng)計及numpy統(tǒng)計函數
這篇文章主要介紹了Python實現Mysql數據統(tǒng)計的實例代碼,給大家介紹了Python數據分析numpy統(tǒng)計函數的相關知識,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-07-07
python?中?關于reverse()?和?reversed()的用法詳解
這篇文章主要介紹了python?中?關于reverse()?和?reversed()的用法介紹,本文結合實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-01-01

