fusion-platform-python-sdk 1.17.9__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.17.9/fusion_platform_python_sdk.egg-info → fusion_platform_python_sdk-2.0.7}/PKG-INFO +3 -3
  2. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/__init__.py +5 -4
  3. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/command.py +9 -14
  4. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/fusion_platform_sdk.pdf +0 -0
  5. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/credit.py +0 -3
  6. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/data.py +24 -12
  7. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/data_file.md +6 -0
  8. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/data_file.py +7 -2
  9. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/model.py +2 -3
  10. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/organisation.py +0 -2
  11. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/process.py +1 -9
  12. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/process_execution.py +1 -5
  13. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/process_service_execution.md +8 -0
  14. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/process_service_execution.py +11 -9
  15. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/process_service_execution_log.py +0 -1
  16. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/service.md +2 -2
  17. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/service.py +0 -11
  18. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/user.py +0 -2
  19. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/session.py +16 -1
  20. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7/fusion_platform_python_sdk.egg-info}/PKG-INFO +3 -3
  21. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/setup.py +1 -2
  22. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/tests/test_session.py +6 -1
  23. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/LICENSE.txt +0 -0
  24. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/MANIFEST.in +0 -0
  25. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/README.md +0 -0
  26. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/__main__.py +0 -0
  27. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/base.py +0 -0
  28. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/common/__init__.py +0 -0
  29. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/common/raise_thread.py +0 -0
  30. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/common/utilities.py +0 -0
  31. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/detailed_example.py +0 -0
  32. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/documentation.py +0 -0
  33. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/glasgow.geojson +0 -0
  34. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/lake_district.geojson +0 -0
  35. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/localisations.py +0 -0
  36. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/localise.py +0 -0
  37. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/__init__.py +0 -0
  38. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/credit.md +0 -0
  39. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/data.md +0 -0
  40. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/fields.py +0 -0
  41. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/organisation.md +0 -0
  42. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/process.md +0 -0
  43. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/process_execution.md +0 -0
  44. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/process_service_execution_log.md +0 -0
  45. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/models/user.md +0 -0
  46. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/quick_example.py +0 -0
  47. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform/translations.py +0 -0
  48. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform_python_sdk.egg-info/SOURCES.txt +0 -0
  49. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform_python_sdk.egg-info/dependency_links.txt +0 -0
  50. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform_python_sdk.egg-info/entry_points.txt +0 -0
  51. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform_python_sdk.egg-info/requires.txt +0 -0
  52. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/fusion_platform_python_sdk.egg-info/top_level.txt +0 -0
  53. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/setup.cfg +0 -0
  54. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/tests/test_base.py +0 -0
  55. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/tests/test_command.py +0 -0
  56. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/tests/test_init.py +0 -0
  57. {fusion_platform_python_sdk-1.17.9 → fusion_platform_python_sdk-2.0.7}/tests/test_localise.py +0 -0
@@ -1,12 +1,11 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: fusion-platform-python-sdk
3
- Version: 1.17.9
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
7
7
  Author-email: support@d-cat.co.uk
8
8
  License: MIT
9
- Classifier: License :: OSI Approved :: MIT License
10
9
  Classifier: Programming Language :: Python :: 3
11
10
  Classifier: Programming Language :: Python :: 3.9
12
11
  Classifier: Programming Language :: Python :: 3.10
@@ -31,6 +30,7 @@ Dynamic: description
31
30
  Dynamic: description-content-type
32
31
  Dynamic: home-page
33
32
  Dynamic: license
33
+ Dynamic: license-file
34
34
  Dynamic: requires-dist
35
35
  Dynamic: summary
36
36
 
@@ -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.17.9'
15
- __version_date__ = '2025-04-29T13:10:22Z'
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))
@@ -26,7 +26,6 @@ class CreditMonthlySpendSchema(Schema):
26
26
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
27
27
  """
28
28
  unknown = EXCLUDE
29
- ordered = True
30
29
 
31
30
 
32
31
  class CreditSsdsSchema(Schema):
@@ -41,7 +40,6 @@ class CreditSsdsSchema(Schema):
41
40
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
42
41
  """
43
42
  unknown = EXCLUDE
44
- ordered = True
45
43
 
46
44
 
47
45
  class CreditSchema(Schema):
