API Star:一個 Python 3 的 API 框架
為了在 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', hello),
]
app = App(routes=routes)
if __name__ == '__main__':
app.main()
它應該返回純文字響應和一個自定義標響應頭。請注意,content
應該是位元組,而不是字串。這就是我編碼它的原因。
繼續
我剛剛介紹了 API Star 的一些特性,API Star 中還有許多非常酷的東西,我建議透過 Github Readme 檔案來了解這個優秀框架所提供的不同功能的更多資訊。我還將嘗試在未來幾天內介紹關於 API Star 的更多簡短的,集中的教程。
via: http://polyglot.ninja/api-star-python-3-api-framework/
作者:MASNUN 譯者:MjSeven 校對:wxy
本文由 LCTT 原創編譯,Linux中國 榮譽推出
相關文章
- Ocelot一個優秀的.NET API閘道器框架API框架
- 使用 Python 構建一個簡單的 RESTful APIPythonRESTAPI
- 實現一個jQuery的APIjQueryAPI
- API資料加密框架monkey-api-encryptAPI加密框架
- 如何藉助 Django 來編寫一個 Python Web APIDjangoPythonWebAPI
- API優先(API-first)是一個壞主意! - stilkovAPI
- 餓了麼在API的實踐——構建API Everything框架API框架
- 【PY】Python APIPythonAPI
- api測試框架 GuardianAPI框架
- 如何設計一個良好的API介面?API
- ApsNetCore打造一個“最安全”的api介面NetCoreAPI
- 自用的一個API快速構建元件API元件
- 實現一個簡單的 RESTful APIRESTAPI
- 用一個通俗的例子講清楚APIAPI
- Android API相容,其他API,UI適配(3)AndroidAPIUI
- 如何做一個api介面?API
- 實現一個簡單的 jQuery 的 APIjQueryAPI
- Python的非同步IO:APIPython非同步API
- Kubernetes 的核心是API框架而非容器API框架
- [譯] 使用 Python Flask 框架釋出機器學習 APIPythonFlask框架機器學習API
- Python Line Messaging ApiPythonAPI
- Flask一分鐘Mock一個APIFlaskMockAPI
- 設計一個高質量的 API 介面API
- 如何設計一個牛逼的API介面API
- 開放API閘道器實踐(一) ——設計一個API閘道器API
- 持續更新免費的 API,做一個 API 的搬運工——終身維護API
- 搭建一個大模型API服務大模型API
- 【API分享】整理一些免費好用的APIAPI
- python中selenium常用的api方法PythonAPI
- BookKeeper 介紹(3)--APIAPI
- 常用API(一):API
- python對接zabbix APIPythonAPI
- python api怎麼用PythonAPI
- python內建方法APIPythonAPI
- 瞧瞧別人家的API介面,那叫一個優雅API
- Zilla:一個事件驅動的API閘道器事件API
- 搭建一個自己的 Laravel API 腳手架 - DelightureLaravelAPI
- kong 一個高效能的 API 閘道器API