标签: python-asyncio

Django Channels Postgres InterfaceError:连接已经关闭

我似乎无法解决这个问题。我正在按照文档中的描述为我的频道消费者编写测试。我通常使用 Django 默认的 unittest,但由于 Channels 需要使用 pytest,我正在使用它,但仍然希望保持编写测试的类结构。

我在编写类似于 unittest 的设置方法时遇到了问题,我会用它来初始化测试属性。我尝试了使用autouse=true 的方法装置、类装置,但它们似乎都不起作用,因为我无法访问测试方法中的实例属性。最后我只是决定编写实例方法并为每个类手动调用它。这是我到目前为止:set_up

@pytest.mark.django_db
@pytest.mark.asyncio
class TestChatConsumer(object):

    @database_sync_to_async
    def set_up(self):

        self.user = UserFactory()
        self.api_client = APIClientFactory()
        self.token = TokenFactory(user=self.user)

        self.credentials = {
            'AUTHORIZATION': self.token.key,
            ...
        }

        self.credentials_params = '&'.join(['{}={}'.format(k, v) for k, v in self.credentials.items()])
        self.authless_endpoint = '/api/v1/ws/'
        self.endpoint = self.authless_endpoint + '?' + self.credentials_params

    async def test_connect_without_credentials(self):
        await self.set_up()
        communicator = WebsocketCommunicator(application, self.authless_endpoint)
        connected, subprotocol = await communicator.connect()
        assert not connected

    async def …
Run Code Online (Sandbox Code Playgroud)

django postgresql pytest python-asyncio django-channels

2
推荐指数
1
解决办法
1885
查看次数

在 asyncio 中批量处理任务

我有一个生成任务(io 绑定任务)的函数:

def get_task():
    while True:
        new_task = _get_task()
        if new_task is not None:
            yield new_task
        else:
            sleep(1)
Run Code Online (Sandbox Code Playgroud)

我正在尝试在 asyncio 中编写一个消费者,该消费者将同时处理最多 10 个任务,完成一项任务,然后将执行新任务。我不确定是否应该使用信号量或者是否有任何类型的 asycio 池执行程序?我开始用线程写一个伪代码:

def run(self)
   while True:
       self.semaphore.acquire() # first acquire, then get task
       t = get_task()
       self.process_task(t)

def process_task(self, task):
   try:
       self.execute_task(task)
       self.mark_as_done(task)
   except:
       self.mark_as_failed(task)
   self.semaphore.release()
Run Code Online (Sandbox Code Playgroud)

有人可以帮助我吗?我不知道把 async/await 关键字放在哪里

concurrency python-3.x python-asyncio

2
推荐指数
1
解决办法
952
查看次数

AttributeError: 模块“asyncio”没有属性“run”

我正在尝试使用 asyncio 运行以下程序:

import asyncio

async def main():
    print('Hello')
    await asyncio.sleep(1)
    print('World')

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

但是,我收到以下错误:

AttributeError: 模块“asyncio”没有属性“run”

python --version 给出:Python 2.7.8

python3 --version 给出:Python 3.7.1

我将脚本作为python3 script.py运行

关于如何在没有任何错误的情况下运行此程序的任何想法?

python-asyncio python-3.7

2
推荐指数
1
解决办法
4552
查看次数

如何停止在执行程序中运行的循环?

我正在运行需要时间才能完成的功能。用户可以选择停止此功能/事件。有没有简单的方法来停止线程或循环?

class ThreadsGenerator:
    MAX_WORKERS = 5

    def __init__(self):
        self._executor = ThreadPoolExecutor(max_workers=self.MAX_WORKERS)
        self.loop = None
        self.future = None

    def execute_function(self, function_to_execute, *args):
        self.loop = asyncio.get_event_loop()
        self.future = self.loop.run_in_executor(self._executor, function_to_execute, *args)

        return self.future
Run Code Online (Sandbox Code Playgroud)

我想在用户单击停止按钮时尽快停止该功能,而不是等待完成其工作。

提前致谢!

python multithreading python-3.x python-asyncio concurrent.futures

2
推荐指数
1
解决办法
1261
查看次数

Python,一种检查任务是否完成的干净方法

loop = asyncio.get_event_loop()
executor = concurrent.futures.ThreadPoolExecutor(max_workers=5)
tasks = [loop.run_in_executor(executor, self.parse_url, url) for url in urls]
await asyncio.wait(tasks, timeout=5)
for (i, task) in zip(urls, tasks):
    result = task.result() if task._state.lower() == 'finished' else []
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我使用 '_state' 属性来检查任务是否确实完成并且没有超时。

有没有更清洁的方法?我认为我不应该像那样访问 '_state' 属性。

python-3.x python-asyncio

2
推荐指数
1
解决办法
2899
查看次数

Python create_task 在运行事件循环时不起作用

我有一段简单的代码让我发疯了一段时间。几天前我发布了这个问题,询问create_task是否与input. 现在我想出了一些与此相关的事情。我在一个单独的线程中运行事件循环并在其中推送任务。非常直接的代码。

import asyncio
import threading


async def printer(message):
    print(f'[printer] {message}')


def loop_runner(loop):
    loop.run_forever()