@@ -73,7 +71,6 @@ class CreditSchema(Schema):
73
71
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
74
72
  """
75
73
  unknown = EXCLUDE
76
- ordered = True
77
74
 
78
75
 
79
76
  class Credit(Model):
@@ -57,7 +57,6 @@ class DataSchema(Schema):
57
57
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
58
58
  """
59
59
  unknown = EXCLUDE
60
- ordered = True
61
60
 
62
61
 
63
62
  class Data(Model):
@@ -150,12 +149,14 @@ class Data(Model):
150
149
  # Make sure we record the thread so we can monitor it, even if it fails.
151
150
  self.__upload_threads[file_id] = thread
152
151
 
153
- def check_analysis_complete(self, wait=False):
152
+ def check_analysis_complete(self, wait=False, extended_analysis=False):
154
153
  """
155
- Checks that the analysis of all files associated with this data object is complete. Optionally waits for the analysis to complete.
154
+ Checks that the analysis of all files associated with this data object is complete. Optionally waits for the analysis to complete. Also, optionally checks
155
+ whether the extended analysis has completed as compared to just the basic analysis which is required for a file to be used.
156
156
 
157
157
  Args:
158
158
  wait: Optionally wait for the analysis to complete? Default False.
159
+ extended_analysis: Optionally check whether the extended analysis has completed, rather than only the required basic analysis. Default False.
159
160
 
160
161
  Returns:
161
162
  True if the analysis is complete for all files.
@@ -168,24 +169,33 @@ class Data(Model):
168
169
  complete = True
169
170
 
170
171
  # Load in each of the file models and check that every file has been uploaded, and has a publishable or error field to indicate that the analysis is
171
- # complete.
172
+ # complete. For extended analysis, the number of ingesters is checked and how many of these have completed.
172
173
  for file in self.files:
173
174
  self._logger.debug('file %s: %s', file.file_name, file.attributes)
174
175
 
175
- has_fields = hasattr(file, self.__class__._FIELD_SIZE) and (
176
+ has_basic_fields = hasattr(file, self.__class__._FIELD_SIZE) and (
176
177
  hasattr(file, self.__class__._FIELD_PUBLISHABLE) or hasattr(file, self.__class__._FIELD_ERROR))
177
178
 
178
- if not has_fields:
179
- self._logger.debug('file %s not yet analysed', file.file_name)
179
+ if not has_basic_fields:
180
+ self._logger.debug('file %s basic analysis not complete', file.file_name)
180
181
  complete = False
181
182
  break
182
183
 
184
+ if extended_analysis:
185
+ number_of_ingesters = file.number_of_ingesters if hasattr(file, self.__class__._FIELD_NUMBER_OF_INGESTERS) else 0
186
+ ingesters = file.ingesters if hasattr(file, self.__class__._FIELD_INGESTERS) else {}
187
+
188
+ if len(ingesters) < number_of_ingesters:
189
+ self._logger.debug('file %s extended analysis not complete', file.file_name)
190
+ complete = False
191
+ break
192
+
183
193
  # Break the loop if we are not waiting or are complete.
184
194
  if (not wait) or complete:
185
195
  break
186
196
 
187
197
  # We are waiting, so block for a short while.
188
- sleep(self.__class__._API_UPDATE_WAIT_PERIOD)
198
+ sleep(self._session.api_update_wait_period)
189
199
 
190
200
  return complete
191
201
 
@@ -252,19 +262,21 @@ class Data(Model):
252
262
  if len(self.__upload_threads) > 0:
253
263
  self.create_complete(wait=wait) # Ignore response.
254
264
 
255
- def create_complete(self, wait=False):
265
+ def create_complete(self, wait=False, extended_analysis=False):
256
266
  """
257
267
  Checks whether the data object file(s) upload and analysis have completed. If an error has occurred during the upload and analysis, then this will raise
258
- a corresponding exception. Optionally waits for the upload and analysis to complete.
268
+ a corresponding exception. Optionally waits for the upload and analysis to complete. Also, optionally checks whether the extended analysis has completed as
269
+ compared to just the basic analysis which is required for a file to be used.
259
270
 
260
271
  Note, a failure of one file upload will not stop the upload of other files. Therefore, if an exception is raised, further calls to this method are required
261
272
  until all upload and analysis (or errored) has completed and this method returns True.
