來自php請求的flask,php獲取請求方式

本文目錄一覽:

如何理解Nginx,uWSGI和Flask之間的關係

總括來說,客戶端從發送一個 HTTP 請求到 Flask 處理請求,分別經過了 web 伺服器層,WSGI層,web框架層,這三個層次。不同的層次其作用也不同,下面簡要介紹各層的作用。

圖1:web伺服器,web框架與 WSGI 的三層關係

Web伺服器層

對於傳統的客戶端 – 伺服器架構,其請求的處理過程是,客戶端向伺服器發送請求,伺服器接收請求並處理請求,然後給客戶端返迴響應。在這個過程中,伺服器的作用是:

接收請求

處理請求

返迴響應

Web伺服器是一類特殊的伺服器,其作用是主要是接收 HTTP 請求並返迴響應。提起 web伺服器大家都不會陌生,常見的 web伺服器有 Nginx,Apache,IIS等。在上圖1的三層結構中,web伺服器是最先接收用戶請求的,並將響應結果返回給用戶。

Web框架層

Web框架的作用主要是方便我們開發 web應用程序,HTTP請求的動態數據就是由 web框架層來提供的。常見的 web框架有Flask,Django等,我們以 Flask 框架為例子,展示 web框架的作用:

Python

from flask import Flask

app = Flask(__name__)

@app.route(‘/hello’)

def hello_world():

return ‘Hello World!’

if __name__ == ‘__main__’:

app.run(host=’0.0.0.0′, port=8080)

1

2

3

4

5

6

7

from flask import Flask

app = Flask(__name__)

@app.route(‘/hello’)

def hello_world():

return ‘Hello World!’

if __name__ == ‘__main__’:

app.run(host=’0.0.0.0′, port=8080)

以上簡單的幾行代碼,就創建了一個 web應用程序對象 app。 app 監聽機器所有 ip 的 8080

埠,接受用戶的請求連接。我們知道,HTTP 協議使用 URL 來定位資源,上面的程序會將路徑 /hello 的請求交由 hello_world

方法處理, hello_world 返回 『Hello World!』 字元串。對於 web框架的使用者來說,他們並不關心如何接收 HTTP

請求,也不關心如何將請求路由到具體方法處理並將響應結果返回給用戶。Web框架的使用者在大部分情況下,只需要關心如何實現業務的邏輯即可。

WSGI層

WSGI 不是伺服器,也不是用於與程序交互的API,更不是真實的代碼,WSGI 只是一種介面,它只適用於 Python 語言,其全稱為

Web Server Gateway Interface,定義了 web伺服器和 web應用之間的介面規範。也就是說,只要 web伺服器和

web應用都遵守WSGI協議,那麼 web伺服器和 web應用就可以隨意的組合。

下面的代碼展示了 web伺服器是如何與 web應用組合在一起的

Python

def application(env, start_response):

start_response(‘200 OK’, [(‘Content-Type’, ‘text/html’)])

return [b”Hello World”]

1

2

3

def application(env, start_response):

start_response(‘200 OK’, [(‘Content-Type’, ‘text/html’)])

return [b”Hello World”]

方法 application由 web伺服器調用,參數 env, start_response 由 web伺服器實現並傳入。其中,

env是一個字典,包含了類似 HTTPHOST,HOSTUSERAGENT,SERVERPROTOCO 等環境變數。

start_response則是一個方法,該方法接受兩個參數,分別是 status, response_headers。

application方法的主要作用是,設置 http 響應的狀態碼和 Content-Type 等頭部信息,並返迴響應的具體結果。

上述代碼就是一個完整的 WSGI 應用,當一個支持 WSGI 的 web伺服器接收到客戶端的請求後,便會調用這個 application

方法。WSGI 層並不需要關心 env, start_response 這兩個變數是如何實現的,就像在 application

裡面所做的,直接使用這兩個變數即可。

值得指出的是,WSGI 是一種協議,需要區分幾個相近的名詞:

uwsgi:同 wsgi 一樣也是一種協議,uWSGI伺服器正是使用了 uwsgi 協議

uWSGI:實現了 uwsgi 和 WSGI 兩種協議的web伺服器。注意 uWSGI 本質上也是一種 web伺服器,處於上面描述的三層結構中的 web伺服器層。

CGI:通用網關介面,並不限於 Python 語言,定義了 web伺服器是如何向客戶端提供動態的內容。例如,規定了客戶端如何將參數傳遞給 web伺服器,web伺服器如何將參數傳遞給 web應用,web應用如何將它的輸出如何發送給客戶端,等等。

生產環境下的 web應用都不使用 CGI 了,CGI進程(類似 Python 解釋器)針對每個請求創建,用完就拋棄,效率低下。WSGI 正是為了替代 CGI 而出現的。

說到這,我們基本理清了 WSGI 在 web伺服器與 web框架之間作用:WSGI 就像一條紐帶,將 web伺服器與

web框架連接起來。回到本文的題目,Nginx 屬於一種 web伺服器,Flask屬於一種 web框架,因此,WSGI 與

Nginx、Flask 的作用就不明而喻了。

Nginx,WSGI,Flask 之間的對話

Nginx:Hey,WSGI,我剛收到了一個請求,我需要你作些準備,然後由Flask來處理這個請求。

WSGI:OK,Nginx。我會設置好環境變數,然後將這個請求傳遞給Flask處理。

Flask:Thanks WSGI!給我一些時間,我將會把請求的響應返回給你。

WSGI:Alright,那我等你。

Flask:Okay,我完成了,這裡是請求的響應結果,請求把結果傳遞給Nginx。 WSGI:Good job!

Nginx,這裡是響應結果,已經按照要求給你傳遞迴來了。

Nginx:Cool,我收到了,我把響應結果返回給客戶端。大家合作愉快~

使用flask開發的網站有哪些

Python 生態圈有兩個現象級的 Web 框架 Flask, Django.

兩個框架風格迥異, 但是都各自帶動了龐大的生態圈, 這得益於二者靈活的擴展能力.

本書講述的是基於 Flask 開發 Web 項目.

在對 Flask 框架的各個部分簡要分析後, 本書介紹了

* 表單處理(Flask-WTF)

* 持久化(Flask-SQLAlchemy, 這貨作者就是 Flask 的作者喲)

* 郵件

* 配置

* 一個真實案例: 模型, 用戶驗證, 角色, 關注, 寫template, 寫API

# 特點

* 線程局部變數

我不知道該把這個稱作特點還是缺點.

至少在Flask的文檔中作者明確給出這樣的解釋: 作為一個碼農, 你也許會感到不適, 但我就想這樣設計.

大部分的 Web 框架, 請求對象是外部注入的, 唯獨 Flask 選擇了全局 (flask.request, flask.g).

這個特點存在意味著你要小心使用這個特性, 否則很容易遇上需要調試大半天的Bug.

另外, request 不是那麼容易造出來的.

不過, 這不是什麼大不了的事情.

這個順便波及到測試, 測試的setup 與 teardown, 你必須去營造一個上下文, 關於這點, 書中有講解如何操作.

* Route/Template

框架的路由使用的是Werkzeug.

Template使用的是Jinja2, 當然不喜歡的話, 用別的也很簡單.

* 足夠小

Flask 只封裝了請求, 路由, 模板這麼幾個功能.

用起來容易, 要寫好也得費點腦子漲點經驗才行.

說穿了也就是一句話:

The idea of Flask is to build a good foundation for all applications.

Everything else is up to you or extensions.

[Ref: What Flask is, What Flask is Not]()

# 工作流

常規的三板斧: 開發, 測試, 部署.

書裡面的部署和配置這兩章節講的很出色, 值得一讀, 我給打五星.

# 插件

借用 @死魚眼28號 常說的一句話, 很多 Flask 插件都寫得很渣.

我表示 +1.

挑選插件時記得看下插件源碼, 給作者的碼力打個分再決定要不要用.

