iris-pex-embedded-python 3.3.1b1__py3-none-any.whl → 3.4.0b2__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.

Potentially problematic release.


This version of iris-pex-embedded-python might be problematic. Click here for more details.

grongier/pex/__init__.py CHANGED
@@ -6,7 +6,7 @@ from iop._business_operation import _BusinessOperation
6
6
  from iop._inbound_adapter import _InboundAdapter
7
7
  from iop._outbound_adapter import _OutboundAdapter
8
8
  from iop._message import _Message
9
- from iop._pickle_message import _PickleMessage
9
+ from iop._message import _PickleMessage
10
10
  from iop._director import _Director
11
11
  from iop._utils import _Utils
12
12
 
iop/__init__.py CHANGED
@@ -3,9 +3,8 @@ from iop._business_process import _BusinessProcess
3
3
  from iop._business_service import _BusinessService
4
4
  from iop._director import _Director
5
5
  from iop._inbound_adapter import _InboundAdapter
6
- from iop._message import _Message
6
+ from iop._message import _Message, _PickleMessage, _PydanticMessage, _PydanticPickleMessage
7
7
  from iop._outbound_adapter import _OutboundAdapter
8
- from iop._pickle_message import _PickleMessage
9
8
  from iop._private_session_duplex import _PrivateSessionDuplex
10
9
  from iop._private_session_process import _PrivateSessionProcess
11
10
  from iop._utils import _Utils
@@ -21,4 +20,6 @@ class DuplexOperation(_PrivateSessionDuplex): pass
21
20
  class DuplexProcess(_PrivateSessionProcess): pass
22
21
  class Message(_Message): pass
23
22
  class PickleMessage(_PickleMessage): pass
23
+ class PydanticMessage(_PydanticMessage): pass
24
+ class PydanticPickleMessage(_PydanticPickleMessage): pass
24
25
  class Director(_Director): pass
iop/_dispatch.py CHANGED
@@ -7,6 +7,7 @@ from typing import Any, Dict, List, Type
7
7
 
8
8
  import iris
9
9
  from dacite import Config, from_dict
10
+ from pydantic import BaseModel
10
11
 
11
12
  from iop._utils import _Utils
12
13
  from iop._serialization import IrisJSONEncoder, IrisJSONDecoder
@@ -165,17 +166,20 @@ def dataclass_from_dict(klass: Type, dikt: Dict) -> Any:
165
166
  Returns:
166
167
  A dataclass object with the fields of the dataclass and the fields of the dictionary.
167
168
  """
168
- ret = from_dict(klass, dikt, Config(check_types=False))
169
-
170
- try:
171
- fieldtypes = klass.__annotations__
172
- except Exception as e:
173
- fieldtypes = []
174
-
175
- for key, val in dikt.items():
176
- if key not in fieldtypes:
177
- setattr(ret, key, val)
178
- return ret
169
+ if issubclass(klass, BaseModel):
170
+ return klass.model_validate(dikt)
171
+ else:
172
+ ret = from_dict(klass, dikt, Config(check_types=False))
173
+
174
+ try:
175
+ fieldtypes = klass.__annotations__
176
+ except Exception as e:
177
+ fieldtypes = []
178
+
179
+ for key, val in dikt.items():
180
+ if key not in fieldtypes:
181
+ setattr(ret, key, val)
182
+ return ret
179
183
 
180
184
  def dispach_message(host, request: Any) -> Any:
181
185
  """Dispatches the message to the appropriate method.
iop/_message.py CHANGED
@@ -1,6 +1,28 @@
1
+ from typing import Any
2
+ from pydantic import BaseModel
3
+
1
4
  class _Message:
2
5
  """ The abstract class that is the superclass for persistent messages sent from one component to another.
3
6
  This class has no properties or methods. Users subclass Message and add properties.
4
7
  The IOP framework provides the persistence to objects derived from the Message class.
5
8
  """