262
273
 
263
274
  Args:
264
275
  wait: Optionally wait for the upload and analysis to complete? Default False.
276
+ extended_analysis: Optionally check whether the extended analysis has completed, rather than only the required basic analysis. Default False.
265
277
 
266
278
  Returns:
267
- True if the upload and analysis are complete for all files.
279
+ True if the upload and (basic or extended) analysis are complete for all files.
268
280
 
269
281
  Raises:
270
282
  RequestError: if any request fails.
@@ -313,7 +325,7 @@ class Data(Model):
313
325
 
314
326
  try:
315
327
  if uploads_finished:
316
- complete = self.check_analysis_complete(wait=wait)
328
+ complete = self.check_analysis_complete(wait=wait, extended_analysis=extended_analysis)
317
329
 
318
330
  except Exception as e:
319
331
  # An error occurred, make sure we treat this as complete to prevent an indefinite loop.
@@ -13,6 +13,8 @@
13
13
  * **area**: The optional total area covered by the file content in metres squared.
14
14
  * **length**: The optional total length covered by the file content in metres.
15
15
  * **points**: The optional total number of points in the file.
16
+ * **lines**: The optional total number of lines in the file.
17
+ * **polygons**: The optional total number of polygons in the file.
16
18
  * **size**: The size of the file in bytes.
17
19
  * **error**: Was there an error encountered during analysis of the file?
18
20
  * **publishable**: Is the file suitable for publishing as it is without optimisation?
@@ -27,6 +29,8 @@
27
29
  * **area**: The optional area for the selector in metres squared.
28
30
  * **length**: The optional length for the selector in metres.
29
31
  * **points**: The optional total number of points in the selector.
32
+ * **lines**: The optional total number of lines in the selector.
33
+ * **polygons**: The optional total number of polygons in the selector.
30
34
  * **initial_values**: The first initial values associated with the selector.
31
35
  * **minimum**: The minimum value associated with the selector values.
32
36
  * **maximum**: The maximum value associated with the selector values.
@@ -35,6 +39,8 @@
35
39
  * **histogram_minimum**: The histogram maximum value associated with the selector values.
36
40
  * **histogram_maximum**: The histogram maximum value associated with the selector values.
37
41
  * **histogram**: The histogram associated with the selector values.
42
+ * **number_of_ingesters**: The expected number of ingesters that may be used to analyse an uploaded, publishable file.
43
+ * **ingesters**: The ingester analysis.
38
44
  * **downloads**: How many times has the file been downloaded?
39
45
  * **geojson**: The content of the associated file if it is a GeoJSON file (of limited size).
40
46
  * **title**: The title for the selector.
@@ -32,6 +32,8 @@ class DataFileSelectorSchema(Schema):
32
32
  area = fields.Decimal(allow_none=True)
33
33
  length = fields.Decimal(allow_none=True)
34
34
  points = fields.Integer(allow_none=True)
35
+ lines = fields.Integer(allow_none=True)
36
+ polygons = fields.Integer(allow_none=True)
35
37
 
36
38
  initial_values = fields.List(fields.String(required=True), allow_none=True)
37
39
  minimum = fields.Decimal(allow_none=True)
@@ -48,7 +50,6 @@ class DataFileSelectorSchema(Schema):
48
50
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
49
51
  """
50
52
  unknown = EXCLUDE
51
- ordered = True
52
53
 
53
54
 
54
55
  class DataFileSchema(Schema):
@@ -80,6 +81,8 @@ class DataFileSchema(Schema):
80
81
  area = fields.Decimal(allow_none=True, metadata={'read_only': True}) # Changed to prevent this being updated.
81
82
  length = fields.Decimal(allow_none=True, metadata={'read_only': True}) # Changed to prevent this being updated.
82
83
  points = fields.Integer(allow_none=True, metadata={'read_only': True}) # Changed to prevent this being updated.
84
+ lines = fields.Integer(allow_none=True, metadata={'read_only': True}) # Changed to prevent this being updated.
85
+ polygons = fields.Integer(allow_none=True, metadata={'read_only': True}) # Changed to prevent this being updated.
83
86
 
84
87
  size = fields.Integer(allow_none=True, metadata={'read_only': True}) # Changed to prevent this being updated.
85
88
  error = fields.Boolean(allow_none=True, metadata={'read_only': True}) # Changed to prevent this being updated.
@@ -90,6 +93,9 @@ class DataFileSchema(Schema):
90
93
 
91
94
  selectors = fields.List(fields.Nested(DataFileSelectorSchema()), allow_none=True, metadata={'read_only': True}) # Changed to prevent this being updated.
92
95
 
96
+ number_of_ingesters = fields.Integer(allow_none=True, metadata={'read_only': True}) # Changed to prevent this being updated.
97
+ ingesters = fields.Dict(allow_none=True, metadata={'read_only': True}) # Changed to prevent this being updated.
98
+
93
99
  downloads = fields.Integer(allow_none=True, metadata={'read_only': True}) # Changed to prevent this being updated.
94
100
  geojson = fields.String(allow_none=True, metadata={'read_only': True}) # Changed to prevent this being updated.
95
101
 
@@ -106,7 +112,6 @@ class DataFileSchema(Schema):
106
112
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
107
113
  """
