标签: python-asyncio

使用 websockets 正常关闭 uvicorn starlette 应用程序

鉴于此示例 Starlette 应用程序具有开放的 websocket 连接,您如何关闭 Starlette 应用程序?我在 uvicorn 上运行。每当我按下Ctrl+C输出时,Waiting for background tasks to complete.它就会永远挂起。

from starlette.applications import Starlette

app = Starlette()

@app.websocket_route('/ws')
async def ws(websocket):
    await websocket.accept()

    while True:
        # How to interrupt this while loop on the shutdown event?
        await asyncio.sleep(0.1)

    await websocket.close()
Run Code Online (Sandbox Code Playgroud)

我尝试在关闭事件上切换 bool 变量,但该变量永远不会更新。它总是False。

例如。

app.state.is_shutting_down = False


@app.on_event('shutdown')
async def shutdown():
    app.state.is_shutting_down = True


@app.websocket_route('/ws')
async def ws(websocket):
    await websocket.accept()

    while app.state.is_shutting_down is False:
Run Code Online (Sandbox Code Playgroud)

python python-asyncio asgi starlette uvicorn

11
推荐指数
1
解决办法
4246
查看次数

Asyncio调用在Gtk主循环中运行

Okey们提出了关于asyncio和Gtk +的问题.如何在Gtk.main循环中运行下面的代码?我搜索了一些例子但找不到任何东西.

#!/usr/bin/python3.4

import asyncio

@asyncio.coroutine
def client_connected_handler(client_reader, client_writer):
    print("Connection received!")
    client_writer.write(b'Hello')
    while True:
        data = yield from client_reader.read(8192)
        if not data:
            break
        if 'EXIT' in data.decode():
            print("Closing server")
            break   
        print(data)
        client_writer.write(data)
    print('Server is closed')


loop = asyncio.get_event_loop()
Server=asyncio.start_server(client_connected_handler, 'localhost', 2222)
server=loop.run_until_complete(Server)
loop.run_forever()
Run Code Online (Sandbox Code Playgroud)

编辑:

哦,我应该用gbulb写下我的经验.首先,我使用pip3搜索它.我发现它并试图安装它但由于链接不好而失败(我使用超级用户进行安装).接下来我从他们的存储库下载并安装它.我得到了这个例子我运行它并在其核心模块中缺少参数时出现了一些错误.我不知道它是什么错误导致我从不同的PC写这个我会更新是尽快的.如果其他人可以测试它,我将不胜感激.

python gtk gtk3 python-asyncio

10
推荐指数
1
解决办法
1725
查看次数

aiohttp - 异常忽略的消息

我正在运行以下代码,通过aiohttp发出5个请求:

import aiohttp
import asyncio

def fetch_page(url, idx):
    try:
        url = 'http://google.com'
        response = yield from aiohttp.request('GET', url)

        print(response.status)
    except Exception as e:
        print(e)

def main():
    try:
        url = 'http://google.com'
        urls = [url] * 5

        coros = []
        for idx, url in enumerate(urls):
            coros.append(asyncio.Task(fetch_page(url, idx)))

        yield from asyncio.gather(*coros)
    except Exception as e:
        print(e)

if __name__ == '__main__':
    try:
        loop = asyncio.get_event_loop()
        loop.run_until_complete(main())
    except Exception as e:
        print(e)
Run Code Online (Sandbox Code Playgroud)

输出:

200
200
200
200
200
Exception ignored in: Exception ignored in: Exception …
Run Code Online (Sandbox Code Playgroud)

python python-3.x python-asyncio aiohttp

10
推荐指数
1
解决办法
2406
查看次数

python 3.5 asyncio和aiohttp Errno 101网络无法访问

我在Ubuntu 16上使用python 3.5.

我正在尝试使用aiohttp来编写一个简单的客户端.

这是我的代码.我从这里拿走了它.这是第一个代码示例,禁用了ssl检查:

