Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions novem/api_ref.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import functools
import os
import sys
import urllib.request
Expand Down Expand Up @@ -132,6 +133,9 @@ def __init__(
self._session = requests.Session()
self._session.headers.update(get_ua(is_cli))
self._session.proxies = urllib.request.getproxies()
self._session.request = functools.partial( # type: ignore[method-assign]
self._session.request, timeout=(10, 120)
)

if cfg.ignore_ssl:
# supress ssl warnings
Expand Down
4 changes: 4 additions & 0 deletions novem/cli/gql.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"""

import datetime
import functools
import json
import re
import shutil
Expand Down Expand Up @@ -35,6 +36,9 @@ def __init__(self, *, debug: bool = False, gql: Any = False, **connection: Any)
_, config = get_current_config(**connection)
self._config = config
self._session = requests.Session()
self._session.request = functools.partial( # type: ignore[method-assign]
self._session.request, timeout=(10, 120)
)
self._debug = debug
# Support both old gql_debug and new gql parameter for debug mode
self._gql_debug = gql is True # True when --gql with no argument
Expand Down
3 changes: 2 additions & 1 deletion novem/job/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ def run(
]
if self._debug:
print(f" files in: {len(upload)} ({list(upload.keys())})")
r = self._session.post(path, files=multipart, stream=bool(output))
r = self._session.post(path, files=multipart, stream=bool(output), timeout=(30, 1800))
else:
if self._debug:
print(" files in: 0")
Expand All @@ -424,6 +424,7 @@ def run(
headers={"Content-type": "application/json; charset=utf-8"},
data="{}",
stream=bool(output),
timeout=(30, 1800),
)

if not r.ok:
Expand Down
46 changes: 46 additions & 0 deletions tests/test_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from unittest.mock import patch

import pytest
from requests import Response

from novem import Job
from novem.exceptions import Novem403, Novem404
Expand Down Expand Up @@ -1015,3 +1016,48 @@ def test_dedup_path_with_conflicts(tmp_path):

open(tmp_path / "file (1).txt", "w").close()
assert _Job._dedup_path(str(tmp_path), "file.txt") == os.path.join(str(tmp_path), "file (2).txt")


# ---------------------------------------------------------------------------
# timeout tests
# ---------------------------------------------------------------------------


def _ok_response(content=b""):
r = Response()
r.status_code = 200
r._content = content
return r


def test_session_default_timeout(requests_mock):
"""Default (10, 120) timeout reaches session.send for ordinary API calls."""
j, _ = _make_job(requests_mock)

with patch.object(j._session, "send", return_value=_ok_response(b"ok")) as mock_send:
j.api_read("/log")

assert mock_send.call_args.kwargs.get("timeout") == (10, 120)


def test_job_run_no_files_uses_job_timeout(requests_mock):
"""run() without files passes timeout=(30, 1800) through to session.send."""
j, _ = _make_job(requests_mock)

with patch.object(j._session, "send", return_value=_ok_response()) as mock_send:
j.run()

assert mock_send.call_args.kwargs.get("timeout") == (30, 1800)


def test_job_run_with_files_uses_job_timeout(requests_mock, tmp_path):
"""run() with files passes timeout=(30, 1800) through to session.send."""
j, _ = _make_job(requests_mock)

f1 = tmp_path / "data.csv"
f1.write_text("a,b\n1,2\n")

with patch.object(j._session, "send", return_value=_ok_response()) as mock_send:
j.run(files=[f"@{f1}"])

assert mock_send.call_args.kwargs.get("timeout") == (30, 1800)