108
114
  unknown = EXCLUDE
109
- ordered = True
110
115
 
111
116
 
112
117
  class DataFile(Model):
@@ -80,6 +80,7 @@ class Model(Base):
80
80
  _FIELD_HISTOGRAM_MINIMUM = 'histogram_minimum'
81
81
  _FIELD_HISTOGRAM_MAXIMUM = 'histogram_maximum'
82
82
  _FIELD_ID = 'id'
83
+ _FIELD_INGESTERS = 'ingesters'
83
84
  _FIELD_INPUT = 'input'
84
85
  _FIELD_INPUTS = 'inputs'
85
86
  _FIELD_KEYWORDS = 'keywords'
@@ -88,6 +89,7 @@ class Model(Base):
88
89
  _FIELD_MINIMUM = 'minimum'
89
90
  _FIELD_NAME = 'name'
90
91
  _FIELD_NON_AGGREGATOR_COUNT = 'non_aggregator_count'
92
+ _FIELD_NUMBER_OF_INGESTERS = 'number_of_ingesters'
91
93
  _FIELD_OPTIONS = 'options'
92
94
  _FIELD_OUTPUTS = 'outputs'
93
95
  _FIELD_PROCESS_STATUS = 'process_status'
@@ -146,9 +148,6 @@ class Model(Base):
146
148
  _METADATA_HIDE = 'hide'
147
149
  _METADATA_READ_ONLY = 'read_only'
148
150
 
149
- # API job update frequency check.
150
- _API_UPDATE_WAIT_PERIOD = 10 # Time in seconds to wait between checking jobs on the API.
151
-
152
151
  def __init__(self, session, schema=None):
153
152
  """
154
153
  Initialises the object.
@@ -32,7 +32,6 @@ class OrganisationUserSchema(Schema):
32
32
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
33
33
  """
34
34
  unknown = EXCLUDE
35
- ordered = True
36
35
 
37
36
 
38
37
  class OrganisationSchema(Schema):
@@ -87,7 +86,6 @@ class OrganisationSchema(Schema):
87
86
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
88
87
  """
89
88
  unknown = EXCLUDE
90
- ordered = True
91
89
 
92
90
 
93
91
  class Organisation(Model):
@@ -298,7 +298,6 @@ class ProcessChainOptionSchema(Schema):
298
298
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
299
299
  """
300
300
  unknown = EXCLUDE
301
- ordered = True
302
301
 
303
302
 
304
303
  class ProcessChainSchema(Schema):
@@ -317,7 +316,6 @@ class ProcessChainSchema(Schema):
317
316
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
318
317
  """
319
318
  unknown = EXCLUDE
320
- ordered = True
321
319
 
322
320
 
323
321
  class ProcessExecutionStatusSchema(Schema):
@@ -342,7 +340,6 @@ class ProcessExecutionStatusSchema(Schema):
342
340
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
343
341
  """
344
342
  unknown = EXCLUDE
345
- ordered = True
346
343
 
347
344
 
348
345
  class ProcessSelectorSchema(Schema):
@@ -360,7 +357,6 @@ class ProcessSelectorSchema(Schema):
360
357
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
361
358
  """
362
359
  unknown = EXCLUDE
363
- ordered = True
364
360
 
365
361
 
366
362
  class ProcessInputSchema(Schema):
@@ -386,7 +382,6 @@ class ProcessInputSchema(Schema):
386
382
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
387
383
  """
