您好,登錄后才能下訂單哦!
為了在 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
(上面的命令是在 Python3 虛擬環境下使用的)
如果你沒有使用虛擬環境或者你的 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 文檔。
這個文檔可以顯示我們在app.py里定義的函數,并且交互式地查看函數返回值
例如我定義了一個函數叫show_task, 輸入是task_id,返回值是這個task的詳細信息,那么我們在交互界面里可以通過輸入一個valid task_id返回查詢的結果
現在讓我們來看看代碼。我們有一個 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(https://github.com/encode/apistar)文件來了解這個優秀框架所提供的不同功能的更多信息。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對億速云的支持。如果你想了解更多相關內容請查看下面相關鏈接
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。