fusion-platform-python-sdk 1.17.6__tar.gz → 1.18.3__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.6/fusion_platform_python_sdk.egg-info → fusion_platform_python_sdk-1.18.3}/PKG-INFO +3 -3
  2. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/__init__.py +2 -2
  3. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/command.py +112 -44
  4. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/credit.py +0 -3
  5. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/data.py +23 -11
  6. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/data_file.md +6 -0
  7. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/data_file.py +7 -2
  8. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/model.py +2 -0
  9. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/organisation.py +0 -2
  10. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/process.py +0 -8
  11. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/process_execution.py +0 -4
  12. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/process_service_execution.md +4 -0
  13. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/process_service_execution.py +4 -6
  14. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/process_service_execution_log.py +0 -1
  15. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/service.py +0 -11
  16. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/user.py +0 -2
  17. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/translations.py +18 -5
  18. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3/fusion_platform_python_sdk.egg-info}/PKG-INFO +3 -3
  19. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/setup.py +1 -2
  20. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/LICENSE.txt +0 -0
  21. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/MANIFEST.in +0 -0
  22. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/README.md +0 -0
  23. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/__main__.py +0 -0
  24. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/base.py +0 -0
  25. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/common/__init__.py +0 -0
  26. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/common/raise_thread.py +0 -0
  27. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/common/utilities.py +0 -0
  28. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/detailed_example.py +0 -0
  29. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/documentation.py +0 -0
  30. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/fusion_platform_sdk.pdf +0 -0
  31. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/glasgow.geojson +0 -0
  32. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/lake_district.geojson +0 -0
  33. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/localisations.py +0 -0
  34. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/localise.py +0 -0
  35. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/__init__.py +0 -0
  36. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/credit.md +0 -0
  37. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/data.md +0 -0
  38. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/fields.py +0 -0
  39. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/organisation.md +0 -0
  40. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/process.md +0 -0
  41. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/process_execution.md +0 -0
  42. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/process_service_execution_log.md +0 -0
  43. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/service.md +0 -0
  44. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/models/user.md +0 -0
  45. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/quick_example.py +0 -0
  46. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform/session.py +0 -0
  47. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform_python_sdk.egg-info/SOURCES.txt +0 -0
  48. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform_python_sdk.egg-info/dependency_links.txt +0 -0
  49. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform_python_sdk.egg-info/entry_points.txt +0 -0
  50. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform_python_sdk.egg-info/requires.txt +0 -0
  51. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/fusion_platform_python_sdk.egg-info/top_level.txt +0 -0
  52. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/setup.cfg +0 -0
  53. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/tests/test_base.py +0 -0
  54. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/tests/test_command.py +0 -0
  55. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/tests/test_init.py +0 -0
  56. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/tests/test_localise.py +0 -0
  57. {fusion_platform_python_sdk-1.17.6 → fusion_platform_python_sdk-1.18.3}/tests/test_session.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.6
3
+ Version: 1.18.3
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.6'
15
- __version_date__ = '2025-03-26T16:04:58Z'
14
+ __version__ = '1.18.3'
15
+ __version_date__ = '2025-07-04T14:43:33Z'
16
16
 
17
17
  # Exclude certain sub-modules from documentation.
18
18
  # @formatter:off
@@ -8,28 +8,28 @@ author: Matthew Casey
8
8
 
9
9
  import argparse
10
10
  from argparse import RawTextHelpFormatter
11
+ from collections import defaultdict
11
12
  from copy import deepcopy
12
13
  import csv
13
14
  from datetime import datetime, timedelta, timezone
14
- from dateutil.relativedelta import relativedelta
15
15
  from decimal import Decimal
16
16
  from functools import partial
17
- import i18n
18
17
  import json
19
18
  import logging
20
- from marshmallow.utils import _Missing
21
19
  import os