# 後記

關於 Web 開發, 我們的選擇有很多:

* PHP(Laravel, CodeIgniter, Yii, Symfony, CakePHP, etc.)

* Ruby(RoR, Sinatra, etc.)

* Python(Flask, Django, Quixote, Web.py, Bottle, etc.)

* Java/Scala(Spring, Play!, etc.)

殊途同歸, 他們也給出了幾乎一樣的解決方案.

我們可以看到大部分的 Web 項目都有著類似的目錄分類, 類似的架構.

Flask 也不外乎如此: 幫你包裝好請求對象, 剩下的路由, 路由邏輯, 響應內容你來填.

上面大部分框架從大學到工作或多或少使用過, 其實真正寫到業務層面時, 框架那些都不是事兒.

你想要的東西, 或框架自己造, 或慫恿隊友幫你造, 或你自己造, 總之基本上你總能拿到你要的信息.

不要被框架局限了視野喲.

flask 比 php 好在哪裡

flask 是python的一個框架

而php是一種編輯語言

你來告訴我:怎麼比?

如何用 flask 優雅的實現 restful api

首先,安裝Flask

pip install flask

閱讀這篇文章之前我假設你已經了解RESTful API的相關概念,如果不清楚,可以閱讀我之前寫的這篇博客[Designing a RESTful Web API

Flask是一個使用Python開發的基於Werkzeug的Web框架。

Flask非常適合於開發RESTful API,因為它具有以下特點:

?使用Python進行開發,Python簡潔易懂

?容易上手

?靈活

?可以部署到不同的環境

?支持RESTful請求分發

我一般是用curl命令進行測試,除此之外,還可以使用Chrome瀏覽器的postman擴展。

資源

首先,我創建一個完整的應用,支持響應/, /articles以及/article/:id。

from flask import Flask, url_for

app = Flask(__name__)

@app.route(‘/’)

def api_root():

return ‘Welcome’

@app.route(‘/articles’)

def api_articles():

return ‘List of ‘ + url_for(‘api_articles’)

@app.route(‘/articles/articleid’)

def api_article(articleid):

return ‘You are reading ‘ + articleid

if __name__ == ‘__main__’:

app.run()

可以使用curl命令發送請求:

響應結果分別如下所示:

GET /

Welcome

GET /articles

List of /articles

GET /articles/123

You are reading 123

路由中還可以使用類型定義:

@app.route(‘/articles/articleid’)

上面的路由可以替換成下面的例子:

@app.route(‘/articles/int:articleid’)

@app.route(‘/articles/float:articleid’)

@app.route(‘/articles/path:articleid’)

默認的類型為字元串。

請求

請求參數

假設需要響應一個/hello請求,使用get方法,並傳遞參數name

from flask import request

@app.route(‘/hello’)

def api_hello():

if ‘name’ in request.args:

return ‘Hello ‘ + request.args[‘name’]

else:

return ‘Hello John Doe’

伺服器會返回如下響應信息:

GET /hello

Hello John Doe

GET /hello?name=Luis

Hello Luis

請求方法

Flask支持不同的請求方法:

@app.route(‘/echo’, methods = [‘GET’, ‘POST’, ‘PATCH’, ‘PUT’, ‘DELETE’])

def api_echo():

if request.method == ‘GET’:

return “ECHO: GET\n”

elif request.method == ‘POST’:

return “ECHO: POST\n”

elif request.method == ‘PATCH’:

return “ECHO: PACTH\n”

elif request.method == ‘PUT’:

return “ECHO: PUT\n”

elif request.method == ‘DELETE’:

return “ECHO: DELETE”

可以使用如下命令進行測試:

curl -X PATCH :5000/echo

不同請求方法的響應如下:

GET /echo

ECHO: GET

POST /ECHO

ECHO: POST

請求數據和請求頭

通常使用POST方法和PATCH方法的時候,都會發送附加的數據,這些數據的格式可能如下:普通文本(plain text), JSON,XML,二進位文件或者用戶自定義格式。

Flask中使用request.headers類字典對象來獲取請求頭信息,使用request.data 獲取請求數據,如果發送類型是application/json,則可以使用request.get_json()來獲取JSON數據。

from flask import json

@app.route(‘/messages’, methods = [‘POST’])

def api_message():

if request.headers[‘Content-Type’] == ‘text/plain’:

return “Text Message: ” + request.data

elif request.headers[‘Content-Type’] == ‘application/json’:

return “JSON Message: ” + json.dumps(request.json)

elif request.headers[‘Content-Type’] == ‘application/octet-stream’:

f = open(‘./binary’, ‘wb’)

f.write(request.data)

f.close()

return “Binary message written!”

else:

return “415 Unsupported Media Type ;)”