6
- pass
9
+ pass
10
+
11
+ class _PickleMessage:
12
+ """ The abstract class that is the superclass for persistent messages sent from one component to another.
13
+ This class has no properties or methods. Users subclass Message and add properties.
14
+ The IOP framework provides the persistence to objects derived from the Message class.
15
+ """
16
+ pass
17
+
18
+ class _PydanticMessage(BaseModel):
19
+ """Base class for Pydantic-based messages that can be serialized to IRIS."""
20
+
21
+ def __init__(self, **data: Any):
22
+ super().__init__(**data)
23
+
24
+ class _PydanticPickleMessage(BaseModel):
25
+ """Base class for Pydantic-based messages that can be serialized to IRIS."""
26
+
27
+ def __init__(self, **data: Any):
28
+ super().__init__(**data)
iop/_message_validator.py CHANGED
@@ -1,9 +1,12 @@
1
1
  import dataclasses
2
2
  from typing import Any, Type
3
+ from iop._message import _Message, _PickleMessage, _PydanticPickleMessage, BaseModel
3
4
 
4
5
 
5
6
  def is_message_instance(obj: Any) -> bool:
6
7
  """Check if object is a valid Message instance."""
8
+ if isinstance(obj, BaseModel):
9
+ return True
7
10
  if is_message_class(type(obj)):
8
11
  if not dataclasses.is_dataclass(obj):
9
12
  raise TypeError(f"{type(obj).__module__}.{type(obj).__qualname__} must be a dataclass")
@@ -13,6 +16,8 @@ def is_message_instance(obj: Any) -> bool:
13
16
 
14
17
  def is_pickle_message_instance(obj: Any) -> bool:
15
18
  """Check if object is a PickleMessage instance."""
19
+ if isinstance(obj, _PydanticPickleMessage):
20
+ return True
16
21
  if is_pickle_message_class(type(obj)):
17
22
  return True
18
23
  return False
@@ -27,15 +32,16 @@ def is_iris_object_instance(obj: Any) -> bool:
27
32
 
28
33
  def is_message_class(klass: Type) -> bool:
29
34
  """Check if class is a Message type."""
30
- name = f"{klass.__module__}.{klass.__qualname__}"
31
- if name in ("iop.Message", "grongier.pex.Message"):
35
+ if issubclass(klass, _Message):
32
36
  return True
33
- return any(is_message_class(c) for c in klass.__bases__)
37
+ return False
38
+
34
39
 
35
40
 
36
41
  def is_pickle_message_class(klass: Type) -> bool:
37
42
  """Check if class is a PickleMessage type."""
38
- name = f"{klass.__module__}.{klass.__qualname__}"
39
- if name in ("iop.PickleMessage", "grongier.pex.PickleMessage"):
43
+ if issubclass(klass, _PickleMessage):
44
+ return True
45
+ if issubclass(klass, _PydanticPickleMessage):
40
46
  return True
41
- return any(is_pickle_message_class(c) for c in klass.__bases__)
47
+ return False
iop/_serialization.py CHANGED
@@ -14,7 +14,9 @@ from typing import Any, Dict, Type, Optional
14
14
  from dacite import Config, from_dict
15
15
  import iris
16
16
 
17
+ from iop._message import _PydanticPickleMessage
17
18
  from iop._utils import _Utils
19
+ from pydantic import BaseModel
18
20
 
19
21
  # Constants
20
22
  DATETIME_FORMAT_LENGTH = 23
@@ -91,6 +93,8 @@ class IrisJSONEncoder(json.JSONEncoder):
91
93
  """JSONEncoder that handles dates, decimals, UUIDs, etc."""
92
94
 
93
95
  def default(self, obj: Any) -> Any:
96
+ if isinstance(obj, BaseModel):
97
+ return obj.model_dump()
94
98
  if obj.__class__.__name__ == 'DataFrame':
95
99
  return f'dataframe:{TypeConverter.convert_to_string("dataframe", obj)}'
96
100
  elif isinstance(obj, datetime.datetime):
@@ -134,6 +138,12 @@ class MessageSerializer:
134
138
  @staticmethod
135
139
  def serialize(message: Any, use_pickle: bool = False) -> iris.cls:
136
140
  """Serializes a message to IRIS format."""