22
- from pathos.multiprocessing import ProcessPool as Pool
23
- from prompt_toolkit import prompt
24
- from prompt_toolkit import print_formatted_text as print
25
- from prompt_toolkit.completion import WordCompleter
26
- from prompt_toolkit.validation import Validator
27
20
  import re
28
21
  import shutil
29
22
  import tempfile
30
23
  from time import sleep
31
- from tqdm import tqdm
32
24
  import uuid
25
+
26
+ from dateutil.relativedelta import relativedelta
27
+ import i18n
28
+ from pathos.multiprocessing import ProcessPool as Pool
29
+ from prompt_toolkit import print_formatted_text as print, prompt
30
+ from prompt_toolkit.completion import WordCompleter
31
+ from prompt_toolkit.validation import Validator
32
+ from tqdm import tqdm
33
33
  import yaml
34
34
 
35
35
  # Make sure localisation is set up before any SDK-specific imports.
@@ -455,9 +455,35 @@ class Command(Base):
455
455
 
456
456
  self.__print_process(process)
457
457
 
458
- # Display the status of any execution.
458
+ # Group executions, if they are in groups.
459
+ groups = defaultdict(list)
460
+
459
461
  for execution in process.executions:
460
- self.__print_execution(execution)
462
+ if (hasattr(execution, Model._FIELD_GROUP_ID) and (execution.group_id is not None)) and (
463
+ hasattr(execution, Model._FIELD_GROUP_INDEX) and (execution.group_index is not None)) and (
464
+ hasattr(execution, Model._FIELD_GROUP_COUNT) and (execution.group_count is not None)):
465
+ groups[execution.group_id].append(execution)
466
+
467
+ # Display the status of any execution, in groups if used.
468
+ if len(groups) > 0:
469
+ group_number = 1
470
+
471
+ for group_id, group_executions in groups.items():
472
+ self.__print(logging.INFO,
473
+ i18n.t('command.log_execution_group_id', group_number=group_number, group_count=len(groups), group_id=group_id))
474
+
475
+ for execution in sorted(group_executions, key=lambda execution: execution.group_index):
476
+ self.__print_execution(execution, label=i18n.t('command.log_execution_group_index', group_index=execution.group_index,
477
+ group_count=execution.group_count))
478
+
479
+ group_number += 1
480
+ self.__print(logging.INFO, i18n.t('command.log_bookend'))
481
+
482
+ else:
483
+ for execution in process.executions:
484
+ self.__print_execution(execution)
485
+
486
+ self.__print(logging.INFO, i18n.t('command.log_bookend'))
461
487
 
462
488
  except CommandError as e:
463
489
  self.__print(logging.DEBUG, str(e))
@@ -507,8 +533,8 @@ class Command(Base):
507
533
  group_count = None
508
534
  group_index = None
509
535
 
510
- if hasattr(execution, Model._FIELD_GROUP_INDEX) and (execution.group_index is not None) and (not isinstance(execution.group_index, _Missing)) and hasattr(
511
- execution, Model._FIELD_GROUP_COUNT) and (execution.group_count is not None) and (not isinstance(execution.group_count, _Missing)):
536
+ if hasattr(execution, Model._FIELD_GROUP_INDEX) and (execution.group_index is not None) and (isinstance(execution.group_index, int)) and hasattr(
537
+ execution, Model._FIELD_GROUP_COUNT) and (execution.group_count is not None) and (isinstance(execution.group_count, int)):
512
538
  group_count = execution.group_count
513
539
  group_index = execution.group_index
514
540
  number_of_group_digits = len(str(group_count))
@@ -528,7 +554,8 @@ class Command(Base):
528
554
  if (started_at is None) or (execution.started_at < started_at):
529
555
  started_at = execution.started_at
530
556
 
531
- execution_ended_at = execution.ended_at if hasattr(execution, Model._FIELD_ENDED_AT) and (execution.ended_at is not None) else datetime.now(timezone.utc)
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)
532
559
 
