iris-pex-embedded-python 3.7.2b1__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 (120) hide show
  1. iop/__init__.py +280 -13
  2. iop/__main__.py +3 -3
  3. iop/cli/__init__.py +1 -0
  4. iop/cli/formatting.py +45 -0
  5. iop/cli/main.py +504 -0
  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 +835 -8
  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/components/common.py +574 -0
  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/components/settings.py +208 -0
  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.2b1.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 -66
  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/_cli.py +0 -453
  107. iop/_common.py +0 -416
  108. iop/_director.py +0 -333
  109. iop/_dispatch.py +0 -194
  110. iop/_local.py +0 -106
  111. iop/_message.py +0 -45
  112. iop/_remote.py +0 -473
  113. iop/_utils.py +0 -710
  114. iop/cls/IOP/Service/WSGI.cls +0 -310
  115. iop/wsgi/handlers.py +0 -112
  116. iris_pex_embedded_python-3.7.2b1.dist-info/RECORD +0 -94
  117. iris_pex_embedded_python-3.7.2b1.dist-info/entry_points.txt +0 -2
  118. iris_pex_embedded_python-3.7.2b1.dist-info/top_level.txt +0 -2
  119. {iris_pex_embedded_python-3.7.2b1.dist-info → iris_pex_embedded_python-4.0.0.dist-info}/WHEEL +0 -0
  120. {iris_pex_embedded_python-3.7.2b1.dist-info → iris_pex_embedded_python-4.0.0.dist-info}/licenses/LICENSE +0 -0
