fusion-platform-python-sdk 1.18.3__tar.gz → 2.0.7__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.18.3/fusion_platform_python_sdk.egg-info → fusion_platform_python_sdk-2.0.7}/PKG-INFO +1 -1
  2. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/__init__.py +5 -4
  3. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/command.py +9 -14
  4. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/fusion_platform_sdk.pdf +0 -0
  5. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/data.py +1 -1
  6. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/model.py +0 -3
  7. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/process.py +1 -1
  8. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/process_execution.py +1 -1
  9. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/process_service_execution.md +4 -0
  10. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/process_service_execution.py +7 -3
  11. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/service.md +2 -2
  12. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/session.py +16 -1
  13. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7/fusion_platform_python_sdk.egg-info}/PKG-INFO +1 -1
  14. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/setup.py +1 -1
  15. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/tests/test_session.py +6 -1
  16. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/LICENSE.txt +0 -0
  17. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/MANIFEST.in +0 -0
  18. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/README.md +0 -0
  19. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/__main__.py +0 -0
  20. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/base.py +0 -0
  21. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/common/__init__.py +0 -0
  22. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/common/raise_thread.py +0 -0
  23. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/common/utilities.py +0 -0
  24. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/detailed_example.py +0 -0
  25. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/documentation.py +0 -0
  26. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/glasgow.geojson +0 -0
  27. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/lake_district.geojson +0 -0
  28. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/localisations.py +0 -0
  29. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/localise.py +0 -0
  30. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/__init__.py +0 -0
  31. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/credit.md +0 -0
  32. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/credit.py +0 -0
  33. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/data.md +0 -0
  34. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/data_file.md +0 -0
  35. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/data_file.py +0 -0
  36. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/fields.py +0 -0
  37. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/organisation.md +0 -0
  38. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/organisation.py +0 -0
  39. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/process.md +0 -0
  40. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/process_execution.md +0 -0
  41. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/process_service_execution_log.md +0 -0
  42. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/process_service_execution_log.py +0 -0
  43. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/service.py +0 -0
  44. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/user.md +0 -0
  45. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/user.py +0 -0
  46. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/quick_example.py +0 -0
  47. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform/translations.py +0 -0
  48. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform_python_sdk.egg-info/SOURCES.txt +0 -0
  49. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform_python_sdk.egg-info/dependency_links.txt +0 -0
  50. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform_python_sdk.egg-info/entry_points.txt +0 -0
  51. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform_python_sdk.egg-info/requires.txt +0 -0
  52. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/fusion_platform_python_sdk.egg-info/top_level.txt +0 -0
  53. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/setup.cfg +0 -0
  54. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/tests/test_base.py +0 -0
  55. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/tests/test_command.py +0 -0
  56. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/tests/test_init.py +0 -0
  57. {fusion_platform_python_sdk-1.18.3 → fusion_platform_python_sdk-2.0.7}/tests/test_localise.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fusion-platform-python-sdk
3
- Version: 1.18.3
3
+ Version: 2.0.7
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
@@ -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.18.3'
15
- __version_date__ = '2025-07-04T14:43:33Z'
14
+ __version__ = '2.0.7'
15
+ __version_date__ = '2025-10-07T07:06:32Z'
16
16
 
17
17
  # Exclude certain sub-modules from documentation.
18
18
  # @formatter:off
@@ -142,7 +142,7 @@ def get_log_level():
142
142
  return logger.level
143
143
 
144
144
 
145
- def login(email=None, user_id=None, password=None, api_url=None):
145
+ def login(email=None, user_id=None, password=None, api_url=None, session_options=None):
146
146
  """
147
147
  Attempts to log into the Fusion Platform<sup>&reg;</sup> to return a user model for the active session.
148
148
 
@@ -151,6 +151,7 @@ def login(email=None, user_id=None, password=None, api_url=None):
151
151
  user_id: The user account user id. Either an email address or a user id must be provided.
152
152
  password: The password for the user account.
153
153
  api_url: The optional custom API URL to use. Defaults to the production Fusion Platform<sup>&reg;</sup>.
154
+ session_options: The optional options to be passed to the session.
154
155
 
155
156
  Returns:
156
157
  The corresponding user model for the account on successful login.
@@ -160,7 +161,7 @@ def login(email=None, user_id=None, password=None, api_url=None):
160
161
  RequestError: on login failure.
161
162
  """