使用如下命令指定請求數據類型進行測試:

curl -H “Content-type: application/json” \

-X POST :5000/messages -d ‘{“message”:”Hello Data”}’

使用下面的curl命令來發送一個文件:

curl -H “Content-type: application/octet-stream” \

-X POST :5000/messages –data-binary @message.bin

不同數據類型的響應結果如下所示:

POST /messages {“message”: “Hello Data”}

Content-type: application/json

JSON Message: {“message”: “Hello Data”}

POST /message message.bin

Content-type: application/octet-stream

Binary message written!

注意Flask可以通過request.files獲取上傳的文件,curl可以使用-F選項模擬上傳文件的過程。

響應

Flask使用Response類處理響應。

from flask import Response

@app.route(‘/hello’, methods = [‘GET’])

def api_hello():

data = {

‘hello’ : ‘world’,

‘number’ : 3

}

js = json.dumps(data)

resp = Response(js, status=200, mimetype=’application/json’)

resp.headers[‘Link’] = ”

return resp

使用-i選項可以獲取響應信息:

curl -i :5000/hello

返回的響應信息如下所示:

GET /hello

HTTP/1.0 200 OK

Content-Type: application/json

Content-Length: 31

Link:

Server: Werkzeug/0.8.2 Python/2.7.1

Date: Wed, 25 Apr 2012 16:40:27 GMT

{“hello”: “world”, “number”: 3}

mimetype指定了響應數據的類型。

上面的過程可以使用Flask提供的一個簡便方法實現:

from flask import jsonify

# 將下面的代碼替換成

resp = Response(js, status=200, mimetype=’application/json’)

# 這裡的代碼

resp = jsonify(data)

resp.status_code = 200

狀態碼和錯誤處理

如果成功響應的話,狀態碼為200。對於404錯誤我們可以這樣處理:

@app.errorhandler(404)

def not_found(error=None):

message = {

‘status’: 404,

‘message’: ‘Not Found: ‘ + request.url,

}

resp = jsonify(message)

resp.status_code = 404

return resp

@app.route(‘/users/userid’, methods = [‘GET’])

def api_users(userid):

users = {‘1′:’john’, ‘2’:’steve’, ‘3’:’bill’}

if userid in users:

return jsonify({userid:users[userid]})

else:

return not_found()

測試上面的兩個URL,結果如下:

GET /users/2

HTTP/1.0 200 OK

{

“2”: “steve”

}

GET /users/4

HTTP/1.0 404 NOT FOUND

{

“status”: 404,

“message”: “Not Found: :5000/users/4”

}

默認的Flask錯誤處理可以使用@error_handler修飾器進行覆蓋或者使用下面的方法:

app.error_handler_spec[None][404] = not_found

即使API不需要自定義錯誤信息,最好還是像上面這樣做,因為Flask默認返回的錯誤信息是HTML格式的。

認證

使用下面的代碼可以處理 HTTP Basic Authentication。

from functools import wraps

def check_auth(username, password):

return username == ‘admin’ and password == ‘secret’

def authenticate():

message = {‘message’: “Authenticate.”}

resp = jsonify(message)

resp.status_code = 401

resp.headers[‘WWW-Authenticate’] = ‘Basic realm=”Example”‘

