исключение подпрограммы lib для netdev - PullRequest
0 голосов
/ 04 февраля 2020

Я уже некоторое время пробую 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, в прогоне возвращает l oop .run_until_complete (основной) файл" 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, в главном результате = await asyncio.gather (задача для задачи в задачах) Файл" D: /Code/async_npa/async_npa.py ", строка 88, в результате = await asyncio.gather (задача для задачи в задачах) RuntimeError: задача получила плохой выход: sys: 1: RuntimeWarning: сопрограмма 'device_connection' никогда не ожидалась

Я также пытался использовать старый синтаксис asyncio, создавая событие l oop и задачи, но все еще нет удача

кодовый блок:

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 Ответ

0 голосов
/ 04 марта 2020

Извините за мой поздний ответ, но я надеюсь, что это поможет вам. Похоже, у вас проблемы с запуском задач.

вместо возврата результатов в device_connection() вы можете определить глобальную переменную output_result_string и добавить ее в каждую задачу. Таким образом, вам не нужно ничего собирать в main()

Затем замените main() на run(), как показано ниже:

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

и запустите его в своем главном block:

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

Вот ссылка на документацию: Пример ссылки на netdev

...