|
1 | 1 | import inspect
|
2 | 2 | import os
|
| 3 | +import platform |
| 4 | +import shutil |
| 5 | +import subprocess |
3 | 6 | import sys
|
4 | 7 | import traceback
|
5 | 8 | from datetime import datetime
|
@@ -1078,3 +1081,68 @@ def run(function: Callable[..., Any]) -> None:
|
1078 | 1081 | app = Typer(add_completion=False)
|
1079 | 1082 | app.command()(function)
|
1080 | 1083 | app()
|
| 1084 | + |
| 1085 | + |
| 1086 | +def _is_macos() -> bool: |
| 1087 | + return platform.system() == "Darwin" |
| 1088 | + |
| 1089 | + |
| 1090 | +def _is_linux_or_bsd() -> bool: |
| 1091 | + if platform.system() == "Linux": |
| 1092 | + return True |
| 1093 | + |
| 1094 | + return "BSD" in platform.system() |
| 1095 | + |
| 1096 | + |
| 1097 | +def launch(url: str, wait: bool = False, locate: bool = False) -> int: |
| 1098 | + """This function launches the given URL (or filename) in the default |
| 1099 | + viewer application for this file type. If this is an executable, it |
| 1100 | + might launch the executable in a new session. The return value is |
| 1101 | + the exit code of the launched application. Usually, ``0`` indicates |
| 1102 | + success. |
| 1103 | +
|
| 1104 | + This function handles url in different operating systems separately: |
| 1105 | + - On macOS (Darwin), it uses the 'open' command. |
| 1106 | + - On Linux and BSD, it uses 'xdg-open' if available. |
| 1107 | + - On Windows (and other OSes), it uses the standard webbrowser module. |
| 1108 | +
|
| 1109 | + The function avoids, when possible, using the webbrowser module on Linux and macOS |
| 1110 | + to prevent spammy terminal messages from some browsers (e.g., Chrome). |
| 1111 | +
|
| 1112 | + Examples:: |
| 1113 | +
|
| 1114 | + typer.launch("https://typer.tiangolo.com/") |
| 1115 | + typer.launch("/my/downloaded/file", locate=True) |
| 1116 | +
|
| 1117 | + :param url: URL or filename of the thing to launch. |
| 1118 | + :param wait: Wait for the program to exit before returning. This |
| 1119 | + only works if the launched program blocks. In particular, |
| 1120 | + ``xdg-open`` on Linux does not block. |
| 1121 | + :param locate: if this is set to `True` then instead of launching the |
| 1122 | + application associated with the URL it will attempt to |
| 1123 | + launch a file manager with the file located. This |
| 1124 | + might have weird effects if the URL does not point to |
| 1125 | + the filesystem. |
| 1126 | + """ |
| 1127 | + |
| 1128 | + if url.startswith("http://") or url.startswith("https://"): |
| 1129 | + if _is_macos(): |
| 1130 | + return subprocess.Popen( |
| 1131 | + ["open", url], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT |
| 1132 | + ).wait() |
| 1133 | + |
| 1134 | + has_xdg_open = _is_linux_or_bsd() and shutil.which("xdg-open") is not None |
| 1135 | + |
| 1136 | + if has_xdg_open: |
| 1137 | + return subprocess.Popen( |
| 1138 | + ["xdg-open", url], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT |
| 1139 | + ).wait() |
| 1140 | + |
| 1141 | + import webbrowser |
| 1142 | + |
| 1143 | + webbrowser.open(url) |
| 1144 | + |
| 1145 | + return 0 |
| 1146 | + |
| 1147 | + else: |
| 1148 | + return click.launch(url) |
0 commit comments