原創(chuàng) 鏈三豐 區(qū)塊鏈研究實驗室 今天 收錄于話題 #Python1 #區(qū)塊鏈技術(shù)33 #區(qū)塊鏈44 #API1 #區(qū)塊鏈應(yīng)用30 本文中,,將向大家介紹如何使用Python異步編程,,以便您可以更快地進行更多的API調(diào)用。那么讓我們開始吧,。請求庫
通常,,當Python使用者希望進行API調(diào)用時,他們會尋找請求庫,。語法是我最喜歡的語法,,因為如果我想進行API調(diào)用,則可以運行:import requestsresponse = requests.get("http:///")print(response) 現(xiàn)在,,可以做一個for循環(huán):import requestsfor i in range(10): response = requests.get("http:///") print(response) 每次我對進行API調(diào)用時,,我都必須完成:
如果想試圖獲取大量數(shù)據(jù)(例如,如果我想從Alpha Vantage API中提取fintech數(shù)據(jù)),,您則需要一個可以設(shè)置的免費密鑰api_key = your_key_here,。import requestsimport osapi_key = os.getenv('ALPHAVANTAGE_API_KEY')url = 'https://www./query?function=OVERVIEW&symbol={}&apikey={}'symbols = ['AAPL', 'GOOG', 'TSLA', 'MSFT', 'PEP']results = []for symbol in symbols: response = requests.get(url.format(symbol, api_key)) results.append(response.json()) 此時必須等待大約1.5秒才能進行5個API調(diào)用,然后需要11秒才能進行50個API調(diào)用,,需要50秒才能進行135個API調(diào)用…… 如果您想獲得2,000家公司或1600萬種顏色的數(shù)據(jù),,我們需要做一些擴展。異步代碼與同步代碼當我們運行Python代碼時,,我們的過程一行一行地讀取代碼,。在執(zhí)行一行時,沒有其他代碼可以運行。這就是所謂的同步代碼-依次進行的所有操作,。在異步代碼中,,我們可以在完成一項任務(wù)之前繼續(xù)執(zhí)行另一項任務(wù)。例如,,如果我們考慮同步烹飪漢堡和蔬菜晚餐,我們的“代碼”將如下所示:cook_burger()cook_vegetables() 在這種情況下,,因為漢堡是同步的,,所以我們要等漢堡完成后才能開始蔬菜。但我們并不總是希望等到漢堡做完之后才能開始烹飪蔬菜,。因此我們可以同時煮,。一旦完成,我們就可以停止處理成品蔬菜或漢堡的任何工作,。在異步代碼中,,它看起來像這樣:async def cook_meal(): await asyncio.gather(cook_burger(), cook_vegetables())asyncio.run(cook_meal()) 我們“收集”我們將要完成的任務(wù),并await讓它們都完成,。我們在事件循環(huán)中運行它們,,以跟蹤完成后如何處理它們。您可以不斷檢查看看其中一個過程是否完成,,從而想到事件循環(huán),。現(xiàn)在您可能已經(jīng)聽說過多線程,并且它們是不同的,,多線程用于擁有多個工作程序,,而異步只有一名工人。事件循環(huán)回到我們的Alpha Vantage API調(diào)用示例?,F(xiàn)在,,在我們的代碼中:如果我們有五個符號,我們將“等待”五次,。那么我們需要代替執(zhí)行此操作,,啟動一個API調(diào)用,然后啟動其他API調(diào)用,,最后再處理響應(yīng),。另外,除了執(zhí)行上述操作之外,我們還可以:在第二個示例中,我們只有一個等待時間,!當返回響應(yīng)時(可能在我們發(fā)出請求時發(fā)生),,因此我們需要一些處理返回的響應(yīng)的方法,這被稱為事件循環(huán),。事件循環(huán)會定期檢查以查看我們的異步操作是否已返回,,并安排它們進行相應(yīng)的處理。當我們正常運行Python時,,沒有運行任何事件循環(huán)來處理該事件,,因此我們需要設(shè)置事件循環(huán),以便可以按順序處理響應(yīng),。然后,,我們可以異步運行我們的代碼。 輸入asyncio和aiohttp我們現(xiàn)在知道,,當我們異步運行代碼時,,我們無須等待代碼操作完成,我們可以使用asyncio和aiohttp來進行操作,。import asyncioimport aiohttpimport osimport timeapi_key = os.getenv('ALPHAVANTAGE_API_KEY')url = 'https://www./query?function=OVERVIEW&symbol={}&apikey={}'symbols = ['AAPL', 'GOOG', 'TSLA', 'MSFT', 'PEP']results = []async def get_symbols(): async with aiohttp.ClientSession() as session: for symbol in symbols: response = await session.get(url.format(symbol, api_key), ssl=False)asyncio.run(get_symbols()) 分解我們將使用asyncio.run(get_symbols()),,這會促使事件循環(huán)的啟動,并且會允許我們使用異步代碼,。此時您會注意到,,在以往許多的示例中,它們?nèi)绾螁邮录h(huán)會更加明確:loop = asyncio.get_event_loop()results = loop.run_until_complete(get_symbols())loop.close() 此代碼塊的作用與asyncio.run(get_symbols())完全相同,,那是我們的切入點,。然后我們轉(zhuǎn)到函數(shù):async def get_symbols(): async with aiohttp.ClientSession() as session: for symbol in symbols: response = await session.get(url.format(symbol, api_key), ssl=False) 我們必須從async關(guān)鍵字開始,這使Python知道此函數(shù)將是異步的,,并且我們可以使用事件循環(huán),。我們將展開一個會話aiohttp,aiohttp是異步版本requests,。我們按照相同的方式進行操作,,并調(diào)用aiohttp版本的request.get(即session.get),此處需要添加內(nèi)容ssl=False,。由于session.get是異步函數(shù)(也稱為協(xié)程),,因此我們必須await做出響應(yīng),,否則它們會返回協(xié)程本身。現(xiàn)在我們已經(jīng)請求代碼復制為異步語法,,此時我們依然需要等待,。收集任務(wù)import asyncioimport aiohttpimport osimport timeapi_key = os.getenv('ALPHAVANTAGE_API_KEY')url = 'https://www./query?function=OVERVIEW&symbol={}&apikey={}'symbols = ['AAPL', 'GOOG', 'TSLA', 'MSFT', 'PEP']results = []def get_tasks(session): tasks = [] for symbol in symbols: tasks.append(session.get(url.format(symbol, api_key), ssl=False)) return tasksasync def get_symbols(): async with aiohttp.ClientSession() as session: tasks = get_tasks(session) responses = await asyncio.gather(*tasks)asyncio.run(get_symbols()) 我們有一個名為的全新功能get_tasks,。此功能將所有協(xié)同程序合并到一個列表中,,以便我們立即啟動。請記住,,此列表中的所有函數(shù)都必須是異步函數(shù)或已放置在事件隊列中的任務(wù),。tasks = [session.get(URL.format(symbol, API_KEY), ssl=False) for symbol in symbols] 在得到要啟動的功能/任務(wù)的列表后,我們可以get_symbols使用以下命令在功能中將它們?nèi)繂樱?/span>responses = await asyncio.gather(*tasks) 我們將等待所有任務(wù)完成并將它們放入responses對象中,。
responses = await asyncio.gather(session.get(URL.format('IBM', API_KEY), ssl=False), session.get(URL.format('AAPL', API_KEY), ssl=False), session.get(URL.format('MSFT', API_KEY), ssl=False)) 因為*tasks只是將列表解引用為變量的一種方法。我們“收集”所有任務(wù)并將其運送出去,,當它們響應(yīng)時,,事件循環(huán)將它們拾取,并在我們交付所有任務(wù)后將它們放入要處理的隊列中,。
協(xié)程與任務(wù)在上面的示例中,,我們向asyncio.gather函數(shù)傳遞了異步協(xié)程列表,以便可以將它們調(diào)度到事件循環(huán)中,,實際上可以更快地將它們調(diào)度到事件循環(huán)中,!在我們的get_tasks函數(shù)中,我們調(diào)用了:tasks.append(session.get(url.format(symbol, api_key), ssl=False)) 我們將該session.get函數(shù)添加到了任務(wù)列表中,,并且僅在調(diào)用時將它們添加到了事件循環(huán)中g(shù)ather,。實際上,您可以使用asyncio.create_task以下命令更快地將其添加到事件循環(huán)中:tasks.append(asyncio.create_task(session.get(url.format(symbol, api_key), ssl=False))) 這會將session.get函數(shù)添加到事件循環(huán)中,,并且asyncio.gather函數(shù)將等待該任務(wù)完成,。請記住它們的不同之處。協(xié)程是函數(shù),,而任務(wù)則是在事件循環(huán)中安排的任務(wù),。asyncio.gather將等待任務(wù)返回和/或?qū)f(xié)程安排到事件循環(huán)中,并等待它們返回,。需要加入?yún)^(qū)塊鏈技術(shù)交流群嗎,,請掃描下方二維碼,助手將邀請您進群,。鏈三豐 你的贊賞是我持續(xù)不斷的動力,,謝 喜歡作者 閱讀 30 贊在看 寫下你的留言
|