netdev lib 协程异常

Posted

技术标签:

【中文标题】netdev lib 协程异常【英文标题】:netdev lib co-routine exception 【发布时间】:2020-05-20 09:33:51 【问题描述】:

我已经尝试 netdev lib 一段时间了,但下面的程序从未通过以下异常运行它:

Traceback(最近一次调用最后一次): 文件“D:/Code/async_npa/async_npa.py”,第 93 行,在 r = asyncio.run(main(dev_data())) 文件“C:\Users\omera\AppData\Local\Programs\Python\Python38-32\lib\asyncio\runners.py”, 第 43 行,运行中 返回 loop.run_until_complete(main) 文件“C:\Users\omera\AppData\Local\Programs\Python\Python38-32\lib\asyncio\base_events.py”, 第 612 行,在 run_until_complete 返回future.result() 文件“D:/Code/async_npa/async_npa.py”,第 88 行,在 main 结果 = 等待 asyncio.gather(任务中任务的任务) 文件“D:/Code/async_npa/async_npa.py”,第 88 行,在 结果 = 等待 asyncio.gather(任务中任务的任务) RuntimeError:任务的产量不好: sys:1: RuntimeWarning: coroutine 'device_connection' 从未等待

我也尝试过使用 asyncio 的旧语法创建事件循环和任务,但仍然没有成功

代码块:

from jinja2 import Environment, FileSystemLoader
import yaml
import asyncio
import netdev


def j2_command(file_name: dict = 'script.j2', directory: str = '.') -> dict:
    env = Environment(loader=FileSystemLoader(directory))
    temp = env.get_template(file_name)
    temp_1 = temp.render()
    temp_1 = temp_1.split('\n')
    return temp_1


def get_host_name(open_connection) -> str:
    hostname = open_connection.base_prompt()
    hostname = hostname.split('#')[0]
    return hostname


def write_to_file(data, dev_conn):
    with open(f'./output/config_get_host_name(dev_conn).txt', 'w') as conf:
        conf.write(data)


def load_yml(yaml_file='inventory.yml'):
    with open(yaml_file) as f:
        host_obj = yaml.safe_load(f)
    return host_obj


async def device_connection(connect_param):
    dev_connect = netdev.create(**connect_param)
    await dev_connect.connect()
    commands = j2_command()
    output = [f'\n\n\n\n\n##########################  1'
              f'  ##########################\n\n\n\n\n']

    for command in commands:
        breaker = f'\n\n\n\n\n##########################  command  ##########################\n\n\n\n\n'
        command_result = await dev_connect.send_command(command)
        output.append(breaker + command_result)
    await dev_connect.disconnect()
    output_result_string = "\n\n".join(output)
    return output_result_string


def dev_data():
    device_data = []
    # devices_names = []
    host_obj = load_yml()

    generic_data = host_obj[0]['generic_data']
    generic_username = generic_data['username']
    generic_password = generic_data['password']
    devices = host_obj[0]['devices']
    device_type = generic_data['device_type']
    device_secret = generic_data['secret']
    for device in devices:
        device_ip = device['ip_address']
        try:
            if device["username"]: generic_username = device['username']
            if device['password']: generic_password = device['password']
            if device["device_type"]: device_type = device['device_type']
            if device['secret']: device_secret = device['secret']

        except:
            pass

        dev = 
            'device_type': device_type,
            'host': device_ip,
            'username': generic_username,
            'password': generic_password,
            'secret': device_secret
        
        print(dev)

        device_data.append(dev)

    return device_data


async def main(device_data):
    tasks = [device_connection(dev) for dev in device_data]
    result = await asyncio.gather(task for task in tasks)
    return result


if __name__ == '__main__':
    r = asyncio.run(main(dev_data()))
    print(r)

任何帮助将不胜感激

【问题讨论】:

【参考方案1】:

对不起,我的回复晚了,但我希望它会对你有所帮助。您似乎在运行任务时遇到问题。

您可以定义一个全局output_result_string变量并将其附加到每个任务中,而不是在device_connection() 中返回结果。这样你就不用在main()收集任何东西了

然后将main() 更改为run(),如下所示:

async def run(device_data):
    tasks = [device_connection(dev) for dev in device_data]
    await asyncio.wait(tasks)

并在您的主块中启动它:

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run())

这里是文档链接:netdev example link

【讨论】:

以上是关于netdev lib 协程异常的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin 协程协程异常处理 ① ( 根协程异常处理 | 自动传播异常 | 在协程体捕获异常 | 向用户暴露异常 | 在 await 处捕获异常 | 非根协程异常处理 | 异常传播特性 )

Kotlin 协程协程异常处理 ⑤ ( 异常传播的特殊情况 | 取消子协程示例 | 子协程抛出异常后父协程处理异常时机示例 | 异常聚合 | 多个子协程抛出的异常会聚合到第一个异常中 )

Kotlin 协程协程异常处理 ⑤ ( 异常传播的特殊情况 | 取消子协程示例 | 子协程抛出异常后父协程处理异常时机示例 | 异常聚合 | 多个子协程抛出的异常会聚合到第一个异常中 )

Kotlin 协程协程异常处理 ③ ( 协程异常处理器 CoroutineExceptionHandler 捕获异常 | 验证 CoroutineScope 协程的异常捕捉示例 )

Kotlin 协程协程异常处理 ③ ( 协程异常处理器 CoroutineExceptionHandler 捕获异常 | 验证 CoroutineScope 协程的异常捕捉示例 )

Kotlin 协程协程异常处理 ④ ( Android 协程中出现异常导致应用崩溃 | Android 协程中使用协程异常处理器捕获异常 | Android 全局异常处理器 )