388
384
  unknown = EXCLUDE
389
- ordered = True
390
385
 
391
386
 
392
387
  class ProcessOptionSchema(Schema):
@@ -416,7 +411,6 @@ class ProcessOptionSchema(Schema):
416
411
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
417
412
  """
418
413
  unknown = EXCLUDE
419
- ordered = True
420
414
 
421
415
 
422
416
  class ProcessDispatcherSchema(Schema):
@@ -435,7 +429,6 @@ class ProcessDispatcherSchema(Schema):
435
429
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
436
430
  """
437
431
  unknown = EXCLUDE
438
- ordered = True
439
432
 
440
433
 
441
434
  class ProcessSchema(Schema):
@@ -498,7 +491,6 @@ class ProcessSchema(Schema):
498
491
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
499
492
  """
500
493
  unknown = EXCLUDE
501
- ordered = True
502
494
 
503
495
 
504
496
  class Process(Model):
@@ -1159,4 +1151,4 @@ class Process(Model):
1159
1151
  raise ModelError(i18n.t('models.process.execution_should_have_started'))
1160
1152
 
1161
1153
  # We are waiting, so block for a short while.
1162
- sleep(self.__class__._API_UPDATE_WAIT_PERIOD)
1154
+ sleep(self._session.api_update_wait_period)
@@ -32,7 +32,6 @@ class ProcessExecutionChainOptionSchema(Schema):
32
32
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
33
33
  """
34
34
  unknown = EXCLUDE
35
- ordered = True
36
35
 
37
36
 
38
37
  class ProcessExecutionChainSchema(Schema):
@@ -51,7 +50,6 @@ class ProcessExecutionChainSchema(Schema):
51
50
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
52
51
  """
53
52
  unknown = EXCLUDE
54
- ordered = True
55
53
 
56
54
 
57
55
  class ProcessExecutionOptionSchema(Schema):
@@ -74,7 +72,6 @@ class ProcessExecutionOptionSchema(Schema):
74
72
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
75
73
  """
76
74
  unknown = EXCLUDE
77
- ordered = True
78
75
 
79
76
 
80
77
  class ProcessExecutionSchema(Schema):
@@ -119,7 +116,6 @@ class ProcessExecutionSchema(Schema):
119
116
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
120
117
  """
121
118
  unknown = EXCLUDE
122
- ordered = True
123
119
 
124
120
 
125
121
  class ProcessExecution(Model):
@@ -202,7 +198,7 @@ class ProcessExecution(Model):
202
198
  break
203
199
 
204
200
  # We are waiting, so block for a short while.
205
- sleep(self.__class__._API_UPDATE_WAIT_PERIOD)
201
+ sleep(self._session.api_update_wait_period)
206
202
 
207
203
  return complete
208
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.
@@ -50,6 +54,10 @@
50
54
  * **swap_free_bytes**: The free swap space in bytes.
51
55
  * **tmp_total_bytes**: The total temporary disk space in bytes.
52
56
  * **tmp_free_bytes**: The free temporary disk space in bytes.
57
+ * **tmp_used_bytes**: The used temporary disk space in bytes.
58
+ * **scratch_total_bytes**: The total scratch disk space in bytes.
59
+ * **scratch_free_bytes**: The free scratch disk space in bytes.
60
+ * **scratch_used_bytes**: The used scratch disk space in bytes.
53
61
  * **s3_transfer_bytes**: The number of bytes transferred in from S3.
54
62
  * **gcs_transfer_bytes**: The number of bytes transferred in from Google Cloud Storage.
55
63
  * **external_transfer_bytes**: The number of bytes transferred in externally.
@@ -46,7 +46,6 @@ class ProcessServiceExecutionActionValueSchema(Schema):
46
46
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
47
47
  """
48
48
  unknown = EXCLUDE
49
- ordered = True
50
49
 
51
50
 
52
51
  class ProcessServiceExecutionActionSchema(Schema):
@@ -64,7 +63,6 @@ class ProcessServiceExecutionActionSchema(Schema):
64
63
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
65
64
  """
66
65
  unknown = EXCLUDE
67
- ordered = True
68
66
 
69
67
 
70
68
  class ProcessServiceExecutionActionsSchema(Schema):
@@ -78,7 +76,6 @@ class ProcessServiceExecutionActionsSchema(Schema):
78
76
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
79
77
  """
