Skip to content

Commit 4d5c6f4

Browse files
authored
feat: fallback method for Windows without requests lib (#91)
1 parent 725abd8 commit 4d5c6f4

File tree

1 file changed

+56
-2
lines changed

1 file changed

+56
-2
lines changed

src/ansys/tools/installer/main.py

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,6 @@ def download_and_install(self):
434434
"""Download and install.
435435
436436
Called when ``self.submit_button.clicked`` is emitted.
437-
438437
"""
439438
self.setEnabled(False)
440439
QtWidgets.QApplication.processEvents()
@@ -452,7 +451,18 @@ def download_and_install(self):
452451
filename = "Miniforge3-22.11.1-4-Windows-x86_64.exe"
453452
LOG.info("Installing miniconda from %s", url)
454453

455-
self._download(url, filename, when_finished=self._run_install_python)
454+
try:
455+
self._download(url, filename, when_finished=self._run_install_python)
456+
except Exception as err:
457+
if os.name == "nt":
458+
LOG.warning(
459+
"Download using requests library failed... Going to fallback method for Windows."
460+
)
461+
self._windows_fallback_download(
462+
url, filename, when_finished=self._run_install_python
463+
)
464+
else:
465+
raise err
456466
except Exception as e:
457467
self.show_error(str(e))
458468
self.setEnabled(True)
@@ -540,6 +550,50 @@ def update(b=1, bsize=1, tsize=None):
540550
if when_finished is not None:
541551
when_finished(output_path)
542552

553+
def _windows_fallback_download(self, url, filename, when_finished=None):
554+
"""Download a file. Fallback method for Windows.
555+
556+
Deletes any pre-existing output file with the same name. Then, performs
557+
the download using PowerShell and the Invoke-RestMethod command.
558+
559+
``when_finished`` must accept one parameter, the path of the file downloaded.
560+
561+
Parameters
562+
----------
563+
url : str
564+
File to download.
565+
filename : str
566+
The basename of the file to download.
567+
when_finished : callable, optional
568+
Function to call when complete. Function should accept one
569+
parameter: the full path of the file downloaded.
570+
"""
571+
# Delete pre-existing cache. This is fail-safe mode
572+
output_path = os.path.join(CACHE_DIR, filename)
573+
if os.path.isfile(output_path):
574+
os.remove(output_path)
575+
576+
# Perform download using Invoke-RestMethod
577+
out, error_code = run_ps(
578+
f"Invoke-RestMethod '{url}' -Method 'GET' -OutFile '{output_path}'"
579+
)
580+
581+
if error_code:
582+
LOG.error(
583+
f"Error while downloading Python on Windows fail-safe mode: {out.decode('utf-8')}"
584+
)
585+
msg = QtWidgets.QMessageBox()
586+
msg.warning(
587+
self,
588+
"Error while downloading Python on Windows fail-safe mode!",
589+
f"Error message:\n\n {out.decode('utf-8')}",
590+
)
591+
self.setEnabled(True)
592+
return
593+
594+
if when_finished is not None:
595+
when_finished(output_path)
596+
543597
def _run_install_python(self, filename):
544598
"""Execute the installation process."""
545599
LOG.debug("Executing run_install_python")

0 commit comments

Comments
 (0)