Flask如何使用grequests?

最近项目中使用了grequests,用来代替requests实现并发请求。使用过程中碰到了一些问题,特此记录一下解决方案。

报错一

启动app时,提示如下告警信息

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$ flask run
 * Environment: development
 * Debug mode: on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 309-614-362
/Users/yeyuqiu/.pyenv/versions/3.7.5/envs/schedule/lib/python3.7/site-packages/grequests.py:22: MonkeyPatchWarning: Monkey-patching ssl after ssl has already been imported may lead to errors, including RecursionError on Python 3.6. It may also silently lead to incorrect behaviour on Python 3.7. Please monkey-patch earlier. See https://github.com/gevent/gevent/issues/1016. Modules that had direct imports (NOT patched): ['botocore.httpsession (/Users/yeyuqiu/.pyenv/versions/3.7.5/envs/schedule/lib/python3.7/site-packages/botocore/httpsession.py)', 'urllib3.contrib.pyopenssl (/Users/yeyuqiu/.pyenv/versions/3.7.5/envs/schedule/lib/python3.7/site-packages/urllib3/contrib/pyopenssl.py)'].
  curious_george.patch_all(thread=False, select=False)
/Users/yeyuqiu/.pyenv/versions/3.7.5/envs/schedule/lib/python3.7/site-packages/grequests.py:22: MonkeyPatchWarning: Monkey-patching ssl after ssl has already been imported may lead to errors, including RecursionError on Python 3.6. It may also silently lead to incorrect behaviour on Python 3.7. Please monkey-patch earlier. See https://github.com/gevent/gevent/issues/1016. Modules that had direct imports (NOT patched): ['urllib3.contrib.pyopenssl (/Users/yeyuqiu/.pyenv/versions/3.7.5/envs/schedule/lib/python3.7/site-packages/urllib3/contrib/pyopenssl.py)', 'botocore.httpsession (/Users/yeyuqiu/.pyenv/versions/3.7.5/envs/schedule/lib/python3.7/site-packages/botocore/httpsession.py)'].
  curious_george.patch_all(thread=False, select=False)

解决办法:在项目启动的第一个文件(wsgi.py)第一行加上import grequests

报错二

正常启动app后,测试接口时报错信息如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  File "src/gevent/_hub_primitives.py", line 317, in gevent.__hub_primitives.wait_on_socket

  File "src/gevent/_hub_primitives.py", line 322, in gevent.__hub_primitives.wait_on_socket

  File "src/gevent/_hub_primitives.py", line 304, in gevent.__hub_primitives._primitive_wait

  File "src/gevent/_hub_primitives.py", line 46, in gevent.__hub_primitives.WaitOperationsGreenlet.wait

  File "src/gevent/_hub_primitives.py", line 46, in gevent.__hub_primitives.WaitOperationsGreenlet.wait

  File "src/gevent/_hub_primitives.py", line 55, in gevent.__hub_primitives.WaitOperationsGreenlet.wait

  File "src/gevent/_waiter.py", line 151, in gevent.__waiter.Waiter.get

  File "src/gevent/_greenlet_primitives.py", line 61, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch

  File "src/gevent/_greenlet_primitives.py", line 61, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch

  File "src/gevent/_greenlet_primitives.py", line 65, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch

  File "src/gevent/__greenlet_primitives.pxd", line 35, in gevent.__greenlet_primitives._greenlet_switch

greenlet.error: cannot switch to a different thread

原因:Flask从1.0版本开始,开发服务器默认使用多线程模式。

解决办法:

  1. 使用flask run --without-threads方式启动app [推荐]

  2. 如果是以app.run方式启动app,threaded参数需要设置为False

1
2
3
4
5
import grequests
app = Flask(__name__)

if __name__ == '__main__':
    app.run(threaded=False)
updatedupdated2020-07-032020-07-03
加载评论