533
560
  if (ended_at is None) or (execution_ended_at > ended_at):
534
561
  ended_at = execution_ended_at
@@ -700,7 +727,7 @@ class Command(Base):
700
727
  progress_bar.close()
701
728
 
702
729
  def download_process_execution(self, organisation, process_name, download_inputs, download_outputs, download_storage, download_intermediate,
703
- download_components, save_metrics, wait_for_execution_to_complete):
730
+ download_components, save_metrics, stac_only, wait_for_execution_to_complete):
704
731
  """
705
732
  Downloads the inputs and/or outputs from a process or execution(s).
706
733
 
@@ -713,6 +740,7 @@ class Command(Base):
713
740
  download_intermediate: Should intermediate components be downloaded?
714
741
  download_components: The names of the components that should be downloaded? If None or [], then all components are downloaded.
715
742
  save_metrics: Save process metrics to file?
743
+ stac_only: Save only stac assets?
716
744
  wait_for_execution_to_complete: Optionally wait for completion of the execution?
717
745
 
718
746
  Returns:
@@ -723,9 +751,9 @@ class Command(Base):
723
751
  if (not download_inputs) and (not download_outputs) and (not download_storage):
724
752
  download_outputs = True
725
753
 
726
- self.__print(logging.INFO,
727
- i18n.t('command.download_process_execution', process=process_name, inputs=download_inputs, outputs=download_outputs, storage=download_storage,
728
- intermediate=download_intermediate, metrics=save_metrics, components=download_components))
754
+ self.__print(logging.INFO, i18n.t('command.download_process_execution', process=process_name, inputs=download_inputs, outputs=download_outputs,
755
+ storage=download_storage, intermediate=download_intermediate, stac_only=stac_only, metrics=save_metrics,
756
+ components=download_components))
729
757
 
730
758
  # We are downloading from an existing process.
731
759
  process, execution = self.get_process_or_execution(organisation, process_name)
@@ -790,8 +818,9 @@ class Command(Base):
790
818
  downloads.extend(execution_downloads)
791
819
  metrics.extend(execution_metrics)
792
820
 
793
- # Download the files.
794
- self.__download_files(downloads)
821
+ # Download the files unless we only want the stac information
822
+ if not stac_only:
823
+ self.__download_files(downloads)
795
824
 
796
825
  # Save the metrics to file.
797
826
  if save_metrics and (len(metrics) > 0):
@@ -1042,6 +1071,38 @@ class Command(Base):
1042
1071
  """
1043
1072
  return uuid.uuid5(uuid.NAMESPACE_URL, f"{process_id}_{group_count}_{group_index}_{ssd_id}_{chain_index}")
1044
1073
 
1074
+ def list_processes(self, organisation):
1075
+ """
1076
+ Lists all configured processes.
1077
+
1078
+ Args:
1079
+ organisation: The logged in organisation.
1080
+ """
1081
+ for process in organisation.processes:
1082
+ executions = [execution for execution in process.executions]
1083
+
1084
+ # Get information about any groups.
1085
+ groups = defaultdict(list)
1086
+
1087
+ for execution in executions:
1088
+ if (hasattr(execution, Model._FIELD_GROUP_ID) and (execution.group_id is not None)) and (
1089
+ hasattr(execution, Model._FIELD_GROUP_INDEX) and (execution.group_index is not None)) and (
1090
+ hasattr(execution, Model._FIELD_GROUP_COUNT) and (execution.group_count is not None)):
1091
+ groups[execution.group_id].append(execution)
1092
+
1093
+ # Calculate the overall progress and for each group.
1094
+ progress = sum([execution.progress for execution in executions]) // len(executions)
1095
+ group_progress = ''
1096
+
1097
+ for i, group in enumerate(groups.values()):
1098
+ progress = sum([execution.progress for execution in group]) // len(group)
1099
+ group_progress += i18n.t('command.log_process_group', group_number=(i + 1), executions=len(group), progress=progress)
1100
+
1101
+ # Log the process information.
1102
+ self.__print(logging.INFO,
1103
+ i18n.t('command.log_process_summary', process=process.name, executions=len(executions), progress=progress, groups=len(groups),
1104
+ group_progress=group_progress))
1105
+
1045
1106
  def login(self, deployment, email, organisation_name):