80
78
  unknown = EXCLUDE
81
- ordered = True
82
79
 
83
80
 
84
81
  class ProcessServiceExecutionMetricSchema(Schema):
@@ -92,6 +89,10 @@ class ProcessServiceExecutionMetricSchema(Schema):
92
89
  swap_free_bytes = fields.Integer(allow_none=True)
93
90
  tmp_total_bytes = fields.Integer(allow_none=True)
94
91
  tmp_free_bytes = fields.Integer(allow_none=True)
92
+ tmp_used_bytes = fields.Integer(allow_none=True)
93
+ scratch_total_bytes = fields.Integer(allow_none=True)
94
+ scratch_free_bytes = fields.Integer(allow_none=True)
95
+ scratch_used_bytes = fields.Integer(allow_none=True)
95
96
  s3_transfer_bytes = fields.Integer(allow_none=True)
96
97
  gcs_transfer_bytes = fields.Integer(allow_none=True)
97
98
  external_transfer_bytes = fields.Integer(allow_none=True)
@@ -103,7 +104,6 @@ class ProcessServiceExecutionMetricSchema(Schema):
103
104
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
104
105
  """
105
106
  unknown = EXCLUDE
106
- ordered = True
107
107
 
108
108
 
109
109
  class ProcessServiceExecutionOptionSchema(Schema):
@@ -120,7 +120,6 @@ class ProcessServiceExecutionOptionSchema(Schema):
120
120
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
121
121
  """
122
122
  unknown = EXCLUDE
123
- ordered = True
124
123
 
125
124
 
126
125
  class ProcessServiceExecutionSchema(Schema):
@@ -149,8 +148,13 @@ class ProcessServiceExecutionSchema(Schema):
149
148
  runtime = fields.Integer(allow_none=True, metadata={'read_only': True}) # Changed to prevent this being updated.
150
149
 
151
150
  # Removed input_size.
151
+ architecture = fields.String(allow_none=True, metadata={'read_only': True}) # Changed to prevent this being updated.
152
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.
153
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
+
154
158
  actions = fields.List(fields.Nested(ProcessServiceExecutionActionSchema()), allow_none=True)
155
159
  options = fields.List(fields.Nested(ProcessServiceExecutionOptionSchema()), allow_none=True,
156
160
  metadata={'read_only': True}) # Changed to prevent this being updated.
@@ -159,9 +163,8 @@ class ProcessServiceExecutionSchema(Schema):
159
163
  # Removed storage_id.
160
164
  intermediate = fields.Boolean(allow_none=True)
161
165
  # Removed task_id.
162
- # Removed task_definition_id.
163
- # Removed access_point_ids.
164
- # Removed security_group_id.
166
+ # Removed task_starts.
167
+ # Removed instance_id.
165
168
  success = fields.Boolean(allow_none=True, metadata={'read_only': True}) # Changed to prevent this being updated.
166
169
 
