當前位置:
首頁 > 知識 > API Star:一個 Python 3 的 API 框架

API Star:一個 Python 3 的 API 框架

(點擊

上方公眾號

,可快速關注)




編譯:linux中國-MjSeven,英文:MASNUN


https://linux.cn/article-9987-1.html




為了在 Python 中快速構建 API,我主要依賴於 

Flask

。最近我遇到了一個名為 「API Star」 的基於 Python 3 的新 API 框架。由於幾個原因,我對它很感興趣。首先,該框架包含 Python 新特點,如類型提示和 asyncio。而且它再進一步為開發人員提供了很棒的開發體驗。我們很快就會講到這些功能,但在我們開始之前,我首先要感謝 Tom Christie,感謝他為 Django REST Framework 和 API Star 所做的所有工作。

現在說回 API Star —— 我感覺這個框架很有成效。我可以選擇基於 asyncio 編寫非同步代碼,或者可以選擇傳統後端方式就像 WSGI 那樣。它配備了一個命令行工具 —— 

apistar

來幫助我們更快地完成工作。它支持 Django ORM 和 SQLAlchemy,這是可選的。它有一個出色的類型系統,使我們能夠定義輸入和輸出的約束,API Star 可以自動生成 API 的模式(包括文檔),提供驗證和序列化功能等等。雖然 API Star 專註於構建 API,但你也可以非常輕鬆地在其上構建 Web 應用程序。在我們自己構建一些東西之前,所有這些可能都沒有意義的。


開始


我們將從安裝 API Star 開始。為此實驗創建一個虛擬環境是一個好主意。如果你不知道如何創建一個虛擬環境,不要擔心,繼續往下看。



pip install

apistar




(譯註:上面的命令是在 Python 3 虛擬環境下使用的)


如果你沒有使用虛擬環境或者你的 Python 3 的 pip 名為 pip3,那麼使用 pip3 install apistar 代替。


一旦我們安裝了這個包,我們就應該可以使用 apistar 命令行工具了。我們可以用它創建一個新項目,讓我們在當前目錄中創建一個新項目。



apistar new

.




現在我們應該創建兩個文件:

app.py

,它包含主應用程序,然後是 

test.py

,它用於測試。讓我們來看看 

app.py

 文件:




from

apistar

import

Include

,

Route


from

apistar

.

frameworks

.

wsgi

import

WSGIApp

as

App


from

apistar

.

handlers

import

docs_urls

,

static_urls


def

welcome

(

name

=

None

)

:


    

if

name

is

None

:


        

return

{

"message"

:

"Welcome to API Star!"

}


    

return

{

"message"

:

"Welcome to API Star, %s!"

%

name

}


routes

=

[


    

Route

(

"/"

,

"GET"

,

welcome

),


    

Include

(

"/docs"

,

docs_urls

),


    

Include

(

"/static"

,

static_urls

)


]


app

=

App

(

routes

=

routes

)


if

__name__

==

"__main__"

:


    

app

.

main

()



在我們深入研究代碼之前,讓我們運行應用程序並查看它是否正常工作。我們在瀏覽器中輸入 

http://127.0.0.1:8080/

,我們將得到以下響應:





{

"message"

:

"Welcome to API Star!"

}




如果我們輸入:

http://127.0.0.1:8080/?name=masnun





{

"message"

:

"Welcome to API Star, masnun!"

}




同樣的,輸入 

http://127.0.0.1:8080/docs/

,我們將看到自動生成的 API 文檔。


現在讓我們來看看代碼。我們有一個 

welcome

 函數,它接收一個名為 

name

 的參數,其默認值為 

None

。API Star 是一個智能的 API 框架。它將嘗試在 url 路徑或者查詢字元串中找到 

name

 鍵並將其傳遞給我們的函數,它還基於其生成 API 文檔。這真是太好了,不是嗎?


然後,我們創建一個 

Route

 和 

Include

 實例的列表,並將列表傳遞給 

App

 實例。

