标签: python-asyncio

异步生成器说它没有实现 __anext__,当它实现时

第一次使用 Aync 生成器。我正在使用Python 3.9。

这是我的实现:

import asyncio

class SubEventStream():
    def __init__(self) -> None:
        self.queue = asyncio.Queue()
        return

    async def __aiter__(self):
        return self

    async def __anext__(self):
        return await self.pop()

    async def append(self, request):
        return await self.queue.put(request)

    async def pop(self):
        r = await self.queue.get()
        self.queue.task_done()
        return r

def create_append_tasks(ls, q):
    return [
        asyncio.create_task(q.append(i))
        for i in ls
    ]

async def append_tasks(q):
    tasks = create_append_tasks(('a', 'b', 'c', 'd', 'e'), q)
    return await asyncio.gather(*tasks)


async def run():
    q = SubEventStream()
    await append_tasks(q)

    async for …
Run Code Online (Sandbox Code Playgroud)

python async-await python-asyncio

3
推荐指数
1
解决办法
1983
查看次数

Django 异步模型保存()

由于请求查询阻塞了我的所有线程,我正在将普通视图转换为异步视图。到目前为止,除了一个问题之外,我已经解决了大部分问题。如何异步保存模型?

async def dashboardAddChart(request, rowId):
    row = (await sync_to_async(list)(DashboardRow.objects.filter(pk=rowId).select_related('dashboard__site', 'dashboard__theme')))[0]

    chart = DashboardChart(dashboard=row.dashboard, dashboardRow=row)
    
    if row.dashboard.theme is not None:
        dashboardThemes.applyThemeToChart(chart)

    chart.save()

    chartData = await getChartData(chart.pk)
Run Code Online (Sandbox Code Playgroud)

我尝试过很多事情,chart.save()包括:

await sync_to_async(chart.save)

t = asyncio.ensure_future(sync_to_async(chart.save))
await asyncio.gather(t)
Run Code Online (Sandbox Code Playgroud)

但我没搞对。

任何帮助将不胜感激!

django django-views python-asyncio

3
推荐指数
1
解决办法
4281
查看次数

带有异步测试的 Pytest:之前和之后的测试设置

我使用 pytest 夹具的测试设置配置有问题:

@pytest.fixture(autouse=True)
async def run_around_tests(elastic_api, catalog):
    es_index_mapping = open('test/resources/es_index_mapping.json')
    es_index_mapping_dict = json.load(es_index_mapping)
    es_cars = open('test/resources/es_cars.json')
    es_cars_dict = json.load(es_cars)
    await elastic_api.create_index(index='catalog_test', payload=es_index_mapping_dict)
    await catalog.upsert_documents(index='catalog_test', payload=es_cars_dict)
    yield
    await elastic_api.delete_index(index='catalog_test')
    await catalog.close()
Run Code Online (Sandbox Code Playgroud)

似乎yield 没有正确执行并且没有等待测试执行。在测试执行期间发生elasticsearch索引的删除,导致测试失败。为什么只有在所有测试完成后才执行此删除?

python pytest python-asyncio

3
推荐指数
1
解决办法
3869
查看次数

asyncio.create_task 实际上做了什么?

我试图了解它asyncio.create_task实际上是如何工作的。假设我有以下代码:

import asyncio
import time

async def delayer():
    await asyncio.sleep(1)

async def messenger():
    await asyncio.sleep(1)
    return "A Message"

async def main():
    message = await messenger()
    await delayer()

start_time = time.time()

asyncio.run(main())

end_time = time.time() - start_time

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

该代码大约需要 2 秒。但是如果我对主体进行一些更改,main如下所示:

import asyncio
import time

async def delayer():
    await asyncio.sleep(1)

async def messenger():
    await asyncio.sleep(1)
    return "A Message"

async def main():
    task1 = asyncio.create_task(delayer())
    task2 = asyncio.create_task(delayer())

    await task1
    await task2

start_time = time.time()

asyncio.run(main())

end_time = …
Run Code Online (Sandbox Code Playgroud)

python coroutine python-asyncio

3
推荐指数
1
解决办法
1118
查看次数

如何使用Python异步查询Azure SQL数据库?

我陷入困境,无法找到使用 Python 异步连接到 Azure SQL 数据库的可行方法。

我已经尝试过asyncio,pyodbc但asyncpg没有成功。

我想这已经很接近了...

import asyncio
import pyodbc

async def query_azure_sql_db():
  connection_string = 'Driver={ODBC Driver 17 for SQL Server};Server=tcp:<mySERVER>.database.windows.net,1433;Database=sqldbstockdata;Uid=<myUN>;Pwd=<myPW>;Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30;'

  async with pyodbc.connect(connection_string) as conn:
    async with conn.cursor() as cursor:
      query = 'SELECT * FROM dbo.<myTABLE>'
      await cursor.execute(query)
      results = cursor.fetchall()
      return results

loop = asyncio.get_event_loop()
results = loop.run_until_complete(query_azure_sql_db())
print(results)
Run Code Online (Sandbox Code Playgroud)

但会导致这个神秘的错误:AttributeError: __aenter__

我对其他图书馆持开放态度。

任何帮助表示赞赏。

python asynchronous pyodbc python-asyncio azure-sql-database

3
推荐指数
1
解决办法
1936
查看次数

程序挂起asyncio

这是我的代码:

import asyncio, socket

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('', 1234))
sock.setblocking(False)

queue = asyncio.Queue()

def sock_reader():
    print(sock.recv(1024))
    # x = yield from queue