import aiohttp
import asyncio
import async_timeout

async def fetch(session, url):
    with async_timeout.timeout(10):
        async with session.get(url) as response:
            return await response.text()

async def main(loop):
    conn = aiohttp.TCPConnector(verify_ssl=False)
    async with aiohttp.ClientSession(loop=loop, connector=conn) as session:
        html = await fetch(session, 'http://www.google.com')
        print(html)

loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))

loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))
Run Code Online (Sandbox Code Playgroud)

对于某些网站,此代码有效.对于其他人,包括http://python.org或http://google.com不起作用.相反,代码会生成此错误:

aiohttp.errors.ClientOSError: [Errno 101] Cannot connect to host google.com:80 ssl:False [Can not connect to google.com:80 [Network is unreachable]]
Run Code Online (Sandbox Code Playgroud)

我尝试了一个简单的requests脚本,如下所示:

import requests …
Run Code Online (Sandbox Code Playgroud)

python python-3.x python-asyncio aiohttp

10
推荐指数
1
解决办法
1181
查看次数

python 3.6和ValueError:loop参数必须与Future一致

我只是想运行一个简单的测试示例,但我得到以下错误.我该如何解决?

import asyncio
import uvloop
import concurrent.futures
import time
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())

async def do_some_work(x):

    while True:
        print("Waiting " + str(x))
        await asyncio.sleep(x)

if __name__ == '__main__': 


    loop = asyncio.new_event_loop()
    tasks = [asyncio.ensure_future(do_some_work(2)), 
             asyncio.ensure_future(do_some_work(5))]
    loop.run_until_complete(asyncio.gather(*tasks))

Traceback (most recent call last):
  File "/Users/worker_why.py", line 23, in <module>
    loop.run_until_complete(asyncio.gather(*tasks))
  File "uvloop/loop.pyx", line 1181, in uvloop.loop.Loop.run_until_complete (uvloop/loop.c:25184)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/tasks.py", line 508, in ensure_future
    raise ValueError('loop argument must agree with Future')
ValueError: loop argument must agree with Future
Run Code Online (Sandbox Code Playgroud)

python python-asyncio python-3.6

10
推荐指数
1
解决办法
3068
查看次数

在python中使用aiohttp获取多个url

在上一个问题中,用户建议使用以下方法来获取多个 url(API 调用)aiohttp:

import asyncio
import aiohttp


url_list = ['https://api.pushshift.io/reddit/search/comment/?q=Nestle&size=30&after=1530396000&before=1530436000', 'https://api.pushshift.io/reddit/search/comment/?q=Nestle&size=30&after=1530436000&before=1530476000']

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.json()['data']


async def fetch_all(session, urls, loop):
    results = await asyncio.gather(*[loop.create_task(fetch(session, url)) for url in urls], return_exceptions= True)
    return results

if __name__=='__main__':
    loop = asyncio.get_event_loop()
    urls = url_list
    with aiohttp.ClientSession(loop=loop) as session:
        htmls = loop.run_until_complete(fetch_all(session, urls, loop))
    print(htmls)
Run Code Online (Sandbox Code Playgroud)

但是,这只会导致返回属性错误:

[AttributeError('__aexit__',), AttributeError('__aexit__',)]
Run Code Online (Sandbox Code Playgroud)

(我启用了,否则它就会中断)。我真的希望这里有人可以帮助解决这个问题,仍然很难找到asyncio等的资源。返回的数据是json格式。最后,我想将所有 json 字典放在一个列表中。

api web-scraping python-3.x python-asyncio aiohttp

10
推荐指数
1
解决办法
7123
查看次数

从异步函数调用同步函数

我正在尝试将flask应用程序移植quart到使用asyncio. 我认为我目前的方法行不通,因为我的整个函数链是在没有考虑异步的情况下编写的 - 考虑以下几点:

def long_running_task(task):
    result = some_synchronous_function(task)
    return result

@app.route('/<task>', methods=['GET'])
async def do_task(task):
    ok = await long_running_task(task)
    if ok:
        return (ok.result)
    else:
        return ('Something went wrong')
Run Code Online (Sandbox Code Playgroud)

如果long_running_task和它的整个函数调用链都没有声明为async,我是否真的从我的路由被声明为中得到任何好处async?

python python-asyncio quart

10
推荐指数
1
解决办法
7775
查看次数

Python 异步任务取消

我正在阅读任务取消的异步文档,我遇到了这个-

要取消正在运行的任务,请使用 cancel() 方法。调用它会导致任务将 CancelledError 异常抛出到包装的协程中。如果协程在取消期间等待 Future 对象,则 Future 对象将被取消。

cancelled() 可用于检查任务是否被取消。如果包装的协程没有抑制 CancelledError 异常并且实际上被取消,则该方法返回 True 。

我在这里有几个问题 -

  • 包装协程是调用取消的协程吗?让我们在这里举个例子——

    async def wrapped_coroutine():
        for task in asyncio.Task.all_tasks():
            task.cancel()
    
    Run Code Online (Sandbox Code Playgroud)

    那么wrapped_coroutine()封装的协程是否会抛出异常呢?

  • 什么时候会抛出这个异常?在哪里?

  • 这里抑制异常是什么意思?是不是这个意思——

    async def wrapped_coroutine():
        for task in asyncio.Task.all_tasks():
            task.cancel()
            try:
                await task
            except asyncio.CancelledError:
                print("Task cancelled")
    
    Run Code Online (Sandbox Code Playgroud)

    如果没有,请提供有关如何抑制此异常的示例。

还有一个不相关的(它与取消任务有关),当我取消这些任务时如何从这些任务中检索异常,所以我看不到这个 -

Task exception was never retrieved future:
Run Code Online (Sandbox Code Playgroud)

是之前task.cancel()还是try之前await task(在上面的例子中)?

python asynchronous python-3.x python-asyncio

10
推荐指数
1
解决办法
1万
查看次数

在python asyncio中是否有理由`return await ...`?

我知道在 js 中它没有await在return语句之前添加任何内容(即return await ...),但是在 python 中也是如此,或者这以某种方式使物化更有可能或不同?

如果两者不等价,最佳实践是什么?

python return async-await python-asyncio

10
推荐指数
2
解决办法
8517
查看次数

aiohttp.client_exceptions.ClientConnectorError: 无法连接到主机 stackoverflow.com:443 ssl:default [连接调用失败 ('151.101.193.69', 443)]

这是我的代码:

import asyncio
from aiohttp import ClientSession


async def main():
    url = "https://stackoverflow.com/"

    async with ClientSession() as session:
        async with session.get(url) as resp:
            print(resp.status)

asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)

如果我在我的电脑上运行它,一切正常,但如果我在 pythonanywhere 上运行它,我会收到这个错误:

Traceback (most recent call last):
  File "/home/0dminnimda/.local/lib/python3.8/site-packages/aiohttp/connector.py", line 936, in _wrap_create_connection
    return await self._loop.create_connection(*args, **kwargs)  # type: ignore  # noqa
  File "/usr/lib/python3.8/asyncio/base_events.py", line 1017, in create_connection
    raise exceptions[0]
  File "/usr/lib/python3.8/asyncio/base_events.py", line 1002, in create_connection
    sock = await self._connect_sock(
  File "/usr/lib/python3.8/asyncio/base_events.py", line 916, in _connect_sock
    await self.sock_connect(sock, address)
  File "/usr/lib/python3.8/asyncio/selector_events.py", line 485, in …
Run Code Online (Sandbox Code Playgroud)

python python-3.x pythonanywhere python-asyncio aiohttp

10
推荐指数
2
解决办法
9949
查看次数