iris-pex-embedded-python 4.0.0b13__py3-none-any.whl → 4.0.0b15__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.
- iop/__init__.py +137 -24
- iop/components/business_host.py +43 -26
- iop/components/business_operation.py +25 -10
- iop/components/business_process.py +109 -47
- iop/components/business_service.py +25 -4
- iop/components/common.py +30 -4
- iop/components/polling_business_service.py +23 -3
- iop/messages/decorators.py +4 -0
- iop/messages/dispatch.py +19 -0
- iop/messages/validation.py +12 -10
- iop/production/model.py +29 -9
- iop/production/types.py +26 -4
- {iris_pex_embedded_python-4.0.0b13.dist-info → iris_pex_embedded_python-4.0.0b15.dist-info}/METADATA +1 -1
- {iris_pex_embedded_python-4.0.0b13.dist-info → iris_pex_embedded_python-4.0.0b15.dist-info}/RECORD +18 -18
- {iris_pex_embedded_python-4.0.0b13.dist-info → iris_pex_embedded_python-4.0.0b15.dist-info}/WHEEL +0 -0
- {iris_pex_embedded_python-4.0.0b13.dist-info → iris_pex_embedded_python-4.0.0b15.dist-info}/entry_points.txt +0 -0
- {iris_pex_embedded_python-4.0.0b13.dist-info → iris_pex_embedded_python-4.0.0b15.dist-info}/licenses/LICENSE +0 -0
- {iris_pex_embedded_python-4.0.0b13.dist-info → iris_pex_embedded_python-4.0.0b15.dist-info}/top_level.txt +0 -0
iop/__init__.py
CHANGED
|
@@ -117,46 +117,137 @@ class OutboundAdapter(_OutboundAdapter):
|
|
|
117
117
|
|
|
118
118
|
|
|
119
119
|
class BusinessService(_BusinessService):
|
|
120
|
-
"""
|
|
120
|
+
"""Purpose:
|
|
121
|
+
Inbound production entry point for messages entering an IoP production.
|
|
121
122
|
|
|
122
|
-
Use
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
|
126
149
|
"""
|
|
127
150
|
|
|
128
151
|
pass
|
|
129
152
|
|
|
130
153
|
|
|
131
154
|
class PollingBusinessService(_PollingBusinessServiceMixin, BusinessService):
|
|
132
|
-
"""
|
|
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())
|
|
133
180
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
on_init(). See docs/cookbooks/add-polling-service.md.
|
|
181
|
+
Related:
|
|
182
|
+
docs/cookbooks/add-polling-service.md
|
|
137
183
|
"""
|
|
138
184
|
|
|
139
185
|
pass
|
|
140
186
|
|
|
141
187
|
|
|
142
188
|
class BusinessOperation(_BusinessOperation):
|
|
143
|
-
"""
|
|
189
|
+
"""Purpose:
|
|
190
|
+
Outbound side-effect boundary for production messages.
|
|
144
191
|
|
|
145
|
-
Use
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
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
|
|
149
215
|
"""
|
|
150
216
|
|
|
151
217
|
pass
|
|
152
218
|
|
|
153
219
|
|
|
154
220
|
class BusinessProcess(_BusinessProcess):
|
|
155
|
-
"""
|
|
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.
|
|
156
227
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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
|
|
160
251
|
"""
|
|
161
252
|
|
|
162
253
|
pass
|
|
@@ -175,12 +266,34 @@ class DuplexProcess(_PrivateSessionProcess):
|
|
|
175
266
|
|
|
176
267
|
|
|
177
268
|
class Message(_Message):
|
|
178
|
-
"""
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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
|
|
184
297
|
"""
|
|
185
298
|
|
|
186
299
|
pass
|
iop/components/business_host.py
CHANGED
|
@@ -108,23 +108,30 @@ class _BusinessHost(_Common):
|
|
|
108
108
|
timeout: int = -1,
|
|
109
109
|
description: str | None = None,
|
|
110
110
|
) -> Any:
|
|
111
|
-
"""
|
|
111
|
+
"""Purpose:
|
|
112
|
+
Send a message to a target component and wait for the response.
|
|
112
113
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
docs/cookbooks/add-business-process.md.
|
|
114
|
+
Use when:
|
|
115
|
+
The caller needs the target response before continuing.
|
|
116
116
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
117
|
+
Lifecycle:
|
|
118
|
+
IoP serializes request, calls the IRIS synchronous dispatch API, and
|
|
119
|
+
deserializes the response before returning.
|
|
120
|
+
|
|
121
|
+
Best practices:
|
|
122
|
+
Pass a target() attribute such as self.Output so the route is
|
|
123
|
+
configurable in the Production graph.
|
|
124
|
+
|
|
125
|
+
Common mistakes:
|
|
126
|
+
Do not use synchronous calls for long-running work unless the caller
|
|
127
|
+
really must block.
|
|
128
|
+
|
|
129
|
+
Minimal example:
|
|
130
|
+
response = self.send_request_sync(self.Output, request)
|
|
131
|
+
|
|
132
|
+
Related:
|
|
133
|
+
docs/cookbooks/add-business-process.md,
|
|
134
|
+
docs/cookbooks/production-settings-and-targets.md
|
|
128
135
|
"""
|
|
129
136
|
target = resolve_target(target)
|
|
130
137
|
return self.iris_handle.dispatchSendRequestSync(
|
|
@@ -138,19 +145,29 @@ class _BusinessHost(_Common):
|
|
|
138
145
|
request: Message | Any,
|
|
139
146
|
description: str | None = None,
|
|
140
147
|
) -> None:
|
|
141
|
-
"""
|
|
148
|
+
"""Purpose:
|
|
149
|
+
Send a message to a target component without waiting for a response.
|
|
142
150
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
docs/cookbooks/add-polling-service.md.
|
|
151
|
+
Use when:
|
|
152
|
+
A service or operation should enqueue downstream work and continue.
|
|
146
153
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
+
Lifecycle:
|
|
155
|
+
IoP serializes request and calls the IRIS asynchronous dispatch API.
|
|
156
|
+
|
|
157
|
+
Best practices:
|
|
158
|
+
Pass a target() attribute such as self.Output so the route is
|
|
159
|
+
configurable in the Production graph.
|
|
160
|
+
|
|
161
|
+
Common mistakes:
|
|
162
|
+
Do not use this helper when the caller requires a response; use
|
|
163
|
+
send_request_sync(...) or the BusinessProcess async response flow.
|
|
164
|
+
|
|
165
|
+
Minimal example:
|
|
166
|
+
self.send_request_async(self.Output, request)
|
|
167
|
+
|
|
168
|
+
Related:
|
|
169
|
+
docs/cookbooks/add-polling-service.md,
|
|
170
|
+
docs/cookbooks/production-settings-and-targets.md
|
|
154
171
|
"""
|
|
155
172
|
target = resolve_target(target)
|
|
156
173
|
return self.iris_handle.dispatchSendRequestAsync(target, request, description)
|
|
@@ -19,16 +19,31 @@ class _BusinessOperation(_BusinessHost):
|
|
|
19
19
|
adapter: Any = None
|
|
20
20
|
|
|
21
21
|
def on_message(self, request: Any) -> Any:
|
|
22
|
-
"""
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
22
|
+
"""Purpose:
|
|
23
|
+
Handle an incoming message sent to a BusinessOperation.
|
|
24
|
+
|
|
25
|
+
Use when:
|
|
26
|
+
The operation must perform an outbound side effect or submit data to
|
|
27
|
+
an external system.
|
|
28
|
+
|
|
29
|
+
Lifecycle:
|
|
30
|
+
IRIS invokes this hook for operation requests unless dispatch routes
|
|
31
|
+
the message to a @handler or typed one-argument method first.
|
|
32
|
+
|
|
33
|
+
Best practices:
|
|
34
|
+
Keep side effects isolated here. Return a response message when the
|
|
35
|
+
caller uses send_request_sync(...).
|
|
36
|
+
|
|
37
|
+
Common mistakes:
|
|
38
|
+
Do not put routing decisions here when a BusinessProcess should
|
|
39
|
+
orchestrate them.
|
|
40
|
+
|
|
41
|
+
Minimal example:
|
|
42
|
+
def on_message(self, request):
|
|
43
|
+
return SubmitResult(ok=True)
|
|
44
|
+
|
|
45
|
+
Related:
|
|
46
|
+
docs/cookbooks/add-business-operation.md
|
|
32
47
|
"""
|
|
33
48
|
warnings.warn(
|
|
34
49
|
f"{self.__class__.__name__} did not override on_message(); "
|
|
@@ -20,16 +20,35 @@ class _BusinessProcess(_BusinessHost):
|
|
|
20
20
|
DISPATCH: list[tuple] = []
|
|
21
21
|
PERSISTENT_PROPERTY_LIST: list[str] | None = None
|
|
22
22
|
|
|
23
|
-
def on_message(self, request: Any) -> Any:
|
|
24
|
-
"""
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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)
|
|
33
52
|
|
|
34
53
|
def on_request(self, request: Any) -> Any:
|
|
35
54
|
"""Process initial requests sent to this component.
|
|
@@ -42,38 +61,67 @@ class _BusinessProcess(_BusinessHost):
|
|
|
42
61
|
"""
|
|
43
62
|
return None
|
|
44
63
|
|
|
45
|
-
def on_response(
|
|
64
|
+
def on_response(
|
|
46
65
|
self,
|
|
47
66
|
request: Any,
|
|
48
67
|
response: Any,
|
|
49
68
|
call_request: Any,
|
|
50
69
|
call_response: Any,
|
|
51
70
|
completion_key: str,
|
|
52
|
-
) -> Any:
|
|
53
|
-
"""
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
+
"""
|
|
65
97
|
return response
|
|
66
98
|
|
|
67
|
-
def on_complete(self, request: Any, response: Any) -> Any:
|
|
68
|
-
"""
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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
|
+
"""
|
|
77
125
|
return response
|
|
78
126
|
|
|
79
127
|
@input_serializer_param(0, "response")
|
|
@@ -93,19 +141,33 @@ class _BusinessProcess(_BusinessHost):
|
|
|
93
141
|
description: str | None = None,
|
|
94
142
|
completion_key: str | None = None,
|
|
95
143
|
response_required: bool = True,
|
|
96
|
-
) -> None:
|
|
97
|
-
"""
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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
|
+
"""
|
|
109
171
|
# Convert boolean to int for Iris API
|
|
110
172
|
if response_required:
|
|
111
173
|
response_required = 1 # type: ignore
|
|
@@ -42,11 +42,32 @@ class _BusinessService(_BusinessHost):
|
|
|
42
42
|
return
|
|
43
43
|
|
|
44
44
|
def on_message(self, request=None):
|
|
45
|
-
"""
|
|
45
|
+
"""Purpose:
|
|
46
|
+
Handle a message received by a BusinessService.
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
|
50
71
|
"""
|
|
51
72
|
warnings.warn(
|
|
52
73
|
f"{self.__class__.__name__} did not override on_message() or "
|
iop/components/common.py
CHANGED
|
@@ -223,10 +223,36 @@ class _Common:
|
|
|
223
223
|
self._log_to_console = value
|
|
224
224
|
self.logger = LogManager.get_logger(self.__class__.__name__, value)
|
|
225
225
|
|
|
226
|
-
# Lifecycle methods
|
|
227
|
-
def on_init(self) -> None:
|
|
228
|
-
"""
|
|
229
|
-
|
|
226
|
+
# Lifecycle methods
|
|
227
|
+
def on_init(self) -> None:
|
|
228
|
+
"""Purpose:
|
|
229
|
+
Component startup hook.
|
|
230
|
+
|
|
231
|
+
Use when:
|
|
232
|
+
A component needs to initialize clients, caches, credentials,
|
|
233
|
+
counters, or other runtime state after IRIS creates the host.
|
|
234
|
+
|
|
235
|
+
Lifecycle:
|
|
236
|
+
IoP calls on_init() from the internal dispatch startup path. IRIS
|
|
237
|
+
may allocate the Python object without calling __init__().
|
|
238
|
+
|
|
239
|
+
Best practices:
|
|
240
|
+
Keep initialization idempotent and quick. Read production settings
|
|
241
|
+
from self inside this method.
|
|
242
|
+
|
|
243
|
+
Common mistakes:
|
|
244
|
+
Do not put component startup work in __init__(); it may not run in
|
|
245
|
+
the IRIS component lifecycle.
|
|
246
|
+
|
|
247
|
+
Minimal example:
|
|
248
|
+
def on_init(self):
|
|
249
|
+
self.client = make_client(self.Endpoint)
|
|
250
|
+
|
|
251
|
+
Related:
|
|
252
|
+
docs/ai-coding.md,
|
|
253
|
+
docs/cookbooks/index.md
|
|
254
|
+
"""
|
|
255
|
+
pass
|
|
230
256
|
|
|
231
257
|
def on_tear_down(self) -> None:
|
|
232
258
|
"""Clean up component before termination."""
|
|
@@ -9,10 +9,30 @@ class _PollingBusinessServiceMixin:
|
|
|
9
9
|
return "Ens.InboundAdapter"
|
|
10
10
|
|
|
11
11
|
def on_poll(self):
|
|
12
|
-
"""
|
|
12
|
+
"""Purpose:
|
|
13
|
+
Run one scheduled polling cycle.
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
Use when:
|
|
16
|
+
A PollingBusinessService fetches or discovers new work from Python.
|
|
17
|
+
|
|
18
|
+
Lifecycle:
|
|
19
|
+
The default IRIS inbound adapter calls on_process_input(), and this
|
|
20
|
+
mixin delegates that call to on_poll().
|
|
21
|
+
|
|
22
|
+
Best practices:
|
|
23
|
+
Do a bounded unit of work, then return. Send produced messages with
|
|
24
|
+
send_request_async(self.Output, message).
|
|
25
|
+
|
|
26
|
+
Common mistakes:
|
|
27
|
+
Do not create an infinite loop inside on_poll(); use the production
|
|
28
|
+
schedule or call interval for repeated execution.
|
|
29
|
+
|
|
30
|
+
Minimal example:
|
|
31
|
+
def on_poll(self):
|
|
32
|
+
self.send_request_async(self.Output, PollRequest())
|
|
33
|
+
|
|
34
|
+
Related:
|
|
35
|
+
docs/cookbooks/add-polling-service.md
|
|
16
36
|
"""
|
|
17
37
|
warnings.warn(
|
|
18
38
|
f"{self.__class__.__name__} did not override on_poll() or "
|
iop/messages/decorators.py
CHANGED
|
@@ -9,6 +9,7 @@ from .dispatch import handler as handler
|
|
|
9
9
|
def input_serializer(fonction: Callable) -> Callable:
|
|
10
10
|
"""Decorator that serializes all input arguments."""
|
|
11
11
|
|
|
12
|
+
@wraps(fonction)
|
|
12
13
|
def _dispatch_serializer(self, *params: Any, **param2: Any) -> Any:
|
|
13
14
|
serialized = [dispatch_serializer(param) for param in params]
|
|
14
15
|
param2 = {key: dispatch_serializer(value) for key, value in param2.items()}
|
|
@@ -41,6 +42,7 @@ def input_serializer_param(position: int, name: str) -> Callable:
|
|
|
41
42
|
def output_deserializer(fonction: Callable) -> Callable:
|
|
42
43
|
"""Decorator that deserializes function output."""
|
|
43
44
|
|
|
45
|
+
@wraps(fonction)
|
|
44
46
|
def _dispatch_deserializer(self, *params: Any, **param2: Any) -> Any:
|
|
45
47
|
return dispatch_deserializer(fonction(self, *params, **param2))
|
|
46
48
|
|
|
@@ -50,6 +52,7 @@ def output_deserializer(fonction: Callable) -> Callable:
|
|
|
50
52
|
def input_deserializer(fonction: Callable) -> Callable:
|
|
51
53
|
"""Decorator that deserializes all input arguments."""
|
|
52
54
|
|
|
55
|
+
@wraps(fonction)
|
|
53
56
|
def _dispatch_deserializer(self, *params: Any, **param2: Any) -> Any:
|
|
54
57
|
serialized = [dispatch_deserializer(param) for param in params]
|
|
55
58
|
param2 = {key: dispatch_deserializer(value) for key, value in param2.items()}
|
|
@@ -61,6 +64,7 @@ def input_deserializer(fonction: Callable) -> Callable:
|
|
|
61
64
|
def output_serializer(fonction: Callable) -> Callable:
|
|
62
65
|
"""Decorator that serializes function output."""
|
|
63
66
|
|
|
67
|
+
@wraps(fonction)
|
|
64
68
|
def _dispatch_serializer(self, *params: Any, **param2: Any) -> Any:
|
|
65
69
|
return dispatch_serializer(fonction(self, *params, **param2))
|
|
66
70
|
|
iop/messages/dispatch.py
CHANGED
|
@@ -7,6 +7,7 @@ from typing import Any
|
|
|
7
7
|
from .persistent import (
|
|
8
8
|
deserialize_persistent_message,
|
|
9
9
|
get_iris_object_classname,
|
|
10
|
+
is_persistent_message_class,
|
|
10
11
|
is_persistent_message_instance,
|
|
11
12
|
serialize_persistent_message,
|
|
12
13
|
)
|
|
@@ -20,7 +21,9 @@ from .serialization import (
|
|
|
20
21
|
)
|
|
21
22
|
from .validation import (
|
|
22
23
|
is_iris_object_instance,
|
|
24
|
+
is_message_class,
|
|
23
25
|
is_message_instance,
|
|
26
|
+
is_pickle_message_class,
|
|
24
27
|
is_pickle_message_instance,
|
|
25
28
|
)
|
|
26
29
|
|
|
@@ -326,7 +329,23 @@ def _message_class_name(message_type: Any) -> str | None:
|
|
|
326
329
|
if is_iris_object_instance(message_type):
|
|
327
330
|
return f"{type(message_type).__module__}.{type(message_type).__name__}"
|
|
328
331
|
|
|
332
|
+
if message_type is Any or message_type is object:
|
|
333
|
+
return None
|
|
334
|
+
|
|
329
335
|
if not isinstance(message_type, type):
|
|
330
336
|
return None
|
|
331
337
|
|
|
338
|
+
if not _is_dispatch_message_class(message_type):
|
|
339
|
+
return None
|
|
340
|
+
|
|
332
341
|
return f"{message_type.__module__}.{message_type.__name__}"
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
def _is_dispatch_message_class(klass: type) -> bool:
|
|
345
|
+
if is_message_class(klass):
|
|
346
|
+
return True
|
|
347
|
+
if is_pickle_message_class(klass):
|
|
348
|
+
return True
|
|
349
|
+
if is_persistent_message_class(klass):
|
|
350
|
+
return True
|
|
351
|
+
return klass.__module__.startswith("iris")
|
iop/messages/validation.py
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import dataclasses
|
|
2
2
|
from typing import Any
|
|
3
3
|
|
|
4
|
-
from .base import
|
|
4
|
+
from .base import _Message, _PickleMessage, _PydanticMessage, _PydanticPickleMessage
|
|
5
|
+
|
|
6
|
+
_PYDANTIC_BASE = _PydanticMessage.__mro__[1]
|
|
5
7
|
|
|
6
8
|
|
|
7
9
|
def is_message_instance(obj: Any) -> bool:
|
|
8
10
|
"""Check if object is a valid Message instance."""
|
|
9
|
-
if isinstance(obj,
|
|
11
|
+
if isinstance(obj, _PYDANTIC_BASE):
|
|
10
12
|
return True
|
|
11
13
|
if is_message_class(type(obj)):
|
|
12
14
|
if not dataclasses.is_dataclass(obj):
|
|
@@ -38,15 +40,15 @@ def is_iris_object_instance(obj: Any) -> bool:
|
|
|
38
40
|
|
|
39
41
|
def is_message_class(klass: type) -> bool:
|
|
40
42
|
"""Check if class is a Message type."""
|
|
41
|
-
|
|
42
|
-
return
|
|
43
|
-
|
|
43
|
+
try:
|
|
44
|
+
return issubclass(klass, (_Message, _PYDANTIC_BASE))
|
|
45
|
+
except TypeError:
|
|
46
|
+
return False
|
|
44
47
|
|
|
45
48
|
|
|
46
49
|
def is_pickle_message_class(klass: type) -> bool:
|
|
47
50
|
"""Check if class is a PickleMessage type."""
|
|
48
|
-
|
|
49
|
-
return
|
|
50
|
-
|
|
51
|
-
return
|
|
52
|
-
return False
|
|
51
|
+
try:
|
|
52
|
+
return issubclass(klass, (_PickleMessage, _PydanticPickleMessage))
|
|
53
|
+
except TypeError:
|
|
54
|
+
return False
|
iop/production/model.py
CHANGED
|
@@ -42,15 +42,35 @@ _MISSING = object()
|
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
class Production(_DeclarativeProductionMixin):
|
|
45
|
-
"""
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
45
|
+
"""Purpose:
|
|
46
|
+
Python authoring DSL for IRIS interoperability production topology.
|
|
47
|
+
|
|
48
|
+
Use when:
|
|
49
|
+
A project should declare services, processes, operations, settings, and
|
|
50
|
+
graph connections in Python.
|
|
51
|
+
|
|
52
|
+
Lifecycle:
|
|
53
|
+
A settings.py module exports PRODUCTIONS = [prod]. Migration renders the
|
|
54
|
+
graph to IRIS; IRIS remains the runtime source of truth.
|
|
55
|
+
|
|
56
|
+
Best practices:
|
|
57
|
+
Declare topology with service(), process(), operation(), target(), and
|
|
58
|
+
connect(). Keep the Production object import-safe.
|
|
59
|
+
|
|
60
|
+
Common mistakes:
|
|
61
|
+
Do not execute migration or runtime side effects at module import time.
|
|
62
|
+
Do not use raw CLASSES entries for graph components.
|
|
63
|
+
|
|
64
|
+
Minimal example:
|
|
65
|
+
prod = Production("Demo.Production")
|
|
66
|
+
svc = prod.service("Demo.Service", MyService)
|
|
67
|
+
op = prod.operation("Demo.Operation", MyOperation)
|
|
68
|
+
prod.connect(svc.Output, op)
|
|
69
|
+
PRODUCTIONS = [prod]
|
|
70
|
+
|
|
71
|
+
Related:
|
|
72
|
+
docs/cookbooks/hello-world-production.md,
|
|
73
|
+
docs/production-graph.md
|
|
54
74
|
"""
|
|
55
75
|
|
|
56
76
|
def __init__(
|
iop/production/types.py
CHANGED
|
@@ -35,11 +35,33 @@ class TargetSetting(Setting):
|
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
def target(**kwargs: Any) -> TargetSetting:
|
|
38
|
-
"""
|
|
38
|
+
"""Purpose:
|
|
39
|
+
Declare a configurable outbound target setting on a component class.
|
|
39
40
|
|
|
40
|
-
Use
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
Use when:
|
|
42
|
+
A service or process sends messages to another production component.
|
|
43
|
+
|
|
44
|
+
Lifecycle:
|
|
45
|
+
The descriptor becomes an IRIS production setting. Production.connect(...)
|
|
46
|
+
binds it to a concrete target component.
|
|
47
|
+
|
|
48
|
+
Best practices:
|
|
49
|
+
Use target() instead of hard-coded component names for routes that
|
|
50
|
+
should be visible and configurable in the production graph.
|
|
51
|
+
|
|
52
|
+
Common mistakes:
|
|
53
|
+
Do not use setting(...) for outbound routing when target() should expose
|
|
54
|
+
a production target.
|
|
55
|
+
|
|
56
|
+
Minimal example:
|
|
57
|
+
class Router(BusinessProcess):
|
|
58
|
+
Output = target()
|
|
59
|
+
|
|
60
|
+
prod.connect(router.Output, operation)
|
|
61
|
+
|
|
62
|
+
Related:
|
|
63
|
+
docs/cookbooks/production-settings-and-targets.md,
|
|
64
|
+
docs/production-graph.md
|
|
43
65
|
"""
|
|
44
66
|
return TargetSetting(**kwargs)
|
|
45
67
|
|
{iris_pex_embedded_python-4.0.0b13.dist-info → iris_pex_embedded_python-4.0.0b15.dist-info}/RECORD
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
iop/__init__.py,sha256=
|
|
1
|
+
iop/__init__.py,sha256=4QGYNWs4t-Zt4-WfjHXmKRosWS5jZ5A27vl2hiObCVc,10621
|
|
2
2
|
iop/__main__.py,sha256=2rUNM7vaYK0W57Jj72rm7GORyIFLMXKwPq3QNLwYBmY,100
|
|
3
3
|
iop/cli/__init__.py,sha256=Y78pBdA-ULzq1c_9xQZsFBlzm3x5xgxSzkvrH5DoM7I,31
|
|
4
4
|
iop/cli/formatting.py,sha256=OLgHA1d8_paAuINQyKkYgihWMLoBhPn7kSXW5whRlIs,1606
|
|
@@ -36,27 +36,27 @@ iop/cls/IOP/Service/Remote/Handler.cls,sha256=JfsXse2jvoVvQfW8_rVEt2DCQJ9SVqReCc
|
|
|
36
36
|
iop/cls/IOP/Service/Remote/Rest/v1.cls,sha256=33FEBVZhHqysYaLL7l0314kJu1eZXyJlvAk2l4Q-B5g,20277
|
|
37
37
|
iop/components/__init__.py,sha256=uRF_YCn_ukkgzFrW0nLLMmC2jJ1dMk-ME7HX9EEEVic,880
|
|
38
38
|
iop/components/async_request.py,sha256=AU36pf6NIQMM9ZYR5h6LeQry0EfXXqDaKAjsP16_hWE,2411
|
|
39
|
-
iop/components/business_host.py,sha256=
|
|
40
|
-
iop/components/business_operation.py,sha256=
|
|
41
|
-
iop/components/business_process.py,sha256=
|
|
42
|
-
iop/components/business_service.py,sha256=
|
|
43
|
-
iop/components/common.py,sha256=
|
|
39
|
+
iop/components/business_host.py,sha256=5EXwzZzfEVYLFlzi519GXKclTz2m5FMcqtl10lLzUyw,12089
|
|
40
|
+
iop/components/business_operation.py,sha256=KycRNz-zuyJs2VneTBVcppyd3rKLekrISjbubCbzHxY,2905
|
|
41
|
+
iop/components/business_process.py,sha256=1xTYwqhvJaXC-BvQ5WoGOud5QwxT9EPpvDPDX4zThXg,9839
|
|
42
|
+
iop/components/business_service.py,sha256=fwSdHGFuC55_qSjFBpW-cLZmrK3Cm8Yxgk1KvxuQv2Y,4718
|
|
43
|
+
iop/components/common.py,sha256=tsP2APRBnks1hVazS9dX0Q8KCoANbUsnaFTlzqOIkVY,19063
|
|
44
44
|
iop/components/debugpy.py,sha256=sNFKaF9MtWBNAqxH4ubSIVqjsIpsHGjRK2jzBU-O59Y,6011
|
|
45
45
|
iop/components/generator_request.py,sha256=NOllwJnY06kk_eC7cQXDQ8NBFKfQakyz3A_AgYJ5f5Y,1351
|
|
46
46
|
iop/components/inbound_adapter.py,sha256=H36HcHHn7fbzUuAMG-f2CwCesOeKnE6FZPuVGCUCEXo,1130
|
|
47
47
|
iop/components/log_manager.py,sha256=nIBMp4sz2Bi5tQml-LKj8cheiGk1LjNh5BiwqUupuZw,3241
|
|
48
48
|
iop/components/outbound_adapter.py,sha256=Bm6KeaLR0fO3z5o9cmJxcMdIiOvdExik-Oc272WZtHg,731
|
|
49
|
-
iop/components/polling_business_service.py,sha256=
|
|
49
|
+
iop/components/polling_business_service.py,sha256=1EkEW8KVx6wW7DCXnrExe2z07NcmuqJN0C6P5hxVNRM,1562
|
|
50
50
|
iop/components/private_session_duplex.py,sha256=IZ50ThI074qwFF1wFyhFCsSJK0huyuoIeVxwlGyweeQ,5157
|
|
51
51
|
iop/components/private_session_process.py,sha256=edugk8iLTjaHMsz_fBuj9VE8aL66IgOz-mMlqPyk3Zc,1731
|
|
52
52
|
iop/components/settings.py,sha256=USAKAisdersKlAEIk8HDu_TuYtkO-Sc3an3PXjPcDRA,6296
|
|
53
53
|
iop/messages/__init__.py,sha256=k1AKplpjdqSxM5Gl7bpWAfw93xUgigovlI4SKhwKHRI,355
|
|
54
54
|
iop/messages/base.py,sha256=ZrVXEz7JrYHnt5b3M7avxcJCB0_OZxm1uWm9gQ4_eAw,1906
|
|
55
|
-
iop/messages/decorators.py,sha256=
|
|
56
|
-
iop/messages/dispatch.py,sha256=
|
|
55
|
+
iop/messages/decorators.py,sha256=CWk08k8U2aTJv7Dx1n2jp8sjZZSCD8NJPoifKLB3W2g,2488
|
|
56
|
+
iop/messages/dispatch.py,sha256=Mgz0OHTQDU02Z8qPxl_lks-nlAvW6ADcJkTS4faYE-Q,10459
|
|
57
57
|
iop/messages/persistent.py,sha256=ibRhRTqzwGcAqem744KZzHiouUlc8-J3ftB4zyzQYx4,16906
|
|
58
58
|
iop/messages/serialization.py,sha256=BW0o-7GaceMW7RMOzOJ8g9rKEv28NYnYFwtTLmAf7Yg,9255
|
|
59
|
-
iop/messages/validation.py,sha256=
|
|
59
|
+
iop/messages/validation.py,sha256=X6MSWsjLZDuyX1Tfx0TP3T6OI4nj1HZccwR2Z9PSubY,1606
|
|
60
60
|
iop/migration/__init__.py,sha256=wp-RvjLKYW_Pi2AJLfiWe1bACxENzEgjXtP9UMNiSVY,36
|
|
61
61
|
iop/migration/io.py,sha256=hAehtApFZFgGzjzgwBmDMxdA1xoRhE-okOcEzvgFdQ4,1822
|
|
62
62
|
iop/migration/manifest.py,sha256=Bs4eC1_i-ZnovlgSW9FKu5WBwy_6Zwy5ZAcsi5A1szU,19351
|
|
@@ -71,13 +71,13 @@ iop/production/declarative.py,sha256=IpHYO46mu7k9wnq3DpFreoALPoX1Vi8DrJb-85O_-bQ
|
|
|
71
71
|
iop/production/diff.py,sha256=NYpcSVklaGpaZOyl933W8eLsDWcwjlf6Upbp4pVGSMU,9975
|
|
72
72
|
iop/production/import_.py,sha256=twBra6j2peolFadv8WyDwZZOd9NznzAkPsk2RbOfZQM,10833
|
|
73
73
|
iop/production/inspection.py,sha256=PPv9DiDS4OrnKROqV7JPbuY8Y0JR-m8syPhap3GgE4g,3363
|
|
74
|
-
iop/production/model.py,sha256=
|
|
74
|
+
iop/production/model.py,sha256=CpI5OBEBBw9z40Lws1rKVL9Mx_P4fhKmwYPoqEUntKU,41705
|
|
75
75
|
iop/production/planning.py,sha256=nCYrXLKlHBlUaQZPzPfqtIERIv62F2sg4gJ0b8mtcKk,23375
|
|
76
76
|
iop/production/reconstruction.py,sha256=5vVteTEM6IOiQUfpe4AUQg6Nt4oaaIDR61-1l6Vu8hk,12532
|
|
77
77
|
iop/production/rendering.py,sha256=UVHLICY4zWEP3W7-99TpB2WeLBNREC2N8rYSnBa_iZM,20240
|
|
78
78
|
iop/production/runtime.py,sha256=6grX1u20OhHnvhzC3yPDTFEoDs_TN4mfs5MxzFzZMls,2637
|
|
79
79
|
iop/production/source_inference.py,sha256=Wl3E9-1hWb4qxD1jwrrZTLSgqN-0vGhOrJtmzDWPCao,21613
|
|
80
|
-
iop/production/types.py,sha256=
|
|
80
|
+
iop/production/types.py,sha256=L_wyXO8deOnqRFin74SX_K8UWILFu-VzIO5pKNa6VXY,16580
|
|
81
81
|
iop/production/validation.py,sha256=14BfjrLXW1AOuP8AdBrs-CY6zynaDc8_AUD9frsYAIU,13753
|
|
82
82
|
iop/runtime/__init__.py,sha256=wcyWMRuPCYE_CLd1NmgmI1M-IbFs2Gz2yIj2-EW_2AA,70
|
|
83
83
|
iop/runtime/director.py,sha256=KW8BvkATK8XuIUPNBD9rMww9r3Zg4K3H54868eOgvl0,12867
|
|
@@ -91,9 +91,9 @@ iop/runtime/remote/director.py,sha256=bkie751GrYLgGs7ApRCowHpSnJA8KupxCOrFDQmjyO
|
|
|
91
91
|
iop/runtime/remote/migration.py,sha256=Iboz-Ye7i9xif9bn433GazCF-gtD-HJW3wiUwWS5P6w,1831
|
|
92
92
|
iop/runtime/remote/settings.py,sha256=P1Hsgld5o57HpSZgPVZzobyjlUmxJj6bstiWvR0JXnc,2144
|
|
93
93
|
iop/runtime/remote/setup.py,sha256=Tr80F3JJTy7oSUso2jyx0iA_KZayd4MYt9vL0BvPpMA,2600
|
|
94
|
-
iris_pex_embedded_python-4.0.
|
|
95
|
-
iris_pex_embedded_python-4.0.
|
|
96
|
-
iris_pex_embedded_python-4.0.
|
|
97
|
-
iris_pex_embedded_python-4.0.
|
|
98
|
-
iris_pex_embedded_python-4.0.
|
|
99
|
-
iris_pex_embedded_python-4.0.
|
|
94
|
+
iris_pex_embedded_python-4.0.0b15.dist-info/licenses/LICENSE,sha256=rZSiBFId_sfbJ6RL0GjjPX-InNLkNS9ou7eQsikciI8,1089
|
|
95
|
+
iris_pex_embedded_python-4.0.0b15.dist-info/METADATA,sha256=FAs1I9jhJCMQabHY14tAR02X2fnv_DS7Yu-yrAZLVso,5284
|
|
96
|
+
iris_pex_embedded_python-4.0.0b15.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
97
|
+
iris_pex_embedded_python-4.0.0b15.dist-info/entry_points.txt,sha256=fzS8ZFsPe8cnpEx208X60DNugCPQmuSloPeg4pyyJDY,42
|
|
98
|
+
iris_pex_embedded_python-4.0.0b15.dist-info/top_level.txt,sha256=BM54-OXQ6l2BDtmesWNXckh033s9gcjoO7bfjbwZbxU,4
|
|
99
|
+
iris_pex_embedded_python-4.0.0b15.dist-info/RECORD,,
|
{iris_pex_embedded_python-4.0.0b13.dist-info → iris_pex_embedded_python-4.0.0b15.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|