python - Python异步等待问题
问题描述
经过研究,我决定使用 asyncio 来更快地获取数千个 API 请求。
async def get_marketcap(session, ticker, marketcap):
url = "https://api.polygon.io/vX/reference/tickers/" + ticker +"&apiKey=" + profile.POLYGON_API_KEY
async with session.get(url, ssl=False) as response:
text = await response.json()
marketcap[ticker] = text['results']['market_cap']
async def scan(api):
df = pd.read_csv('./data/tickers/polygon_list.csv')
tickers = df['ticker'].tolist()
marketcap = {}
async with aiohttp.ClientSession() as session:
tasks = [get_marketcap(session, ticker, marketcap) for ticker in tickers]
await asyncio.gather(*tasks)
return marketcap
这会从 csv 文件中获取股票代码列表,并使用 aiohttp 执行大约 9,000 个 API 请求,以从 JSON 响应中获取每个代码的市值。(我设置 ssl=False 因为它之前给了我一个 SSL 错误)
Asyncio.run(scan(api))
从不同的 python 文件调用。
Traceback (most recent call last):
File "/Users/jakeyoon/Documents/Python Programs/Trade Bot/trader.py", line 22, in <module>
tickers = asyncio.run(test.scan(api))
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
return future.result()
File "/Users/jakeyoon/Documents/Python Programs/Trade Bot/test.py", line 25, in scan
await asyncio.gather(*tasks)
File "/Users/jakeyoon/Documents/Python Programs/Trade Bot/test.py", line 12, in get_marketcap
with session.get(url, ssl=False) as response:
AttributeError: __enter__
这是我得到的错误......我也试过
asyncio.ensure_future()
这修复了下面的错误,但由于某种我不明白的原因给了我一个 KeyError ['results'] ......肯定有一个属性'result'。我一直在查看多个堆栈溢出帖子、YouTube 和教程,但仍然无法理解问题所在。似乎 asyncio 经常更新,所以我不确定使用的最佳方法和实践是什么。
你能帮我理解什么是错的或更好地理解 asychio 概念吗?谢谢!
解决方案
设置 ssl=False 不是一个好的解决方法,因为 API 似乎发生了变化,并且说无法建立 SSL 握手
Install Certificates.command
对我不起作用,所以必须复制并粘贴 python 文件并独立运行
# install_certifi.py
#
# sample script to install or update a set of default Root Certificates
# for the ssl module. Uses the certificates provided by the certifi package:
# https://pypi.python.org/pypi/certifi
import os
import os.path
import ssl
import stat
import subprocess
import sys
STAT_0o775 = ( stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR
| stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP
| stat.S_IROTH | stat.S_IXOTH )
def main():
openssl_dir, openssl_cafile = os.path.split(
ssl.get_default_verify_paths().openssl_cafile)
print(" -- pip install --upgrade certifi")
subprocess.check_call([sys.executable,
"-E", "-s", "-m", "pip", "install", "--upgrade", "certifi"])
import certifi
# change working directory to the default SSL directory
os.chdir(openssl_dir)
relpath_to_certifi_cafile = os.path.relpath(certifi.where())
print(" -- removing any existing file or link")
try:
os.remove(openssl_cafile)
except FileNotFoundError:
pass
print(" -- creating symlink to certifi certificate bundle")
os.symlink(relpath_to_certifi_cafile, openssl_cafile)
print(" -- setting permissions")
os.chmod(openssl_cafile, STAT_0o775)
print(" -- update complete")
if __name__ == '__main__':
main()
task = asyncio.ensure_future(get_marketcap(session, ticker, marketcap))
tasks.append(task)
Asyncio.gather(*tasks)
也修复了问题
根据评论中的建议,我添加了 try 异常以捕获 404 或其他 API 错误,并且我的代码确实有 async ,但仍然给出了错误,但我猜堆栈跟踪是之前复制的。
谢谢!
推荐阅读
- r - r - 在列表的任何元素中查找字符串,然后使用该列表元素的名称
- haskell - Haskell中的函数类型签名而不使用解释器
- c++ - 将复杂参数列表与类模板一起使用
- java - 在 Java 中设置不同的驻留堆大小和总换出的虚拟内存大小
- structured-data - Google结构化数据测试工具和微格式hcard的问题
- html - 找不到 Django 全局静态文件
- java - 您将如何重构 Arrays.copyOf() 方法以删除 @SuppressWarnings("unchecked") 注释?
- java - 警报对话框仅模糊部分屏幕
- security - Oauth 2 流程:AWS Cognito 的 id_token 是否应该传递给浏览器进行会话管理?
- php - Acquia Dev Desktop 为 Drush 使用了错误的 PHP