pinexq-client 0.4.2.20241009.1__py3-none-any.whl → 0.5.0.20241030.1__py3-none-any.whl

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.
@@ -5,13 +5,13 @@ from httpx import URL
5
5
 
6
6
  from pinexq_client.core import Entity, Action, execute_action, raise_exception_on_error, ClientException
7
7
  from pinexq_client.core.hco.hco_base import ClientContainer
8
- from pinexq_client.core.hco.unavailable import UnavailableAction
8
+ from pinexq_client.core.hco.unavailable import UnavailableAction, HypermediaAvailability
9
9
 
10
10
  TEntity = TypeVar('TEntity', bound=Entity)
11
11
  THcoEntity = TypeVar('THcoEntity', bound=Entity)
12
12
 
13
13
 
14
- class ActionHco(ClientContainer):
14
+ class ActionHco(ClientContainer, HypermediaAvailability):
15
15
  _client: httpx.Client
16
16
  _action: Action
17
17
 
@@ -51,6 +51,10 @@ class ActionHco(ClientContainer):
51
51
  f"Error while mapping mandatory action {name}: does not exist")
52
52
  return result
53
53
 
54
+ @staticmethod
55
+ def is_available() -> bool:
56
+ return True
57
+
54
58
  def _execute_internal(self) -> None | URL:
55
59
  response = execute_action(self._client, self._action)
56
60
  raise_exception_on_error(f"Error while executing action, unexpected response", response)
@@ -6,12 +6,12 @@ from pydantic import BaseModel
6
6
 
7
7
  from pinexq_client.core import Entity, Action, execute_action, raise_exception_on_error, ClientException
8
8
  from pinexq_client.core.hco.hco_base import ClientContainer
9
- from pinexq_client.core.hco.unavailable import UnavailableAction
9
+ from pinexq_client.core.hco.unavailable import UnavailableAction, HypermediaAvailability
10
10
 
11
11
  TParameters = TypeVar('TParameters', bound=BaseModel)
12
12
 
13
13
 
14
- class ActionWithParametersHco(ClientContainer, Generic[TParameters]):
14
+ class ActionWithParametersHco(ClientContainer, Generic[TParameters], HypermediaAvailability):
15
15
  _client: httpx.Client
16
16
  _action: Action
17
17
 
@@ -52,6 +52,10 @@ class ActionWithParametersHco(ClientContainer, Generic[TParameters]):
52
52
  f"Error while mapping mandatory action {name}: action does not exist")
53
53
  return result
54
54
 
55
+ @staticmethod
56
+ def is_available() -> bool:
57
+ return True
58
+
55
59
  def _execute_internal(self, parameters: BaseModel) -> None | URL:
56
60
  if parameters is None:
57
61
  raise ClientException(f"Error while executing action: action requires parameters")
@@ -5,10 +5,11 @@ from httpx import URL
5
5
 
6
6
  from pinexq_client.core import Link, Entity, navigate, ensure_siren_response, ClientException
7
7
  from pinexq_client.core.hco.hco_base import ClientContainer, TEntity
8
- from pinexq_client.core.hco.unavailable import UnavailableLink
8
+ from pinexq_client.core.hco.unavailable import UnavailableLink, HypermediaAvailability
9
9
 
10
10
 
11
- class LinkHco(ClientContainer):
11
+ class LinkHco(ClientContainer, HypermediaAvailability):
12
+
12
13
  _client: httpx.Client
13
14
  _link: Link
14
15
 
@@ -46,6 +47,10 @@ class LinkHco(ClientContainer):
46
47
 
47
48
  return result
48
49
 
50
+ @staticmethod
51
+ def is_available() -> bool:
52
+ return True
53
+
49
54
  def _navigate_internal(self, parse_type: Type[TEntity] = Entity) -> TEntity:
50
55
  response = navigate(self._client, self._link, parse_type)
51
56
  return ensure_siren_response(response)
@@ -1,17 +1,36 @@
1
+ from abc import ABC, ABCMeta, abstractmethod
2
+
1
3
  from pinexq_client.core import NotAvailableException
2
4
 
3
5
 
4
- class UnavailableAction:
6
+ class HypermediaAvailability(ABC):
7
+ def __bool__(self) -> bool:
8
+ return self.is_available()
9
+
10
+ @staticmethod
11
+ @abstractmethod
12
+ def is_available() -> bool:
13
+ ...
14
+
15
+ class UnavailableAction(HypermediaAvailability):
5
16
  """This class is used to represent an action that is not available. It is used to avoid None
6
17
  checks in the code."""
7
18
 
8
19
  def execute(self, *args, **kwargs):
9
20
  raise NotAvailableException(f"Error while executing action: action is not available")
10
21
 
22
+ @staticmethod
23
+ def is_available() -> bool:
24
+ return False
11
25
 
12
- class UnavailableLink:
26
+
27
+ class UnavailableLink(HypermediaAvailability):
13
28
  """This class is used to represent a link that is not available. It is used to avoid None
14
29
  checks in the code."""
15
30
 
16
31
  def navigate(self):
17
32
  raise NotAvailableException(f"Error while navigating: link is not available")
33
+
34
+ @staticmethod
35
+ def is_available() -> bool:
36
+ return False
@@ -1,3 +1,5 @@
1
+ from typing import Any
2
+
1
3
  from pydantic import BaseModel, Field, ConfigDict
2
4
 
3
5
 
@@ -7,6 +9,7 @@ class ProblemDetails(BaseModel):
7
9
  status: int | None = None
8
10
  detail: str | None = None
9
11
  instance: str | None = None
12
+ errors: Any = None
10
13
 
11
14
  def __str__(self):
12
15
  message = [f" {key}: {value}" for key, value in self.model_dump().items() if value]