return resp

def requires_auth(f):

@wraps(f)

def decorated(*args, **kwargs):

auth = request.authorization

if not auth:

return authenticate()

elif not check_auth(auth.username, auth.password):

return authenticate()

return f(*args, **kwargs)

return decorated

接下來只需要給路由增加@require_auth修飾器就可以在請求之前進行認證了:

@app.route(‘/secrets’)

@requires_auth

def api_hello():

return “Shhh this is top secret spy stuff!”

現在,如果沒有通過認證的話,響應如下所示:

GET /secrets

HTTP/1.0 401 UNAUTHORIZED

WWW-Authenticate: Basic realm=”Example”

{

“message”: “Authenticate.”

}

curl通過-u選項來指定HTTP basic authentication,使用-v選項列印請求頭:

curl -v -u “admin:secret”

響應結果如下:

GET /secrets Authorization: Basic YWRtaW46c2VjcmV0

Shhh this is top secret spy stuff!

Flask使用MultiDict來存儲頭部信息,為了給客戶端展示不同的認證機制,可以給header添加更多的WWW-Autheticate。

resp.headers[‘WWW-Authenticate’] = ‘Basic realm=”Example”‘resp.headers.add(‘WWW-Authenticate’, ‘Bearer realm=”Example”‘)

調試與日誌

通過設置debug=True來開啟調試信息:

app.run(debug=True)

使用Python的logging模塊可以設置日誌信息:

import logging

file_handle(‘app.log’)

app.logger.addHandler(file_handler)

app.logger.setLevel(logging.INFO)

@app.route(‘/hello’, methods = [‘GET’])

def api_hello():

app.logger.info(‘informing’)

app.logger.warning(‘warning’)

app.logger.error(‘screaming bloody murder!’)

return “check your logs\n”

CURL 命令參考

選項

作用

-X 指定HTTP請求方法,如POST,GET

-H 指定請求頭,例如Content-type:application/json

-d 指定請求數據

–data-binary 指定發送的文件

-i 顯示響應頭部信息

-u 指定認證用戶名與密碼

-v 輸出請求頭部信息

python輕量框架–Flask(入門教程)

1.建立: F:\Python\flask文件夾路徑

2.安裝virtualenv,在此路徑下打開命令行窗口輸入:

3.新建一個目錄,並在裡邊創建virtualenv環境,在DOS下

如圖:

這時你創建的myproject文件夾裡面就多了一個venv文件夾:

4.激活虛擬環境

現在命令行前面多了個(venv)表示你在venv環境內

5.在virtualenv里安裝Flask

完成。如圖:

6.驗證是否安裝,你可以進入 Python 解釋器,嘗試導入 Flask:

如果沒有報錯,那麼就安裝成功了~如圖:

1.在myproject文件夾下打開命令行:

cd app #進入app文件夾

mkdir static

mkdir templates

我們的應用程序包是放置於 app 文件夾中。子文件夾 static 是我們存放靜態文件像圖片,JS文件以及樣式文件。子文件夾 templates 顯然是存放模板文件。

2.為我們的 app 包(文件 app/ init .py )創建一個簡單的初始化腳本:

上面的腳本簡單地創建應用對象,接著導入視圖模塊,該模塊我們暫未編寫。

視圖是響應來自網頁瀏覽器的請求的處理器。在 Flask 中,視圖是編寫成 Python 函數。每一個視圖函數是映射到一個或多個請求的 URL。

3.讓我們編寫第一個視圖函數(文件 app/views.py ):

其實這個視圖是非常簡單,它只是返回一個字元串,在客戶端的網頁瀏覽器上顯示。兩個 route 裝飾器創建了從網址 / 以及 /index 到這個函數的映射。

4.能夠完整工作的 Web 應用程序的最後一步是創建一個腳本,啟動我們的應用程序的開發 Web 伺服器。讓我們稱這個腳本為 run.py,並把它置於根目錄:

這個腳本簡單地從我們的 app 包中導入 app 變數並且調用它的 run 方法來啟動伺服器。請記住 app 變數中含有我們在之前創建的 Flask 實例。

5.要啟動應用程序,您只需運行此腳本(run.py)

如圖:

6.在伺服器初始化後,它將會監聽 5000 埠等待著連接。現在打開你的網頁瀏覽器輸入如下 URL:

另外你也可以使用這個 URL:

你看清楚了路由映射是如何工作的嗎?第一個 URL 映射到 /,而第二個 URL 映射到 /index。這兩個路由都關聯到我們的視圖函數,因此它們的作用是一樣的。如果你輸入其它的網址,你將會獲得一個錯誤,因為只有這兩個 URL 映射到視圖函數。

你可以通過 Ctrl-C 來終止伺服器

入門就到這裡,比較簡單的。

下一章:

python輕量框架–Flask(模板詳細版)

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/251001.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-13 13:31
下一篇 2024-12-13 13:31

相關推薦

  • PHP和Python哪個好找工作?

    PHP和Python都是非常流行的編程語言,它們被廣泛應用於不同領域的開發中。但是,在考慮擇業方向的時候,很多人都會有一個問題:PHP和Python哪個好找工作?這篇文章將從多個方…

    編程 2025-04-29
  • 做Python的Flask開發,必須安裝PyCharm

    PyCharm是一款專業的Python集成開發環境(IDE),適用於Flask、Django等Web開發框架,提供了強大的代碼編輯、調試和版本控制等功能,大大提高了開發效率和代碼質…

    編程 2025-04-29
  • PHP怎麼接幣

    想要在自己的網站或應用中接受比特幣等加密貨幣的支付,就需要對該加密貨幣擁有一定的了解,並使用對應的API進行開發。本文將從多個方面詳細闡述如何使用PHP接受加密貨幣的支付。 一、環…

    編程 2025-04-29
  • Python緩存圖片的處理方式

    本文將從多個方面詳細闡述Python緩存圖片的處理方式,包括緩存原理、緩存框架、緩存策略、緩存更新和緩存清除等方面。 一、緩存原理 緩存是一種提高應用程序性能的技術,在網路應用中流…

    編程 2025-04-29
  • 使用PHP foreach遍歷有相同屬性的值

    本篇文章將介紹如何使用PHP foreach遍歷具有相同屬性的值,並給出相應的代碼示例。 一、基礎概念 在講解如何使用PHP foreach遍歷有相同屬性的值之前,我們需要先了解幾…

    編程 2025-04-28
  • Python在線編輯器的優勢與實現方式

    Python在線編輯器是Python語言愛好者的重要工具之一,它可以讓用戶方便快捷的在線編碼、調試和分享代碼,無需在本地安裝Python環境。本文將從多個方面對Python在線編輯…

    編程 2025-04-28
  • Java表單提交方式

    Java表單提交有兩種方式,分別是get和post。下面我們將從以下幾個方面詳細闡述這兩種方式。 一、get方式 1、什麼是get方式 在get方式下,表單的數據會以查詢字元串的形…

    編程 2025-04-27
  • PHP獲取301跳轉後的地址

    本文將為大家介紹如何使用PHP獲取301跳轉後的地址。301重定向是什麼呢?當我們訪問一個網頁A,但是它已經被遷移到了另一個地址B,此時若伺服器端做了301重定向,那麼你的瀏覽器在…

    編程 2025-04-27
  • 用Pythonic的方式編寫高效代碼

    Pythonic是一種編程哲學,它強調Python編程風格的簡單、清晰、優雅和明確。Python應該描述為一種語言而不是一種編程語言。Pythonic的編程方式不僅可以使我們在編碼…

    編程 2025-04-27
  • Java多版本支持實現方式

    本文將從以下幾個方面闡述如何實現Java多版本支持,並給出可行的代碼示例。 一、多版本Java環境概述 Java是一門跨平台的編程語言,但是在不同的應用場景下,可能需要使用不同版本…

    編程 2025-04-27

發表回復

登錄後才能評論