141
+ # Check for PydanticPickleMessage first
142
+ if isinstance(message, _PydanticPickleMessage):
143
+ return MessageSerializer._serialize_pickle(message)
144
+ if isinstance(message, BaseModel):
145
+ return (MessageSerializer._serialize_pickle(message)
146
+ if use_pickle else MessageSerializer._serialize_json(message))
137
147
  if use_pickle:
138
148
  return MessageSerializer._serialize_pickle(message)
139
149
  return MessageSerializer._serialize_json(message)
@@ -155,7 +165,11 @@ class MessageSerializer:
155
165
 
156
166
  @staticmethod
157
167
  def _serialize_json(message: Any) -> iris.cls:
158
- json_string = json.dumps(message, cls=IrisJSONEncoder, ensure_ascii=False)
168
+ if isinstance(message, BaseModel):
169
+ json_string = json.dumps(message.model_dump(), cls=IrisJSONEncoder, ensure_ascii=False)
170
+ else:
171
+ json_string = json.dumps(message, cls=IrisJSONEncoder, ensure_ascii=False)
172
+
159
173
  msg = iris.cls('IOP.Message')._New()
160
174
  msg.classname = f"{message.__class__.__module__}.{message.__class__.__name__}"
161
175
 
@@ -187,7 +201,10 @@ class MessageSerializer:
187
201
 
188
202
  try:
189
203
  json_dict = json.loads(json_string, cls=IrisJSONDecoder)
190
- return dataclass_from_dict(msg_class, json_dict)
204
+ if issubclass(msg_class, BaseModel):
205
+ return msg_class.model_validate(json_dict)
206
+ else:
207
+ return dataclass_from_dict(msg_class, json_dict)
191
208
  except Exception as e:
192
209
  raise SerializationError(f"Failed to deserialize JSON: {str(e)}")
193
210
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: iris_pex_embedded_python
3
- Version: 3.3.1b1
3
+ Version: 3.4.0b2
4
4
  Summary: Iris Interoperability based on Embedded Python
5
5
  Author-email: grongier <guillaume.rongier@intersystems.com>
6
6
  License: MIT License
@@ -45,6 +45,7 @@ Classifier: Topic :: Utilities
45
45
  Description-Content-Type: text/markdown
46
46
  License-File: LICENSE
47
47
  Requires-Dist: dacite>=1.6.0
48
+ Requires-Dist: pydantic>=2.0.0
48
49
  Requires-Dist: xmltodict>=0.12.0
49
50
  Requires-Dist: iris-embedded-python-wrapper>=0.0.6
50
51
  Requires-Dist: setuptools>=40.8.0
@@ -19,7 +19,7 @@ grongier/cls/Grongier/PEX/PrivateSession/Message/Poll.cls,sha256=pcUgHgxX1pMH-wQ
19
19
  grongier/cls/Grongier/PEX/PrivateSession/Message/Start.cls,sha256=T3jNoR8RjKr1InQ6SgqBYTgFwpSB0Q60WholjbvForg,433
20
20
  grongier/cls/Grongier/PEX/PrivateSession/Message/Stop.cls,sha256=zy30ZXXN4XcovPij-kOF3PuH1SkP1EUvlEJQRx2S9RU,431
21
21
  grongier/cls/Grongier/Service/WSGI.cls,sha256=7u2SsFmnsubMfdazvaDchKCM3yesPRMfKBzMIkwQ9xc,77
22
- grongier/pex/__init__.py,sha256=zHFF0Znipx1fwHYUEBZjNOYoZH1ro7z4IgYDU32kdn0,1067
22
+ grongier/pex/__init__.py,sha256=CPLDFa4dusvGX9VZYTUk-M0Xa_yR4e4Gqku1rIT75qo,1060
23
23
  grongier/pex/__main__.py,sha256=pQzVtkDhAeI6dpNRC632dVk2SGZZIEDwDufdgZe8VWs,98
24
24
  grongier/pex/_business_host.py,sha256=dlV8CWJad8Pr2TNfD9OjcVKaq5gEYQACZla1FK6-bDM,44