@@ -22,7 +22,7 @@ def get_resource(client: httpx.Client, href: str, media_type: str = MediaTypes.S
22
22
  # assume get for links
23
23
  response = client.get(href)
24
24
  except (httpx.ConnectTimeout, httpx.ConnectError) as exc:
25
- raise ClientException(f"Http-client error requesting resource: {href}") from exc
25
+ raise ClientException(f"Http-client error requesting resource: {href}\nMessage:{exc}\nCurrent client timeout:{client.timeout}") from exc
26
26
  expected_type = media_type or MediaTypes.SIREN # if not specified expect siren
27
27
 
28
28
  if response.status_code == httpx.codes.OK:
@@ -84,7 +84,7 @@ def upload_file(client: httpx.Client, action: Action, file: BinaryIO, filename:
84
84
  try:
85
85
  response = client.request(method=action.method, url=action.href, files=files)
86
86
  except httpx.RequestError as exc:
87
- raise ClientException(f"Error from httpx while uploading data to: {action.href}") from exc
87
+ raise ClientException(f"Error from httpx while uploading data to: {action.href}\nMessage:{exc}\nCurrent client timeout:{client.timeout}") from exc
88
88
  return handle_action_result(response)
89
89
 
90
90
 
@@ -119,7 +119,7 @@ def execute_action(client: httpx.Client, action: Action,
119
119
  headers={Headers.CONTENT_TYPE.value: MediaTypes.APPLICATION_JSON.value}
120
120
  )
121
121
  except httpx.RequestError as exc:
122
- raise ClientException(f"Error from httpx while executing action: {action.href}") from exc
122
+ raise ClientException(f"Error from httpx while executing action: {action.href}\nMessage:{exc}\nCurrent client timeout:{client.timeout}") from exc
123
123
 
124
124
  return handle_action_result(response)
125
125
 
@@ -3,4 +3,4 @@ from .enterjma import enter_jma
3
3
  from .tool import Job, ProcessingStep, WorkData
4
4
 
5
5
  # Protocol version the JMA is using
6
- __jma_version__ = [6, 2, 3]
6
+ __jma_version__ = [7, 0, 0]
@@ -13,171 +13,185 @@ from pinexq_client.job_management.hcos import InputDataSlotHco
13
13
  from pinexq_client.job_management.hcos.output_dataslot_hco import OutputDataSlotHco
14
14
  from pinexq_client.job_management.hcos.processing_step_hco import ProcessingStepLink
15
15
  from pinexq_client.job_management.known_relations import Relations
16
+ from pinexq_client.job_management.model import SetJobErrorStateParameters
16
17
  from pinexq_client.job_management.model.open_api_generated import JobStates, ProcessingView, RenameJobParameters, \
17
- SelectProcessingParameters, SetJobTagsParameters
18
+ SelectProcessingParameters, SetJobTagsParameters
18
19
  from pinexq_client.job_management.model.sirenentities import JobEntity, InputDataSlotEntity, OutputDataSlotEntity
19
20
 
20
21
 
21
22
  class JobRenameAction(ActionWithParametersHco[RenameJobParameters]):
22
- def execute(self, parameters: RenameJobParameters):
23
- self._execute(parameters)
23
+ def execute(self, parameters: RenameJobParameters):
24
+ self._execute(parameters)
24
25
 
25
- def default_parameters(self) -> RenameJobParameters:
26
- return self._get_default_parameters(RenameJobParameters, RenameJobParameters())
26
+ def default_parameters(self) -> RenameJobParameters:
27
+ return self._get_default_parameters(RenameJobParameters, RenameJobParameters())
27
28
 
28
29
 
29
30
  class JobSelectProcessingAction(ActionWithParametersHco[SelectProcessingParameters]):
30
- def execute(self, parameters: SelectProcessingParameters):
31
- self._execute(parameters)
31
+ def execute(self, parameters: SelectProcessingParameters):
32
+ self._execute(parameters)
32
33
 
33
- def default_parameters(self) -> SelectProcessingParameters:
34
- return self._get_default_parameters(SelectProcessingParameters, SelectProcessingParameters())
34
+ def default_parameters(self) -> SelectProcessingParameters:
35
+ return self._get_default_parameters(SelectProcessingParameters, SelectProcessingParameters())
35
36
 
36
37
 
37
38
  class JobHideAction(ActionHco):
38
- def execute(self):
39
- self._execute_internal()
39
+ def execute(self):
40
+ self._execute_internal()
40
41
 
41
42
 
42
43
  class JobUnHideAction(ActionHco):
43
- def execute(self):
44
- self._execute_internal()
44
+ def execute(self):
45
+ self._execute_internal()
45
46
 
46
47
 
47
48
  class JobDeleteAction(ActionHco):
48
- def execute(self):
49
- self._execute_internal()
49
+ def execute(self):
50
+ self._execute_internal()
50
51
 
51
52
 
52
53
  class JobAllowOutputDataDeletionAction(ActionHco):
53
- def execute(self):
54
- self._execute_internal()
54
+ def execute(self):
55
+ self._execute_internal()
55
56
 
56
57
 
57
58
  class JobDisAllowOutputDataDeletionAction(ActionHco):
58
- def execute(self):
59
- self._execute_internal()
59
+ def execute(self):
60
+ self._execute_internal()
60
61
 
61
62
 
62
63
  class GenericProcessingConfigureParameters(BaseModel):
63
- """Generic parameter model, that can be set with any dictionary"""
64
- model_config = ConfigDict(extra='allow')
64
+ """Generic parameter model, that can be set with any dictionary"""
65
+ model_config = ConfigDict(extra='allow')
65
66
 
66
67
 
67
68
  class JobConfigureProcessingAction(ActionWithParametersHco[GenericProcessingConfigureParameters]):
68
- def execute(self, parameters: GenericProcessingConfigureParameters):
69
- self._execute(parameters)
69
+ def execute(self, parameters: GenericProcessingConfigureParameters):
70
+ self._execute(parameters)
70
71
 
71
- def default_parameters(self) -> GenericProcessingConfigureParameters:
72
- return self._get_default_parameters(GenericProcessingConfigureParameters,
73
- GenericProcessingConfigureParameters())
72
+ def default_parameters(self) -> GenericProcessingConfigureParameters:
73
+ return self._get_default_parameters(GenericProcessingConfigureParameters,
74
+ GenericProcessingConfigureParameters())
74
75
 
75
76
 
76
77
  class JobStartProcessingAction(ActionHco):
77
- def execute(self):
78
- self._execute_internal()
78
+ def execute(self):
79
+ self._execute_internal()
79
80
 
80
81
 
81
82
  class JobLink(LinkHco):
82
- def navigate(self) -> 'JobHco':
83
- return JobHco.from_entity(self._navigate_internal(JobEntity), self._client)
83
+ def navigate(self) -> 'JobHco':
84
+ return JobHco.from_entity(self._navigate_internal(JobEntity), self._client)
84
85
 
85
86
 
86
87
  class ParentJobLink(LinkHco):
87
- def navigate(self) -> 'JobHco':
88
- return JobHco.from_entity(self._navigate_internal(JobEntity), self._client)
88
+ def navigate(self) -> 'JobHco':
89
+ return JobHco.from_entity(self._navigate_internal(JobEntity), self._client)
89
90
 
90
91
 
91
92
  class JobEditTagsAction(ActionWithParametersHco[SetJobTagsParameters]):
92
- def execute(self, parameters: SetJobTagsParameters):
93
- self._execute(parameters)
93
+ def execute(self, parameters: SetJobTagsParameters):
94
+ self._execute(parameters)
94
95
 
95
- def default_parameters(self) -> SetJobTagsParameters:
96
- # todo check why we have to manually set tags
97
- return self._get_default_parameters(SetJobTagsParameters, SetJobTagsParameters(tags=[]))
96
+ def default_parameters(self) -> SetJobTagsParameters:
97
+ # todo check why we have to manually set tags
98
+ return self._get_default_parameters(SetJobTagsParameters, SetJobTagsParameters(tags=[]))
99
+
100
+
101
+ class JobSetToErrorStateAction(ActionWithParametersHco[SetJobErrorStateParameters]):
102
+ def execute(self, parameters: SetJobErrorStateParameters):
103
+ self._execute(parameters)
104
+
105
+ def default_parameters(self) -> SetJobErrorStateParameters:
106
+ return self._get_default_parameters(SetJobErrorStateParameters, SetJobErrorStateParameters(
107
+ message='Manually set to error state by admin'
108
+ ))
98
109
 
99
110
 
100
111
  class JobHco(Hco[JobEntity]):
101
- name: str = Property()
102
- state: JobStates = Property()
103
- hidden: bool = Property()
104
- tags: list[str] | None = Property()
105
- output_is_deletable: bool = Property()
106
- created_at: datetime = Property()
107
- completed_at: datetime = Property()
108
- error_description: str = Property()
109
- processing: ProcessingView = Property()
110
- result: str = Property()
111
-
112
- self_link: JobLink
113
- parent_link: ParentJobLink | UnavailableLink
114
- selected_processing_step_link: ProcessingStepLink | UnavailableLink
115
-
116
- rename_action: JobRenameAction | UnavailableAction
117
- select_processing_action: JobSelectProcessingAction | UnavailableAction
118
- configure_processing_action: JobConfigureProcessingAction | UnavailableAction
119
- start_processing_action: JobStartProcessingAction | UnavailableAction
120
- hide_action: JobHideAction | UnavailableAction
121
- unhide_action: JobUnHideAction | UnavailableAction
122
- delete_action: JobDeleteAction | UnavailableAction
123
- allow_output_data_deletion_action: JobAllowOutputDataDeletionAction | UnavailableAction
124
- disallow_output_data_deletion_action: JobDisAllowOutputDataDeletionAction | UnavailableAction
125
- edit_tags_action: JobEditTagsAction | UnavailableAction
126
-
127
- input_dataslots: List[InputDataSlotHco]
128
- output_dataslots: List[OutputDataSlotHco]
129
-
130
- @classmethod
131
- def from_entity(cls, entity: JobEntity, client: httpx.Client) -> Self:
132
- instance = cls(client, entity)
133
-
134
- Hco.check_classes(instance._entity.class_, ["Job"])
135
-
136
- instance.self_link = JobLink.from_entity(
137
- instance._client, instance._entity, Relations.SELF)
138
- instance.parent_link = ParentJobLink.from_entity_optional(
139
- instance._client, instance._entity, Relations.PARENT_JOB)
140
- instance.selected_processing_step_link = ProcessingStepLink.from_entity_optional(
141
- instance._client, instance._entity, Relations.SELECTED_PROCESSING_STEP)
142
-
143
- # actions
144
- instance.hide_action = JobHideAction.from_entity_optional(
145
- client, instance._entity, "Hide")
146
- instance.unhide_action = JobUnHideAction.from_entity_optional(
147
- client, instance._entity, "UnHide")
148
- instance.delete_action = JobDeleteAction.from_entity_optional(
149
- client, instance._entity, "Delete")
150
- instance.rename_action = JobRenameAction.from_entity_optional(
151
- client, instance._entity, "Rename")
152
- instance.select_processing_action = JobSelectProcessingAction.from_entity_optional(
153
- client, instance._entity, "SelectProcessing")
154
- instance.configure_processing_action = JobConfigureProcessingAction.from_entity_optional(
155
- client, instance._entity, "ConfigureProcessing")
156
- instance.start_processing_action = JobStartProcessingAction.from_entity_optional(
157
- client, instance._entity, "StartProcessing")
158
- instance.allow_output_data_deletion_action = JobAllowOutputDataDeletionAction.from_entity_optional(
159
- client, instance._entity, "AllowOutputDataDeletion")
160
- instance.disallow_output_data_deletion_action = JobDisAllowOutputDataDeletionAction.from_entity_optional(
161
- client, instance._entity, "DisallowOutputDataDeletion")
162
- instance.edit_tags_action = JobEditTagsAction.from_entity_optional(
163
- client, instance._entity, "EditTags")
164
-
165
- # entities
166
- instance._extract_input_dataslots()
167
- instance._extract_output_dataslots()
168
-
169
- return instance
170
-
171
- def _extract_input_dataslots(self):
172
- self.input_dataslots = []
173
- input_dataslots = self._entity.find_all_entities_with_relation(Relations.INPUT_DATASLOT, InputDataSlotEntity)
174
- for input_dataslot in input_dataslots:
175
- input_dataslot_hco: InputDataSlotHco = InputDataSlotHco.from_entity(input_dataslot, self._client)
176
- self.input_dataslots.append(input_dataslot_hco)
177
-
178
- def _extract_output_dataslots(self):
179
- self.output_dataslots = []
180
- output_dataslots = self._entity.find_all_entities_with_relation(Relations.OUTPUT_DATASLOT, OutputDataSlotEntity)
181
- for output_dataslot in output_dataslots:
182
- output_dataslot_hco: OutputDataSlotHco = OutputDataSlotHco.from_entity(output_dataslot, self._client)
183
- self.output_dataslots.append(output_dataslot_hco)
112
+ name: str = Property()
113
+ state: JobStates = Property()
114
+ hidden: bool = Property()
115
+ tags: list[str] | None = Property()
116
+ output_is_deletable: bool = Property()
117
+ created_at: datetime = Property()
118
+ completed_at: datetime = Property()
119
+ error_description: str = Property()
120
+ processing: ProcessingView = Property()
121
+ result: str = Property()
122
+
123
+ self_link: JobLink
124
+ parent_link: ParentJobLink | UnavailableLink
125
+ selected_processing_step_link: ProcessingStepLink | UnavailableLink
126
+
127
+ rename_action: JobRenameAction | UnavailableAction
128
+ select_processing_action: JobSelectProcessingAction | UnavailableAction
129
+ configure_processing_action: JobConfigureProcessingAction | UnavailableAction
130
+ start_processing_action: JobStartProcessingAction | UnavailableAction
131
+ hide_action: JobHideAction | UnavailableAction
132
+ unhide_action: JobUnHideAction | UnavailableAction
133
+ delete_action: JobDeleteAction | UnavailableAction
134
+ allow_output_data_deletion_action: JobAllowOutputDataDeletionAction | UnavailableAction
135
+ disallow_output_data_deletion_action: JobDisAllowOutputDataDeletionAction | UnavailableAction
136
+ edit_tags_action: JobEditTagsAction | UnavailableAction
137
+ set_to_error_state_action: JobSetToErrorStateAction | UnavailableAction
138
+
139
+ input_dataslots: List[InputDataSlotHco]
140
+ output_dataslots: List[OutputDataSlotHco]
141
+
142
+ @classmethod
143
+ def from_entity(cls, entity: JobEntity, client: httpx.Client) -> Self:
144
+ instance = cls(client, entity)
145
+
146
+ Hco.check_classes(instance._entity.class_, ["Job"])
147
+
148
+ instance.self_link = JobLink.from_entity(
149
+ instance._client, instance._entity, Relations.SELF)
150
+ instance.parent_link = ParentJobLink.from_entity_optional(
151
+ instance._client, instance._entity, Relations.PARENT_JOB)
152
+ instance.selected_processing_step_link = ProcessingStepLink.from_entity_optional(
153
+ instance._client, instance._entity, Relations.SELECTED_PROCESSING_STEP)
154
+
155
+ # actions
156
+ instance.hide_action = JobHideAction.from_entity_optional(
157
+ client, instance._entity, "Hide")
158
+ instance.unhide_action = JobUnHideAction.from_entity_optional(
159
+ client, instance._entity, "UnHide")
160
+ instance.delete_action = JobDeleteAction.from_entity_optional(
161
+ client, instance._entity, "Delete")
162
+ instance.rename_action = JobRenameAction.from_entity_optional(
163
+ client, instance._entity, "Rename")
164
+ instance.select_processing_action = JobSelectProcessingAction.from_entity_optional(
165
+ client, instance._entity, "SelectProcessing")
166
+ instance.configure_processing_action = JobConfigureProcessingAction.from_entity_optional(
167
+ client, instance._entity, "ConfigureProcessing")
168
+ instance.start_processing_action = JobStartProcessingAction.from_entity_optional(
169
+ client, instance._entity, "StartProcessing")
170
+ instance.allow_output_data_deletion_action = JobAllowOutputDataDeletionAction.from_entity_optional(
171
+ client, instance._entity, "AllowOutputDataDeletion")
172
+ instance.disallow_output_data_deletion_action = JobDisAllowOutputDataDeletionAction.from_entity_optional(
173
+ client, instance._entity, "DisallowOutputDataDeletion")
174
+ instance.set_to_error_state_action = JobSetToErrorStateAction.from_entity_optional(
175
+ client, instance._entity, "SetJobToErrorState")
176
+ instance.edit_tags_action = JobEditTagsAction.from_entity_optional(
177
+ client, instance._entity, "EditTags")
178
+
179
+ # entities
180
+ instance._extract_input_dataslots()
181
+ instance._extract_output_dataslots()
182
+
183
+ return instance
184
+
185
+ def _extract_input_dataslots(self):
186
+ self.input_dataslots = []
187
+ input_dataslots = self._entity.find_all_entities_with_relation(Relations.INPUT_DATASLOT, InputDataSlotEntity)
188
+ for input_dataslot in input_dataslots:
189
+ input_dataslot_hco: InputDataSlotHco = InputDataSlotHco.from_entity(input_dataslot, self._client)
190
+ self.input_dataslots.append(input_dataslot_hco)
191
+
192
+ def _extract_output_dataslots(self):
193
+ self.output_dataslots = []
194
+ output_dataslots = self._entity.find_all_entities_with_relation(Relations.OUTPUT_DATASLOT, OutputDataSlotEntity)
195
+ for output_dataslot in output_dataslots:
196
+ output_dataslot_hco: OutputDataSlotHco = OutputDataSlotHco.from_entity(output_dataslot, self._client)
197
+ self.output_dataslots.append(output_dataslot_hco)
@@ -10,73 +10,74 @@ from pinexq_client.core.hco.link_hco import LinkHco
10
10
  from pinexq_client.core.hco.unavailable import UnavailableAction, UnavailableLink
11
11
  from pinexq_client.job_management.hcos.job_hco import JobLink
12
12
  from pinexq_client.job_management.hcos.job_query_result_hco import (
13
- JobQueryResultHco,
14
- JobQueryResultLink
13
+ JobQueryResultHco,
14
+ JobQueryResultLink
15
15
  )
16
16
  from pinexq_client.job_management.hcos.job_used_tags_hco import JobUsedTagsLink
17
17
  from pinexq_client.job_management.known_relations import Relations
18
18
  from pinexq_client.job_management.model.open_api_generated import (
19
- CreateJobParameters,
20
- JobQueryParameters,
21
- CreateSubJobParameters
19
+ CreateJobParameters,
20
+ JobQueryParameters,
21
+ CreateSubJobParameters
22
22
  )
23
23
  from pinexq_client.job_management.model.sirenentities import JobsRootEntity
24
24
 
25
25
 
26
26
  class CreateJobAction(ActionWithParametersHco[CreateJobParameters]):
27
- def execute(self, parameters: CreateJobParameters) -> JobLink:
28
- url: URL = self._execute_returns_url(parameters)
29
- link = Link.from_url(url, [str(Relations.CREATED_RESSOURCE)], "Created job", MediaTypes.SIREN)
30
- return JobLink.from_link(self._client, link)
27
+ def execute(self, parameters: CreateJobParameters) -> JobLink:
28
+ url: URL = self._execute_returns_url(parameters)
29
+ link = Link.from_url(url, [str(Relations.CREATED_RESSOURCE)], "Created job", MediaTypes.SIREN)
30
+ return JobLink.from_link(self._client, link)
31
31
 
32
- def default_parameters(self) -> CreateJobParameters:
33
- return self._get_default_parameters(CreateJobParameters, CreateJobParameters())
32
+ def default_parameters(self) -> CreateJobParameters:
33
+ return self._get_default_parameters(CreateJobParameters, CreateJobParameters())
34
34
 
35
35
 
36
36
  class CreateSubJobAction(ActionWithParametersHco[CreateSubJobParameters]):
37
- def execute(self, parameters: CreateSubJobParameters) -> JobLink:
38
- url = self._execute_returns_url(parameters)
39
- link = Link.from_url(url, [str(Relations.CREATED_RESSOURCE)], "Created sub-job", MediaTypes.SIREN)
40
- return JobLink.from_link(self._client, link)
37
+ def execute(self, parameters: CreateSubJobParameters) -> JobLink:
38
+ url = self._execute_returns_url(parameters)
39
+ link = Link.from_url(url, [str(Relations.CREATED_RESSOURCE)], "Created sub-job", MediaTypes.SIREN)
40
+ return JobLink.from_link(self._client, link)
41
41
 
42
- def default_parameters(self) -> CreateSubJobParameters:
43
- return self._get_default_parameters(CreateSubJobParameters, CreateSubJobParameters())
42
+ def default_parameters(self) -> CreateSubJobParameters:
43
+ return self._get_default_parameters(CreateSubJobParameters, CreateSubJobParameters())
44
44
 
45
45
 
46
46
  class JobQueryAction(ActionWithParametersHco):
47
- def execute(self, parameters: JobQueryParameters) -> JobQueryResultHco:
48
- url = self._execute_returns_url(parameters)
49
- link = Link.from_url(url, [str(Relations.CREATED_RESSOURCE)], "Created job query", MediaTypes.SIREN)
50
- # resolve link immediately
51
- return JobQueryResultLink.from_link(self._client, link).navigate()
47
+ def execute(self, parameters: JobQueryParameters) -> JobQueryResultHco:
48
+ url = self._execute_returns_url(parameters)
49
+ link = Link.from_url(url, [str(Relations.CREATED_RESSOURCE)], "Created job query", MediaTypes.SIREN)
50
+ # resolve link immediately
51
+ return JobQueryResultLink.from_link(self._client, link).navigate()
52
52
 
53
- def default_parameters(self) -> JobQueryParameters:
54
- return self._get_default_parameters(JobQueryParameters, JobQueryParameters())
53
+ def default_parameters(self) -> JobQueryParameters:
54
+ return self._get_default_parameters(JobQueryParameters, JobQueryParameters())
55
55
 
56
56
 
57
57
  class JobsRootHco(Hco[JobsRootEntity]):
58
- create_job_action: CreateJobAction | UnavailableAction
59
- job_query_action: JobQueryAction | UnavailableAction
60
- create_subjob_action: CreateSubJobAction | UnavailableAction
61
- used_tags_link: JobUsedTagsLink | UnavailableLink
58
+ create_job_action: CreateJobAction | UnavailableAction
59
+ job_query_action: JobQueryAction | UnavailableAction
60
+ create_subjob_action: CreateSubJobAction | UnavailableAction
61
+ used_tags_link: JobUsedTagsLink | UnavailableLink
62
62
 
63
- self_link: 'JobsRootLink'
63
+ self_link: 'JobsRootLink'
64
64
 
65
- @classmethod
66
- def from_entity(cls, entity: JobsRootEntity, client: httpx.Client) -> Self:
67
- instance = cls(client, entity)
65
+ @classmethod
66
+ def from_entity(cls, entity: JobsRootEntity, client: httpx.Client) -> Self:
67
+ instance = cls(client, entity)
68
68
 
69
- Hco.check_classes(instance._entity.class_, ["JobsRoot"])
70
- instance.create_job_action = CreateJobAction.from_entity_optional(client, instance._entity, "CreateJob")
71
- instance.create_subjob_action = CreateSubJobAction.from_entity_optional(client, instance._entity,
72
- "CreateSubJob")
73
- instance.job_query_action = JobQueryAction.from_entity_optional(client, instance._entity, "CreateJobQuery")
74
- instance.used_tags_link = JobUsedTagsLink.from_entity_optional(
75
- instance._client, instance._entity, Relations.USED_TAGS)
76
- instance.self_link = JobsRootLink.from_entity(instance._client, instance._entity, Relations.SELF)
77
- return instance
69
+ Hco.check_classes(instance._entity.class_, ["JobsRoot"])
70
+ instance.create_job_action = CreateJobAction.from_entity_optional(client, instance._entity, "CreateJob")
71
+ instance.create_subjob_action = CreateSubJobAction.from_entity_optional(client, instance._entity,
72
+ "CreateSubJob")
73
+ instance.job_query_action = JobQueryAction.from_entity_optional(client, instance._entity, "CreateJobQuery")
74
+ instance.used_tags_link = JobUsedTagsLink.from_entity_optional(
75
+ instance._client, instance._entity, Relations.USED_TAGS)
76
+ instance.self_link = JobsRootLink.from_entity(instance._client, instance._entity, Relations.SELF)
77
+
78
+ return instance
78
79
 
79
80
 
80
81
  class JobsRootLink(LinkHco):
81
- def navigate(self) -> JobsRootHco:
82
- return JobsRootHco.from_entity(self._navigate_internal(JobsRootEntity), self._client)
82
+ def navigate(self) -> JobsRootHco:
83
+ return JobsRootHco.from_entity(self._navigate_internal(JobsRootEntity), self._client)
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: openapi.json
3
- # timestamp: 2024-09-24T10:14:32+00:00
3
+ # timestamp: 2024-10-28T09:17:20+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -356,6 +356,14 @@ class SetCommentWorkDataParameters(BaseModel):
356
356
  comment: str | None = Field(None, alias='Comment')
357
357
 
358
358
 
359
+ class SetJobErrorStateParameters(BaseModel):
360
+ model_config = ConfigDict(
361
+ extra='allow',
362
+ populate_by_name=True,
363
+ )
364
+ message: constr(min_length=1) = Field(..., alias='Message')
365
+
366
+
359
367
  class SetJobTagsParameters(BaseModel):
360
368
  model_config = ConfigDict(
361
369
  extra='allow',
@@ -486,6 +494,8 @@ class AdminJobFilterParameter(BaseModel):
486
494
  state: JobStates | None = Field(None, alias='State')
487
495
  show_hidden: bool | None = Field(None, alias='ShowHidden')
488
496
  parent_job_url: str | None = Field(None, alias='ParentJobUrl')
497
+ created_before: AwareDatetime | None = Field(None, alias='CreatedBefore')
498
+ created_after: AwareDatetime | None = Field(None, alias='CreatedAfter')
489
499
  tags_by_and: List[str] | None = Field(None, alias='TagsByAnd')
490
500
  tags_by_or: List[str] | None = Field(None, alias='TagsByOr')
491
501
  user_url: str | None = Field(None, alias='UserUrl')
@@ -611,6 +621,8 @@ class JobFilterParameter(BaseModel):
611
621
  name: str | None = Field(None, alias='Name')
612
622
  show_hidden: bool | None = Field(None, alias='ShowHidden')
613
623
  processing_step_url: str | None = Field(None, alias='ProcessingStepUrl')
624
+ created_before: AwareDatetime | None = Field(None, alias='CreatedBefore')
625
+ created_after: AwareDatetime | None = Field(None, alias='CreatedAfter')
614
626
  tags_by_and: List[str] | None = Field(None, alias='TagsByAnd')
615
627
  tags_by_or: List[str] | None = Field(None, alias='TagsByOr')
616
628
  parent_job_url: str | None = Field(None, alias='ParentJobUrl')
@@ -40,6 +40,7 @@ from pinexq_client.job_management.model import (
40
40
  from pinexq_client.job_management.tool.processing_step import ProcessingStep
41
41
  from pinexq_client.job_management.tool.workdata import WorkData
42
42
 
43
+
43
44
  class Job:
44
45
  """Convenience wrapper for handling JobHcos in the JobManagement-Api.
45
46
 
@@ -615,3 +616,12 @@ class Job:
615
616
 
616
617
  def self_link(self) -> JobLink:
617
618
  return self._job.self_link
619
+
620
+ def set_to_error_state(self) -> Self:
621
+ """Set this job to error state.
622
+
623
+ Returns:
624
+ This `Job` object
625
+ """
626
+ self._job.set_to_error_state_action.execute()
627
+ return self
@@ -125,17 +125,29 @@ class JobGroup:
125
125
  """
126
126
  return [job for job in self._jobs if job.get_state() == JobStates.error]
127
127
 
128
- def remove(self, job_name: str) -> Self:
128
+ def remove(self, jobs: Job | list[Job]) -> Self:
129
129
  """
130
- Removes all jobs from the group whose name matches the provided name
130
+ Removes given job(s) from the group
131
131
 
132
132
  Args:
133
- job_name:
134
- The name of the job(s) to be removed
133
+ jobs:
134
+ The Job instance(s) to be removed
135
135
  Returns:
136
136
  This `JobGroup` object
137
137
  """
138
- self._jobs = [job for job in self._jobs if job.get_name() != job_name]
138
+
139
+ def remove_by_url(job_url: str):
140
+ for existing_job in self._jobs:
141
+ if existing_job.self_link().get_url() == job_url:
142
+ self._jobs.remove(existing_job)
143
+ break
144
+
145
+ if isinstance(jobs, list):
146
+ for job in jobs:
147
+ remove_by_url(str(job.self_link().get_url()))
148
+ else:
149
+ remove_by_url(str(jobs.self_link().get_url()))
150
+
139
151
  return self
140
152
 
141
153
  def clear(self) -> Self:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pinexq-client
3
- Version: 0.4.2.20241009.1
3
+ Version: 0.5.0.20241030.1
4
4
  Summary: A hypermedia-based client for the DataCybernetics PinexQ platform.
5
5
  Author-Email: =?utf-8?q?Sebastian_H=C3=B6fer?= <hoefer@data-cybernetics.com>, Mathias Reichardt <reichardt@data-cybernetics.com>, Jasim Ahmed <ahmed@data-cybernetics.com>, Pratik Poudel <poudel@data-cybernetics.com>
6
6
  Maintainer-Email: Mathias Reichardt <reichardt@data-cybernetics.com>, =?utf-8?q?Sebastian_H=C3=B6fer?= <hoefer@data-cybernetics.com>, Carsten Blank <blank@data-cybernetics.com>
@@ -1,36 +1,36 @@
1
- pinexq_client-0.4.2.20241009.1.dist-info/METADATA,sha256=OwWRTY8LrZ0sTtVPcvKWudbDLVg_25sdw9B8inJczfc,3278
2
- pinexq_client-0.4.2.20241009.1.dist-info/WHEEL,sha256=Vza3XR51HW1KmFP0iIMUVYIvz0uQuKJpIXKYOBGQyFQ,90
3
- pinexq_client-0.4.2.20241009.1.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
4
- pinexq_client-0.4.2.20241009.1.dist-info/licenses/LICENSE,sha256=3oz3tAhM7kOgRukkRe7wmh5T_HihZY77ZtJDJm91ZN8,1072
1
+ pinexq_client-0.5.0.20241030.1.dist-info/METADATA,sha256=KinUo0StjaqqHggN1Wq4WIpxQnqdKUIQPUtjpeQMTBQ,3278
2
+ pinexq_client-0.5.0.20241030.1.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
+ pinexq_client-0.5.0.20241030.1.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
4
+ pinexq_client-0.5.0.20241030.1.dist-info/licenses/LICENSE,sha256=3oz3tAhM7kOgRukkRe7wmh5T_HihZY77ZtJDJm91ZN8,1072
5
5
  pinexq_client/core/__init__.py,sha256=8SVD_PRgJtpUCOtVjdR6fRrv6KPNk7HD6UQrn0FKR04,235
6
6
  pinexq_client/core/base_relations.py,sha256=oIUS58pkbMDdqm-3YOdsenhL1smtzeAk4fp7-U595MY,162
7
7
  pinexq_client/core/enterapi.py,sha256=sL9TmF1L5LaDJnre1l_tiHDUo9vTbZ8cvPSov3Q1UTs,671
8
8
  pinexq_client/core/exceptions.py,sha256=NqB3y1ufjOfG3kv7Rz4ppXqJRAugt2zlgxkto2nIVQU,2228
9
9
  pinexq_client/core/hco/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- pinexq_client/core/hco/action_hco.py,sha256=lctChgDHHwRqv0LU_8r8YRS708n5blYFxVkFNYf8YC8,2219
11
- pinexq_client/core/hco/action_with_parameters_hco.py,sha256=V-8n7-X2oSglQ4fYbLm4YKNcFhIoaT3SNIUVDflI9yY,3161
10
+ pinexq_client/core/hco/action_hco.py,sha256=6bWea-SkFjn52m5sYywkZeNOe74Nxmsvj338jSB6RZo,2338
11
+ pinexq_client/core/hco/action_with_parameters_hco.py,sha256=qvtoqTfDHddxB0ALanWXNDobSpazCmK2_ulTuvax2A4,3280
12
12
  pinexq_client/core/hco/download_link_hco.py,sha256=_ijLtRfzy0qKG_QXpsWBZ8FJfp60o5Lw7QVv4_EpgPY,1335
13
13
  pinexq_client/core/hco/hco_base.py,sha256=NglQuS6p1EimgtIx55G8ngBDGXc4lzyq08jsXzztE1I,3367
14
- pinexq_client/core/hco/link_hco.py,sha256=m-TxPtlBg7bVEcj_fztD84Kwvf5lWpqcAS_MBHdggkc,2063
15
- pinexq_client/core/hco/unavailable.py,sha256=rbIAXEtIjW7G0lQB5xsFSrakDDc_xAnr100sh2VE_Ds,566
14
+ pinexq_client/core/hco/link_hco.py,sha256=LamrK6XyD6Gf_pl1tnNO_aIphPqcklPMjrxx8jx9HVw,2183
15
+ pinexq_client/core/hco/unavailable.py,sha256=CBJN_YnQRPPTwYr-3MIXQIgYXIDLw9ozIM2TNo0uewY,942
16
16
  pinexq_client/core/hco/upload_action_hco.py,sha256=oOGw0Z_nx67CbqJ-QkQJbffdXajBgKmBAfSfFtyq8wk,4690
17
17
  pinexq_client/core/http_headers.py,sha256=tY4h3DKVDMkjw9DLFn57HdEnwR1NAixMF8Yjgy3gjQY,183
18
18
  pinexq_client/core/media_types.py,sha256=qU-Jd92H5HKczWDk51EstFHadO6A_QJL4lLXHRlfgjQ,600
19
19
  pinexq_client/core/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- pinexq_client/core/model/error.py,sha256=FNJrXVTkVnh6oDkHHc3sSZ2wNtEPCZyqgzZT01MG8Tc,390
20
+ pinexq_client/core/model/error.py,sha256=MZHma9zCxcTCUp21KZeD22EXK0xhcrKWDQVTEk7WAn4,437
21
21
  pinexq_client/core/model/sirenmodels.py,sha256=vGRQlhM2cSa2caxQel91Jr48KWqM-vMYX32iaQCzIds,5547
22
22
  pinexq_client/core/polling.py,sha256=Z6VXn-PCGk4XX-4tQWZG59qJyCIS0eIrpPUORQDIGrs,1077
23
- pinexq_client/core/sirenaccess.py,sha256=5GDTolgIlt9rW2g9qG7LerUlmz0BQNKYGp78T2UPrv0,6771
24
- pinexq_client/job_management/__init__.py,sha256=pvdID8cHtpXcjx-PKW9svc9DxMGG58cXyW-mhYEJPQE,164
23
+ pinexq_client/core/sirenaccess.py,sha256=moZQz2ujFsl8_WP_jfl8eM6lOzTHD6CK0dXBD8Wrg2g,6939
24
+ pinexq_client/job_management/__init__.py,sha256=UcBfBCxxj858ePyl9kFQmUGU6YedgBPaXparMI7V7fk,164
25
25
  pinexq_client/job_management/enterjma.py,sha256=Ivl_jVPw_gaLyU5nKbywM-bbVGpn0MoCrZ0DMbJYf3s,1411
26
26
  pinexq_client/job_management/hcos/__init__.py,sha256=vMIdxGHBsVcKYKrVkCzD4a_VaheKSNxCimospFn5N88,396
27
27
  pinexq_client/job_management/hcos/entrypoint_hco.py,sha256=qodjAwO_MtawUuhmaYjhGXHV-uW1k94V9gKRYZRkhn4,2234
28
28
  pinexq_client/job_management/hcos/info_hco.py,sha256=zWjR63SCEO_sUcZ9ha_aIoC_qUzAWLf50Xu4AHddAn8,1328
29
29
  pinexq_client/job_management/hcos/input_dataslot_hco.py,sha256=SDflhyW8kjpcTUfKAXnJxNR-etPzAHfoTqlYUcJZrxs,3442
30
- pinexq_client/job_management/hcos/job_hco.py,sha256=0ZzeBXjwJd3kbe3peIdGgnIHR_cvwSz1_yuO5135g34,7340
30
+ pinexq_client/job_management/hcos/job_hco.py,sha256=CwF0eD07pd88iZPQUb_10iDtotiemy48BJ5exYN5gRc,8649
31
31
  pinexq_client/job_management/hcos/job_query_result_hco.py,sha256=I0G8YIlYDhTahLz8n06L8BywlcsMGNWUEsmEr4Sk0GU,3315
32
32
  pinexq_client/job_management/hcos/job_used_tags_hco.py,sha256=nys6E97NNXATdnvX6KZ46JR9qEb2lnqol9ZvJVEiNpQ,944
33
- pinexq_client/job_management/hcos/jobsroot_hco.py,sha256=aLVlGEl4BG3HboelTu3srTdbQOXPQJWVZrYPHeWe3m4,3594
33
+ pinexq_client/job_management/hcos/jobsroot_hco.py,sha256=P8C5CaIEq_bkh6YgJBuQEp45Cc4fHuU5lYuWNdgtISY,3853
34
34
  pinexq_client/job_management/hcos/output_dataslot_hco.py,sha256=zxpo-fI9eHcp_pMKcf2l-gRoPHX1RzQO53auHMRB_T8,1549
35
35
  pinexq_client/job_management/hcos/processing_step_hco.py,sha256=MykmFssysIc8fIUoPyNOLEGLGQNoC4zFgjIAIjf0v7U,5190
36
36
  pinexq_client/job_management/hcos/processing_step_used_tags_hco.py,sha256=90-2IWlYTcYX62NzmAPnmcUCwMDhmMZyBrNs_G3yigs,1067
@@ -43,11 +43,11 @@ pinexq_client/job_management/hcos/workdata_used_tags_query_result_hco.py,sha256=
43
43
  pinexq_client/job_management/hcos/workdataroot_hco.py,sha256=LdEPW2JJTqAWi-6zj-40lfREhthcDL6nPXQk_nfMtCA,3936
44
44
  pinexq_client/job_management/known_relations.py,sha256=UlOF-sua8SyOPNNKzT_j6JVG8T-aewHIzn7S2ajXBhI,593
45
45
  pinexq_client/job_management/model/__init__.py,sha256=ApHhNfjx4bPuz10sQnyBA2zajYbU7loDTZSKC5H_jBY,34
46
- pinexq_client/job_management/model/open_api_generated.py,sha256=9VQtoenAmAVsRdR9GaQSBqrJIPrWFYkF5DKv8n9Z6Ow,30354
46
+ pinexq_client/job_management/model/open_api_generated.py,sha256=uofaSjihzqg0B9CRtjs8Lz5MzlTwcecleYGT457ZCS0,30864
47
47
  pinexq_client/job_management/model/sirenentities.py,sha256=OInvxHpC6mnnYQjOMM2xAw7uLtvWwj9E2EQSRJe2jDo,3202
48
48
  pinexq_client/job_management/tool/__init__.py,sha256=58CRDcP8ifSx9eA2uyTLEg0_fX3FUuNUogY_lirx9AY,96
49
- pinexq_client/job_management/tool/job.py,sha256=BA1S2NY6D4Cpa3Mmoly0M3qCzCiv6p-MP7_decSlP-0,22209
50
- pinexq_client/job_management/tool/job_group.py,sha256=4zW_SEbQMLVNqu_zLUP57epkypBbRc5gxjPLp_FZgZo,4515
49
+ pinexq_client/job_management/tool/job.py,sha256=aUa03aZ8rYPJA1SPAbCmdYS65G1s2xIPC9kEhzEnw08,22427
50
+ pinexq_client/job_management/tool/job_group.py,sha256=ticUSWw1Pgf1NOX5rqvSvod6nRL0tW7X-waQTgw9bWk,4835
51
51
  pinexq_client/job_management/tool/processing_step.py,sha256=0qq64JOESPFAgpUpmM9hWndh21BnCB95EExd21ZHYOg,9730
52
52
  pinexq_client/job_management/tool/workdata.py,sha256=8DwvzcjefKL-wBuCxy9ziaUC7gTf0TMXAa1WoCmHvZM,4903
53
- pinexq_client-0.4.2.20241009.1.dist-info/RECORD,,
53
+ pinexq_client-0.5.0.20241030.1.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: pdm-backend (2.4.1)
2
+ Generator: pdm-backend (2.4.3)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any