1919from cloudshell .rest .models import ShellInfo , StandardInfo
2020from cloudshell .rest .progress_bar import iter_resp_with_pb , upload_with_pb
2121
22+ DEFAULT_API_TIMEOUT = 15
23+
2224
2325@define
2426class 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