您好,登錄后才能下訂單哦!
本篇內容主要講解“怎么用Python異步編程進行API調用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么用Python異步編程進行API調用”吧!
通常,當Python使用者希望進行API調用時,他們會尋找請求庫。語法是我最喜歡的語法,因為如果我想進行API調用,則可以運行:
import requests response = requests.get("http://example.com/") print(response)
現在,可以做一個for循環:
import requests for i in range(10): response = requests.get("http://example.com/") print(response)
每次我對進行API調用時example.com,我都必須完成:
將請求發送至example.com。
等待回應。
得到回應。
如果想試圖獲取大量數據(例如,如果我想從Alpha Vantage API中提取fintech數據),您則需要一個可以設置的免費密鑰api_key = your_key_here。
import requests import os api_key = os.getenv('ALPHAVANTAGE_API_KEY') url = 'https://www.alphavantage.co/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調用,然后需要11秒才能進行50個API調用,需要50秒才能進行135個API調用……
如果您想獲得2,000家公司或1600萬種顏色的數據,我們需要做一些擴展。
當我們運行Python代碼時,我們的過程一行一行地讀取代碼。在執行一行時,沒有其他代碼可以運行。這就是所謂的同步代碼-依次進行的所有操作。
在異步代碼中,我們可以在完成一項任務之前繼續執行另一項任務。例如,如果我們考慮同步烹飪漢堡和蔬菜晚餐,我們的“代碼”將如下所示:
cook_burger() cook_vegetables()
在這種情況下,因為漢堡是同步的,所以我們要等漢堡完成后才能開始蔬菜。但我們并不總是希望等到漢堡做完之后才能開始烹飪蔬菜。因此我們可以同時煮。一旦完成,我們就可以停止處理成品蔬菜或漢堡的任何工作。在異步代碼中,它看起來像這樣:
async def cook_meal(): await asyncio.gather(cook_burger(), cook_vegetables()) asyncio.run(cook_meal())
我們“收集”我們將要完成的任務,并await讓它們都完成。我們在事件循環中運行它們,以跟蹤完成后如何處理它們。您可以不斷檢查看看其中一個過程是否完成,從而想到事件循環。
現在您可能已經聽說過多線程,并且它們是不同的,多線程用于擁有多個工作程序,而異步只有一名工人。
回到我們的Alpha Vantage API調用示例。現在,在我們的代碼中:
發出第一個請求。
等待。
得到第一反應。
發出第二個請求。
等待。
得到第二個答復。
如果我們有五個符號,我們將“等待”五次。那么我們需要代替執行此操作,啟動一個API調用,然后啟動其他API調用,最后再處理響應。
另外,除了執行上述操作之外,我們還可以:
發出第一個請求。
發出第二個請求。
等待。
得到第一反應。
得到第二個答復。
在第二個示例中,我們只有一個等待時間!當返回響應時(可能在我們發出請求時發生),因此我們需要一些處理返回的響應的方法,這被稱為事件循環。
事件循環會定期檢查以查看我們的異步操作是否已返回,并安排它們進行相應的處理。當我們正常運行Python時,沒有運行任何事件循環來處理該事件,因此我們需要設置事件循環,以便可以按順序處理響應。
然后,我們可以異步運行我們的代碼。
我們現在知道,當我們異步運行代碼時,我們無須等待代碼操作完成,我們可以使用asyncio和aiohttp來進行操作。
import asyncio import aiohttp import os import time api_key = os.getenv('ALPHAVANTAGE_API_KEY') url = 'https://www.alphavantage.co/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()),這會促使事件循環的啟動,并且會允許我們使用異步代碼。
此時您會注意到,在以往許多的示例中,它們如何啟動事件循環會更加明確:
loop = asyncio.get_event_loop() results = loop.run_until_complete(get_symbols()) loop.close()
此代碼塊的作用與asyncio.run(get_symbols())完全相同,那是我們的切入點。然后我們轉到函數:
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關鍵字開始,這使Python知道此函數將是異步的,并且我們可以使用事件循環。
我們將展開一個會話aiohttp,aiohttp是異步版本requests。
我們按照相同的方式進行操作,并調用aiohttp版本的request.get(即session.get),此處需要添加內容ssl=False。
由于session.get是異步函數(也稱為協程),因此我們必須await做出響應,否則它們會返回協程本身。
現在我們已經請求代碼復制為異步語法,此時我們依然需要等待。
我們即將要啟動所有API調用。
import asyncio import aiohttp import os import time api_key = os.getenv('ALPHAVANTAGE_API_KEY') url = 'https://www.alphavantage.co/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 tasks async def get_symbols(): async with aiohttp.ClientSession() as session: tasks = get_tasks(session) responses = await asyncio.gather(*tasks) asyncio.run(get_symbols())
我們有一個名為的全新功能get_tasks。此功能將所有協同程序合并到一個列表中,以便我們立即啟動。請記住,此列表中的所有函數都必須是異步函數或已放置在事件隊列中的任務。
我們還可以通過以下方式獲得所有任務:
tasks = [session.get(URL.format(symbol, API_KEY), ssl=False) for symbol in symbols]
在得到要啟動的功能/任務的列表后,我們可以get_symbols使用以下命令在功能中將它們全部啟動:
responses = await asyncio.gather(*tasks)
我們將等待所有任務完成并將它們放入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只是將列表解引用為變量的一種方法。
我們“收集”所有任務并將其運送出去,當它們響應時,事件循環將它們拾取,并在我們交付所有任務后將它們放入要處理的隊列中。
在上面的示例中,我們向asyncio.gather函數傳遞了異步協程列表,以便可以將它們調度到事件循環中,實際上可以更快地將它們調度到事件循環中!
在我們的get_tasks函數中,我們調用了:
tasks.append(session.get(url.format(symbol, api_key), ssl=False))
我們將該session.get函數添加到了任務列表中,并且僅在調用時將它們添加到了事件循環中gather。實際上,您可以使用asyncio.create_task以下命令更快地將其添加到事件循環中:
tasks.append(asyncio.create_task(session.get(url.format(symbol, api_key), ssl=False)))
這會將session.get函數添加到事件循環中,并且asyncio.gather函數將等待該任務完成。
請記住它們的不同之處。協程是函數,而任務則是在事件循環中安排的任務。asyncio.gather將等待任務返回和/或將協程安排到事件循環中,并等待它們返回。
到此,相信大家對“怎么用Python異步編程進行API調用”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。