1

Downloading Files With Iron Python In TCAdmin

This post will be short and sweet.  Below is an example of using an Iron Python script in TC Admin to download and save a file.

In this example we use the .NET WebClient class which is part of System.Net

from System.IO import Path
from System.Net import WebClient

output_file = Path.Combine(ThisService.WorkingDirectory, 'example.zip')
download_url = 'http://testing.com/example.zip'

web_client = WebClient()
web_client.DownloadFile(download_url, output_file)

In the example above, example.zip will be downloaded to the root directory of the service that is executing the script.

Async File Downloads

Another trick you can use is starting a download in a new thread.  This will allow you to kick off the download in the background and continue doing other tasks in your script.  This method is a bit more complicated but opens the door to cool features such as displaying download progress.

from System.Net import WebClient
from System.IO import Path
from System.Threading.Thread import Sleep
from System.Threading import Thread, ThreadStart

# Function to call from the new thread
def do_dl():
     dl_url = "http://example.com/test.zip"
     downloader = WebClient()
     downloader.DownloadFile(dl_url, Path.Combine(ThisService.WorkingDirectory, 'test.zip'))

dl_thread = Thread(ThreadStart(do_dl))
dl_thread.IsBackground = True  # Set thread in background to prevent blocking main thread
dl_thread.Start()

# While the download thread is active sleep in a loop until complete. 
# Here you could be calling other functions to complete tasks
while dl_thread.IsAlive:
     Sleep(1000)

Script.WriteToConsole('Download Complete')

 

Async File Downloads With Progress Indicator

This next example builds on the previous and adds an output showing the progress of the download.  Admittedly the output is not very pretty since you cannot clear the contents of TC Admin’s web console.

In this example we are changing from the .NET DownloadFile method to the DownloadFileAsync method.  This gives us access to the DownloadProgressChanged event so we can get the percent complete.  However, doing this means we need to introduce a flag variable ‘dl_running’ so we can detect when the download is done and break out of the loop. Since DownloadFileAsync spawns it’s own thread we can no longer use the thread.IsAlive value.

Another thing to note, the DownloadProgressChanged event is called thousands of times very quickly.  Due to this you do not want to output to the console with each call.  For this example we track the last percent value and only output when it has changed.

 

from System.Net import WebClient
from System.IO import Path
from System.Threading.Thread import Sleep
from System.Threading import Thread, ThreadStart
from System import Uri

last_percent = 0
dl_running = True
def dl_prog(sender, event_args):
    # Only print the percent if it has changed since last call
    global last_percent
    if event_args.ProgressPercentage != last_percent:
        Script.WriteToConsole(str(event_args.ProgressPercentage) + "% Downloaded")
        last_percent = event_args.ProgressPercentage

def do_dl():

    dl_uri = Uri('http://example.com/test.zip') # DownloadFileAsync needs a URI object instead of a string
    downloader = WebClient()
    downloader.DownloadProgressChanged += dl_prog
    downloader.DownloadFileCompleted += dl_complete
    downloader.DownloadFileAsync(dl_uri, Path.Combine(ThisService.WorkingDirectory, 'test.zip'))

def dl_complete(sender, event_args):
    # When download finishes change dl_running flag to None
    global dl_running
    dl_running = None

dl_thread = Thread(ThreadStart(do_dl))
dl_thread.IsBackground = True
dl_thread.Start()


while dl_running:
    Sleep(1000)

Script.WriteToConsole('Download Complete')

Download Progress

matt

One Comment

Leave a Reply

Your email address will not be published. Required fields are marked *