25
25
  grongier/pex/_cli.py,sha256=hOHz3n-aHtULuhdCkqZ_SSb3sv7M6j2WhRxgCTvgR9I,64
@@ -90,7 +90,7 @@ intersystems_iris/pex/_InboundAdapter.py,sha256=gZlWl7afumamkj8pNbpLyKFSzhaTAiAX
90
90
  intersystems_iris/pex/_Message.py,sha256=Ugaa_lsEYke__pI5kdC7phAuyPQ7rxXUcROJL4cUxVQ,320
91
91
  intersystems_iris/pex/_OutboundAdapter.py,sha256=ao2Ubbta2DcrQGdzDUD_j1Zsk8bvUfcZNKTZkzPTNBU,1628
92
92
  intersystems_iris/pex/__init__.py,sha256=l_I1dpnluWawbFrGMDC0GLHpuHwjbpd-nho8otFX6TE,1379
93
- iop/__init__.py,sha256=fX1Osx2Dmcuv8C5hmvoG4fPDIbk0qksJcIgpQibJ_p4,1067
93
+ iop/__init__.py,sha256=1C589HojSVK0yJf1KuTPA39ZjrOYO0QFLv45rqbZpA4,1183
94
94
  iop/__main__.py,sha256=pQzVtkDhAeI6dpNRC632dVk2SGZZIEDwDufdgZe8VWs,98
95
95
  iop/_async_request.py,sha256=btDFNFaO-Yvl6wvgXrCYNWoQb2RtbzEvTJsk7j03b30,2170
96
96
  iop/_business_host.py,sha256=wI2LlVTVjEqE8GWE9nSz1WHvqTduAuJQTk7Ky7qkz4U,9658
@@ -101,16 +101,15 @@ iop/_cli.py,sha256=IwvVxglSTVkCDXwANLMqnd8mfxGtWB6GjBSdEy8EMm0,7551
101
101
  iop/_common.py,sha256=E_Mn2t--klAtT4p1MzW1KtcKcLrB1g4Flq5H4JlV8Vs,11619
102
102
  iop/_decorators.py,sha256=ZpgEETLdKWv58AoSMfXnm3_mA-6qPphIegjG-npDgwg,2324
103
103
  iop/_director.py,sha256=DrswFoqJ6IG62hkW-0ZffTtZdxw6KNozlZSIq3O6d-o,11629
104
- iop/_dispatch.py,sha256=4317Z0ujXxDGUQaL7WX6zfGzBPOdw70MWiqmLUKxhik,6611
104
+ iop/_dispatch.py,sha256=q9oCE4b5FazW1t2oczvBGQtKzip_-yykY9WvXUp1urE,6775
105
105
  iop/_inbound_adapter.py,sha256=PS5ToqhrYcXq9ZdLbCBqAfVp8kCeRACm_KF66pwBO9U,1652
106
106
  iop/_log_manager.py,sha256=PZnGWsi-zvWo-bumQO5BK-8kHG2XW-WnZ6ShL7QeZ4c,3499
107
- iop/_message.py,sha256=LSkfZcmEu1aj2hdSg3sUHSWNc8tWWZR8Q2_h9_axVrs,325
108
- iop/_message_validator.py,sha256=xMMPOZOop3Nv12E3_QPI5caTgYgAzoKlRxcMmUkrj2c,1379
107
+ iop/_message.py,sha256=pJQOjRIdw4wSDoJamvItGODMe-UjDU71XihgWdtCAqc,1120
108
+ iop/_message_validator.py,sha256=K6FxLe72gBHQXZTLVrFw87rABGM0F6CTaNtZ2MqJoss,1408
109
109
  iop/_outbound_adapter.py,sha256=YTAhLrRf9chEAd53mV6KKbpaHOKNOKJHoGgj5wakRR0,726
110
- iop/_pickle_message.py,sha256=noKfc2VkXufV3fqjKvNHN_oANQ1YN9ffCaSV0XSTAIE,331
111
110
  iop/_private_session_duplex.py,sha256=mzlFABh-ly51X1uSWw9YwQbktfMvuNdp2ALlRvlDow4,5152
