diff --git a/openformsclient/admin.py b/openformsclient/admin.py index 8a1f544..ce4463e 100644 --- a/openformsclient/admin.py +++ b/openformsclient/admin.py @@ -16,6 +16,7 @@ class ConfigurationAdmin(SingletonModelAdmin): "fields": ( "api_root", "api_token", + "client_timeout", "status", ) }, diff --git a/openformsclient/client.py b/openformsclient/client.py index 1504278..599ded2 100644 --- a/openformsclient/client.py +++ b/openformsclient/client.py @@ -9,15 +9,15 @@ class Client: - def __init__(self, api_root, api_token): + def __init__(self, api_root, api_token, client_timeout): self.api_root = api_root self.api_token = api_token + self.timeout = client_timeout def _request(self, method, relative_url, **extra_kwargs): - kwargs = { "headers": {"Authorization": f"Token {self.api_token}"}, - "timeout": 5, + "timeout": self.timeout, } kwargs.update(extra_kwargs) diff --git a/openformsclient/migrations/0001_initial.py b/openformsclient/migrations/0001_initial.py index 0b10859..5a9680e 100644 --- a/openformsclient/migrations/0001_initial.py +++ b/openformsclient/migrations/0001_initial.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - initial = True dependencies = [] diff --git a/openformsclient/migrations/0002_alter_configuration_options.py b/openformsclient/migrations/0002_alter_configuration_options.py index d651b1d..c9ea2c6 100644 --- a/openformsclient/migrations/0002_alter_configuration_options.py +++ b/openformsclient/migrations/0002_alter_configuration_options.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("openformsclient", "0001_initial"), ] diff --git a/openformsclient/migrations/0003_configuration_client_timeout.py b/openformsclient/migrations/0003_configuration_client_timeout.py new file mode 100644 index 0000000..89f0372 --- /dev/null +++ b/openformsclient/migrations/0003_configuration_client_timeout.py @@ -0,0 +1,21 @@ +# Generated by Django 3.2.23 on 2024-02-13 08:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("openformsclient", "0002_alter_configuration_options"), + ] + + operations = [ + migrations.AddField( + model_name="configuration", + name="client_timeout", + field=models.PositiveIntegerField( + default=5, + help_text="The timeout that is used for requests (in seconds)", + verbose_name="Client request timeout", + ), + ), + ] diff --git a/openformsclient/models.py b/openformsclient/models.py index 8c9330a..fcaec5a 100644 --- a/openformsclient/models.py +++ b/openformsclient/models.py @@ -36,6 +36,11 @@ class Configuration(SingletonModel): "The Open Forms API token value. Example: 7ab84e80b3d68d52a5f9e1712e3d0eda27d21e58" ), ) + client_timeout = models.PositiveIntegerField( + _("Client request timeout"), + default=5, + help_text=_("The timeout that is used for requests (in seconds)"), + ) sdk_css_url = models.URLField( _("SDK CSS URL"), @@ -73,7 +78,7 @@ def save(self, *args, **kwargs): @cached_property def client(self): - return Client(self.api_root, self.api_token) + return Client(self.api_root, self.api_token, self.client_timeout) class OpenFormsBaseField: diff --git a/tests/test_client.py b/tests/test_client.py index 3956099..00b473f 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -1,3 +1,5 @@ +from unittest.mock import patch + from django.test import TestCase import requests_mock @@ -11,11 +13,12 @@ class ClientTests(TestCase): def setUp(self): self.api_root = "https://example.com/api/v1/" self.api_token = "token" - self.client = Client(self.api_root, self.api_token) + self.client_timeout = 2 + self.client = Client(self.api_root, self.api_token, self.client_timeout) def test_has_config(self, m): self.assertTrue(self.client.has_config()) - self.assertFalse(Client("", "").has_config()) + self.assertFalse(Client("", "", "").has_config()) def test_is_healthy(self, m): m.head( @@ -76,3 +79,13 @@ def test_get_form_with_error(self, m): with self.assertRaises(HTTPError): self.client.get_form("myform") + + def test_request_uses_configured_timeout(self, m): + with patch("openformsclient.client.requests.request") as mock_request: + self.client.get_form("myform") + mock_request.assert_called_with( + "get", + "https://example.com/api/v1/forms/myform", + headers={"Authorization": "Token token"}, + timeout=2, + ) diff --git a/tests/test_utils.py b/tests/test_utils.py index 6df90a5..64f325d 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -16,7 +16,7 @@ def setUp(self): ) def test_get_form_choices_without_config(self, m): - client = Client("", "") + client = Client("", "", "") result = get_form_choices(client) self.assertEqual(result, [])