1046
1107
  """
1047
1108
  Logs into the desired Fusion Platform(r) deployment and allows the user to select an organisation.
@@ -1117,12 +1178,16 @@ class Command(Base):
1117
1178
  # Login to the correct deployment and select the organisation.
1118
1179
  organisation, _, _ = self.login(arguments.deployment, arguments.email, arguments.organisation)
1119
1180
 
1120
- # Perform the display, start, define or download.
1121
- if arguments.command == i18n.t('command.display.command'):
1122
- # Display a service or process with the specified name or ids. If a service is displayed, we do not display a process.
1181
+ # Perform the list, display, start, define or download.
1182
+ if arguments.command == i18n.t('command.list.command'):
1183
+ # List all processes.
1184
+ self.list_processes(organisation)
1185
+
1186
+ elif arguments.command == i18n.t('command.display.command'):
1187
+ # Display a service or process with the specified name or ids. If a process is displayed, we do not display a service.
1123
1188
  for process_or_service in arguments.process_or_service:
1124
- if not self.display_service(organisation, process_or_service):
1125
- if not self.display_process(organisation, process_or_service):
1189
+ if not self.display_process(organisation, process_or_service):
1190
+ if not self.display_service(organisation, process_or_service):
1126
1191
  self.__print(logging.WARNING, i18n.t('command.no_process_or_service', process_or_service=process_or_service))
1127
1192
 
1128
1193
  elif arguments.command == i18n.t('command.start.command'):
@@ -1142,7 +1207,7 @@ class Command(Base):
1142
1207
  # Also perform the download, if required.
1143
1208
  if arguments.download:
1144
1209
  process = self.download_process_execution(organisation, process_name, arguments.inputs, arguments.outputs, arguments.storage,
1145
- arguments.intermediate, arguments.component, arguments.metrics,
1210
+ arguments.intermediate, arguments.component, arguments.metrics, arguments.stac,
1146
1211
  not arguments.no_wait_for_completion)
1147
1212
 
1148
1213
  # And optionally remove the process and its inputs.
@@ -1166,7 +1231,8 @@ class Command(Base):
1166
1231
  for process_name in arguments.process:
1167
1232
  # Download the process.
1168
1233
  process = self.download_process_execution(organisation, process_name, arguments.inputs, arguments.outputs, arguments.storage,
1169
- arguments.intermediate, arguments.component, arguments.metrics, not arguments.no_wait_for_completion)
1234
+ arguments.intermediate, arguments.component, arguments.metrics, arguments.stac,
1235
+ not arguments.no_wait_for_completion)
1170
1236
 
1171
1237
  # And optionally remove the process and its inputs.
1172
1238
  if arguments.remove:
@@ -1203,13 +1269,14 @@ class Command(Base):
1203
1269
  version=i18n.t('command.version_content', version=fusion_platform.__version__, version_date=fusion_platform.__version_date__))
1204
1270
 
1205
1271
  subparsers.required = True
1272
+ parser_list = subparsers.add_parser(i18n.t('command.list.command'), help=i18n.t('command.list.help'))
1206
1273
  parser_display = subparsers.add_parser(i18n.t('command.display.command'), help=i18n.t('command.display.help'))
1207
1274
  parser_start = subparsers.add_parser(i18n.t('command.start.command'), help=i18n.t('command.start.help'))
1208
1275
  parser_define = subparsers.add_parser(i18n.t('command.define.command'), help=i18n.t('command.define.help'))
1209
1276
  parser_download = subparsers.add_parser(i18n.t('command.download.command'), help=i18n.t('command.download.help'))
1210
1277
 
1211
1278
  # Add in the common arguments.
1212
- for subparser in [parser_display, parser_start, parser_define, parser_download]:
1279
+ for subparser in [parser_list, parser_display, parser_start, parser_define, parser_download]:
1213
1280
  subparser.add_argument(i18n.t('command.deployment_short'), i18n.t('command.deployment_long'), help=i18n.t('command.deployment_help'),
1214
1281
  default=Command._DEPLOYMENT_PRODUCTION_IRL)
1215
1282
  subparser.add_argument(i18n.t('command.email_short'), i18n.t('command.email_long'), help=i18n.t('command.email_help'))
@@ -1222,9 +1289,10 @@ class Command(Base):
1222
1289
 
1223
1290
  # Start arguments.
1224
1291
  parser_start.add_argument(i18n.t('command.start.definition_long'), help=i18n.t('command.start.definition_help'), nargs='+')
1225
- parser_start.add_argument(i18n.t('command.start.input_list_short'), i18n.t('command.start.input_list_long'), help=i18n.t('command.start.input_list_help'),
1292
+ parser_start.add_argument(i18n.t('command.start.input_list_short'), i18n.t('command.start.input_list_long'),
1293
+ help=i18n.t('command.start.input_list_help'), nargs='*')
1294
+ parser_start.add_argument(i18n.t('command.start.options_short'), i18n.t('command.start.options_long'), help=i18n.t('command.start.options_help'),
1226
1295
  nargs='*')
1227
- parser_start.add_argument(i18n.t('command.start.options_short'), i18n.t('command.start.options_long'), help=i18n.t('command.start.options_help'), nargs='*')
1228
1296
  parser_start.add_argument(i18n.t('command.start.wait_for_start_short'), i18n.t('command.start.wait_for_start_long'),
1229
1297
  help=i18n.t('command.start.wait_for_start_help'), default=False, action="store_true")
1230
1298
  parser_start.add_argument(i18n.t('command.start.download_short'), i18n.t('command.start.download_long'), help=i18n.t('command.start.download_help'),
@@ -1245,6 +1313,8 @@ class Command(Base):
1245
1313
  nargs='*')
1246
1314
  parser_start.add_argument(i18n.t('command.start.no_wait_for_completion_short'), i18n.t('command.start.no_wait_for_completion_long'),
1247
1315
  help=i18n.t('command.start.no_wait_for_completion_help'), default=False, action="store_true")
1316
+ parser_start.add_argument(i18n.t('command.start.stac_only_short'), i18n.t('command.start.stac_only_long'), help=i18n.t('command.start.stac_only_help'),
1317
+ default=False, action="store_true")
1248
1318
 
1249
1319
  # Define arguments.
1250
1320
  parser_define.add_argument(i18n.t('command.define.process_long'), help=i18n.t('command.define.process_help'), nargs='+')
@@ -1267,10 +1337,12 @@ class Command(Base):
1267
1337
  help=i18n.t('command.start.intermediate_help'), default=False, action="store_true")
1268
1338
  parser_download.add_argument(i18n.t('command.start.metrics_short'), i18n.t('command.start.metrics_long'), help=i18n.t('command.start.metrics_help'),
1269
1339
  default=False, action="store_true")
1270
- parser_download.add_argument(i18n.t('command.start.component_short'), i18n.t('command.start.component_long'), help=i18n.t('command.start.component_help'),
1271
- nargs='*')
1340
+ parser_download.add_argument(i18n.t('command.start.component_short'), i18n.t('command.start.component_long'),
1341
+ help=i18n.t('command.start.component_help'), nargs='*')
1272
1342
  parser_download.add_argument(i18n.t('command.start.no_wait_for_completion_short'), i18n.t('command.start.no_wait_for_completion_long'),
1273
1343
  help=i18n.t('command.start.no_wait_for_completion_help'), default=False, action="store_true")
1344
+ parser_download.add_argument(i18n.t('command.start.stac_only_short'), i18n.t('command.start.stac_only_long'), help=i18n.t('command.start.stac_only_help'),
1345
+ default=False, action="store_true")
1274
1346
 
1275
1347
  return parser.parse_args()
1276
1348
 
@@ -1290,18 +1362,20 @@ class Command(Base):
1290
1362
  else:
1291
1363
  print(message)
1292
1364
 
1293
- def __print_execution(self, execution):
1365
+ def __print_execution(self, execution, label=None):
1294
1366
  """
