項(xiàng)目地址: https://github.com/mirrorhanyu/WeGit
掃碼體驗(yàn)
WeGit-api
├── Dockerfile
├── go.sh
├── main.py
├── requirements.txt
├── settings.py
├── database
│ ├── models
│ ├── database_helper.py
│ ├── database_initializer.py
│ ├── database_engine.py
├── decorators
├── deploy
├── migration
├── notifications
├── rest
│ ├── developer.py
│ ├── health_check.py
│ ├── language.py
│ ├── repository.py
│ └── search.py
└── utils
整體項(xiàng)目可以從 Dockerfile 開(kāi)始往里查看
FROM frolvlad/alpine-python3
RUN apk add --update alpine-sdk libxslt-dev libffi-dev libxml2-dev openssl-dev postgresql-dev python3-dev
RUN pip3 install virtualenv
WORKDIR /app
COPY ./ /app
EXPOSE 5000
CMD ["sh", "go.sh"]
Dockerfile 定義基于 frolvlad/alpine-python3 基礎(chǔ)鏡像捐友,并 install virtualenv,提供隔離的 python 環(huán)境。然后把項(xiàng)目代碼拷貝到鏡像禁舷,當(dāng)鏡像run起來(lái)會(huì)最終執(zhí)行入口文件 go.sh
那么我們?nèi)?go.sh 文件里看看
function run {
setUp
migrate
gunicorn -w 4 -b 0.0.0.0:5000 main:app
}
run
setup 配置 python 環(huán)境,并 pip install 需要的依賴凰萨。
migrate 管理數(shù)據(jù)庫(kù)的 Schema 遷移
最后用 gunicorn host 整個(gè) flask application冤议。
這里沒(méi)有采用 flask 內(nèi)置的 server,是因?yàn)?flask run 內(nèi)置的 server 是開(kāi)發(fā)版停巷,不夠高效耍攘,穩(wěn)定和安全。
更多細(xì)節(jié)可參考:
Deploy Flask to Production
Standalone WSGI Containers
可以看到 flask application 其實(shí)是定義在 main:app 中畔勤,讓我們?cè)偃タ纯?main.py 里的 app 是什么蕾各。
app 其實(shí)就是一個(gè) Flask 實(shí)例, 通過(guò) register_blueprint 注冊(cè)加載路由庆揪。
同時(shí)式曲,flask 還提供很多 decorations,比如 @errorhandler缸榛,@after_request 注冊(cè)(Registering)對(duì)應(yīng)事件的處理邏輯(Handling)
當(dāng) request 進(jìn)來(lái)到 flask application 中吝羞,對(duì)應(yīng)路由的 handler 會(huì)有相應(yīng)的處理邏輯兰伤,然后返回 response 給消費(fèi)端。
如果請(qǐng)求鏈路中出錯(cuò)脆贵,或者請(qǐng)求結(jié)束医清,注冊(cè)過(guò) @errorhandler,@after_request 的 handlers 會(huì)做相應(yīng)的處理卖氨。
decorates
這里采用 functors会烙,以項(xiàng)目中一個(gè)代碼片段為例,
def require_requests_session(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
requests_session = requests.Session()
requests_session.hooks.update({
'response': [log_request_and_response, raise_for_status]
})
return func(*args, **kwargs, requests_session=requests_session)
return wrapper
這里提供了一個(gè) @require_requests_session 的裝飾器筒捺。
首先獲取 requests 的 session 實(shí)例柏腻,然后加上 requests 包提供的 hook,當(dāng)獲取到 response 的時(shí)候系吭,打印 request 和 response 的具體內(nèi)容五嫂,并且 raise exception 當(dāng) response status code 不是 200 的時(shí)候。
裝飾上 @require_requests_session 的函數(shù)會(huì)額外接收一個(gè)名為 requests_session 的參數(shù)肯尺∥衷担可以用這個(gè)加上 hook 的 session 去做請(qǐng)求。會(huì)在請(qǐng)求結(jié)束時(shí)完成打印则吟,和驗(yàn)證請(qǐng)求結(jié)果槐臀。