167
170
  metrics = fields.List(fields.Nested(ProcessServiceExecutionMetricSchema()), allow_none=True,
@@ -172,7 +175,6 @@ class ProcessServiceExecutionSchema(Schema):
172
175
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
173
176
  """
174
177
  unknown = EXCLUDE
175
- ordered = True
176
178
 
177
179
 
178
180
  class ProcessServiceExecution(Model):
@@ -36,7 +36,6 @@ class ProcessServiceExecutionLogSchema(Schema):
36
36
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
37
37
  """
38
38
  unknown = EXCLUDE
39
- ordered = True
40
39
 
41
40
 
42
41
  class ProcessServiceExecutionLog(Model):
@@ -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.
@@ -50,7 +50,6 @@ class ServiceActionValueSchema(Schema):
50
50
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
51
51
  """
52
52
  unknown = EXCLUDE
53
- ordered = True
54
53
 
55
54
 
56
55
  class ServiceActionSchema(Schema):
@@ -68,7 +67,6 @@ class ServiceActionSchema(Schema):
68
67
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
69
68
  """
70
69
  unknown = EXCLUDE
71
- ordered = True
72
70
 
73
71
 
74
72
  class ServiceDefinitionLinkageSchema(Schema):
@@ -83,7 +81,6 @@ class ServiceDefinitionLinkageSchema(Schema):
83
81
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
84
82
  """
85
83
  unknown = EXCLUDE
86
- ordered = True
87
84
 
88
85
 
89
86
  class ServiceDefinitionSchema(Schema):
@@ -99,7 +96,6 @@ class ServiceDefinitionSchema(Schema):
99
96
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
100
97
  """
101
98
  unknown = EXCLUDE
102
- ordered = True
103
99
 
104
100
 
105
101
  class ServiceGroupAggregatorOptionSchema(Schema):
@@ -115,7 +111,6 @@ class ServiceGroupAggregatorOptionSchema(Schema):
115
111
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
116
112
  """
117
113
  unknown = EXCLUDE
118
- ordered = True
119
114
 
120
115
 
121
116
  class ServiceGroupAggregatorSchema(Schema):
@@ -132,7 +127,6 @@ class ServiceGroupAggregatorSchema(Schema):
132
127
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
133
128
  """
134
129
  unknown = EXCLUDE
135
- ordered = True
136
130
 
137
131
 
138
132
  class ServiceInputExpressionSchema(Schema):
@@ -150,7 +144,6 @@ class ServiceInputExpressionSchema(Schema):
150
144
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
151
145
  """
152
146
  unknown = EXCLUDE
153
- ordered = True
154
147
 
155
148
 
156
149
  class ServiceOptionExpressionSchema(Schema):
@@ -166,7 +159,6 @@ class ServiceOptionExpressionSchema(Schema):
166
159
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
167
160
  """
168
161
  unknown = EXCLUDE
169
- ordered = True
170
162
 
171
163
 
172
164
  class ServiceValidationSchema(Schema):
@@ -181,7 +173,6 @@ class ServiceValidationSchema(Schema):
181
173
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
182
174
  """
183
175
  unknown = EXCLUDE
184
- ordered = True
185
176
 
186
177
 
187
178
  class ServiceOrganisationChargeExpressionSchema(Schema):
@@ -197,7 +188,6 @@ class ServiceOrganisationChargeExpressionSchema(Schema):
197
188
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
198
189
  """
199
190
  unknown = EXCLUDE
200
- ordered = True
201
191
 
202
192
 
203
193
  class ServiceSchema(Schema):
@@ -268,7 +258,6 @@ class ServiceSchema(Schema):
268
258
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
269
259
  """
270
260
  unknown = EXCLUDE
271
- ordered = True
272
261
 
273
262
 
274
263
  class Service(Model):
@@ -29,7 +29,6 @@ class UserOrganisationSchema(Schema):
29
29
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
30
30
  """
31
31
  unknown = EXCLUDE
32
- ordered = True
33
32
 
34
33
 
35
34
  class UserSchema(Schema):
@@ -81,7 +80,6 @@ class UserSchema(Schema):
81
80
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
82
81
  """
83
82
  unknown = EXCLUDE
84
- ordered = True
85
83
 
86
84
 
87
85
  class User(Model):
@@ -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,12 +1,11 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: fusion-platform-python-sdk
3
- Version: 1.17.9
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
7
7
  Author-email: support@d-cat.co.uk
8
8
  License: MIT
9
- Classifier: License :: OSI Approved :: MIT License
10
9
  Classifier: Programming Language :: Python :: 3
11
10
  Classifier: Programming Language :: Python :: 3.9
12
11
  Classifier: Programming Language :: Python :: 3.10
@@ -31,6 +30,7 @@ Dynamic: description
31
30
  Dynamic: description-content-type
32
31
  Dynamic: home-page
33
32
  Dynamic: license
33
+ Dynamic: license-file
34
34
  Dynamic: requires-dist
35
35
  Dynamic: summary
36
36
 
@@ -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.17.9',
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',
@@ -28,7 +28,6 @@ setup(
28
28
  author_email='support@d-cat.co.uk',
29
29
  license='MIT',
30
30
  classifiers=[
31
- 'License :: OSI Approved :: MIT License',
32
31
  'Programming Language :: Python :: 3',
33
32
  'Programming Language :: Python :: 3.9',
34
33
  'Programming Language :: Python :: 3.10',
@@ -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
  """