def test_sock_reader():
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.sendto(b'HELLO', ('127.0.0.1', 1234))

loop = asyncio.get_event_loop()
loop.add_reader(sock, sock_reader)
loop.call_later(0.5, test_sock_reader)
loop.run_forever()
loop.close()
Run Code Online (Sandbox Code Playgroud)

这是输出:

b'HELLO'
Run Code Online (Sandbox Code Playgroud)

# x = yield from queue取消注释该行时,程序不再打印b'Hello'.

为什么yield from影响应该已经执行的命令?

python python-asyncio python-3.5

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

asyncio模块如何工作,为什么我的更新样本同步运行?

我在Python 3.6中为asyncio尝试了以下代码:示例1:

import asyncio
import time

async def hello():

    print('hello')
    await asyncio.sleep(1)
    print('hello again')

tasks=[hello(),hello()]    
loop=asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
Run Code Online (Sandbox Code Playgroud)

输出符合预期:

hello
hello
hello again
hello again
Run Code Online (Sandbox Code Playgroud)

然后我想将asyncio.sleep更改为另一个def:

async def sleep():
    time.sleep(1)

async def hello():

    print('hello')
    await sleep()
    print('hello again')


tasks=[hello(),hello()]    
loop=asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
Run Code Online (Sandbox Code Playgroud)

输出:

hello
hello again
hello
hello again
Run Code Online (Sandbox Code Playgroud)

它似乎不是以异步模式运行,而是以正常同步模式运行.

问题是:为什么它不是以异步模式运行?如何将旧的同步模块更改为"异步"模块?

python async-await python-asyncio

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

任务添加到不同线程中的空循环时的奇怪行为

我有一个应用程序,它将协同程序添加到已经运行的事件循环中.这些协同程序的参数依赖于I/O,并且在我最初启动事件循环时不可用 - 使用loop.run_forever(),所以我稍后添加任务.为了演示这种现象,这里有一些示例代码:

import asyncio
from threading import Thread
from time import sleep

loop = asyncio.new_event_loop()

def foo():
    loop.run_forever()

async def bar(s):
    while True:
        await asyncio.sleep(1)
        print("s")

#loop.create_task(bar("A task created before thread created & before loop started"))
t = Thread(target=foo)
t.start()
sleep(1)
loop.create_task(bar("secondary task"))
Run Code Online (Sandbox Code Playgroud)

奇怪的行为是,当调用loop.run_forever()时,循环中至少有一个任务时,一切都按预期工作.即当注释行没有被注释掉时.

但是当它被注释掉时,如上所示,没有打印任何内容,看起来我无法向event_loop添加任务.我应该避免在不添加单个任务的情况下调用run_forever()吗?我不明白为什么这应该是一个问题.在运行后将任务添加到event_loop是标准的,为什么空案例会成为问题?

python python-asyncio

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

如何从C访问asyncio/uvloop循环

我是python的新手,但是有一个使用uvloop的异步python应用程序,它使用我创建的C api模块,它也需要访问异步循环.

1)asyncio还没有这个c-api?任何在C中使用事件循环的hack?这是在哪里讨论?

2)uvloop使用我在C中熟悉的libuv.如果我可以抓取uv_loop_t指针,我可以挂钩循环.我想我可以:

A)使用PyObject*到uvloop的循环计算uv_loop_t*的偏移并使用它?假设我知道PyObject_HEAD的长度?

libuv_loop = (uv_loop_t*)((void*)(loop)+0x8);

struct __pyx_obj_6uvloop_4loop_Loop {
    PyObject_HEAD
    uv_loop_t *uvloop;
Run Code Online (Sandbox Code Playgroud)

B)或非hacky修改uvloop以暴露循环指针.因为我从来没有看过cython代码,所以我完全无能为力.我可以在循环上创建一个python函数,从我的C代码调用它并获取C指针吗?喜欢:

(uv_loop_t*)PyObject_CallFunctionObjArgs( getLoop, NULL )
Run Code Online (Sandbox Code Playgroud)

通过在这里添加getLoop:

https://github.com/MagicStack/uvloop/blob/master/uvloop/loop.pyx

cdef uv.uv_loop_t* _getLoop(self):
    return self.uvloop
Run Code Online (Sandbox Code Playgroud)

cython c-api python-asyncio uvloop

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

Python3.x RuntimeError:事件循环已关闭

我在用aiohttp / asyncio做错了。当我尝试run_my_job()一次循环运行另一个文件时,如果我一次性运行它,则下面的代码可以正常工作:

main.py
========================================
 count = 0
    batch_count = math.ceil((abc.get_count()/100))
    print("there are {} batches to complete.".format(batch_count))
    while count < batch_count:
        print("starting batch {}...".format(count))
        abc.run_my_job()
        print("batch {} completed...".format(count))
        count += 1


abc.py
===============================
def run_my_job(self):
    self.queue_manager(self.do_stuff(all_the_tasks))

def queue_manager(self, method):
    print('starting event queue')
    loop = asyncio.get_event_loop()
    future = asyncio.ensure_future(method)
    loop.run_until_complete(future)
    loop.close()

async def async_post(self, resource, session, data):
    async with session.post(self.api_attr.api_endpoint + resource, headers=self.headers, data=data) as response:
        resp = await response.read()
    return resp

async def do_stuff(self, data):
    print('queueing tasks')

    tasks …
Run Code Online (Sandbox Code Playgroud)

python python-asyncio aiohttp python-3.6

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