iop/__init__.py CHANGED
@@ -1,21 +1,107 @@
1
- from iop._business_operation import _BusinessOperation
2
- from iop._business_process import _BusinessProcess
3
- from iop._business_service import _BusinessService
4
- from iop._director import _Director
5
- from iop._inbound_adapter import _InboundAdapter
6
- from iop._message import (
1
+ from iop.components.business_operation import _BusinessOperation
2
+ from iop.components.business_process import _BusinessProcess
3
+ from iop.components.business_service import _BusinessService
4
+ from iop.components.inbound_adapter import _InboundAdapter
5
+ from iop.components.outbound_adapter import _OutboundAdapter
6
+ from iop.components.polling_business_service import _PollingBusinessServiceMixin
7
+ from iop.components.private_session_duplex import _PrivateSessionDuplex
8
+ from iop.components.private_session_process import _PrivateSessionProcess
9
+ from iop.components.settings import Category as Category
10
+ from iop.components.settings import Setting as Setting
11
+ from iop.components.settings import controls as controls
12
+ from iop.components.settings import setting as setting
13
+ from iop.messages.base import (
7
14
  _Message,
8
15
  _PickleMessage,
9
16
  _PydanticMessage,
10
17
  _PydanticPickleMessage,
11
18
  )
12
- from iop._outbound_adapter import _OutboundAdapter
13
- from iop._persistent_message import Field as Field
14
- from iop._persistent_message import Model as Model
15
- from iop._persistent_message import _PersistentMessage
16
- from iop._private_session_duplex import _PrivateSessionDuplex
17
- from iop._private_session_process import _PrivateSessionProcess
18
- from iop._utils import _Utils
19
+ from iop.messages.decorators import handler as handler
20
+ from iop.messages.persistent import Field as Field
21
+ from iop.messages.persistent import Model as Model
22
+ from iop.messages.persistent import _PersistentMessage
23
+ from iop.migration.utils import _Utils
24
+ from iop.migration.utils import bind_component as bind_component
25
+ from iop.migration.utils import list_bindings as list_bindings
26
+ from iop.migration.utils import register_component as register_component
27
+ from iop.migration.utils import unbind_component as unbind_component
28
+ from iop.migration.utils import unregister_component as unregister_component
29
+ from iop.production import ComponentItem as ComponentItem
30
+ from iop.production import ComponentRef as ComponentRef
31
+ from iop.production import OperationItem as OperationItem
32
+ from iop.production import ProcessItem as ProcessItem
33
+ from iop.production import Production as Production
34
+ from iop.production import ProductionApplyResult as ProductionApplyResult
35
+ from iop.production import ProductionChangePlan as ProductionChangePlan
36
+ from iop.production import ProductionDiff as ProductionDiff
37
+ from iop.production import ProductionDiffEntry as ProductionDiffEntry
38
+ from iop.production import ProductionGraph as ProductionGraph
39
+ from iop.production import ProductionPlanOperation as ProductionPlanOperation
40
+ from iop.production import ProductionValidationError as ProductionValidationError
41
+ from iop.production import ProductionValidationIssue as ProductionValidationIssue
42
+ from iop.production import ProductionValidationReport as ProductionValidationReport
43
+ from iop.production import ProductionValidationWarning as ProductionValidationWarning
44
+ from iop.production import ProductionVerifyResult as ProductionVerifyResult
45
+ from iop.production import Route as Route
46
+ from iop.production import ServiceItem as ServiceItem
47
+ from iop.production import TargetSetting as TargetSetting
48
+ from iop.production import TargetSettingRef as TargetSettingRef
49
+ from iop.production import target as target
50
+ from iop.runtime.director import _Director
51
+ from iop.runtime.protocol import DirectorProtocol as DirectorProtocol
52
+
53
+ __all__ = [
54
+ "BusinessOperation",
55
+ "BusinessProcess",
56
+ "BusinessService",
57
+ "Category",
58
+ "ComponentItem",
59
+ "ComponentRef",
60
+ "Director",
61
+ "DirectorProtocol",
62
+ "DuplexOperation",
63
+ "DuplexProcess",
64
+ "DuplexService",
65
+ "Field",
66
+ "InboundAdapter",
67
+ "Message",
68
+ "Model",
69
+ "OperationItem",
70
+ "OutboundAdapter",
71
+ "PersistentMessage",
72
+ "PickleMessage",
73
+ "PollingBusinessService",
74
+ "ProcessItem",
75
+ "Production",
76
+ "ProductionApplyResult",
77
+ "ProductionChangePlan",
78
+ "ProductionDiff",
79
+ "ProductionDiffEntry",
80
+ "ProductionGraph",
81
+ "ProductionPlanOperation",
82
+ "ProductionVerifyResult",
83
+ "ProductionValidationError",
84
+ "ProductionValidationIssue",
85
+ "ProductionValidationReport",
86
+ "ProductionValidationWarning",
87
+ "PydanticMessage",
88
+ "PydanticPickleMessage",
89
+ "Route",
90
+ "ServiceItem",
91
+ "Setting",
92
+ "TargetSetting",
93
+ "TargetSettingRef",
94
+ "Utils",
95
+ "bind_component",
96
+ "controls",
97
+ "handler",
98
+ "list_bindings",
99
+ "register_component",
100
+ "setting",
101
+ "target",
102
+ "unbind_component",
103
+ "unregister_component",
104
+ ]
19
105
 
20
106
 
21
107
  class Utils(_Utils):
@@ -31,14 +117,139 @@ class OutboundAdapter(_OutboundAdapter):
31
117
 
32
118
 
33
119
  class BusinessService(_BusinessService):
120
+ """Purpose:
121
+ Inbound production entry point for messages entering an IoP production.
122
+
123
+ Use when:
124
+ External data, an adapter, or custom code must send a message into the
125
+ production graph.
126
+
127
+ Lifecycle:
128
+ IRIS calls on_process_input(); the default implementation delegates to
129
+ on_process_input(request).
130
+
131
+ Best practices:
132
+ Declare outbound routes with target() and wire them in a Production
133
+ graph. Use PollingBusinessService for scheduled Python polling.
134
+
135
+ Common mistakes:
136
+ Do not put startup work in __init__(); use on_init(). Do not instantiate
137
+ downstream components directly.
138
+
139
+ Minimal example:
140
+ class FileIn(BusinessService):
141
+ Output = target()
142
+
143
+ def on_process_input(self, request):
144
+ self.send_request_async(self.Output, request)
145
+
146
+ Related:
147
+ docs/cookbooks/add-polling-service.md,
148
+ docs/cookbooks/hl7v2-native-input.md
149
+ """
150
+
151
+ pass
152
+
153
+
154
+ class PollingBusinessService(_PollingBusinessServiceMixin, BusinessService):
155
+ """Purpose:
156
+ Scheduled Python service called by the default IRIS inbound adapter.
157
+
158
+ Use when:
159
+ A production must poll an API, directory, queue, database, or other
160
+ source from Python.
161
+
162
+ Lifecycle:
163
+ IRIS calls on_process_input(); the mixin delegates that call to
164
+ on_poll().
165
+
166
+ Best practices:
167
+ Put one polling cycle in on_poll(). Declare outbound routes with
168
+ target() and send messages with send_request_async(...).
169
+
170
+ Common mistakes:
171
+ Do not block forever inside on_poll(). Do not put startup work in
172
+ __init__(); use on_init().
173
+
174
+ Minimal example:
175
+ class ApiPoller(PollingBusinessService):
176
+ Output = target()
177
+
178
+ def on_poll(self):
179
+ self.send_request_async(self.Output, MyRequest())
180
+
181
+ Related:
182
+ docs/cookbooks/add-polling-service.md
183
+ """
184
+
34
185
  pass
35
186
 
36
187
 
37
188
  class BusinessOperation(_BusinessOperation):
189
+ """Purpose:
190
+ Outbound side-effect boundary for production messages.
191
+
192
+ Use when:
193
+ A production must call an external API, write a file, update a database,
194
+ submit FHIR resources, or perform another side effect.
195
+
196
+ Lifecycle:
197
+ IRIS calls on_message(request). IoP can dispatch to @handler methods,
198
+ typed one-argument methods, or the on_message fallback.
199
+
200
+ Best practices:
201
+ Keep external-system code here. Return a response message when callers
202
+ expect synchronous results.
203
+
204
+ Common mistakes:
205
+ Do not put routing orchestration in an operation when a BusinessProcess
206
+ should own the decision.
207
+
208
+ Minimal example:
209
+ class SubmitOrder(BusinessOperation):
210
+ def on_message(self, request):
211
+ return SubmitResult(ok=True)
212
+
213
+ Related:
214
+ docs/cookbooks/add-business-operation.md
215
+ """
216
+
38
217
  pass
39
218
 
40
219
 
41
220
  class BusinessProcess(_BusinessProcess):
221
+ """Purpose:
222
+ Routing, orchestration, decision, and transformation component.
223
+
224
+ Use when:
225
+ A production needs branching, enrichment, transformation, fan-out,
226
+ request/reply orchestration, or response aggregation.
227
+
228
+ Lifecycle:
229
+ IRIS calls on_message(request). For async requests, IRIS can later call
230
+ on_response(...) and on_complete(...).
231
+
232
+ Best practices:
233
+ Declare outbound routes with target() and wire them with
234
+ Production.connect(...). Use @handler(MessageType) or typed methods for
235
+ multiple message types.
236
+
237
+ Common mistakes:
238
+ Do not hard-code target component names when target() can expose a
239
+ configurable route.
240
+
241
+ Minimal example:
242
+ class Router(BusinessProcess):
243
+ Accepted = target()
244
+
245
+ def on_message(self, request):
246
+ return self.send_request_sync(self.Accepted, request)
247
+
248
+ Related:
249
+ docs/cookbooks/add-business-process.md,
250
+ docs/cookbooks/production-settings-and-targets.md
251
+ """
252
+
42
253
  pass
43
254
 
44
255
 
@@ -55,22 +266,78 @@ class DuplexProcess(_PrivateSessionProcess):
55
266
 
56
267
 
57
268
  class Message(_Message):
269
+ """Purpose:
270
+ Python-only JSON-serialized message contract.
271
+
272
+ Use when:
273
+ IoP components exchange structured Python data and IRIS does not need a
274
+ native persistent message body.
275
+
276
+ Lifecycle:
277
+ IoP serializes dataclass fields into IOP.Message and restores the Python
278
+ class on receipt.
279
+
280
+ Best practices:
281
+ Decorate subclasses with @dataclass. Use PydanticMessage when runtime
282
+ validation is more important.
283
+
284
+ Common mistakes:
285
+ Do not use Message without @dataclass. Do not register Message classes
286
+ in CLASSES; use PersistentMessage for native IRIS message bodies.
287
+
288
+ Minimal example:
289
+ @dataclass
290
+ class OrderRequest(Message):
291
+ order_id: str
292
+
293
+ Related:
294
+ docs/cookbooks/add-business-process.md,
295
+ docs/cookbooks/add-business-operation.md,
296
+ docs/getting-started/register-component.md
297
+ """
298
+
58
299
  pass
59
300
 
60
301
 
61
302
  class PickleMessage(_PickleMessage):
303
+ """Python-only pickle-serialized message contract.
304
+
305
+ Prefer Message or PydanticMessage for new app code unless JSON-compatible
306
+ fields cannot represent the payload.
307
+ """
308
+
62
309
  pass
63
310
 
64
311
 
65
312
  class PydanticMessage(_PydanticMessage):
313
+ """Python-only Pydantic message contract with validation.
314
+
315
+ Use for app messages that benefit from Pydantic validation. Do not decorate
316
+ PydanticMessage classes with @dataclass and do not put these classes in
317
+ CLASSES; see docs/getting-started/register-component.md.
318
+ """
319
+
66
320
  pass
67
321
 
68
322
 
69
323
  class PydanticPickleMessage(_PydanticPickleMessage):
324
+ """Pydantic message contract serialized through pickle.
325
+
326
+ Prefer PydanticMessage unless the payload must preserve Python-only object
327
+ shapes that JSON serialization cannot represent.
328
+ """
329
+
70
330
  pass
71
331
 
72
332
 
73
333
  class PersistentMessage(_PersistentMessage):
334
+ """Native persistent IRIS message body contract.
335
+
336
+ Use when IRIS needs a generated message class or persistent message body.
337
+ Prefer Message or PydanticMessage for Python-only routing. See
338
+ docs/getting-started/register-component.md and docs/settings.md.
339
+ """
340
+
74
341
  _iop_persistent_message_abstract = True
75
342
 
76
343
 
iop/__main__.py CHANGED
@@ -1,5 +1,5 @@
1
- # main entry is _cli.main()
1
+ # main entry is cli.main()
2
2
  if __name__ == "__main__":
3
- import iop._cli as _cli
3
+ from iop.cli.main import main
4
4
 
5
- _cli.main()
5
+ main()
iop/cli/__init__.py ADDED
@@ -0,0 +1 @@
1
+ from .main import main as main
iop/cli/formatting.py ADDED
@@ -0,0 +1,45 @@
1
+ from __future__ import annotations
2
+
3
+ import dataclasses
4
+ import json
5
+ from typing import Any
6
+
7
+
8
+ def format_test_response(response: Any) -> str:
9
+ """Pretty-print any test_component() return value."""
10
+ if isinstance(response, dict):
11
+ parts = []
12
+ if response.get("error"):
13
+ return f"Error: {response['error']}"
14
+ if response.get("classname"):
15
+ parts.append(f"classname: {response['classname']}")
16
+ body = response.get("body", "")
17
+ if body:
18
+ try:
19
+ parsed = json.loads(body)
20
+ parts.append("body:\n" + json.dumps(parsed, indent=4))
21
+ except (json.JSONDecodeError, TypeError):
22
+ parts.append(f"body: {body}")
23
+ if response.get("truncated"):
24
+ parts.append("(response body was truncated)")
25
+ return "\n".join(parts) if parts else str(response)
26
+
27
+ if isinstance(response, str):
28
+ if " : " in response:
29
+ classname_part, _, body_part = response.partition(" : ")
30
+ try:
31
+ parsed = json.loads(body_part)
32
+ return (
33
+ f"classname: {classname_part.strip()}\n"
34
+ f"body:\n{json.dumps(parsed, indent=4)}"
35
+ )
36
+ except (json.JSONDecodeError, TypeError):
37
+ pass
38
+ try:
39
+ return json.dumps(json.loads(response), indent=4)
40
+ except (json.JSONDecodeError, TypeError):
41
+ return response
42
+
43
+ if dataclasses.is_dataclass(response):
44
+ return json.dumps(dataclasses.asdict(response), indent=4)
45
+ return str(response)