Skip to content

Commit 584aaee

Browse files
authored
add timeouts to all requests (#5881)
* add timeouts to all requests * make the requests timeout a constant * 15s (matching the default in pip)
1 parent a3aafa8 commit 584aaee

File tree

7 files changed

+30
-7
lines changed

7 files changed

+30
-7
lines changed

src/poetry/publishing/uploader.py

+3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from urllib3 import util
2323

2424
from poetry.__version__ import __version__
25+
from poetry.utils.constants import REQUESTS_TIMEOUT
2526
from poetry.utils.patterns import wheel_file_re
2627

2728

@@ -262,6 +263,7 @@ def _upload_file(
262263
data=monitor,
263264
allow_redirects=False,
264265
headers={"Content-Type": monitor.content_type},
266+
timeout=REQUESTS_TIMEOUT,
265267
)
266268
if resp is None or 200 <= resp.status_code < 300:
267269
bar.set_format(
@@ -320,6 +322,7 @@ def _register(self, session: requests.Session, url: str) -> requests.Response:
320322
data=encoder,
321323
allow_redirects=False,
322324
headers={"Content-Type": encoder.content_type},
325+
timeout=REQUESTS_TIMEOUT,
323326
)
324327

325328
resp.raise_for_status()

src/poetry/repositories/http.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from poetry.repositories.exceptions import RepositoryError
2525
from poetry.repositories.link_sources.html import HTMLPage
2626
from poetry.utils.authenticator import Authenticator
27+
from poetry.utils.constants import REQUESTS_TIMEOUT
2728
from poetry.utils.helpers import download_file
2829
from poetry.utils.patterns import wheel_file_re
2930

@@ -260,7 +261,9 @@ def _links_to_data(self, links: list[Link], data: PackageInfo) -> dict[str, Any]
260261
def _get_response(self, endpoint: str) -> requests.Response | None:
261262
url = self._url + endpoint
262263
try:
263-
response: requests.Response = self.session.get(url, raise_for_status=False)
264+
response: requests.Response = self.session.get(
265+
url, raise_for_status=False, timeout=REQUESTS_TIMEOUT
266+
)
264267
if response.status_code in (401, 403):
265268
self._log(
266269
f"Authorization error accessing {url}",

src/poetry/repositories/pypi_repository.py

+10-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from poetry.repositories.exceptions import PackageNotFound
1818
from poetry.repositories.http import HTTPRepository
1919
from poetry.utils._compat import to_str
20+
from poetry.utils.constants import REQUESTS_TIMEOUT
2021

2122

2223
cache_control_logger.setLevel(logging.ERROR)
@@ -103,7 +104,9 @@ def search(self, query: str) -> list[Package]:
103104

104105
search = {"q": query}
105106

106-
response = requests.session().get(self._base_url + "search", params=search)
107+
response = requests.session().get(
108+
self._base_url + "search", params=search, timeout=REQUESTS_TIMEOUT
109+
)
107110
content = parse(response.content, namespaceHTMLElements=False)
108111
for result in content.findall(".//*[@class='package-snippet']"):
109112
name_element = result.find("h3/*[@class='package-snippet__name']")
@@ -244,14 +247,18 @@ def _get_release_info(
244247
def _get(self, endpoint: str) -> dict[str, Any] | None:
245248
try:
246249
json_response = self.session.get(
247-
self._base_url + endpoint, raise_for_status=False
250+
self._base_url + endpoint,
251+
raise_for_status=False,
252+
timeout=REQUESTS_TIMEOUT,
248253
)
249254
except requests.exceptions.TooManyRedirects:
250255
# Cache control redirect loop.
251256
# We try to remove the cache and try again
252257
self.session.delete_cache(self._base_url + endpoint)
253258
json_response = self.session.get(
254-
self._base_url + endpoint, raise_for_status=False
259+
self._base_url + endpoint,
260+
raise_for_status=False,
261+
timeout=REQUESTS_TIMEOUT,
255262
)
256263

257264
if json_response.status_code != 200:

src/poetry/utils/authenticator.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
from poetry.config.config import Config
2323
from poetry.exceptions import PoetryException
24+
from poetry.utils.constants import REQUESTS_TIMEOUT
2425
from poetry.utils.password_manager import HTTPAuthCredential
2526
from poetry.utils.password_manager import PasswordManager
2627

@@ -219,7 +220,7 @@ def request(
219220

220221
# Send the request.
221222
send_kwargs = {
222-
"timeout": kwargs.get("timeout"),
223+
"timeout": kwargs.get("timeout", REQUESTS_TIMEOUT),
223224
"allow_redirects": kwargs.get("allow_redirects", True),
224225
}
225226
send_kwargs.update(settings)

src/poetry/utils/constants.py

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from __future__ import annotations
2+
3+
4+
# Timeout for HTTP requests using the requests library.
5+
REQUESTS_TIMEOUT = 15

src/poetry/utils/helpers.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
from typing import Iterator
1414
from typing import Mapping
1515

16+
from poetry.utils.constants import REQUESTS_TIMEOUT
17+
1618

1719
if TYPE_CHECKING:
1820
from collections.abc import Callable
@@ -89,7 +91,7 @@ def download_file(
8991

9092
get = requests.get if not session else session.get
9193

92-
response = get(url, stream=True)
94+
response = get(url, stream=True, timeout=REQUESTS_TIMEOUT)
9395
response.raise_for_status()
9496

9597
set_indicator = False

tests/repositories/test_legacy_repository.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,9 @@ def test_get_redirected_response_url(
426426
repo = MockHttpRepository({"/foo": 200}, http)
427427
redirect_url = "http://legacy.redirect.bar"
428428

429-
def get_mock(url: str, raise_for_status: bool = True) -> requests.Response:
429+
def get_mock(
430+
url: str, raise_for_status: bool = True, timeout: int = 5
431+
) -> requests.Response:
430432
response = requests.Response()
431433
response.status_code = 200
432434
response.url = redirect_url + "/foo"

0 commit comments

Comments
 (0)