如何使用Python异步编程进行API调用 | 区块链研究实验室

原创 链三丰 区块链研究实验室 今天

收录于话题

#Python1

#区块链技术33

#区块链44

#API1

#区块链应用30

本文中,将向大家介绍如何使用Python异步编程,以便您可以更快地进行更多的API调用。那么让我们开始吧。

请求库

通常,当Python使用者希望进行API调用时,他们会寻找请求库。语法是我最喜欢的语法,因为如果我想进行API调用,则可以运行:
import requestsresponse = requests.get("http://example.com/")print(response)
现在,可以做一个for循环:
import requestsfor 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 requestsimport osapi_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

我们现在知道,当我们异步运行代码时,我们无须等待代码操作完成,我们可以使用asyncio和aiohttp来进行操作。
import asyncioimport aiohttpimport osimport timeapi_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 asyncioimport aiohttpimport osimport timeapi_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 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。此功能将所有协同程序合并到一个列表中,以便我们立即启动。请记住,此列表中的所有函数都必须是异步函数或已放置在事件队列中的任务。
我们还可以通过以下方式获得所有任务:
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将等待任务返回和/或将协程安排到事件循环中,并等待它们返回。
需要加入区块链技术交流群吗,请扫描下方二维码,助手将邀请您进群。

链三丰

你的赞赏是我持续不断的动力,谢

喜欢作者

阅读 30

赞在看

写下你的留言
(0)

相关推荐

  • 理解 asyncio 来构建高性能 Python 网络程序

    Python 是一门上手快.优雅简洁的编程语言,其多范式.丰富的标准库和第三方库能够让编程人员把精力集中在逻辑和思维方法上,而不用去担心复杂语法.类型系统等外在因素,从而高效地达成自己的编程目标.Py ...

  • awesome asyncio-精选python异步框架清单集合

    Python 3.4引入标准库的Python asyncio模块提供了使用协程编写单线程并发代码,通过套接字和其他资源对I / O进行多路访问,运行网络客户端和服务器以及其他相关原语的基础结构. As ...

  • 应用程序Python的日志记录模板 | 区块链研究实验室

    原创 链三丰 区块链研究实验室 4天前 通过定义明确,信息量大且结构方便的日志,调试和跟踪应用程序执行的理想方式. 它们是任何编程语言(不仅仅是Python)中任何大型,中型或大型项目必不可少的组成部 ...

  • 区块链研究实验室 | 如何使用Python部署智能合约

    今天 在本文中,我们将使用Python部署智能合约. 我喜欢Python,它具备着开发人员出色的经验.能够写作print("hi")而又不会过于冗长System.out.print ...

  • 【Python核心编程笔记】一、Python中一切皆对象

    Python中一切皆对象 本章节首先对比静态语言以及动态语言,然后介绍 python 中最底层也是面向对象最重要的几个概念-object.type和class之间的关系,以此来引出在python如何做 ...

  • Python游戏编程(Pygame)

    安装Pygame pip install pygame 1 C:\Users> pip install pygame Collecting pygame Downloading https:// ...

  • Python GUI编程:界面设计(tkinter)

    本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. 作者:xubingtao 来源:分享录xubingtao Python爬虫.数据分析.网站开发等案 ...

  • C# 异步编程

    基于Task的异步编程模式(TAP)是Microsoft为.Net平台下使用Task进行编程所提供的一组建议,这种模式提供了可以被await消耗(调用)方法的APIs,并且当使用async关键字编写遵 ...

  • 【汇总】Python网络编程框架有哪些?

    伴随着人工智能时代的到来,Python这门语言变得非常受欢迎,成为了很多开发人员的热捧,甚至还有不少小白.其他岗位就业人员想要转行学习Python,尤其是想要从事网络编程的人员,那么你知道Python ...

  • Python 面向对象编程(一)

    虽然Python是解释性语言,但是它是面向对象的,能够进行对象编程.下面就来了解一下如何在Python中进行对象编程. 一.如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类 ...

  • Python面向对象编程(二)

    在前面一篇文章中谈到了类的基本定义和使用方法,这只体现了面向对象编程的三大特点之一:封装.下面就来了解一下另外两大特征:继承和多态. 在Python中,如果需要的话,可以让一个类去继承一个类,被继承的 ...