iris-pex-embedded-python 3.7.2b2__py3-none-any.whl → 4.0.0__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.
Files changed (119) hide show
  1. iop/__init__.py +276 -18
  2. iop/__main__.py +3 -3
  3. iop/cli/__init__.py +1 -0
  4. iop/cli/formatting.py +45 -0
  5. iop/{_cli.py → cli/main.py} +238 -216
  6. iop/cli/parser.py +165 -0
  7. iop/cli/types.py +73 -0
  8. iop/cls/IOP/Common.cls +11 -2
  9. iop/cls/IOP/PrivateSession/Duplex.cls +1 -1
  10. iop/cls/IOP/Service/Remote/Rest/v1.cls +152 -5
  11. iop/cls/IOP/Utils.cls +814 -7
  12. iop/cls/IOP/Wrapper.cls +1 -1
  13. iop/components/__init__.py +16 -0
  14. iop/{_async_request.py → components/async_request.py} +7 -7
  15. iop/components/business_host.py +363 -0
  16. iop/components/business_operation.py +84 -0
  17. iop/{_business_process.py → components/business_process.py} +145 -125
  18. iop/components/business_service.py +106 -0
  19. iop/{_common.py → components/common.py} +160 -164
  20. iop/{_debugpy.py → components/debugpy.py} +11 -11
  21. iop/{_generator_request.py → components/generator_request.py} +4 -4
  22. iop/{_inbound_adapter.py → components/inbound_adapter.py} +10 -18
  23. iop/{_log_manager.py → components/log_manager.py} +1 -1
  24. iop/{_outbound_adapter.py → components/outbound_adapter.py} +1 -1
  25. iop/components/polling_business_service.py +48 -0
  26. iop/{_private_session_duplex.py → components/private_session_duplex.py} +7 -9
  27. iop/{_private_session_process.py → components/private_session_process.py} +2 -2
  28. iop/{_settings.py → components/settings.py} +23 -3
  29. iop/messages/__init__.py +7 -0
  30. iop/messages/base.py +61 -0
  31. iop/{_decorators.py → messages/decorators.py} +8 -2
  32. iop/messages/dispatch.py +351 -0
  33. iop/{_persistent_message.py → messages/persistent.py} +24 -19
  34. iop/{_serialization.py → messages/serialization.py} +34 -21
  35. iop/{_message_validator.py → messages/validation.py} +15 -13
  36. iop/migration/__init__.py +1 -0
  37. iop/migration/io.py +61 -0
  38. iop/migration/manifest.py +534 -0
  39. iop/migration/plans.py +80 -0
  40. iop/migration/utils.py +1126 -0
  41. iop/production/__init__.py +55 -0
  42. iop/production/actions.py +525 -0
  43. iop/production/common.py +103 -0
  44. iop/production/component.py +234 -0
  45. iop/production/declarations.py +190 -0
  46. iop/production/declarative.py +214 -0
  47. iop/production/diff.py +327 -0
  48. iop/production/import_.py +296 -0
  49. iop/production/inspection.py +92 -0
  50. iop/production/model.py +1143 -0
  51. iop/production/planning.py +678 -0
  52. iop/production/reconstruction.py +341 -0
  53. iop/production/rendering.py +610 -0
  54. iop/production/runtime.py +91 -0
  55. iop/production/source_inference.py +729 -0
  56. iop/production/types.py +546 -0
  57. iop/production/validation.py +452 -0
  58. iop/runtime/__init__.py +1 -0
  59. iop/runtime/director.py +415 -0
  60. iop/runtime/environment.py +59 -0
  61. iop/{_iris.py → runtime/iris.py} +2 -2
  62. iop/runtime/local.py +145 -0
  63. iop/{_director_protocol.py → runtime/protocol.py} +25 -8
  64. iop/runtime/remote/__init__.py +12 -0
  65. iop/runtime/remote/client.py +90 -0
  66. iop/runtime/remote/director.py +283 -0
  67. iop/runtime/remote/migration.py +57 -0
  68. iop/runtime/remote/settings.py +69 -0
  69. iop/runtime/remote/setup.py +72 -0
  70. {iris_pex_embedded_python-3.7.2b2.dist-info → iris_pex_embedded_python-4.0.0.dist-info}/METADATA +11 -2
  71. iris_pex_embedded_python-4.0.0.dist-info/RECORD +99 -0
  72. iris_pex_embedded_python-4.0.0.dist-info/entry_points.txt +2 -0
  73. iris_pex_embedded_python-4.0.0.dist-info/top_level.txt +1 -0
  74. grongier/__init__.py +0 -0
  75. grongier/cls/Grongier/PEX/BusinessOperation.cls +0 -8
  76. grongier/cls/Grongier/PEX/BusinessProcess.cls +0 -13
  77. grongier/cls/Grongier/PEX/BusinessService.cls +0 -8
  78. grongier/cls/Grongier/PEX/Common.cls +0 -10
  79. grongier/cls/Grongier/PEX/Director.cls +0 -10
  80. grongier/cls/Grongier/PEX/Duplex/Operation.cls +0 -4
  81. grongier/cls/Grongier/PEX/Duplex/Process.cls +0 -13
  82. grongier/cls/Grongier/PEX/Duplex/Service.cls +0 -4
  83. grongier/cls/Grongier/PEX/InboundAdapter.cls +0 -8
  84. grongier/cls/Grongier/PEX/Message.cls +0 -13
  85. grongier/cls/Grongier/PEX/OutboundAdapter.cls +0 -8
  86. grongier/cls/Grongier/PEX/PickleMessage.cls +0 -13
  87. grongier/cls/Grongier/PEX/PrivateSession/Duplex.cls +0 -8
  88. grongier/cls/Grongier/PEX/PrivateSession/Message/Ack.cls +0 -14
  89. grongier/cls/Grongier/PEX/PrivateSession/Message/Poll.cls +0 -14
  90. grongier/cls/Grongier/PEX/PrivateSession/Message/Start.cls +0 -14
  91. grongier/cls/Grongier/PEX/PrivateSession/Message/Stop.cls +0 -14
  92. grongier/cls/Grongier/PEX/Test.cls +0 -10
  93. grongier/cls/Grongier/PEX/Utils.cls +0 -10
  94. grongier/cls/Grongier/Service/WSGI.cls +0 -4
  95. grongier/pex/__init__.py +0 -75
  96. grongier/pex/__main__.py +0 -4
  97. grongier/pex/_business_host.py +0 -1
  98. grongier/pex/_cli.py +0 -4
  99. grongier/pex/_common.py +0 -1
  100. grongier/pex/_director.py +0 -1
  101. grongier/pex/_utils.py +0 -1
  102. grongier/pex/wsgi/handlers.py +0 -104
  103. iop/_business_host.py +0 -322
  104. iop/_business_operation.py +0 -77
  105. iop/_business_service.py +0 -67
  106. iop/_director.py +0 -333
  107. iop/_dispatch.py +0 -194
  108. iop/_local.py +0 -106
  109. iop/_message.py +0 -45
  110. iop/_polling_business_service.py +0 -6
  111. iop/_remote.py +0 -473
  112. iop/_utils.py +0 -912
  113. iop/cls/IOP/Service/WSGI.cls +0 -310
  114. iop/wsgi/handlers.py +0 -112
  115. iris_pex_embedded_python-3.7.2b2.dist-info/RECORD +0 -96
  116. iris_pex_embedded_python-3.7.2b2.dist-info/entry_points.txt +0 -2
  117. iris_pex_embedded_python-3.7.2b2.dist-info/top_level.txt +0 -2
  118. {iris_pex_embedded_python-3.7.2b2.dist-info → iris_pex_embedded_python-4.0.0.dist-info}/WHEEL +0 -0
  119. {iris_pex_embedded_python-3.7.2b2.dist-info → iris_pex_embedded_python-4.0.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,8 +1,13 @@
1
- from typing import Any, List, Optional, Union
1
+ from typing import Any
2
2
 
3
- from ._business_host import _BusinessHost
4
- from ._decorators import input_deserializer, input_serializer_param, output_serializer
5
- from ._dispatch import create_dispatch, dispach_message
3
+ from ..messages.decorators import (
4
+ input_deserializer,
5
+ input_serializer_param,
6
+ output_serializer,
7
+ )
8
+ from ..messages.dispatch import create_dispatch, dispatch_message
9
+ from ..production import TargetSettingRef, resolve_target
10
+ from .business_host import _BusinessHost
6
11
 
7
12
 
8
13
  class _BusinessProcess(_BusinessHost):
@@ -12,19 +17,38 @@ class _BusinessProcess(_BusinessHost):
12
17
  It can modify messages, transform formats, and route based on content.
13
18
  """
14
19
 
15
- DISPATCH: List[tuple] = []
16
- PERSISTENT_PROPERTY_LIST: Optional[List[str]] = None
17
-
18
- def on_message(self, request: Any) -> Any:
19
- """Handle incoming messages.
20
-
21
- Args:
22
- request: The incoming message
23
-
24
- Returns:
25
- Response message
26
- """
27
- return self.on_request(request)
20
+ DISPATCH: list[tuple] = []
21
+ PERSISTENT_PROPERTY_LIST: list[str] | None = None
22
+
23
+ def on_message(self, request: Any) -> Any:
24
+ """Purpose:
25
+ Handle an incoming message sent to a BusinessProcess.
26
+
27
+ Use when:
28
+ The process owns routing, orchestration, transformation, or
29
+ decisions for a request.
30
+
31
+ Lifecycle:
32
+ IRIS invokes this hook for process requests unless dispatch routes
33
+ the message to a @handler or typed one-argument method first. The
34
+ default implementation delegates to on_request(request).
35
+
36
+ Best practices:
37
+ Declare outbound routes with target() and call
38
+ send_request_sync(...) or send_request_async(...).
39
+
40
+ Common mistakes:
41
+ Do not hide routing in raw strings when target() can make routes
42
+ configurable in the production graph.
43
+
44
+ Minimal example:
45
+ def on_message(self, request):
46
+ return self.send_request_sync(self.Output, request)
47
+
48
+ Related:
49
+ docs/cookbooks/add-business-process.md
50
+ """
51
+ return self.on_request(request)
28
52
 
29
53
  def on_request(self, request: Any) -> Any:
30
54
  """Process initial requests sent to this component.
@@ -35,43 +59,70 @@ class _BusinessProcess(_BusinessHost):
35
59
  Returns:
36
60
  Response message
37
61
  """
38
- return self.OnRequest(request)
62
+ return None
39
63
 
40
- def on_response(
64
+ def on_response(
41
65
  self,
42
66
  request: Any,
43
67
  response: Any,
44
68
  call_request: Any,
45
69
  call_response: Any,
46
70
  completion_key: str,
47
- ) -> Any:
48
- """Handle responses to messages sent by this component.
49
-
50
- Args:
51
- request: The initial request message
52
- response: The response message
53
- call_request: The request sent to the target
54
- call_response: The incoming response
55
- completion_key: The completion key specified in the outgoing SendAsync() method
56
-
57
- Returns:
58
- Response message
59
- """
60
- return self.OnResponse(
61
- request, response, call_request, call_response, completion_key
62
- )
63
-
64
- def on_complete(self, request: Any, response: Any) -> Any:
65
- """Called after all responses to requests sent by this component have been handled.
66
-
67
- Args:
68
- request: The initial request message
69
- response: The response message
70
-
71
- Returns:
72
- Response message
73
- """
74
- return self.OnComplete(request, response)
71
+ ) -> Any:
72
+ """Purpose:
73
+ Handle one async response received by a BusinessProcess.
74
+
75
+ Use when:
76
+ The process sends async requests and needs to merge, inspect, or
77
+ transform each returned response.
78
+
79
+ Lifecycle:
80
+ IRIS calls on_response(...) after an async target response arrives.
81
+ on_complete(...) can run after all expected responses complete.
82
+
83
+ Best practices:
84
+ Use completion_key to identify which async call returned. Return
85
+ the accumulated or transformed response state.
86
+
87
+ Common mistakes:
88
+ Do not assume responses arrive in request order.
89
+
90
+ Minimal example:
91
+ def on_response(self, request, response, call_request, call_response, completion_key):
92
+ return call_response
93
+
94
+ Related:
95
+ docs/cookbooks/add-business-process.md
96
+ """
97
+ return response
98
+
99
+ def on_complete(self, request: Any, response: Any) -> Any:
100
+ """Purpose:
101
+ Finish async request orchestration for a BusinessProcess.
102
+
103
+ Use when:
104
+ The process must return or finalize an aggregate response after
105
+ async sends, timers, or response handling.
106
+
107
+ Lifecycle:
108
+ IRIS calls on_complete(request, response) after expected async
109
+ responses have been handled or the completion path is reached.
110
+
111
+ Best practices:
112
+ Return the final response message expected by the original caller.
113
+
114
+ Common mistakes:
115
+ Do not put per-response logic here; use on_response(...) for each
116
+ individual async response.
117
+
118
+ Minimal example:
119
+ def on_complete(self, request, response):
120
+ return response
121
+
122
+ Related:
123
+ docs/cookbooks/add-business-process.md
124
+ """
125
+ return response
75
126
 
76
127
  @input_serializer_param(0, "response")
77
128
  def reply(self, response: Any) -> None:
@@ -83,37 +134,52 @@ class _BusinessProcess(_BusinessHost):
83
134
  return self.iris_handle.dispatchReply(response)
84
135
 
85
136
  @input_serializer_param(1, "request")
86
- def send_request_async(
87
- self,
88
- target: str,
89
- request: Any,
90
- description: Optional[str] = None,
91
- completion_key: Optional[str] = None,
137
+ def send_request_async(
138
+ self,
139
+ target: str | TargetSettingRef,
140
+ request: Any,
141
+ description: str | None = None,
142
+ completion_key: str | None = None,
92
143
  response_required: bool = True,
93
- ) -> None:
94
- """Send the specified message to the target business process or business operation asynchronously.
95
-
96
- Args:
97
- target: The name of the business process or operation to receive the request
98
- request: The message to send to the target
99
- description: An optional description property in the message header
100
- completion_key: A string that will be returned with the response if the maximum time is exceeded
101
- response_required: Whether a response is required
102
-
103
- Raises:
104
- TypeError: If request is not of type Message or IRISObject
105
- """
144
+ ) -> None:
145
+ """Purpose:
146
+ Send a message asynchronously from a BusinessProcess.
147
+
148
+ Use when:
149
+ The process should continue without blocking for a target response,
150
+ or when responses will be handled later by on_response(...).
151
+
152
+ Lifecycle:
153
+ IoP serializes request before dispatching to IRIS. IRIS can call
154
+ on_response(...) and on_complete(...) when response_required is true.
155
+
156
+ Best practices:
157
+ Pass a target() attribute such as self.Output. Use completion_key
158
+ for fan-out or multiple async calls.
159
+
160
+ Common mistakes:
161
+ Do not pass an unresolved component instance or a hard-coded route
162
+ when the route should be configurable.
163
+
164
+ Minimal example:
165
+ self.send_request_async(self.Output, request, completion_key="out")
166
+
167
+ Related:
168
+ docs/cookbooks/add-business-process.md,
169
+ docs/cookbooks/production-settings-and-targets.md
170
+ """
106
171
  # Convert boolean to int for Iris API
107
172
  if response_required:
108
173
  response_required = 1 # type: ignore
109
- else:
110
- response_required = 0 # type: ignore
111
- return self.iris_handle.dispatchSendRequestAsync(
112
- target, request, response_required, completion_key, description
113
- )
174
+ else:
175
+ response_required = 0 # type: ignore
176
+ target = resolve_target(target)
177
+ return self.iris_handle.dispatchSendRequestAsync(
178
+ target, request, response_required, completion_key, description
179
+ )
114
180
 
115
181
  def set_timer(
116
- self, timeout: Union[int, str], completion_key: Optional[str] = None
182
+ self, timeout: int | str, completion_key: str | None = None
117
183
  ) -> None:
118
184
  """Specify the maximum time the business process will wait for responses.
119
185
 
@@ -161,11 +227,12 @@ class _BusinessProcess(_BusinessHost):
161
227
  self._save_persistent_properties(host_object)
162
228
  return
163
229
 
164
- def _dispatch_on_init(self, host_object: Any) -> None:
165
- """For internal use only."""
166
- self._restore_persistent_properties(host_object)
167
- create_dispatch(self)
168
- self.on_init()
230
+ def _dispatch_on_init(self, host_object: Any) -> None:
231
+ """For internal use only."""
232
+ self._log_custom_init_warning()
233
+ self._restore_persistent_properties(host_object)
234
+ create_dispatch(self)
235
+ self.on_init()
169
236
  self._save_persistent_properties(host_object)
170
237
  return
171
238
 
@@ -181,7 +248,7 @@ class _BusinessProcess(_BusinessHost):
181
248
  def _dispatch_on_request(self, host_object: Any, request: Any) -> Any:
182
249
  """For internal use only."""
183
250
  self._restore_persistent_properties(host_object)
184
- return_object = dispach_message(self, request)
251
+ return_object = dispatch_message(self, request)
185
252
  self._save_persistent_properties(host_object)
186
253
  return return_object
187
254
 
@@ -215,50 +282,3 @@ class _BusinessProcess(_BusinessHost):
215
282
  self._save_persistent_properties(host_object)
216
283
  return return_object
217
284
 
218
- def OnRequest(self, request: Any) -> Any:
219
- """
220
- DEPRECATED: Use on_request.
221
-
222
- Args:
223
- request: The incoming request message
224
-
225
- Returns:
226
- Response message
227
- """
228
- return
229
-
230
- def OnResponse(
231
- self,
232
- request: Any,
233
- response: Any,
234
- call_request: Any,
235
- call_response: Any,
236
- completion_key: str,
237
- ) -> Any:
238
- """
239
- DEPRECATED: Use on_response.
240
-
241
- Args:
242
- request: The initial request message
243
- response: The response message
244
- call_request: The request sent to the target
245
- call_response: The incoming response
246
- completion_key: The completion key specified in the outgoing SendAsync() method
247
-
248
- Returns:
249
- Response message
250
- """
251
- return response
252
-
253
- def OnComplete(self, request: Any, response: Any) -> Any:
254
- """
255
- DEPRECATED: Use on_complete.
256
-
257
- Args:
258
- request: The initial request message
259
- response: The response message
260
-
261
- Returns:
262
- Response message
263
- """
264
- return response
@@ -0,0 +1,106 @@
1
+ import importlib
2
+ import warnings
3
+ from inspect import signature
4
+
5
+ from ..messages.decorators import input_deserializer, output_serializer
6
+ from .business_host import _BusinessHost
7
+
8
+
9
+ def _accepts_process_input_argument(method) -> bool:
10
+ try:
11
+ return len(signature(method).parameters) > 0
12
+ except (TypeError, ValueError):
13
+ return True
14
+
15
+
16
+ def _call_process_input(method, request):
17
+ if _accepts_process_input_argument(method):
18
+ return method(request)
19
+ return method()
20
+
21
+
22
+ class _BusinessService(_BusinessHost):
23
+ """This class is responsible for receiving the data from external system and sending it to business processes or business operations in the production.
24
+ The business service can use an adapter to access the external system, which is specified in the InboundAdapter property.
25
+ There are three ways of implementing a business service:
26
+ 1) Polling business service with an adapter - The production framework at regular intervals calls the adapter's task method,
27
+ which sends incoming data to the business service process input method.
28
+ 2) Polling business service that uses the default adapter - In this case, the framework calls the default adapter's OnTask method with no data.
29
+ The on_process_input() method then performs the role of the adapter and is responsible for accessing the external system and receiving the data.
30
+ 3) Nonpolling business service - The production framework does not initiate the business service. Instead custom code in either a long-running process
31
+ or one that is started at regular intervals initiates the business service through the Director API.
32
+ """
33
+
34
+ Adapter = adapter = None
35
+ _wait_for_next_call_interval = False
36
+
37
+ def _dispatch_on_init(self, host_object) -> None:
38
+ """For internal use only."""
39
+ self._log_custom_init_warning()
40
+ self.on_init()
41
+
42
+ return
43
+
44
+ def on_message(self, request=None):
45
+ """Purpose:
46
+ Handle a message received by a BusinessService.
47
+
48
+ Use when:
49
+ A service receives data from an adapter, Director API call, or
50
+ custom entry point and should send work into the production graph.
51
+
52
+ Lifecycle:
53
+ The default on_process_input(message_input) implementation delegates
54
+ to on_message(message_input).
55
+
56
+ Best practices:
57
+ Validate or normalize inbound data, then send a Message to a target
58
+ declared with target().
59
+
60
+ Common mistakes:
61
+ Do not call downstream component methods directly. Use
62
+ send_request_async(...) or send_request_sync(...).
63
+
64
+ Minimal example:
65
+ def on_message(self, request):
66
+ self.send_request_async(self.Output, request)
67
+
68
+ Related:
69
+ docs/cookbooks/add-polling-service.md,
70
+ docs/cookbooks/hl7v2-native-input.md
71
+ """
72
+ warnings.warn(
73
+ f"{self.__class__.__name__} did not override on_message() or "
74
+ "on_process_input(); the incoming service message was ignored. "
75
+ "This default no-op handler will raise NotImplementedError in v5.0.",
76
+ RuntimeWarning,
77
+ stacklevel=2,
78
+ )
79
+ return None
80
+
81
+ def on_process_input(self, message_input=None):
82
+ """Receives the message from the inbond adapter via the PRocessInput method and is responsible for forwarding it to target business processes or operations.
83
+ If the business service does not specify an adapter, then the default adapter calls this method with no message
84
+ and the business service is responsible for receiving the data from the external system and validating it.
85
+
86
+ Parameters:
87
+ message_input: an instance of IRISObject or subclass of Message containing the data that the inbound adapter passes in.
88
+ The message can have any structure agreed upon by the inbound adapter and the business service.
89
+ """
90
+ return self.on_message(message_input)
91
+
92
+ def _set_iris_handles(self, handle_current, handle_partner):
93
+ """For internal use only."""
94
+ self.iris_handle = handle_current
95
+ if type(handle_partner).__module__.find("iris") == 0:
96
+ if handle_partner._IsA("IOP.InboundAdapter"):
97
+ module = importlib.import_module(handle_partner.GetModule())
98
+ handle_partner = getattr(module, handle_partner.GetClassname())()
99
+ self.Adapter = self.adapter = handle_partner
100
+ return
101
+
102
+ @input_deserializer
103
+ @output_serializer
104
+ def _dispatch_on_process_input(self, request):
105
+ """For internal use only."""
106
+ return _call_process_input(self.on_process_input, request)