112
111
  iop/_private_session_process.py,sha256=todprfYFSDr-h-BMvWL_IGC6wbQqkMy3mPHWEWCUSE0,1686
113
- iop/_serialization.py,sha256=jHJGTMpKI2QDcF_m7R0WyH_J-vjQyYpNpD0ktn9Rqo4,8106
112
+ iop/_serialization.py,sha256=hGpFYHWjYRcDuQv4Ml9N16onW8vmHGhDwA3bv_NwFnM,8923
114
113
  iop/_utils.py,sha256=Aqtp9Jx3ghzkNs4f2cOZXYwv8cGsjmdBocnkP64fa3M,19574
115
114
  iop/cls/IOP/BusinessOperation.cls,sha256=lrymqZ8wHl5kJjXwdjbQVs5sScV__yIWGh-oGbiB_X0,914
116
115
  iop/cls/IOP/BusinessProcess.cls,sha256=s3t38w1ykHqM26ETcbCYLt0ocjZyVVahm-_USZkuJ1E,2855
@@ -136,9 +135,9 @@ iop/cls/IOP/Service/WSGI.cls,sha256=VLNCXEwmHW9dBnE51uGE1nvGX6T4HjhqePT3LVhsjAE,
136
135
  iop/wsgi/handlers.py,sha256=NrFLo_YbAh-x_PlWhAiWkQnUUN2Ss9HoEm63dDWCBpQ,2947
137
136
  irisnative/_IRISNative.py,sha256=HQ4nBhc8t8_5OtxdMG-kx1aa-T1znf2I8obZOPLOPzg,665
138
137
  irisnative/__init__.py,sha256=6YmvBLQSURsCPKaNg7LK-xpo4ipDjrlhKuwdfdNb3Kg,341
139
- iris_pex_embedded_python-3.3.1b1.dist-info/LICENSE,sha256=rZSiBFId_sfbJ6RL0GjjPX-InNLkNS9ou7eQsikciI8,1089
140
- iris_pex_embedded_python-3.3.1b1.dist-info/METADATA,sha256=BcT-Xi5r6ps-VXr5Kk_e7njZ8JU_Gqg6CoSQzUH9i5U,4427
141
- iris_pex_embedded_python-3.3.1b1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
142
- iris_pex_embedded_python-3.3.1b1.dist-info/entry_points.txt,sha256=pj-i4LSDyiSP6xpHlVjMCbg1Pik7dC3_sdGY3Yp9Vhk,38
143
- iris_pex_embedded_python-3.3.1b1.dist-info/top_level.txt,sha256=VWDlX4YF4qFVRGrG3-Gs0kgREol02i8gIpsHNbhfFPw,42
144
- iris_pex_embedded_python-3.3.1b1.dist-info/RECORD,,
138
+ iris_pex_embedded_python-3.4.0b2.dist-info/LICENSE,sha256=rZSiBFId_sfbJ6RL0GjjPX-InNLkNS9ou7eQsikciI8,1089
139
+ iris_pex_embedded_python-3.4.0b2.dist-info/METADATA,sha256=wSmLx_zkXK9oTutFdot5ManhtmjC7_-eYrZLeCC4w_Q,4458
140
+ iris_pex_embedded_python-3.4.0b2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
141
+ iris_pex_embedded_python-3.4.0b2.dist-info/entry_points.txt,sha256=pj-i4LSDyiSP6xpHlVjMCbg1Pik7dC3_sdGY3Yp9Vhk,38
142
+ iris_pex_embedded_python-3.4.0b2.dist-info/top_level.txt,sha256=VWDlX4YF4qFVRGrG3-Gs0kgREol02i8gIpsHNbhfFPw,42
143
+ iris_pex_embedded_python-3.4.0b2.dist-info/RECORD,,
iop/_pickle_message.py DELETED
@@ -1,6 +0,0 @@
1
- class _PickleMessage:
2
- """ The abstract class that is the superclass for persistent messages sent from one component to another.
3
- This class has no properties or methods. Users subclass Message and add properties.
4
- The PEX framework provides the persistence to objects derived from the Message class.
5
- """
6
- pass