prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  [TEST][TENSORFLOW] Cache the Downloaded File
  So far the model files used in the TF end to end tests re-download the file in each test run. 
  This causes the test execution to be slow. Eventually, the test server can be blocked by the place that hosts the data-source.
  
  We need to change the implementation to cache to local and only re-download the file if necessary.
  
  cc @srkreddy1238 @icemelon9 
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `python/tvm/contrib/download.py`
  Content:
  ```
  1 """Helper utility for downloading"""
  2 from __future__ import print_function
  3 from __future__ import absolute_import as _abs
  4 
  5 import os
  6 import sys
  7 import time
  8 
  9 def download(url, path, overwrite=False, size_compare=False, verbose=1):
  10     """Downloads the file from the internet.
  11     Set the input options correctly to overwrite or do the size comparison
  12 
  13     Parameters
  14     ----------
  15     url : str
  16         Download url.
  17 
  18     path : str
  19         Local file path to save downloaded file
  20 
  21     overwrite : bool, optional
  22         Whether to overwrite existing file
  23 
  24     size_compare : bool, optional
  25         Whether to do size compare to check downloaded file.
  26 
  27     verbose: int, optional
  28         Verbose level
  29     """
  30     if sys.version_info >= (3,):
  31         import urllib.request as urllib2
  32     else:
  33         import urllib2
  34 
  35     if os.path.isfile(path) and not overwrite:
  36         if size_compare:
  37             import requests
  38             file_size = os.path.getsize(path)
  39             res_head = requests.head(url)
  40             res_get = requests.get(url, stream=True)
  41             if 'Content-Length' not in res_head.headers:
  42                 res_get = urllib2.urlopen(url)
  43             url_file_size = int(res_get.headers['Content-Length'])
  44             if url_file_size != file_size:
  45                 print("exist file got corrupted, downloading %s file freshly..." % path)
  46                 download(url, path, True, False)
  47                 return
  48         print('File {} exists, skip.'.format(path))
  49         return
  50 
  51     if verbose >= 1:
  52         print('Downloading from url {} to {}'.format(url, path))
  53 
  54     # Stateful start time
  55     start_time = time.time()
  56 
  57     def _download_progress(count, block_size, total_size):
  58         #pylint: disable=unused-argument
  59         """Show the download progress.
  60         """
  61         if count == 0:
  62             return
  63         duration = time.time() - start_time
  64         progress_size = int(count * block_size)
  65         speed = int(progress_size / (1024 * duration))
  66         percent = min(int(count * block_size * 100 / total_size), 100)
  67         sys.stdout.write("\r...%d%%, %.2f MB, %d KB/s, %d seconds passed" %
  68                          (percent, progress_size / (1024.0 * 1024), speed, duration))
  69         sys.stdout.flush()
  70 
  71     if sys.version_info >= (3,):
  72         urllib2.urlretrieve(url, path, reporthook=_download_progress)
  73         print("")
  74     else:
  75         f = urllib2.urlopen(url)
  76         data = f.read()
  77         with open(path, "wb") as code:
  78             code.write(data)
  79
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/python/tvm/contrib/download.py b/python/tvm/contrib/download.py
  --- a/python/tvm/contrib/download.py
  +++ b/python/tvm/contrib/download.py
  @@ -5,8 +5,10 @@
   import os
   import sys
   import time
  +import uuid
  +import shutil
   
  -def download(url, path, overwrite=False, size_compare=False, verbose=1):
  +def download(url, path, overwrite=False, size_compare=False, verbose=1, retries=3):
       """Downloads the file from the internet.
       Set the input options correctly to overwrite or do the size comparison
   
  @@ -53,6 +55,11 @@
   
       # Stateful start time
       start_time = time.time()
  +    dirpath = os.path.dirname(path)
  +    if not os.path.isdir(dirpath):
  +        os.makedirs(dirpath)
  +    random_uuid = str(uuid.uuid4())
  +    tempfile = os.path.join(dirpath, random_uuid)
   
       def _download_progress(count, block_size, total_size):
           #pylint: disable=unused-argument
  @@ -68,11 +75,62 @@
                            (percent, progress_size / (1024.0 * 1024), speed, duration))
           sys.stdout.flush()
   
  -    if sys.version_info >= (3,):
  -        urllib2.urlretrieve(url, path, reporthook=_download_progress)
  -        print("")
  +    while retries >= 0:
  +        # Disable pyling too broad Exception
  +        # pylint: disable=W0703
  +        try:
  +            if sys.version_info >= (3,):
  +                urllib2.urlretrieve(url, tempfile, reporthook=_download_progress)
  +                print("")
  +            else:
  +                f = urllib2.urlopen(url)
  +                data = f.read()
  +                with open(tempfile, "wb") as code:
  +                    code.write(data)
  +            shutil.move(tempfile, path)
  +            break
  +        except Exception as err:
  +            retries -= 1
  +            if retries == 0:
  +                os.remove(tempfile)
  +                raise err
  +            else:
  +                print("download failed due to {}, retrying, {} attempt{} left"
  +                      .format(repr(err), retries, 's' if retries > 1 else ''))
  +
  +
  +TEST_DATA_ROOT_PATH = os.path.join(os.path.expanduser('~'), '.tvm_test_data')
  +if not os.path.exists(TEST_DATA_ROOT_PATH):
  +    os.mkdir(TEST_DATA_ROOT_PATH)
  +
  +def download_testdata(url, relpath, module=None):
  +    """Downloads the test data from the internet.
  +
  +    Parameters
  +    ----------
  +    url : str
  +        Download url.
  +
  +    relpath : str
  +        Relative file path.
  +
  +    module : Union[str, list, tuple], optional
  +        Subdirectory paths under test data folder.
  +
  +    Returns
  +    -------
  +    abspath : str
  +        Absolute file path of downloaded file
  +    """
  +    global TEST_DATA_ROOT_PATH
  +    if module is None:
  +        module_path = ''
  +    elif isinstance(module, str):
  +        module_path = module
  +    elif isinstance(module, (list, tuple)):
  +        module_path = os.path.join(*module)
       else:
  -        f = urllib2.urlopen(url)
  -        data = f.read()
  -        with open(path, "wb") as code:
  -            code.write(data)
  +        raise ValueError("Unsupported module: " + module)
  +    abspath = os.path.join(TEST_DATA_ROOT_PATH, module_path, relpath)
  +    download(url, abspath, overwrite=False, size_compare=True)
  +    return abspath
  
verification_info: {"golden_diff": "diff --git a/python/tvm/contrib/download.py b/python/tvm/contrib/download.py\n--- a/python/tvm/contrib/download.py\n+++ b/python/tvm/contrib/download.py\n@@ -5,8 +5,10 @@\n import os\n import sys\n import time\n+import uuid\n+import shutil\n \n-def download(url, path, overwrite=False, size_compare=False, verbose=1):\n+def download(url, path, overwrite=False, size_compare=False, verbose=1, retries=3):\n     \"\"\"Downloads the file from the internet.\n     Set the input options correctly to overwrite or do the size comparison\n \n@@ -53,6 +55,11 @@\n \n     # Stateful start time\n     start_time = time.time()\n+    dirpath = os.path.dirname(path)\n+    if not os.path.isdir(dirpath):\n+        os.makedirs(dirpath)\n+    random_uuid = str(uuid.uuid4())\n+    tempfile = os.path.join(dirpath, random_uuid)\n \n     def _download_progress(count, block_size, total_size):\n         #pylint: disable=unused-argument\n@@ -68,11 +75,62 @@\n                          (percent, progress_size / (1024.0 * 1024), speed, duration))\n         sys.stdout.flush()\n \n-    if sys.version_info >= (3,):\n-        urllib2.urlretrieve(url, path, reporthook=_download_progress)\n-        print(\"\")\n+    while retries >= 0:\n+        # Disable pyling too broad Exception\n+        # pylint: disable=W0703\n+        try:\n+            if sys.version_info >= (3,):\n+                urllib2.urlretrieve(url, tempfile, reporthook=_download_progress)\n+                print(\"\")\n+            else:\n+                f = urllib2.urlopen(url)\n+                data = f.read()\n+                with open(tempfile, \"wb\") as code:\n+                    code.write(data)\n+            shutil.move(tempfile, path)\n+            break\n+        except Exception as err:\n+            retries -= 1\n+            if retries == 0:\n+                os.remove(tempfile)\n+                raise err\n+            else:\n+                print(\"download failed due to {}, retrying, {} attempt{} left\"\n+                      .format(repr(err), retries, 's' if retries > 1 else ''))\n+\n+\n+TEST_DATA_ROOT_PATH = os.path.join(os.path.expanduser('~'), '.tvm_test_data')\n+if not os.path.exists(TEST_DATA_ROOT_PATH):\n+    os.mkdir(TEST_DATA_ROOT_PATH)\n+\n+def download_testdata(url, relpath, module=None):\n+    \"\"\"Downloads the test data from the internet.\n+\n+    Parameters\n+    ----------\n+    url : str\n+        Download url.\n+\n+    relpath : str\n+        Relative file path.\n+\n+    module : Union[str, list, tuple], optional\n+        Subdirectory paths under test data folder.\n+\n+    Returns\n+    -------\n+    abspath : str\n+        Absolute file path of downloaded file\n+    \"\"\"\n+    global TEST_DATA_ROOT_PATH\n+    if module is None:\n+        module_path = ''\n+    elif isinstance(module, str):\n+        module_path = module\n+    elif isinstance(module, (list, tuple)):\n+        module_path = os.path.join(*module)\n     else:\n-        f = urllib2.urlopen(url)\n-        data = f.read()\n-        with open(path, \"wb\") as code:\n-            code.write(data)\n+        raise ValueError(\"Unsupported module: \" + module)\n+    abspath = os.path.join(TEST_DATA_ROOT_PATH, module_path, relpath)\n+    download(url, abspath, overwrite=False, size_compare=True)\n+    return abspath\n", "issue": "[TEST][TENSORFLOW] Cache the Downloaded File\nSo far the model files used in the TF end to end tests re-download the file in each test run. \r\nThis causes the test execution to be slow. Eventually, the test server can be blocked by the place that hosts the data-source.\r\n\r\nWe need to change the implementation to cache to local and only re-download the file if necessary.\r\n\r\ncc @srkreddy1238 @icemelon9 \n", "before_files": [{"content": "\"\"\"Helper utility for downloading\"\"\"\nfrom __future__ import print_function\nfrom __future__ import absolute_import as _abs\n\nimport os\nimport sys\nimport time\n\ndef download(url, path, overwrite=False, size_compare=False, verbose=1):\n    \"\"\"Downloads the file from the internet.\n    Set the input options correctly to overwrite or do the size comparison\n\n    Parameters\n    ----------\n    url : str\n        Download url.\n\n    path : str\n        Local file path to save downloaded file\n\n    overwrite : bool, optional\n        Whether to overwrite existing file\n\n    size_compare : bool, optional\n        Whether to do size compare to check downloaded file.\n\n    verbose: int, optional\n        Verbose level\n    \"\"\"\n    if sys.version_info >= (3,):\n        import urllib.request as urllib2\n    else:\n        import urllib2\n\n    if os.path.isfile(path) and not overwrite:\n        if size_compare:\n            import requests\n            file_size = os.path.getsize(path)\n            res_head = requests.head(url)\n            res_get = requests.get(url, stream=True)\n            if 'Content-Length' not in res_head.headers:\n                res_get = urllib2.urlopen(url)\n            url_file_size = int(res_get.headers['Content-Length'])\n            if url_file_size != file_size:\n                print(\"exist file got corrupted, downloading %s file freshly...\" % path)\n                download(url, path, True, False)\n                return\n        print('File {} exists, skip.'.format(path))\n        return\n\n    if verbose >= 1:\n        print('Downloading from url {} to {}'.format(url, path))\n\n    # Stateful start time\n    start_time = time.time()\n\n    def _download_progress(count, block_size, total_size):\n        #pylint: disable=unused-argument\n        \"\"\"Show the download progress.\n        \"\"\"\n        if count == 0:\n            return\n        duration = time.time() - start_time\n        progress_size = int(count * block_size)\n        speed = int(progress_size / (1024 * duration))\n        percent = min(int(count * block_size * 100 / total_size), 100)\n        sys.stdout.write(\"\\r...%d%%, %.2f MB, %d KB/s, %d seconds passed\" %\n                         (percent, progress_size / (1024.0 * 1024), speed, duration))\n        sys.stdout.flush()\n\n    if sys.version_info >= (3,):\n        urllib2.urlretrieve(url, path, reporthook=_download_progress)\n        print(\"\")\n    else:\n        f = urllib2.urlopen(url)\n        data = f.read()\n        with open(path, \"wb\") as code:\n            code.write(data)\n", "path": "python/tvm/contrib/download.py"}], "after_files": [{"content": "\"\"\"Helper utility for downloading\"\"\"\nfrom __future__ import print_function\nfrom __future__ import absolute_import as _abs\n\nimport os\nimport sys\nimport time\nimport uuid\nimport shutil\n\ndef download(url, path, overwrite=False, size_compare=False, verbose=1, retries=3):\n    \"\"\"Downloads the file from the internet.\n    Set the input options correctly to overwrite or do the size comparison\n\n    Parameters\n    ----------\n    url : str\n        Download url.\n\n    path : str\n        Local file path to save downloaded file\n\n    overwrite : bool, optional\n        Whether to overwrite existing file\n\n    size_compare : bool, optional\n        Whether to do size compare to check downloaded file.\n\n    verbose: int, optional\n        Verbose level\n    \"\"\"\n    if sys.version_info >= (3,):\n        import urllib.request as urllib2\n    else:\n        import urllib2\n\n    if os.path.isfile(path) and not overwrite:\n        if size_compare:\n            import requests\n            file_size = os.path.getsize(path)\n            res_head = requests.head(url)\n            res_get = requests.get(url, stream=True)\n            if 'Content-Length' not in res_head.headers:\n                res_get = urllib2.urlopen(url)\n            url_file_size = int(res_get.headers['Content-Length'])\n            if url_file_size != file_size:\n                print(\"exist file got corrupted, downloading %s file freshly...\" % path)\n                download(url, path, True, False)\n                return\n        print('File {} exists, skip.'.format(path))\n        return\n\n    if verbose >= 1:\n        print('Downloading from url {} to {}'.format(url, path))\n\n    # Stateful start time\n    start_time = time.time()\n    dirpath = os.path.dirname(path)\n    if not os.path.isdir(dirpath):\n        os.makedirs(dirpath)\n    random_uuid = str(uuid.uuid4())\n    tempfile = os.path.join(dirpath, random_uuid)\n\n    def _download_progress(count, block_size, total_size):\n        #pylint: disable=unused-argument\n        \"\"\"Show the download progress.\n        \"\"\"\n        if count == 0:\n            return\n        duration = time.time() - start_time\n        progress_size = int(count * block_size)\n        speed = int(progress_size / (1024 * duration))\n        percent = min(int(count * block_size * 100 / total_size), 100)\n        sys.stdout.write(\"\\r...%d%%, %.2f MB, %d KB/s, %d seconds passed\" %\n                         (percent, progress_size / (1024.0 * 1024), speed, duration))\n        sys.stdout.flush()\n\n    while retries >= 0:\n        # Disable pyling too broad Exception\n        # pylint: disable=W0703\n        try:\n            if sys.version_info >= (3,):\n                urllib2.urlretrieve(url, tempfile, reporthook=_download_progress)\n                print(\"\")\n            else:\n                f = urllib2.urlopen(url)\n                data = f.read()\n                with open(tempfile, \"wb\") as code:\n                    code.write(data)\n            shutil.move(tempfile, path)\n            break\n        except Exception as err:\n            retries -= 1\n            if retries == 0:\n                os.remove(tempfile)\n                raise err\n            else:\n                print(\"download failed due to {}, retrying, {} attempt{} left\"\n                      .format(repr(err), retries, 's' if retries > 1 else ''))\n\n\nTEST_DATA_ROOT_PATH = os.path.join(os.path.expanduser('~'), '.tvm_test_data')\nif not os.path.exists(TEST_DATA_ROOT_PATH):\n    os.mkdir(TEST_DATA_ROOT_PATH)\n\ndef download_testdata(url, relpath, module=None):\n    \"\"\"Downloads the test data from the internet.\n\n    Parameters\n    ----------\n    url : str\n        Download url.\n\n    relpath : str\n        Relative file path.\n\n    module : Union[str, list, tuple], optional\n        Subdirectory paths under test data folder.\n\n    Returns\n    -------\n    abspath : str\n        Absolute file path of downloaded file\n    \"\"\"\n    global TEST_DATA_ROOT_PATH\n    if module is None:\n        module_path = ''\n    elif isinstance(module, str):\n        module_path = module\n    elif isinstance(module, (list, tuple)):\n        module_path = os.path.join(*module)\n    else:\n        raise ValueError(\"Unsupported module: \" + module)\n    abspath = os.path.join(TEST_DATA_ROOT_PATH, module_path, relpath)\n    download(url, abspath, overwrite=False, size_compare=True)\n    return abspath\n", "path": "python/tvm/contrib/download.py"}]}