162
163
  # Create the session and attempt to login.
163
- session = Session()
164
+ session = Session(options=session_options)
164
165
  session.login(email, user_id, password, api_url)
165
166
 
166
167
  # Now load the corresponding user model using the user id obtained from the session.
@@ -510,8 +510,6 @@ class Command(Base):
510
510
  The list of file tuples to be downloaded (file model, download path), and the metrics.
511
511
  """
512
512
  download_components = [] if download_components is None else download_components
513
- started_at = process.created_at
514
- ended_at = None
515
513
  metrics = []
516
514
  downloads = []
517
515
 
@@ -526,7 +524,7 @@ class Command(Base):
526
524
  complete = True
527
525
 
528
526
  if not complete:
529
- sleep(Model._API_UPDATE_WAIT_PERIOD)
527
+ sleep(process._session.api_update_wait_period)
530
528
 
531
529
  # Now download the inputs and/or outputs.
532
530
  execution_dir = output_dir
@@ -551,15 +549,6 @@ class Command(Base):
551
549
  )
552
550
  ]
553
551
 
554
- if (started_at is None) or (execution.started_at < started_at):
555
- started_at = execution.started_at
556
-
557
- execution_ended_at = execution.ended_at if hasattr(execution, Model._FIELD_ENDED_AT) and (execution.ended_at is not None) else datetime.now(
558
- timezone.utc)
559
-
560
- if (ended_at is None) or (execution_ended_at > ended_at):
561
- ended_at = execution_ended_at
562
-
563
552
  for j, component in enumerate(components):
564
553
  # Download the component.
565
554
  component_name = '_'.join([item for item in re.sub(r'[\W]', '_', component.name).split('_') if len(item) > 0])
@@ -567,6 +556,8 @@ class Command(Base):
567
556
  component_options = {item.get(Model._FIELD_NAME): item.get(Model._FIELD_VALUE) for item in component.options} if hasattr(component,
568
557
  Model._FIELD_OPTIONS) and (
569
558
  component.options is not None) else {}
559
+ component_started_at = component.started_at if hasattr(component, Model._FIELD_STARTED_AT) and (component.started_at is not None) else None
560
+ component_ended_at = component.ended_at if hasattr(component, Model._FIELD_ENDED_AT) and (component.ended_at is not None) else None
570
561
  component_success = component.success if hasattr(component, Model._FIELD_SUCCESS) and (component.success is not None) else False
571
562
  component_runtime = component.runtime if hasattr(component, Model._FIELD_RUNTIME) and (component.runtime is not None) else 0
572
563
 
@@ -575,7 +566,7 @@ class Command(Base):
575
566
  metric = {
576
567
  Command._METRICS_EXECUTION: group_index if group_index is not None else 1,
577
568
  Command._METRICS_PROCESS: process.name,
578
- Command._METRICS_DURATION: ended_at - started_at if (started_at is not None) and (ended_at is not None) else 0,
569
+ Command._METRICS_DURATION: (component_ended_at - component_started_at).total_seconds() if (component_started_at is not None) and (component_ended_at is not None) else 0,
579
570
  Command._METRICS_COMPONENT: component.name,
580
571
  Command._METRICS_SUCCESS: component_success,
581
572
  Command._METRICS_CPU: component.cpu,
@@ -1015,7 +1006,11 @@ class Command(Base):
1015
1006
 
1016
1007
  # If the service still cannot be found, then try it as a specific service for the organisation.
1017
1008
  if service is None:
1018
- service = next((item for item in organisation.own_services if (str(item.id) == service_name) or (str(item.ssd_id) == service_name)), None)
1009
+ try:
1010
+ service = next((item for item in organisation.own_services if (str(item.id) == service_name) or (str(item.ssd_id) == service_name)), None)
1011
+ except RequestError:
1012
+ # We will get a RequestError if the user is not sufficiently privileged to list the organisation's own services. We therefore ignore this error.
1013
+ pass
1019
1014
 
1020
1015
  if service is None:
1021
1016
  raise CommandError(i18n.t('command.no_such_service', service=service_name))
@@ -195,7 +195,7 @@ class Data(Model):
195
195
  break
196
196
 
197
197
  # We are waiting, so block for a short while.
198
- sleep(self.__class__._API_UPDATE_WAIT_PERIOD)
198
+ sleep(self._session.api_update_wait_period)
199
199
 
200
200
  return complete
201
201
 
@@ -148,9 +148,6 @@ class Model(Base):
148
148
  _METADATA_HIDE = 'hide'
149
149
  _METADATA_READ_ONLY = 'read_only'
150
150
 
151
- # API job update frequency check.
152
- _API_UPDATE_WAIT_PERIOD = 10 # Time in seconds to wait between checking jobs on the API.
153
-
154
151
  def __init__(self, session, schema=None):
155
152
  """
