fusion-platform-python-sdk 1.9.2__tar.gz → 1.11.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. {fusion-platform-python-sdk-1.9.2/fusion_platform_python_sdk.egg-info → fusion-platform-python-sdk-1.11.1}/PKG-INFO +10 -3
  2. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/README.md +2 -2
  3. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/__init__.py +2 -2
  4. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/fusion_platform_sdk.pdf +0 -0
  5. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1/fusion_platform_python_sdk.egg-info}/PKG-INFO +10 -3
  6. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform_python_sdk.egg-info/SOURCES.txt +6 -1
  7. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform_python_sdk.egg-info/requires.txt +1 -1
  8. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/setup.py +3 -2
  9. fusion-platform-python-sdk-1.11.1/tests/test_base.py +29 -0
  10. fusion-platform-python-sdk-1.11.1/tests/test_command.py +23 -0
  11. fusion-platform-python-sdk-1.11.1/tests/test_init.py +88 -0
  12. fusion-platform-python-sdk-1.11.1/tests/test_localise.py +42 -0
  13. fusion-platform-python-sdk-1.11.1/tests/test_session.py +306 -0
  14. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/LICENSE.txt +0 -0
  15. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/MANIFEST.in +0 -0
  16. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/__main__.py +0 -0
  17. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/base.py +0 -0
  18. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/command.py +0 -0
  19. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/common/__init__.py +0 -0
  20. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/common/raise_thread.py +0 -0
  21. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/common/utilities.py +0 -0
  22. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/detailed_example.py +0 -0
  23. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/documentation.py +0 -0
  24. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/glasgow.geojson +0 -0
  25. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/lake_district.geojson +0 -0
  26. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/localisations.py +0 -0
  27. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/localise.py +0 -0
  28. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/__init__.py +0 -0
  29. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/credit.md +0 -0
  30. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/credit.py +0 -0
  31. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/data.md +0 -0
  32. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/data.py +0 -0
  33. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/data_file.md +0 -0
  34. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/data_file.py +0 -0
  35. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/fields.py +0 -0
  36. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/model.py +0 -0
  37. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/organisation.md +0 -0
  38. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/organisation.py +0 -0
  39. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/process.md +0 -0
  40. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/process.py +0 -0
  41. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/process_execution.md +0 -0
  42. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/process_execution.py +0 -0
  43. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/process_service_execution.md +0 -0
  44. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/process_service_execution.py +0 -0
  45. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/process_service_execution_log.md +0 -0
  46. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/process_service_execution_log.py +0 -0
  47. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/service.md +0 -0
  48. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/service.py +0 -0
  49. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/user.md +0 -0
  50. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/models/user.py +0 -0
  51. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/quick_example.py +0 -0
  52. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/session.py +0 -0
  53. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform/translations.py +0 -0
  54. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform_python_sdk.egg-info/dependency_links.txt +0 -0
  55. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform_python_sdk.egg-info/entry_points.txt +0 -0
  56. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/fusion_platform_python_sdk.egg-info/top_level.txt +0 -0
  57. {fusion-platform-python-sdk-1.9.2 → fusion-platform-python-sdk-1.11.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fusion-platform-python-sdk
3
- Version: 1.9.2
3
+ Version: 1.11.1
4
4
  Summary: Python SDK used to interact with the Fusion Platform(r)
5
5
  Home-page: https://github.com/d-cat-support/fusion-platform-python-sdk
6
6
  Author: Digital Content Analysis Technology Ltd
@@ -12,8 +12,15 @@ Classifier: Programming Language :: Python :: 3.8
12
12
  Classifier: Programming Language :: Python :: 3.9
13
13
  Classifier: Programming Language :: Python :: 3.10
14
14
  Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
15
16
  Description-Content-Type: text/markdown
16
17
  License-File: LICENSE.txt
18
+ Requires-Dist: marshmallow
19
+ Requires-Dist: pyjwt
20
+ Requires-Dist: python-dateutil
21
+ Requires-Dist: python-i18n[YAML]
22
+ Requires-Dist: requests
23
+ Requires-Dist: tenacity
17
24
 
18
25
  # Fusion Platform<sup>&reg;</sup> Python SDK
19
26
 
@@ -29,8 +36,8 @@ API, and this is defined within the corresponding OpenAPI 3.0 specification, whi
29
36
 
30
37
  ## Installation
31
38
 
32
- The SDK has been built for Python 3, and is tested against Python 3.8, 3.9, 3.10 and 3.11. To install the SDK into a suitable Python environment containing `pip`,
33
- execute the following:
39
+ The SDK has been built for Python 3, and is tested against Python 3.8, 3.9, 3.10, 3.11 and 3.12. To install the SDK into a suitable Python environment containing
40
+ `pip`, execute the following:
34
41
 
35
42
  ```shell
36
43
  pip install fusion-platform-python-sdk
@@ -12,8 +12,8 @@ API, and this is defined within the corresponding OpenAPI 3.0 specification, whi
12
12
 
13
13
  ## Installation
14
14
 
15
- The SDK has been built for Python 3, and is tested against Python 3.8, 3.9, 3.10 and 3.11. To install the SDK into a suitable Python environment containing `pip`,
16
- execute the following:
15
+ The SDK has been built for Python 3, and is tested against Python 3.8, 3.9, 3.10, 3.11 and 3.12. To install the SDK into a suitable Python environment containing
16
+ `pip`, execute the following:
17
17
 
18
18
  ```shell
19
19
  pip install fusion-platform-python-sdk
@@ -11,8 +11,8 @@ API, and this is defined within the corresponding OpenAPI 3.0 specification, whi
11
11
  """
12
12
 
13
13
  # Do not modify the following two lines as they are maintained by the version.sh script.
14
- __version__ = '1.9.2'
15
- __version_date__ = '2024-01-04T07:44:52Z'
14
+ __version__ = '1.11.1'
15
+ __version_date__ = '2024-04-08T10:20:23Z'
16
16
 
17
17
  # Exclude certain sub-modules from documentation.
18
18
  # @formatter:off
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fusion-platform-python-sdk
3
- Version: 1.9.2
3
+ Version: 1.11.1
4
4
  Summary: Python SDK used to interact with the Fusion Platform(r)
5
5
  Home-page: https://github.com/d-cat-support/fusion-platform-python-sdk
6
6
  Author: Digital Content Analysis Technology Ltd
@@ -12,8 +12,15 @@ Classifier: Programming Language :: Python :: 3.8
12
12
  Classifier: Programming Language :: Python :: 3.9
13
13
  Classifier: Programming Language :: Python :: 3.10
14
14
  Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
15
16
  Description-Content-Type: text/markdown
16
17
  License-File: LICENSE.txt
18
+ Requires-Dist: marshmallow
19
+ Requires-Dist: pyjwt
20
+ Requires-Dist: python-dateutil
21
+ Requires-Dist: python-i18n[YAML]
22
+ Requires-Dist: requests
23
+ Requires-Dist: tenacity
17
24
 
18
25
  # Fusion Platform<sup>&reg;</sup> Python SDK
19
26
 
@@ -29,8 +36,8 @@ API, and this is defined within the corresponding OpenAPI 3.0 specification, whi
29
36
 
30
37
  ## Installation
31
38
 
32
- The SDK has been built for Python 3, and is tested against Python 3.8, 3.9, 3.10 and 3.11. To install the SDK into a suitable Python environment containing `pip`,
33
- execute the following:
39
+ The SDK has been built for Python 3, and is tested against Python 3.8, 3.9, 3.10, 3.11 and 3.12. To install the SDK into a suitable Python environment containing
40
+ `pip`, execute the following:
34
41
 
35
42
  ```shell
36
43
  pip install fusion-platform-python-sdk
@@ -47,4 +47,9 @@ fusion_platform_python_sdk.egg-info/SOURCES.txt
47
47
  fusion_platform_python_sdk.egg-info/dependency_links.txt
48
48
  fusion_platform_python_sdk.egg-info/entry_points.txt
49
49
  fusion_platform_python_sdk.egg-info/requires.txt
50
- fusion_platform_python_sdk.egg-info/top_level.txt
50
+ fusion_platform_python_sdk.egg-info/top_level.txt
51
+ tests/test_base.py
52
+ tests/test_command.py
53
+ tests/test_init.py
54
+ tests/test_localise.py
55
+ tests/test_session.py
@@ -1,6 +1,6 @@
1
1
  marshmallow
2
2
  pyjwt
3
3
  python-dateutil
4
- python-i18n[yaml]
4
+ python-i18n[YAML]
5
5
  requests
6
6
  tenacity
@@ -19,7 +19,7 @@ PACKAGE_DIR = pathlib.Path(__file__).parent
19
19
  # @formatter:off
20
20
  setup(
21
21
  name='fusion-platform-python-sdk',
22
- version='1.9.2',
22
+ version='1.11.1',
23
23
  description='Python SDK used to interact with the Fusion Platform(r)',
24
24
  long_description=(PACKAGE_DIR / 'README.md').read_text(),
25
25
  long_description_content_type='text/markdown',
@@ -33,7 +33,8 @@ setup(
33
33
  'Programming Language :: Python :: 3.8',
34
34
  'Programming Language :: Python :: 3.9',
35
35
  'Programming Language :: Python :: 3.10',
36
- 'Programming Language :: Python :: 3.11'
36
+ 'Programming Language :: Python :: 3.11',
37
+ 'Programming Language :: Python :: 3.12',
37
38
  ],
38
39
  packages=find_packages(exclude='tests'),
39
40
  include_package_data=True,
@@ -0,0 +1,29 @@
1
+ #
2
+ # Base class test file.
3
+ #
4
+ # @author Matthew Casey
5
+ #
6
+ # (c) Digital Content Analysis Technology Ltd 2022
7
+ #
8
+
9
+ from tests.custom_test_case import CustomTestCase
10
+
11
+ from fusion_platform.base import Base
12
+
13
+
14
+ class TestBase(CustomTestCase):
15
+ """
16
+ Base tests.
17
+ """
18
+
19
+ def test_init(self):
20
+ """
21
+ Test initialisation of the class to ensure no exceptions are raised.
22
+ """
23
+ Base()
24
+
25
+ def test_main(self):
26
+ """
27
+ Test main entry point to ensure no exceptions are raised.
28
+ """
29
+ Base.main()
@@ -0,0 +1,23 @@
1
+ #
2
+ # Command test file.
3
+ #
4
+ # @author Matthew Casey
5
+ #
6
+ # (c) Digital Content Analysis Technology Ltd 2022
7
+ #
8
+
9
+ from tests.custom_test_case import CustomTestCase
10
+
11
+ from fusion_platform.command import fusion_platform
12
+
13
+
14
+ class TestCommand(CustomTestCase):
15
+ """
16
+ Command tests.
17
+ """
18
+
19
+ def test_fusion_platform(self):
20
+ """
21
+ Test main entry point to ensure no exceptions are raised.
22
+ """
23
+ fusion_platform()
@@ -0,0 +1,88 @@
1
+ #
2
+ # Package init test file.
3
+ #
4
+ # @author Matthew Casey
5
+ #
6
+ # (c) Digital Content Analysis Technology Ltd 2022
7
+ #
8
+
9
+ import json
10
+ import jwt
11
+ import os
12
+ import logging
13
+ import pytest
14
+ import requests
15
+ import requests_mock
16
+ import uuid
17
+
18
+ from tests.custom_test_case import CustomTestCase
19
+
20
+ import fusion_platform
21
+ from fusion_platform.models.model import Model
22
+ from fusion_platform.models.user import User
23
+ from fusion_platform.session import Session, RequestError
24
+
25
+
26
+ class TestInit(CustomTestCase):
27
+ """
28
+ Module tests.
29
+ """
30
+
31
+ def test_examples(self):
32
+ """
33
+ Test obtaining example files.
34
+ """
35
+ path = fusion_platform.EXAMPLE_GLASGOW_FILE
36
+ self.assertIsNotNone(path)
37
+ self.assertTrue(os.path.exists(path))
38
+
39
+ def test_log_level(self):
40
+ """
41
+ Test setting the log level.
42
+ """
43
+ logger = logging.getLogger(fusion_platform.FUSION_PLATFORM_LOGGER)
44
+ logger.setLevel(logging.INFO)
45
+ self.assertEqual(logging.INFO, logger.level)
46
+
47
+ fusion_platform.set_log_level(logging.DEBUG)
48
+ self.assertEqual(logging.DEBUG, logger.level)
49
+
50
+ self.assertEqual(logging.DEBUG, fusion_platform.get_log_level())
51
+
52
+ def test_login(self):
53
+ """
54
+ Test logging in.
55
+ """
56
+ key = b'-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp\nwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5\n1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh\n3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2\npIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX\nGukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il\nAkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF\nL0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k\nX6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl\nU9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ\n37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=\n-----END RSA PRIVATE KEY-----'
57
+ user_id = str(uuid.uuid4())
58
+ access_token = 'token'
59
+ id_token = jwt.encode({'sub': user_id}, key=key, algorithm='RS256')
60
+ body = {'access_token': access_token, 'id_token': id_token}
61
+
62
+ with open(self.fixture_path('user.json'), 'r') as file:
63
+ content = json.loads(file.read())
64
+
65
+ with requests_mock.Mocker() as mock:
66
+ with pytest.raises(RequestError):
67
+ mock.post(f"{Session.API_URL_DEFAULT}/users/login", exc=requests.exceptions.ConnectTimeout)
68
+ fusion_platform.login(email='me@test.com', password='password')
69
+
70
+ with pytest.raises(RequestError):
71
+ mock.post(f"{Session.API_URL_DEFAULT}/users/login", text='{}')
72
+ fusion_platform.login(email='me@test.com', password='password')
73
+
74
+ mock.post(f"{Session.API_URL_DEFAULT}/users/login", text=json.dumps(body))
75
+ mock.get(f"{Session.API_URL_DEFAULT}{User._PATH_GET.format(user_id=user_id)}", text=json.dumps({Model._RESPONSE_KEY_MODEL: content}))
76
+
77
+ user = fusion_platform.login(email='me@test.com', password='password')
78
+ self.assertIsNotNone(user)
79
+
80
+ user = fusion_platform.login(user_id=str(uuid.uuid4()), password='password')
81
+ self.assertIsNotNone(user)
82
+
83
+ def test_version(self):
84
+ """
85
+ Test getting the version.
86
+ """
87
+ self.assertIsNotNone(fusion_platform.__version__)
88
+ self.assertIsNotNone(fusion_platform.__version_date__)
@@ -0,0 +1,42 @@
1
+ #
2
+ # Localise test file.
3
+ #
4
+ # @author Matthew Casey
5
+ #
6
+ # (c) Digital Content Analysis Technology Ltd 2022
7
+ #
8
+
9
+ import i18n
10
+
11
+ from tests.custom_test_case import CustomTestCase
12
+
13
+ from fusion_platform.localise import Localise
14
+
15
+
16
+ class TestLocalise(CustomTestCase):
17
+ """
18
+ Localise tests.
19
+ """
20
+
21
+ def test_setup(self):
22
+ """
23
+ Test setup to ensure no exceptions are raised and that the localisations are loaded.
24
+ """
25
+ Localise.setup()
26
+ self.assertEqual(Localise._FALLBACK_LOCALE, i18n.get('fallback'))
27
+ self.assertTrue(i18n.get('error_on_missing_translation'))
28
+ self.assertTrue(i18n.get('error_on_missing_placeholder'))
29
+ self.assertTrue(i18n.get('error_on_missing_plural'))
30
+ self.assertTrue(i18n.get('enable_memoization'))
31
+
32
+ self.assertEqual('Fusion Platform(r) SDK', i18n.t('fusion_platform.sdk'))
33
+
34
+ def test_set_locale(self):
35
+ """
36
+ Test set locale to ensure that the locale is changed.
37
+ """
38
+ Localise.setup()
39
+ self.assertEqual(Localise._FALLBACK_LOCALE, i18n.get('locale'))
40
+
41
+ Localise.set_locale('ja_JP')
42
+ self.assertEqual('ja_JP', i18n.get('locale'))
@@ -0,0 +1,306 @@
1
+ #
2
+ # Session class test file.
3
+ #
4
+ # @author Matthew Casey
5
+ #
6
+ # (c) Digital Content Analysis Technology Ltd 2022
7
+ #
8
+
9
+ import json
10
+ import jwt
11
+ import os
12
+ import pytest
13
+ import requests
14
+ import requests_mock
15
+ import tempfile
16
+ import uuid
17
+
18
+ from tests.custom_test_case import CustomTestCase
19
+
20
+ from fusion_platform.session import RequestError, Session, ValueError
21
+
22
+
23
+ class TestSession(CustomTestCase):
24
+ """
25
+ Session tests.
26
+ """
27
+
28
+ def __init__(self, methodName):
29
+ """
30
+ Initialises the test case.
31
+
32
+ :param methodName: The test method name.
33
+ """
34
+ super(TestSession, self).__init__(methodName)
35
+
36
+ # Initialise the fields.
37
+ self._download_size = None
38
+
39
+ def download_callback(self, url, destination, size):
40
+ """
41
+ Test download callback method.
42
+
43
+ :param url: The URL to download as a file.
44
+ :param destination: The destination file path.
45
+ :param size: The total size in bytes so far downloaded.
46
+ """
47
+ if self._download_size is None:
48
+ self._download_size = size
49
+ else:
50
+ self._download_size += size
51
+
52
+ def test_init(self):
53
+ """
54
+ Test initialisation of the class to ensure no exceptions are raised.
55
+ """
56
+ Session()
57
+
58
+ def test_download_file(self):
59
+ """
60
+ Test that a file can be downloaded, checking that missing endpoints are handled correctly.
61
+ """
62
+
63
+ with tempfile.TemporaryDirectory() as dir:
64
+ destination = os.path.join(dir, 'file.pdf')
65
+
66
+ session = Session()
67
+
68
+ with pytest.raises(RequestError):
69
+ session.download_file('https://www.d-cat.co.uk/rails/active_storage/blobs/rubbish/Water%20RA%20Webinar%20IoT%20September%202020.pdf?', destination)
70
+
71
+ self.assertFalse(os.path.exists(destination))
72
+ session.download_file(
73
+ 'https://www.d-cat.co.uk/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBkUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--8a6deba9596edd3e9f0c341d274ae1317da59bbc/Water%20RA%20Webinar%20IoT%20September%202020.pdf?',
74
+ destination, self.download_callback)
75
+ self.assertTrue(os.path.exists(destination))
76
+ self.assertIsNotNone(self._download_size)
77
+
78
+ def test_login(self):
79
+ """
80
+ Test login using various parameters.
81
+ """
82
+ with pytest.raises(ValueError):
83
+ Session().login()
84
+
85
+ with pytest.raises(ValueError):
86
+ Session().login(password='password')
87
+
88
+ with pytest.raises(ValueError):
89
+ Session().login(email='me@test.com')
90
+
91
+ with requests_mock.Mocker() as mock:
92
+ mock.post(f"{Session.API_URL_DEFAULT}/users/login", text='{}')
93
+
94
+ with pytest.raises(RequestError):
95
+ Session().login(email='me@test.com', password='password')
96
+
97
+ with pytest.raises(RequestError):
98
+ Session().login(user_id=str(uuid.uuid4()), password='password')
99
+
100
+ key = b'-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp\nwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5\n1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh\n3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2\npIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX\nGukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il\nAkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF\nL0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k\nX6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl\nU9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ\n37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=\n-----END RSA PRIVATE KEY-----'
101
+ user_id = str(uuid.uuid4())
102
+ access_token = 'token'
103
+ id_token = jwt.encode({'sub': user_id}, key=key, algorithm='RS256')
104
+ body = {'access_token': access_token, 'id_token': id_token}
105
+
106
+ with requests_mock.Mocker() as mock:
107
+ mock.post(f"{Session.API_URL_DEFAULT}/users/login", text=json.dumps(body))
108
+
109
+ session = Session()
110
+ self.assertIsNotNone(session)
111
+ self.assertIsNone(session.user_id)
112
+ self.assertIsNone(session._Session__bearer_token)
113
+
114
+ session.login(email='me@test.com', password='password')
115
+ self.assertEqual(user_id, session.user_id)
116
+ self.assertEqual(access_token, session._Session__bearer_token)
117
+
118
+ with requests_mock.Mocker() as mock:
119
+ mock.post(f"{Session.API_URL_DEFAULT}/users/login", text=json.dumps(body))
120
+
121
+ session = Session()
122
+ self.assertIsNotNone(session)
123
+ self.assertIsNone(session.user_id)
124
+ self.assertIsNone(session._Session__bearer_token)
125
+
126
+ session.login(user_id=str(uuid.uuid4()), password='password')
127
+ self.assertEqual(user_id, session.user_id)
128
+ self.assertEqual(access_token, session._Session__bearer_token)
129
+
130
+ def test_request_delete(self):
131
+ """
132
+ Test a delete request and error handling.
133
+ """
134
+ path = '/path'
135
+ body = {'test': True}
136
+ error = 'My Error'
137
+
138
+ session = Session()
139
+ self.assertIsNotNone(session)
140
+
141
+ with requests_mock.Mocker() as mock:
142
+ with pytest.raises(RequestError):
143
+ mock.delete(f"{Session.API_URL_DEFAULT}{path}", exc=requests.exceptions.ConnectTimeout)
144
+ session.request(path=path, method=Session.METHOD_DELETE)
145
+
146
+ with pytest.raises(RequestError):
147
+ mock.delete(f"{Session.API_URL_DEFAULT}{path}", status_code=400)
148
+ session.request(path=path, method=Session.METHOD_DELETE)
149
+
150
+ with pytest.raises(RequestError):
151
+ mock.delete(f"{Session.API_URL_DEFAULT}{path}", text=json.dumps({'error_message': error}), status_code=400)
152
+ session.request(path=path, method=Session.METHOD_DELETE)
153
+
154
+ mock.delete(f"{Session.API_URL_DEFAULT}{path}", text=json.dumps(body))
155
+ response = session.request(path=path, method=Session.METHOD_DELETE)
156
+ self.assertIsNotNone(response)
157
+ self.assertEqual(body, response)
158
+
159
+ def test_request_get(self):
160
+ """
161
+ Test a get request and error handling.
162
+ """
163
+ path = '/path'
164
+ query_parameters = {'name': 'Joe', 'value': 1}
165
+ body = {'test': True}
166
+ error = 'My Error'
167
+
168
+ session = Session()
169
+ self.assertIsNotNone(session)
170
+
171
+ with requests_mock.Mocker() as mock:
172
+ with pytest.raises(RequestError):
173
+ mock.get(f"{Session.API_URL_DEFAULT}{path}", exc=requests.exceptions.ConnectTimeout)
174
+ session.request(path=path, query_parameters=query_parameters, method=Session.METHOD_GET)
175
+
176
+ with pytest.raises(RequestError):
177
+ mock.get(f"{Session.API_URL_DEFAULT}{path}", status_code=400)
178
+ session.request(path=path, query_parameters=query_parameters, method=Session.METHOD_GET)
179
+
180
+ with pytest.raises(RequestError):
181
+ mock.get(f"{Session.API_URL_DEFAULT}{path}", text=json.dumps({'error_message': error}), status_code=400)
182
+ session.request(path=path, query_parameters=query_parameters, method=Session.METHOD_GET)
183
+
184
+ mock.get(f"{Session.API_URL_DEFAULT}{path}", text=json.dumps(body))
185
+ response = session.request(path=path, query_parameters=query_parameters, method=Session.METHOD_GET)
186
+ self.assertIsNotNone(response)
187
+ self.assertEqual(body, response)
188
+
189
+ def test_request_patch(self):
190
+ """
191
+ Test a patch request and error handling.
192
+ """
193
+ path = '/path'
194
+ body = {'test': True}
195
+ error = 'My Error'
196
+
197
+ session = Session()
198
+ self.assertIsNotNone(session)
199
+
200
+ with requests_mock.Mocker() as mock:
201
+ with pytest.raises(RequestError):
202
+ mock.patch(f"{Session.API_URL_DEFAULT}{path}", exc=requests.exceptions.ConnectTimeout)
203
+ session.request(path=path, method=Session.METHOD_PATCH)
204
+
205
+ with pytest.raises(RequestError):
206
+ mock.patch(f"{Session.API_URL_DEFAULT}{path}", status_code=400)
207
+ session.request(path=path, method=Session.METHOD_PATCH)
208
+
209
+ with pytest.raises(RequestError):
210
+ mock.patch(f"{Session.API_URL_DEFAULT}{path}", text=json.dumps({'error_message': error}), status_code=400)
211
+ session.request(path=path, method=Session.METHOD_PATCH)
212
+
213
+ def callback(request, _):
214
+ return request.text
215
+
216
+ mock.patch(f"{Session.API_URL_DEFAULT}{path}", text=callback)
217
+ response = session.request(path=path, method=Session.METHOD_PATCH, body=body)
218
+ self.assertIsNotNone(response)
219
+ self.assertEqual(body, response)
220
+
221
+ def test_request_post(self):
222
+ """
223
+ Test a post request and error handling.
224
+ """
225
+ path = '/path'
226
+ body = {'test': True}
227
+ error = 'My Error'
228
+
229
+ session = Session()
230
+ self.assertIsNotNone(session)
231
+
232
+ with requests_mock.Mocker() as mock:
233
+ with pytest.raises(RequestError):
234
+ mock.post(f"{Session.API_URL_DEFAULT}{path}", exc=requests.exceptions.ConnectTimeout)
235
+ session.request(path=path, method=Session.METHOD_POST)
236
+
237
+ with pytest.raises(RequestError):
238
+ mock.post(f"{Session.API_URL_DEFAULT}{path}", status_code=400)
239
+ session.request(path=path, method=Session.METHOD_POST)
240
+
241
+ with pytest.raises(RequestError):
242
+ mock.post(f"{Session.API_URL_DEFAULT}{path}", text=json.dumps({'error_message': error}), status_code=400)
243
+ session.request(path=path, method=Session.METHOD_POST)
244
+
245
+ def callback(request, _):
246
+ return request.text
247
+
248
+ mock.post(f"{Session.API_URL_DEFAULT}{path}", text=callback)
249
+ response = session.request(path=path, method=Session.METHOD_POST, body=body)
250
+ self.assertIsNotNone(response)
251
+ self.assertEqual(body, response)
252
+
253
+ def test_request_put(self):
254
+ """
255
+ Test a put request and error handling.
256
+ """
257
+ path = '/path'
258
+ body = {'test': True}
259
+ error = 'My Error'
260
+
261
+ session = Session()
262
+ self.assertIsNotNone(session)
263
+
264
+ with requests_mock.Mocker() as mock:
265
+ with pytest.raises(RequestError):
266
+ mock.put(f"{Session.API_URL_DEFAULT}{path}", exc=requests.exceptions.ConnectTimeout)
267
+ session.request(path=path, method=Session.METHOD_PUT)
268
+
269
+ with pytest.raises(RequestError):
270
+ mock.put(f"{Session.API_URL_DEFAULT}{path}", status_code=400)
271
+ session.request(path=path, method=Session.METHOD_PUT)
272
+
273
+ with pytest.raises(RequestError):
274
+ mock.put(f"{Session.API_URL_DEFAULT}{path}", text=json.dumps({'error_message': error}), status_code=400)
275
+ session.request(path=path, method=Session.METHOD_PUT)
276
+
277
+ def callback(request, _):
278
+ return request.text
279
+
280
+ mock.put(f"{Session.API_URL_DEFAULT}{path}", text=callback)
281
+ response = session.request(path=path, method=Session.METHOD_PUT, body=body)
282
+ self.assertIsNotNone(response)
283
+ self.assertEqual(body, response)
284
+
285
+ def test_upload_file(self):
286
+ """
287
+ Test that a file can be uploaded, checking that missing endpoints are handled correctly.
288
+ """
289
+ source = self.fixture_path('user.json')
290
+ url = 'https://upload.com/test'
291
+
292
+ session = Session()
293
+ self.assertIsNotNone(session)
294
+
295
+ with requests_mock.Mocker() as mock:
296
+ with pytest.raises(RequestError):
297
+ mock.put(url, exc=requests.exceptions.ConnectTimeout)
298
+ session.upload_file(url, source)
299
+
300
+ with pytest.raises(RequestError):
301
+ mock.put(url, status_code=400)
302
+ session.upload_file(url, source)
303
+
304
+ adapter = mock.put(url, status_code=200)
305
+ session.upload_file(url, source)
306
+ self.assertIsNotNone(adapter.last_request.text)