if __name__ == '__main__':
    event_loop = asyncio.get_event_loop()
    t = threading.Thread(target=loop_runner, args=(event_loop,))
    t.start()

    for m in ['hello', 'world', 'foo', 'bar']:
        print(f'[loop running ?] {event_loop.is_running()}')
        event_loop.create_task(printer(m))
Run Code Online (Sandbox Code Playgroud)

除了这些日志消息外,什么都不会打印。

[loop running ?] True
[loop running ?] True
[loop running ?] True
[loop running ?] True
Run Code Online (Sandbox Code Playgroud)

现在,如果我在事件循环线程中阻塞并让它在像这样暂停后运行。

def loop_runner(loop):
    time.sleep(1 / 1000)
    loop.run_forever()
Run Code Online (Sandbox Code Playgroud)

一切正常,这被打印出来

[loop running ?] False
[loop running ?] False
[loop running ?] …
Run Code Online (Sandbox Code Playgroud)

python multithreading event-loop python-asyncio

2
推荐指数
1
解决办法
4991
查看次数

如何将多个值从异步函数返回到同步上下文?

我需要从异步调用中收集结果并将它们返回给一个普通函数——桥接异步和同步代码部分让我感到困惑。

首先尝试,使用丑陋的 inout 参数。

import asyncio
import aiohttp

async def one_call(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            txt = await response.text()
            return txt[0:20]


async def do_all(result_inout):
    urls = ["https://cnn.com", "https://nyt.com", "http://reuters.com"]
    out = await asyncio.gather(*[one_call(url) for url in urls])
    result_inout += out

if __name__ == "__main__":
    result_inout = []
    asyncio.run(do_all(result_inout))

    print(result_inout)
Run Code Online (Sandbox Code Playgroud)

第二次尝试,但直接使用事件循环,不鼓励应用程序代码。

if __name__ == "__main__":
    # same imports, same one_call, same urls
    loop = asyncio.get_event_loop()

    aggregate_future = asyncio.gather(*[one_call(url) for url in urls])
    results …
Run Code Online (Sandbox Code Playgroud)

python python-asyncio python-3.7

2
推荐指数
1
解决办法
1081
查看次数

运行时警告:从未等待过协程。如何异步/等待回调

我有一个服务网络套接字的类,并听 PostgreSQL。使用 asyncpg,当我尝试使用 add_listener 时,出现错误:RuntimeWarning: coroutine was never awaited。如何异步/等待回调。我尝试添加“等待 self.listener”,但它不起作用。

有没有办法以另一种方式处理这个问题?

import asyncio
import http
import websockets
import asyncpg

class App(object):

    def __init__(self, loop):
        self.loop = loop
        self.ws_list = []
        self.conn = None

    async def ws_handler(self, ws, path):
        if self.conn is None:
            self.conn = await asyncpg.connect(user='xxx', password='xxx', database='pgws', host='127.0.0.1')
            await self.conn.add_listener('todo_updates', self.listener)
        print('new socket!!!')
        self.ws_list.append(ws)
        while True:
            await asyncio.sleep(1)

    async def listener(self, conn, pid, channel, payload):
        print(payload)
        for ws in self.ws_list:
            task = asyncio.create_task()
            await ws.send(payload)

if __name__ == "__main__": …
Run Code Online (Sandbox Code Playgroud)

python asynchronous python-asyncio asyncpg

2
推荐指数
1
解决办法
9680
查看次数

asyncio.gather 抛出 RuntimeError: Task got bad yield

我想使用asyncio.gather() “并行”运行一些任务:

import asyncio

async def foo():
    return 42

async def main():
    results = await asyncio.gather(foo() for i in range(10))
    print(results)

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

但它失败了RuntimeError: Task got bad yield:

/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/events.py:88: RuntimeWarning: coroutine 'foo' was never awaited
  self._context.run(self._callback, *self._args)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/runners.py", line 43, in run
    return loop.run_until_complete(main)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 583, in run_until_complete
    return future.result()
  File "<stdin>", line 2, in …
Run Code Online (Sandbox Code Playgroud)

python python-asyncio

2
推荐指数
1
解决办法
871
查看次数

如何将参数和标头传递给 aiohttp ClientSession

我希望传递params和headers到aiohttp.ClientSession如图所示这里。

这是我尝试过的:

    async def make_request(self, url, headers, params):
        async with aiohttp.ClientSession(headers=headers, params=params) as session:
            async with self.limit, session.get(url=url) as response:
                await asyncio.sleep(self.rate)
                resp = await response.read()
                return resp
Run Code Online (Sandbox Code Playgroud)
async def process(url, url_id, update_id, rate, limit):
    limit = asyncio.BoundedSemaphore(limit)

    f = Fetch(
        rate=rate,
        limit=limit,
    )

    if "coinmarketcap" in url:
        params = {
            'start': '1',
            'limit': '1',
            'convert': 'USD,BTC'
        }
        headers = {
            'Accepts': 'application/json',
            'X-CMC_PRO_API_KEY': API_KEY,
        }
    else:
        params = {}
        headers = …
Run Code Online (Sandbox Code Playgroud)

python-3.x python-requests python-asyncio aiohttp

2
推荐指数
1
解决办法
2815
查看次数