Skip to content

Commit ba16b23

Browse files
committed
add timeout for API calls
1 parent d79d67f commit ba16b23

File tree

1 file changed

+27
-9
lines changed

1 file changed

+27
-9
lines changed

cloudshell/rest/api.py

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,16 @@
1919
from cloudshell.rest.models import ShellInfo, StandardInfo
2020
from cloudshell.rest.progress_bar import iter_resp_with_pb, upload_with_pb
2121

22+
DEFAULT_API_TIMEOUT = 15
23+
2224

2325
@define
2426
class PackagingRestApiClient:
2527
host: str
2628
_token: str = field(repr=False)
2729
port: int = 9000
2830
_show_progress: bool = field(default=False, repr=False)
31+
_api_timeout: int = field(default=DEFAULT_API_TIMEOUT, repr=False)
2932
_api_url: str = field(init=False)
3033
_headers: dict[str, str] = field(init=False)
3134

@@ -42,20 +45,23 @@ def login(
4245
domain: str = "Global",
4346
port: int = 9000,
4447
show_progress: bool = False,
48+
api_timeout: int = DEFAULT_API_TIMEOUT,
4549
) -> Self:
4650
url = urljoin(_get_api_url(host, port), "Auth/Login")
4751
req_data = {
4852
"username": username,
4953
"password": password,
5054
"domain": domain,
5155
}
52-
resp = requests.put(url, data=req_data)
56+
resp = requests.put(url, data=req_data, timeout=api_timeout)
5357
if resp.status_code == 401:
5458
raise LoginFailedError(resp.text)
5559
elif resp.status_code != 200:
5660
raise PackagingRestApiError(resp.text)
5761
token = resp.text.strip("'\"")
58-
return cls(host, token, port, show_progress=show_progress)
62+
return cls(
63+
host, token, port, show_progress=show_progress, api_timeout=api_timeout
64+
)
5965

6066
def add_shell_from_buffer(self, file_obj: BinaryIO | bytes) -> None:
6167
"""Add a new Shell from the buffer or binary."""
@@ -64,7 +70,9 @@ def add_shell_from_buffer(self, file_obj: BinaryIO | bytes) -> None:
6470
headers = self._headers.copy()
6571

6672
with upload_with_pb(req_data, headers, show=self._show_progress) as new_data:
67-
resp = requests.post(url, data=new_data, headers=headers)
73+
resp = requests.post(
74+
url, data=new_data, headers=headers, timeout=self._api_timeout
75+
)
6876

6977
if resp.status_code != 201:
7078
msg = f"Can't add shell, response: {resp.text}"
@@ -87,7 +95,9 @@ def update_shell_from_buffer(
8795
headers = self._headers.copy()
8896

8997
with upload_with_pb(req_data, headers, show=self._show_progress) as new_data:
90-
resp = requests.put(url, data=new_data, headers=headers)
98+
resp = requests.put(
99+
url, data=new_data, headers=headers, timeout=self._api_timeout
100+
)
91101

92102
if resp.status_code == 404:
93103
raise ShellNotFound()
@@ -106,7 +116,7 @@ def update_shell(
106116
def get_installed_standards(self) -> list[dict]:
107117
"""Gets all standards installed on CloudShell."""
108118
url = urljoin(self._api_url, "Standards")
109-
resp = requests.get(url, headers=self._headers)
119+
resp = requests.get(url, headers=self._headers, timeout=self._api_timeout)
110120
if resp.status_code == 404:
111121
raise FeatureUnavailable()
112122
elif resp.status_code != 200:
@@ -120,7 +130,7 @@ def get_installed_standards_as_models(self) -> list[StandardInfo]:
120130
def get_shell(self, shell_name: str) -> dict:
121131
"""Get a Shell's information."""
122132
url = urljoin(self._api_url, f"Shells/{shell_name}")
123-
resp = requests.get(url, headers=self._headers)
133+
resp = requests.get(url, headers=self._headers, timeout=self._api_timeout)
124134
if resp.status_code == 404:
125135
raise FeatureUnavailable()
126136
elif resp.status_code == 400:
@@ -136,7 +146,7 @@ def get_shell_as_model(self, shell_name: str) -> ShellInfo:
136146
def delete_shell(self, shell_name: str) -> None:
137147
"""Delete a Shell from the CloudShell."""
138148
url = urljoin(self._api_url, f"Shells/{shell_name}")
139-
resp = requests.delete(url, headers=self._headers)
149+
resp = requests.delete(url, headers=self._headers, timeout=self._api_timeout)
140150
if resp.status_code == 404:
141151
raise FeatureUnavailable()
142152
elif resp.status_code == 400:
@@ -148,7 +158,13 @@ def export_package(self, topologies: list[str]) -> Generator[bytes, None, None]:
148158
"""Export a package with the topologies from the CloudShell."""
149159
url = urljoin(self._api_url, "Package/ExportPackage")
150160
req_data = {"TopologyNames": topologies}
151-
resp = requests.post(url, headers=self._headers, json=req_data, stream=True)
161+
resp = requests.post(
162+
url,
163+
headers=self._headers,
164+
json=req_data,
165+
stream=True,
166+
timeout=self._api_timeout,
167+
)
152168

153169
if resp.status_code == 404:
154170
raise FeatureUnavailable()
@@ -172,7 +188,9 @@ def import_package_from_buffer(self, file_obj: BinaryIO | bytes) -> None:
172188
headers = self._headers.copy()
173189

174190
with upload_with_pb(req_data, headers, show=self._show_progress) as new_data:
175-
resp = requests.post(url, data=new_data, headers=headers)
191+
resp = requests.post(
192+
url, data=new_data, headers=headers, timeout=self._api_timeout
193+
)
176194

177195
if resp.status_code == 404:
178196
raise FeatureUnavailable()

0 commit comments

Comments
 (0)