diff --git a/CHANGELOG.md b/CHANGELOG.md index e62f91e2c..b90f46589 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,7 +40,7 @@ Attention: The newest changes should be on top --> ### Fixed -- +- BUG: Add explicit timeouts to ThrustCurve API requests [#935](https://github.com/RocketPy-Team/RocketPy/pull/935) ## [v1.12.0] - 2026-03-08 diff --git a/rocketpy/motors/motor.py b/rocketpy/motors/motor.py index 373154512..ea42dd71c 100644 --- a/rocketpy/motors/motor.py +++ b/rocketpy/motors/motor.py @@ -1946,8 +1946,11 @@ def _call_thrustcurve_api(name: str, no_cache: bool = False): # pylint: disable ------ ValueError If no motor is found or if the downloaded .eng data is missing. + requests.exceptions.Timeout + If a search or download request to the ThrustCurve API exceeds the + timeout limit (5 s connect / 30 s read). requests.exceptions.RequestException - If a network or HTTP error occurs during the API call. + If any other network or HTTP error occurs during the API call. Notes ----- @@ -1973,8 +1976,13 @@ def _call_thrustcurve_api(name: str, no_cache: bool = False): # pylint: disable ) base_url = "https://www.thrustcurve.org/api/v1" + _timeout = (5, 30) # (connect timeout, read timeout) in seconds # Step 1. Search motor - response = requests.get(f"{base_url}/search.json", params={"commonName": name}) + response = requests.get( + f"{base_url}/search.json", + params={"commonName": name}, + timeout=_timeout, + ) response.raise_for_status() data = response.json() @@ -1994,6 +2002,7 @@ def _call_thrustcurve_api(name: str, no_cache: bool = False): # pylint: disable dl_response = requests.get( f"{base_url}/download.json", params={"motorIds": motor_id, "format": "RASP", "data": "file"}, + timeout=_timeout, ) dl_response.raise_for_status() dl_data = dl_response.json()