1295
1367
  Prints an execution. This just shows the status in a simple format.
1296
1368
 
1297
1369
  Args:
1298
1370
  execution: The execution to be logged.
1371
+ label: Optional label for the execution. Default None.
1299
1372
  """
1373
+ label = '' if label is None else label
1300
1374
 
1301
1375
  # Form the status of the execution.
1302
1376
  status = ''
1303
- group = ''
1304
- abort_reason = i18n.t('command.log_execution_abort_reason', abort_reason=execution.abort_reason) if hasattr(execution, Model._FIELD_ABORT_REASON) else ''
1377
+ abort_reason = i18n.t('command.log_execution_abort_reason', abort_reason=execution.abort_reason) if hasattr(execution,
1378
+ Model._FIELD_ABORT_REASON) else ''
1305
1379
  exit_type = i18n.t('command.log_execution_exit_type', exit_type=execution.exit_type) if hasattr(execution, Model._FIELD_EXIT_TYPE) else ''
1306
1380
 
1307
1381
  if execution.success:
@@ -1323,16 +1397,10 @@ class Command(Base):
1323
1397
  ended_at = i18n.t('command.log_execution_ended_at', ended_at=execution.ended_at.strftime('%Y-%m-%d %H:%M:%S')) if hasattr(execution,
1324
1398
  Model._FIELD_ENDED_AT) else ''
1325
1399
  period = i18n.t('command.log_execution_period', started_at=started_at, ended_at=ended_at)
1326
- duration = i18n.t('command.log_execution_duration', minutes=round((execution.ended_at - execution.started_at).total_seconds() // 60)) if hasattr(execution,
1327
- Model._FIELD_ENDED_AT) and (
1328
- execution.ended_at is not None) else ''
1329
-
1330
- if (hasattr(execution, Model._FIELD_GROUP_ID) and (execution.group_id is not None)) and (
1331
- hasattr(execution, Model._FIELD_GROUP_INDEX) and (execution.group_index is not None)) and (
1332
- hasattr(execution, Model._FIELD_GROUP_COUNT) and (execution.group_count is not None)):
1333
- group = i18n.t('command.log_execution_group', group_id=execution.group_id, group_index=execution.group_index, group_count=execution.group_count)
1400
+ duration = i18n.t('command.log_execution_duration', minutes=round((execution.ended_at - execution.started_at).total_seconds() // 60)) if hasattr(
1401
+ execution, Model._FIELD_ENDED_AT) and (execution.ended_at is not None) else ''
1334
1402
 
1335
- self.__print(logging.INFO, i18n.t('command.log_execution', id=execution.id, period=period, status=status, duration=duration, group=group))
1403
+ self.__print(logging.INFO, i18n.t('command.log_execution', id=execution.id, label=label, period=period, status=status, duration=duration))
1336
1404
 
1337
1405
  def __print_process(self, process):
1338
1406
  """
