Closed zhenningx closed 2 years ago
Hi, @zhenningx.
On the blog post, there seem to be missing code or missing parameters for the actual download of the file.
As stated in the documentation, the function will return a urllib3.response.HTTPResponse class.
The download_a_file_by_fileid function has parameters that handle that response, iterate over its content and write it to file. Those parameters are dirpath and save_file; the file's name is the Content-Disposition header's filename value.
So one quick way to do it is changing this line
cmd_output = dnac.file.download_a_file_by_fileid(task_progress['fileId'])
to
// This saves to the current working directory got by Python: os.getcwd()
cmd_output = dnac.file.download_a_file_by_fileid(task_progress['fileId'], save_file=True).
or
// This saves to the directory /tmp
cmd_output = dnac.file.download_a_file_by_fileid(task_progress['fileId'], dirpath='/tmp', save_file=True).
I hope that helps.
That worked. Thanks so much!
Hello, is it possible to specify a file name with The download_a_file_by_field function? If I loop through multiple devices, it creates multiple files. I want to present one file with the show command outputs from multiple devices.
Thanks!
For now, it is not possible. However, I am working on a solution. I'll update here when it is done.
The new dnacentersdk version, v2.4.8 is up.
Below is a quick non-production code that demonstrates the changes.
import json
import logging
from dnacentersdk import DNACenterAPI
api = DNACenterAPI(verify=False, debug=False)
logging.getLogger('dnacentersdk').addHandler(logging.StreamHandler())
def get_device_list():
devices = api.devices.get_device_list()
device_list = []
for device in devices.response:
if device.family == 'Switches and Hubs':
device_list.append(device.id)
return device_list
def cmd_runner(device):
run_cmd = api.command_runner.run_read_only_commands_on_devices(commands=["show run"], deviceUuids=[device])
task_info = api.task.get_task_by_id(run_cmd.response.taskId)
task_progress = task_info.response.progress
while task_progress == 'CLI Runner request creation':
task_progress = api.task.get_task_by_id(run_cmd.response.taskId).response.progress
task_progress = json.loads(task_progress)
return task_progress
def solution_issue():
device_list = get_device_list()
filename = "final_command_output.log"
filedata = bytes()
for device in device_list:
task_progress = cmd_runner(device)
# save_file=False to avoid downloading the files of each device's command output
cmd_output = api.file.download_a_file_by_fileid(task_progress['fileId'], save_file=False)
# Adds an optional line to describe which original filename corresponds to the content
filedata += bytes("\nFilename: " + cmd_output.filename + '\n', encoding='utf-8')
# Adds the download data of the current device's command output
filedata += cmd_output.data
# Waits til the end to write to the file
with open(filename, 'w') as f:
f.write(filedata.decode(encoding='utf-8'))
if __name__ == '__main__':
solution_issue()
@zhenningx
You could also pass the list of device ids directly to the run_read_only_commands_on_devices.
def cmd_runner_v2(devices):
run_cmd = api.command_runner.run_read_only_commands_on_devices(commands=["show run"], deviceUuids=devices)
task_info = api.task.get_task_by_id(run_cmd.response.taskId)
task_progress = task_info.response.progress
while task_progress == 'CLI Runner request creation':
task_progress = api.task.get_task_by_id(run_cmd.response.taskId).response.progress
task_progress = json.loads(task_progress)
return task_progress
def solution_issue_v2():
device_list = get_device_list()
filename = "final_command_output_2.log"
task_progress = cmd_runner_v2(device_list)
api.file.download_a_file_by_fileid(task_progress['fileId'], save_file=True,
dirpath='/tmp/devices',
filename=filename)
if __name__ == '__main__':
solution_issue_v2()
Note: for both solutions you will need the new SDK version
I hope that helps.
@wastorga The solution works well! Thanks!
@zhenningx. Your welcome. If there is nothing more, please close the issue.
Closing the issue. Thanks again.
From this blog: https://blogs.cisco.com/developer/network-automation-cisco-dna-center-sdk-2
How do you "Retrieve the results and save them to file"? This part is missing from the blog.
The result from the code given in the blog is a class cmd_output, not a file with the results.
More discussion here: https://community.cisco.com/t5/cisco-digital-network/dnac-command-runner-question/m-p/4570843
Need to have a way to save the command runner to a file to complete the task.