Route

 對象用於定義用戶自定義路由。顧名思義,

Include

 包含了在給定的路徑下的其它 url 路徑。


路由


路由很簡單。當構造 

App

 實例時,我們需要傳遞一個列表作為 

routes

 參數,這個列表應該有我們剛才看到的 

Route

 或 

Include

 對象組成。對於 

Route

,我們傳遞一個 url 路徑,http 方法和可調用的請求處理程序(函數或者其他)。對於 

Include

 實例,我們傳遞一個 url 路徑和一個 

Routes

 實例列表。


路徑參數


我們可以在花括弧內添加一個名稱來聲明 url 路徑參數。例如 

/user/{user_id}

 定義了一個 url,其中 

user_id

 是路徑參數,或者說是一個將被注入到處理函數(實際上是可調用的)中的變數。這有一個簡單的例子:



from

apistar

import

Route


from

apistar

.

frameworks

.

wsgi

import

WSGIApp

as

App


def

user_profile

(

user_id

:

int

)

:


    

return

{

"message"

:

"Your profile id is: {}"

.

format

(

user_id

)}


routes

=

[


    

Route

(

"/user/{user_id}"

,

"GET"

,

user_profile

),


]


app

=

App

(

routes

=

routes

)


if

__name__

==

"__main__"

:


    

app

.

main

()




如果我們訪問 

http://127.0.0.1:8080/user/23

,我們將得到以下響應:





{

"message"

:

"Your profile id is: 23"

}




但如果我們嘗試訪問 

http://127.0.0.1:8080/user/some_string

,它將無法匹配。因為我們定義了 

user_profile

 函數,且為 

user_id

 參數添加了一個類型提示。如果它不是整數,則路徑不匹配。但是如果我們繼續刪除類型提示,只使用 

user_profile(user_id)

,它將匹配此 url。這也展示了 API Star 的智能之處和利用類型和好處。


包含/分組路由


有時候將某些 url 組合在一起是有意義的。假設我們有一個處理用戶相關功能的 

user

 模塊,將所有與用戶相關的 url 分組在 

/user

 路徑下可能會更好。例如 

/user/new

/user/1

/user/1/update

 等等。我們可以輕鬆地在單獨的模塊或包中創建我們的處理程序和路由,然後將它們包含在我們自己的路由中。


讓我們創建一個名為 

user

 的新模塊,文件名為 

user.py

。我們將以下代碼放入這個文件:



from

apistar

import

Route


def

user_new

()

:


    

return

{

"message"

:

"Create a new user"

}


def

user_update

(

user_id

:

int

)

:


    

return

{

"message"

:

"Update user #{}"

.

format

(

user_id

)}


def

user_profile

(

user_id

:

int

)

:


    

return

{

"message"

:

"User Profile for: {}"

.

format

(

user_id

)}


user_routes

=

[


    

Route

(

"/new"

,

"GET"

,

user_new

),


    

Route

(

"/{user_id}/update"

,

"GET"

,

user_update

),


    

Route

(

"/{user_id}/profile"

,

"GET"

,

user_profile

),


]



現在我們可以從 app 主文件中導入 

user_routes

,並像這樣使用它:





from

apistar

import

Include


from

apistar

.

frameworks

.

wsgi

import

WSGIApp

as

App


from

user

import

user_routes


routes

=

[


    

Include

(

"/user"

,

user_routes

)


]


app

=

App

(

routes

=

routes

)


if

__name__

==

"__main__"

:


    

app

.

main

()




現在 

/user/new

 將委託給 

user_new

 函數。


訪問查詢字元串/查詢參數


查詢參數中傳遞的任何參數都可以直接注入到處理函數中。比如 url 

/call?phone=1234

,處理函數可以定義一個 

phone

 參數,它將從查詢字元串/查詢參數中接收值。如果 url 查詢字元串不包含 

phone

 的值,那麼它將得到 

None

。我們還可以為參數設置一個默認值,如下所示:



def

welcome

(

name

=

None

)

:


    

if

name