@@ -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,18 +169,27 @@ 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
@@ -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'
@@ -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):
@@ -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):
@@ -50,6 +50,10 @@
50
50
  * **swap_free_bytes**: The free swap space in bytes.
51
51
  * **tmp_total_bytes**: The total temporary disk space in bytes.
52
52
  * **tmp_free_bytes**: The free temporary disk space in bytes.
53
+ * **tmp_used_bytes**: The used temporary disk space in bytes.
54
+ * **scratch_total_bytes**: The total scratch disk space in bytes.
55
+ * **scratch_free_bytes**: The free scratch disk space in bytes.
56
+ * **scratch_used_bytes**: The used scratch disk space in bytes.
53
57
  * **s3_transfer_bytes**: The number of bytes transferred in from S3.
54
58
  * **gcs_transfer_bytes**: The number of bytes transferred in from Google Cloud Storage.
55
59
  * **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):
@@ -172,7 +171,6 @@ class ProcessServiceExecutionSchema(Schema):
172
171
  When loading an object, make sure we exclude any unknown fields, rather than raising an exception, and put fields in their definition order.
173
172
  """
174
173
  unknown = EXCLUDE
175
- ordered = True
176
174
 
177
175
 
178
176
  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):
@@ -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):
@@ -20,7 +20,10 @@ i18n.add_translation('command.no_such_organisation', 'No such organisation \'%{o
20
20
  i18n.add_translation('command.no_such_input', 'No such input \'%{input_name}\'', 'en')
21
21
  i18n.add_translation('command.no_executions', 'No executions for process \'%{process}\'', 'en')
22
22
  i18n.add_translation('command.invalid_login_response', 'Incorrect username or password', 'en')
23
- i18n.add_translation('command.log_execution_group', ' (group \'%{group_id}\' %{group_index} of %{group_count})', 'en')
23
+ i18n.add_translation('command.log_process_summary', '\'%{process}\': %{executions} execution(s) in %{groups} group(s) (%{progress}%% complete);%{group_progress}', 'en')
24
+ i18n.add_translation('command.log_process_group', ' %{group_number}: %{executions} execution(s) (%{progress}%% complete);', 'en')
25
+ i18n.add_translation('command.log_execution_group_index', ' %{group_index} of %{group_count}', 'en')
26
+ i18n.add_translation('command.log_execution_group_id', 'Group %{group_number} of %{group_count} (%{group_id}):', 'en')
24
27
  i18n.add_translation('command.log_execution_duration', ' - %{minutes} minute(s)', 'en')
25
28
  i18n.add_translation('command.log_execution_period', ' (%{started_at}%{ended_at})', 'en')
26
29
  i18n.add_translation('command.log_execution_ended_at', ' -> %{ended_at}', 'en')
@@ -39,7 +42,7 @@ i18n.add_translation('command.log_dispatchers', 'Dispatchers:', 'en')
39
42
  i18n.add_translation('command.log_options', 'Options:', 'en')
40
43
  i18n.add_translation('command.log_outputs', 'Outputs:', 'en')
41
44
  i18n.add_translation('command.log_inputs', 'Inputs:', 'en')
42
- i18n.add_translation('command.log_execution', 'Execution \'%{id}\'%{period}: %{status}%{duration}%{group}', 'en')
45
+ i18n.add_translation('command.log_execution', 'Execution%{label} \'%{id}\'%{period}: %{status}%{duration}', 'en')
43
46
  i18n.add_translation('command.log_service', 'Service \'%{service}\'', 'en')
44
47
  i18n.add_translation('command.log_process', 'Process \'%{process}\'', 'en')
45
48
  i18n.add_translation('command.log_field', '%{field}: %{value}', 'en')
@@ -65,7 +68,7 @@ i18n.add_translation('command.organisation', 'Organisation', 'en')
65
68
  i18n.add_translation('command.find_inputs', 'Finding %{inputs} input file(s)...', 'en')
66
69
  i18n.add_translation('command.executing', 'Executing...', 'en')
67
70
  i18n.add_translation('command.email', 'Email', 'en')
68
- i18n.add_translation('command.download_process_execution', 'Downloading \'%{process}\' (inputs %{inputs}, outputs %{outputs}, storage %{storage}, intermediate %{intermediate}, metrics %{metrics}, components %{components})', 'en')
71
+ i18n.add_translation('command.download_process_execution', 'Downloading \'%{process}\' (inputs %{inputs}, outputs %{outputs}, storage %{storage}, intermediate %{intermediate}, STAC only %{stac_only}, metrics %{metrics}, components %{components})', 'en')
69
72
  i18n.add_translation('command.download_process', 'Downloading process \'%{process}\' to %{output}', 'en')
70
73
  i18n.add_translation('command.download_files', 'Downloading %{files} file(s)...', 'en')
71
74
  i18n.add_translation('command.download_executions', 'Gathering files%{wait} for %{executions} execution(s)...', 'en')
@@ -83,9 +86,12 @@ i18n.add_translation('command.define.process_help', 'the name of the process, th
83
86
  i18n.add_translation('command.define.process_long', 'process', 'en')
84
87
  i18n.add_translation('command.define.help', 'outputs a YAML file for each existing process', 'en')
85
88
  i18n.add_translation('command.define.command', 'define', 'en')
86
- i18n.add_translation('command.start.no_wait_for_completion_help', 'do not wait for the execution to complete (default %%(default)s)\'', 'en')
89
+ i18n.add_translation('command.start.no_wait_for_completion_help', 'do not wait for the execution to complete (default %%(default)s)', 'en')
87
90
  i18n.add_translation('command.start.no_wait_for_completion_long', '--no_wait_for_completion', 'en')
88
91
  i18n.add_translation('command.start.no_wait_for_completion_short', '-n', 'en')
92
+ i18n.add_translation('command.start.stac_only_help', 'only download the STAC metadata for the files (default %%(default)s)', 'en')
93
+ i18n.add_translation('command.start.stac_only_long', '--stac', 'en')
94
+ i18n.add_translation('command.start.stac_only_short', '-a', 'en')
89
95
  i18n.add_translation('command.start.metrics_help', 'save process metrics to file (default %%(default)s)', 'en')
90
96
  i18n.add_translation('command.start.metrics_long', '--metrics', 'en')
91
97
  i18n.add_translation('command.start.metrics_short', '-t', 'en')
@@ -127,6 +133,8 @@ i18n.add_translation('command.display.service_or_process_help', 'the names of th
127
133
  i18n.add_translation('command.display.service_or_process_long', 'process_or_service', 'en')
128
134
  i18n.add_translation('command.display.help', 'displays service information or a configured process', 'en')
129
135
  i18n.add_translation('command.display.command', 'display', 'en')
136
+ i18n.add_translation('command.list.help', 'lists configured processes', 'en')
137
+ i18n.add_translation('command.list.command', 'list', 'en')
130
138
  i18n.add_translation('command.subparser', 'displays a service or process, or starts, defines or downloads a process', 'en')
131
139
  i18n.add_translation('command.version_content', '%%(prog)s %{version} (%{version_date})', 'en')
132
140
  i18n.add_translation('command.version_help', 'show the version information and exit', 'en')
@@ -147,6 +155,7 @@ i18n.add_translation('command.deployment_short', '-y', 'en')
147
155
  i18n.add_translation('command.epilog', '''
148
156
  For more detailed options, use:
149
157
 
158
+ fusion_platform list --help
150
159
  fusion_platform display --help
151
160
  fusion_platform start --help
152
161
  fusion_platform define --help
@@ -158,7 +167,11 @@ Use this command to display service information and processes, and to start, dow
158
167
  defined by a YAML file.
159
168
 
160
169
  Usage:
161
- The following will display information about one or more services or processes from the given \'service_or_process_name\'.
170
+ The following will list all currently configured processes:
171
+
172
+ fusion_platform list
173
+
174
+ The following will display information about one or more services or processes from the given \'service_or_process_name\':
162
175
 
163
176
  fusion_platform display <service_or_process_name> ...
164
177
 
@@ -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.6
3
+ Version: 1.18.3
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.6',
22
+ version='1.18.3',
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',