156
153
  Initialises the object.
@@ -1151,4 +1151,4 @@ class Process(Model):
1151
1151
  raise ModelError(i18n.t('models.process.execution_should_have_started'))
1152
1152
 
1153
1153
  # We are waiting, so block for a short while.
1154
- sleep(self.__class__._API_UPDATE_WAIT_PERIOD)
1154
+ sleep(self._session.api_update_wait_period)
@@ -198,7 +198,7 @@ class ProcessExecution(Model):
198
198
  break
199
199
 
200
200
  # We are waiting, so block for a short while.
201
- sleep(self.__class__._API_UPDATE_WAIT_PERIOD)
201
+ sleep(self._session.api_update_wait_period)
202
202
 
203
203
  return complete
204
204
 
@@ -11,8 +11,12 @@
11
11
  * **started_at**: When did the execution start?
12
12
  * **ended_at**: When did the execution end?
13
13
  * **runtime**: The execution runtime in seconds.
14
+ * **architecture**: The processor architecture used to run the image.
14
15
  * **cpu**: The number of CPUs used to run the image.
16
+ * **gpu**: The number of GPUs used to run the image.
15
17
  * **memory**: The memory in megabytes used to run the image.
18
+ * **storage**: The local storage space in gigabytes used to run the image.
19
+ * **instance_type**: The instance type allocated for use by the service.
16
20
  * **actions**: The custom actions associated with this execution.
17
21
  * **name**: The name of the value.
18
22
  * **values**: The values required for the action.
@@ -148,8 +148,13 @@ class ProcessServiceExecutionSchema(Schema):
148
148
  runtime = fields.Integer(allow_none=True, metadata={'read_only': True}) # Changed to prevent this being updated.
149
149
 
150
150
  # Removed input_size.
151
+ architecture = fields.String(allow_none=True, metadata={'read_only': True}) # Changed to prevent this being updated.
151
152
  cpu = fields.Decimal(required=True, metadata={'read_only': True}) # Changed to prevent this being updated.
153
+ gpu = fields.Decimal(allow_none=True, metadata={'read_only': True}) # Changed to prevent this being updated.
152
154
  memory = fields.Decimal(required=True, metadata={'read_only': True}) # Changed to prevent this being updated.
155
+ storage = fields.Decimal(allow_none=True, metadata={'read_only': True}) # Changed to prevent this being updated.
156
+ instance_type = fields.String(allow_none=True, metadata={'read_only': True}) # Changed to prevent this being updated.
157
+
153
158
  actions = fields.List(fields.Nested(ProcessServiceExecutionActionSchema()), allow_none=True)
154
159
  options = fields.List(fields.Nested(ProcessServiceExecutionOptionSchema()), allow_none=True,
155
160
  metadata={'read_only': True}) # Changed to prevent this being updated.
@@ -158,9 +163,8 @@ class ProcessServiceExecutionSchema(Schema):
158
163
  # Removed storage_id.
159
164
  intermediate = fields.Boolean(allow_none=True)
160
165
  # Removed task_id.
