iris-pex-embedded-python 4.0.1b1__py3-none-any.whl → 4.0.1b3__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 +2 -2
- iop/components/business_service.py +12 -16
- iop/messages/dispatch.py +38 -1
- iop/migration/utils.py +16 -16
- {iris_pex_embedded_python-4.0.1b1.dist-info → iris_pex_embedded_python-4.0.1b3.dist-info}/METADATA +30 -6
- {iris_pex_embedded_python-4.0.1b1.dist-info → iris_pex_embedded_python-4.0.1b3.dist-info}/RECORD +10 -10
- {iris_pex_embedded_python-4.0.1b1.dist-info → iris_pex_embedded_python-4.0.1b3.dist-info}/WHEEL +0 -0
- {iris_pex_embedded_python-4.0.1b1.dist-info → iris_pex_embedded_python-4.0.1b3.dist-info}/entry_points.txt +0 -0
- {iris_pex_embedded_python-4.0.1b1.dist-info → iris_pex_embedded_python-4.0.1b3.dist-info}/licenses/LICENSE +0 -0
- {iris_pex_embedded_python-4.0.1b1.dist-info → iris_pex_embedded_python-4.0.1b3.dist-info}/top_level.txt +0 -0
iop/__init__.py
CHANGED
|
@@ -125,8 +125,8 @@ class BusinessService(_BusinessService):
|
|
|
125
125
|
production graph.
|
|
126
126
|
|
|
127
127
|
Lifecycle:
|
|
128
|
-
IRIS calls on_process_input(); the default implementation delegates
|
|
129
|
-
|
|
128
|
+
IRIS calls on_process_input(); the default implementation delegates the
|
|
129
|
+
incoming request to on_message(request).
|
|
130
130
|
|
|
131
131
|
Best practices:
|
|
132
132
|
Declare outbound routes with target() and wire them in a Production
|
|
@@ -20,16 +20,13 @@ def _call_process_input(method, request):
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
class _BusinessService(_BusinessHost):
|
|
23
|
-
"""
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
"""
|
|
23
|
+
"""Runtime base for inbound production entry points.
|
|
24
|
+
|
|
25
|
+
IRIS invokes on_process_input(...). By default, that hook delegates to
|
|
26
|
+
on_message(...). Application code should normally subclass iop.BusinessService
|
|
27
|
+
or iop.PollingBusinessService and wire outbound routes with target() in a
|
|
28
|
+
Production graph.
|
|
29
|
+
"""
|
|
33
30
|
|
|
34
31
|
Adapter = adapter = None
|
|
35
32
|
_wait_for_next_call_interval = False
|
|
@@ -79,13 +76,12 @@ class _BusinessService(_BusinessHost):
|
|
|
79
76
|
return None
|
|
80
77
|
|
|
81
78
|
def on_process_input(self, message_input=None):
|
|
82
|
-
"""
|
|
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.
|
|
79
|
+
"""Handle IRIS ProcessInput and delegate to on_message(message_input).
|
|
85
80
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
81
|
+
Override this low-level hook only when an inbound adapter or Director
|
|
82
|
+
call needs custom ProcessInput handling. For simple services, override
|
|
83
|
+
on_message(...); for scheduled polling, use PollingBusinessService and
|
|
84
|
+
override on_poll().
|
|
89
85
|
"""
|
|
90
86
|
return self.on_message(message_input)
|
|
91
87
|
|
iop/messages/dispatch.py
CHANGED
|
@@ -306,8 +306,9 @@ def get_handler_info(host: Any, method_name: str) -> tuple[str, str] | None:
|
|
|
306
306
|
if len(params) != 1:
|
|
307
307
|
return None
|
|
308
308
|
|
|
309
|
+
method = getattr(host, method_name)
|
|
309
310
|
param: Parameter = next(iter(params.values()))
|
|
310
|
-
annotation = param.annotation
|
|
311
|
+
annotation = _resolve_annotation(host, method, param.annotation)
|
|
311
312
|
|
|
312
313
|
if annotation == Parameter.empty:
|
|
313
314
|
return None
|
|
@@ -322,6 +323,42 @@ def get_handler_info(host: Any, method_name: str) -> tuple[str, str] | None:
|
|
|
322
323
|
return None
|
|
323
324
|
|
|
324
325
|
|
|
326
|
+
def _resolve_annotation(host: Any, method: Callable, annotation: Any) -> Any:
|
|
327
|
+
if not isinstance(annotation, str):
|
|
328
|
+
return annotation
|
|
329
|
+
|
|
330
|
+
globalns = _annotation_globalns(method)
|
|
331
|
+
localns = _annotation_localns(host)
|
|
332
|
+
|
|
333
|
+
try:
|
|
334
|
+
resolved = eval(annotation, globalns, localns) # noqa: B307
|
|
335
|
+
except Exception:
|
|
336
|
+
resolved = annotation
|
|
337
|
+
|
|
338
|
+
if isinstance(resolved, str):
|
|
339
|
+
# Quoted postponed annotations evaluate to a string first.
|
|
340
|
+
try:
|
|
341
|
+
resolved = eval(resolved, globalns, localns) # noqa: B307
|
|
342
|
+
except Exception:
|
|
343
|
+
if "." in resolved:
|
|
344
|
+
return resolved
|
|
345
|
+
return Parameter.empty
|
|
346
|
+
|
|
347
|
+
return resolved
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
def _annotation_globalns(method: Callable) -> dict[str, Any]:
|
|
351
|
+
function = getattr(method, "__func__", method)
|
|
352
|
+
return getattr(function, "__globals__", {})
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
def _annotation_localns(host: Any) -> dict[str, Any]:
|
|
356
|
+
namespace: dict[str, Any] = {}
|
|
357
|
+
for klass in reversed(type(host).__mro__):
|
|
358
|
+
namespace.update(vars(klass))
|
|
359
|
+
return namespace
|
|
360
|
+
|
|
361
|
+
|
|
325
362
|
def _message_class_name(message_type: Any) -> str | None:
|
|
326
363
|
if isinstance(message_type, str):
|
|
327
364
|
return message_type
|
iop/migration/utils.py
CHANGED
|
@@ -193,8 +193,11 @@ def register_component(
|
|
|
193
193
|
overwrite: int = 1,
|
|
194
194
|
iris_classname: str = "Python",
|
|
195
195
|
):
|
|
196
|
-
"""
|
|
197
|
-
|
|
196
|
+
"""Register a Python component as an IRIS proxy class.
|
|
197
|
+
|
|
198
|
+
Prefer a Python Production graph in PRODUCTIONS for new application
|
|
199
|
+
components. Use register_component() directly for standalone bindings,
|
|
200
|
+
legacy migration helpers, or manual proxy registration only.
|
|
198
201
|
|
|
199
202
|
:param module: The name of the module that contains the class
|
|
200
203
|
:type module: str
|
|
@@ -239,8 +242,11 @@ def bind_component(
|
|
|
239
242
|
overwrite: int = 1,
|
|
240
243
|
iris_classname: str = "Python",
|
|
241
244
|
):
|
|
242
|
-
"""
|
|
243
|
-
|
|
245
|
+
"""Public alias for register_component().
|
|
246
|
+
|
|
247
|
+
Prefer a Python Production graph in PRODUCTIONS for new application
|
|
248
|
+
components. Use bind_component() directly only for standalone bindings,
|
|
249
|
+
legacy migration helpers, or manual proxy registration.
|
|
244
250
|
"""
|
|
245
251
|
return register_component(module, classname, path, overwrite, iris_classname)
|
|
246
252
|
|
|
@@ -436,18 +442,12 @@ def migrate(
|
|
|
436
442
|
namespace: str | None = None,
|
|
437
443
|
strict_production_validation: bool = False,
|
|
438
444
|
):
|
|
439
|
-
"""
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
* PRODUCTIONS
|
|
446
|
-
list of dictionaries:
|
|
447
|
-
* key: the name of the production
|
|
448
|
-
* value: a dictionary containing the settings for the production
|
|
449
|
-
* SCHEMAS
|
|
450
|
-
List of classes
|
|
445
|
+
"""Read a migration file and apply its registrations to IRIS.
|
|
446
|
+
|
|
447
|
+
New Python-authored applications should normally export Production objects
|
|
448
|
+
through PRODUCTIONS. CLASSES remains available for standalone bindings,
|
|
449
|
+
native PersistentMessage classes, and legacy migration files. SCHEMAS
|
|
450
|
+
registers Message or PydanticMessage schemas for DTL support.
|
|
451
451
|
"""
|
|
452
452
|
settings, path = _load_settings(filename)
|
|
453
453
|
|
{iris_pex_embedded_python-4.0.1b1.dist-info → iris_pex_embedded_python-4.0.1b3.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: iris_pex_embedded_python
|
|
3
|
-
Version: 4.0.
|
|
3
|
+
Version: 4.0.1b3
|
|
4
4
|
Summary: Iris Interoperability based on Embedded Python
|
|
5
5
|
Author-email: grongier <guillaume.rongier@intersystems.com>
|
|
6
6
|
License: MIT License
|
|
@@ -69,14 +69,38 @@ For application repositories, start from the [reusable AGENTS.md template](https
|
|
|
69
69
|
|
|
70
70
|
## Example
|
|
71
71
|
|
|
72
|
-
Here's a
|
|
72
|
+
Here's a tiny Python-authored production:
|
|
73
73
|
|
|
74
74
|
```python
|
|
75
|
-
from
|
|
75
|
+
from dataclasses import dataclass
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
from iop import BusinessOperation, Message, PollingBusinessService, Production, target
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@dataclass
|
|
81
|
+
class HelloRequest(Message):
|
|
82
|
+
text: str = "Hello World"
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class HelloService(PollingBusinessService):
|
|
86
|
+
Output = target()
|
|
87
|
+
|
|
88
|
+
def on_poll(self):
|
|
89
|
+
self.send_request_async(self.Output, HelloRequest())
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class HelloOperation(BusinessOperation):
|
|
93
|
+
def on_message(self, request: HelloRequest):
|
|
94
|
+
self.log_info(request.text)
|
|
95
|
+
return request
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
prod = Production("HelloWorld.Production", testing_enabled=True)
|
|
99
|
+
service = prod.service("HelloService", HelloService)
|
|
100
|
+
operation = prod.operation("HelloOperation", HelloOperation)
|
|
101
|
+
prod.connect(service.Output, operation)
|
|
102
|
+
|
|
103
|
+
PRODUCTIONS = [prod]
|
|
80
104
|
```
|
|
81
105
|
|
|
82
106
|
## Installation
|
{iris_pex_embedded_python-4.0.1b1.dist-info → iris_pex_embedded_python-4.0.1b3.dist-info}/RECORD
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
iop/__init__.py,sha256=
|
|
1
|
+
iop/__init__.py,sha256=bnhSiC7XcOIiS7e51uY8fr9Li7RYjhCnlCyVDzZI6-I,10636
|
|
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
|
|
@@ -39,7 +39,7 @@ iop/components/async_request.py,sha256=AU36pf6NIQMM9ZYR5h6LeQry0EfXXqDaKAjsP16_h
|
|
|
39
39
|
iop/components/business_host.py,sha256=5EXwzZzfEVYLFlzi519GXKclTz2m5FMcqtl10lLzUyw,12089
|
|
40
40
|
iop/components/business_operation.py,sha256=KycRNz-zuyJs2VneTBVcppyd3rKLekrISjbubCbzHxY,2905
|
|
41
41
|
iop/components/business_process.py,sha256=1xTYwqhvJaXC-BvQ5WoGOud5QwxT9EPpvDPDX4zThXg,9839
|
|
42
|
-
iop/components/business_service.py,sha256=
|
|
42
|
+
iop/components/business_service.py,sha256=Bp47bJzTWHp66kp0Zo_D-blOKHzj4i6kXu-lCRMMzfg,3597
|
|
43
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
|
|
@@ -53,7 +53,7 @@ iop/components/settings.py,sha256=USAKAisdersKlAEIk8HDu_TuYtkO-Sc3an3PXjPcDRA,62
|
|
|
53
53
|
iop/messages/__init__.py,sha256=k1AKplpjdqSxM5Gl7bpWAfw93xUgigovlI4SKhwKHRI,355
|
|
54
54
|
iop/messages/base.py,sha256=ZrVXEz7JrYHnt5b3M7avxcJCB0_OZxm1uWm9gQ4_eAw,1906
|
|
55
55
|
iop/messages/decorators.py,sha256=CWk08k8U2aTJv7Dx1n2jp8sjZZSCD8NJPoifKLB3W2g,2488
|
|
56
|
-
iop/messages/dispatch.py,sha256=
|
|
56
|
+
iop/messages/dispatch.py,sha256=wfoKyaMOcJTzMEAE5hEHYEt3aiRsaUR_TYmROT2fDrg,11592
|
|
57
57
|
iop/messages/persistent.py,sha256=ibRhRTqzwGcAqem744KZzHiouUlc8-J3ftB4zyzQYx4,16906
|
|
58
58
|
iop/messages/serialization.py,sha256=BW0o-7GaceMW7RMOzOJ8g9rKEv28NYnYFwtTLmAf7Yg,9255
|
|
59
59
|
iop/messages/validation.py,sha256=X6MSWsjLZDuyX1Tfx0TP3T6OI4nj1HZccwR2Z9PSubY,1606
|
|
@@ -61,7 +61,7 @@ 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
|
|
63
63
|
iop/migration/plans.py,sha256=5kx3aqQiPDJ3F8hU9pp9_mOO1_N6GA0Ps7--G1Iv6z8,2549
|
|
64
|
-
iop/migration/utils.py,sha256=
|
|
64
|
+
iop/migration/utils.py,sha256=pOojLPMZes05KXrGN2ap45ffppP5Z4tS4bjJ0gSD5Oc,38183
|
|
65
65
|
iop/production/__init__.py,sha256=95VmJgC3lWtHpUJijLqyKKxFZa65OcRni8803kb4aHE,2148
|
|
66
66
|
iop/production/actions.py,sha256=TLVAjPTPq21oLj9c-IG10qMNJ2hvPzueviMy_c1a0ZU,17199
|
|
67
67
|
iop/production/common.py,sha256=IoUg9jkFzSQwDsHcXvkVAC4qxpWKs3kTfXFm_EP07EU,3091
|
|
@@ -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.1b3.dist-info/licenses/LICENSE,sha256=rZSiBFId_sfbJ6RL0GjjPX-InNLkNS9ou7eQsikciI8,1089
|
|
95
|
+
iris_pex_embedded_python-4.0.1b3.dist-info/METADATA,sha256=UFR3F4n2-7iQJSkQ0WLBQYtmNaBwO08z7gZLl-q-_Hg,5846
|
|
96
|
+
iris_pex_embedded_python-4.0.1b3.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
97
|
+
iris_pex_embedded_python-4.0.1b3.dist-info/entry_points.txt,sha256=fzS8ZFsPe8cnpEx208X60DNugCPQmuSloPeg4pyyJDY,42
|
|
98
|
+
iris_pex_embedded_python-4.0.1b3.dist-info/top_level.txt,sha256=BM54-OXQ6l2BDtmesWNXckh033s9gcjoO7bfjbwZbxU,4
|
|
99
|
+
iris_pex_embedded_python-4.0.1b3.dist-info/RECORD,,
|
{iris_pex_embedded_python-4.0.1b1.dist-info → iris_pex_embedded_python-4.0.1b3.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|