is

None

:


        

return

{

"message"

:

"Welcome to API Star!"

}


    

return

{

"message"

:

"Welcome to API Star, %s!"

%

name

}




在上面的例子中,我們為 

name

 設置了一個默認值 

None


注入對象


通過給一個請求程序添加類型提示,我們可以將不同的對象注入到視圖中。注入請求相關的對象有助於處理程序直接從內部訪問它們。API Star 內置的 

http

 包中有幾個內置對象。我們也可以使用它的類型系統來創建我們自己的自定義對象並將它們注入到我們的函數中。API Star 還根據指定的約束進行數據驗證。


讓我們定義自己的 

User

 類型,並將其注入到我們的請求處理程序中:



from

apistar

import

Include

,

Route


from

apistar

.

frameworks

.

wsgi

import

WSGIApp

as

App


from

apistar

import

typesystem


class

User

(

typesystem

.

Object

)

:


    

properties

=

{


    

"name"

:

typesystem

.

string

(

max_length

=

100

),


    

"email"

:

typesystem

.

string

(

max_length

=

100

),


    

"age"

:

typesystem

.

integer

(

maximum

=

100

,

minimum

=

18

)


    

}


    

required

=

[

"name"

,

"age"

,

"email"

]


def

new_user

(

user

:

User

)

:


    

return

user


routes

=

[


    

Route

(

"/"

,

"POST"

,

new_user

),


]


app

=

App

(

routes

=

routes

)


if

__name__

==

"__main__"

:


    

app

.

main

()




現在如果我們發送這樣的請求:





curl

-

X

POST


  

http

://

127.0.0.1

:

8080

/


  -

H

"Cache-Control: no-cache"


  -

H

"Content-Type: application/json"


  -

d

"{"name": "masnun", "email": "masnun@gmail.com", "age": 12}"




猜猜發生了什麼?我們得到一個錯誤,說年齡必須等於或大於 18。類型系允許我們進行智能數據驗證。如果我們啟用了 

docs

 url,我們還將自動記錄這些參數。


發送響應


如果你已經注意到,到目前為止,我們只可以傳遞一個字典,它將被轉換為 JSON 並作為默認返回。但是,我們可以使用 

apistar

 中的 

Response

 類來設置狀態碼和其它任意響應頭。這有一個簡單的例子:



from

apistar

import

Route

,

Response


from

apistar

.

frameworks

.

wsgi

import

WSGIApp

as

App


def

hello

()

:


    

return

Response

(


    

content

=

"Hello"

.

encode

(

"utf-8"

),


    

status

=

200

,


    

headers

=

{

"X-API-Framework"

:

"API Star"

},


    

content_type

=

"text/plain"


    

)


routes

=

[


    

Route

(

"/"

,

"GET"

,

h

ello

),



]


app

=

App

(

routes

=

routes

)


if

__name__

==

"__main__"

:


    

app

.

main

()




它應該返回純文本響應和一個自定義標響應頭。請注意,

content

 應該是位元組,而不是字元串。這就是我編碼它的原因。


繼續


我剛剛介紹了 API Star 的一些特性,API Star 中還有許多非常酷的東西,我建議通過 

Github Readme (鏈接:https://github.com/encode/apistar)

文件來了解這個優秀框架所提供的不同功能的更多信息。我還將嘗試在未來幾天內介紹關於 API Star 的更多簡短的,集中的教程。




【關於投稿】




如果大家有原創好文投稿,請直接給公號發送留言。




① 留言格式:


【投稿】+《 文章標題》+ 文章鏈接

② 示例:


【投稿】

《不要自稱是程序員,我十多年的 IT 職場總結》:


http://blog.jobbole.com/94148/



③ 最後請附上您的個人簡介哈~






看完本文有收穫?請轉

發分享給更多人


關注「P

ython開發者」,提升Python技能



喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python開發者 的精彩文章:

一文讀懂 PySpark 數據框
用代碼向 90 後逝去的青春致敬

TAG:Python開發者 |