161
- # Removed task_definition_id.
162
- # Removed access_point_ids.
163
- # Removed security_group_id.
166
+ # Removed task_starts.
167
+ # Removed instance_id.
164
168
  success = fields.Boolean(allow_none=True, metadata={'read_only': True}) # Changed to prevent this being updated.
165
169
 
166
170
  metrics = fields.List(fields.Nested(ProcessServiceExecutionMetricSchema()), allow_none=True,
@@ -46,8 +46,8 @@
46
46
  * **url**: The URL which can be executed to receive the value of the action.
47
47
  * **title**: The title for the action.
48
48
  * **description**: The description of the action.
49
- * **urls**: The list of allowed external URLs the service can access.
50
- * **cidrs**: The list of allowed external IP addresses as CIDRs the service can access.
49
+ * **urls**:
50
+ * **cidrs**:
51
51
  * **input_expressions**: The list of expressions which are applied to the inputs of the service.
52
52
  * **lhs_ssd_id**: The SSD associated with the left-hand side of the input expression.
53
53
  * **lhs_input**: The input associated with the left-hand side of the input expression.
@@ -93,15 +93,22 @@ class Session(Base):
93
93
  # Default Fusion Platform<sup>&reg;</sup> API endpoint.
94
94
  API_URL_DEFAULT = 'https://api.thefusionplatform.com'
95
95
 
96
+ # Session option fields and their defaults.
97
+ API_UPDATE_WAIT_PERIOD = 'api_update_wait_period' # Time in seconds to wait between checking jobs on the API.
98
+ API_UPDATE_WAIT_PERIOD_DEFAULT = 10
99
+
96
100
  # Mask keys.
97
101
  _MASK_KEYS = ['password', 'old_password', 'new_password', 'access_token', 'id_token', 'refresh_token']
98
102
 
99
103
  # Download temporary file name extension.
100
104
  DOWNLOAD_EXTENSION = '.download'
101
105
 
102
- def __init__(self):
106
+ def __init__(self, options=None):
103
107
  """
104
108
  Initialises the object.
109
+
110
+ Args:
111
+ options: The optional session options.
105
112
  """
106
113
  super(Session, self).__init__()
107
114
 
@@ -110,6 +117,11 @@ class Session(Base):
110
117
  self.__bearer_token = None
111
118
  self.__api_url = Session.API_URL_DEFAULT
112
119
 
120
+ # Extract any options.
121
+ options = {} if options is None else options
122
+ self.api_update_wait_period = options.get(Session.API_UPDATE_WAIT_PERIOD, Session.API_UPDATE_WAIT_PERIOD_DEFAULT)
123
+ self._logger.debug('api_update_wait_period: %d', self.api_update_wait_period)
124
+
113
125
  def download_file(self, url, destination, callback=None):
114
126
  """
115
127
  Downloads a file to the destination path. The destination directories are created if they do not exist. The optional callback function receives three
@@ -267,6 +279,9 @@ class Session(Base):
267
279
  except:
268
280
  pass # Ignore the inability to extract the error message.
269
281
 
282
+ if message is None:
283
+ message = response
284
+
270
285
  raise RequestError(i18n.t('session.request_failed', message=message))
271
286
 
272
287
  payload = response.json()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fusion-platform-python-sdk
3
- Version: 1.18.3
3
+ Version: 2.0.7
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
@@ -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.18.3',
22
+ version='2.0.7',
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',
@@ -53,7 +53,12 @@ class TestSession(CustomTestCase):
53
53
  """
54
54
  Test initialisation of the class to ensure no exceptions are raised.
55
55
  """
56
- Session()
56
+ session = Session()
57
+ self.assertEqual(Session.API_UPDATE_WAIT_PERIOD_DEFAULT, session.api_update_wait_period)
58
+
59
+ api_update_wait_period_default = 45
60
+ session = Session(options={Session.API_UPDATE_WAIT_PERIOD: api_update_wait_period_default})
61
+ self.assertEqual(api_update_wait_period_default, session.api_update_wait_period)
57
62
 
58
63
  def test_download_file(self):
59
64
  """