iris-pex-embedded-python 2.3.27b2__py3-none-any.whl → 3.2.1b2__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.

Files changed (85) hide show
  1. grongier/cls/Grongier/PEX/BusinessOperation.cls +1 -28
  2. grongier/cls/Grongier/PEX/BusinessProcess.cls +1 -100
  3. grongier/cls/Grongier/PEX/BusinessService.cls +1 -28
  4. grongier/cls/Grongier/PEX/Common.cls +1 -194
  5. grongier/cls/Grongier/PEX/Director.cls +1 -48
  6. grongier/cls/Grongier/PEX/Duplex/Operation.cls +1 -26
  7. grongier/cls/Grongier/PEX/Duplex/Process.cls +1 -217
  8. grongier/cls/Grongier/PEX/Duplex/Service.cls +1 -6
  9. grongier/cls/Grongier/PEX/InboundAdapter.cls +1 -15
  10. grongier/cls/Grongier/PEX/Message.cls +1 -116
  11. grongier/cls/Grongier/PEX/OutboundAdapter.cls +1 -29
  12. grongier/cls/Grongier/PEX/PickleMessage.cls +1 -46
  13. grongier/cls/Grongier/PEX/PrivateSession/Duplex.cls +1 -253
  14. grongier/cls/Grongier/PEX/PrivateSession/Message/Ack.cls +1 -19
  15. grongier/cls/Grongier/PEX/PrivateSession/Message/Poll.cls +1 -19
  16. grongier/cls/Grongier/PEX/PrivateSession/Message/Start.cls +1 -19
  17. grongier/cls/Grongier/PEX/PrivateSession/Message/Stop.cls +1 -35
  18. grongier/cls/Grongier/PEX/Test.cls +1 -53
  19. grongier/cls/Grongier/PEX/Utils.cls +1 -365
  20. grongier/cls/Grongier/Service/WSGI.cls +1 -307
  21. grongier/pex/__init__.py +11 -11
  22. grongier/pex/__main__.py +1 -1
  23. grongier/pex/_business_host.py +1 -511
  24. grongier/pex/_cli.py +2 -150
  25. grongier/pex/_common.py +1 -347
  26. grongier/pex/_director.py +1 -286
  27. grongier/pex/_utils.py +1 -369
  28. intersystems_iris/_ConnectionInformation.py +22 -20
  29. intersystems_iris/dbapi/_DBAPI.py +6 -1
  30. intersystems_iris/dbapi/_ResultSetRow.py +26 -15
  31. intersystems_iris/dbapi/preparser/_PreParser.py +4 -1
  32. iop/__init__.py +24 -0
  33. iop/__main__.py +4 -0
  34. iop/_business_host.py +675 -0
  35. iop/_business_operation.py +71 -0
  36. iop/_business_process.py +220 -0
  37. {grongier/pex → iop}/_business_service.py +2 -2
  38. iop/_cli.py +141 -0
  39. iop/_common.py +352 -0
  40. iop/_director.py +301 -0
  41. {grongier/pex → iop}/_inbound_adapter.py +1 -1
  42. iop/_log_manager.py +81 -0
  43. {grongier/pex → iop}/_message.py +1 -1
  44. {grongier/pex → iop}/_outbound_adapter.py +1 -1
  45. {grongier/pex → iop}/_private_session_duplex.py +3 -2
  46. {grongier/pex → iop}/_private_session_process.py +2 -2
  47. iop/_utils.py +458 -0
  48. iop/cls/IOP/BusinessOperation.cls +35 -0
  49. iop/cls/IOP/BusinessProcess.cls +124 -0
  50. iop/cls/IOP/BusinessService.cls +35 -0
  51. iop/cls/IOP/Common.cls +344 -0
  52. iop/cls/IOP/Director.cls +62 -0
  53. iop/cls/IOP/Duplex/Operation.cls +29 -0
  54. iop/cls/IOP/Duplex/Process.cls +229 -0
  55. iop/cls/IOP/Duplex/Service.cls +9 -0
  56. iop/cls/IOP/InboundAdapter.cls +22 -0
  57. iop/cls/IOP/Message/JSONSchema.cls +125 -0
  58. iop/cls/IOP/Message.cls +729 -0
  59. iop/cls/IOP/OutboundAdapter.cls +36 -0
  60. iop/cls/IOP/PickleMessage.cls +58 -0
  61. iop/cls/IOP/PrivateSession/Duplex.cls +260 -0
  62. iop/cls/IOP/PrivateSession/Message/Ack.cls +32 -0
  63. iop/cls/IOP/PrivateSession/Message/Poll.cls +32 -0
  64. iop/cls/IOP/PrivateSession/Message/Start.cls +32 -0
  65. iop/cls/IOP/PrivateSession/Message/Stop.cls +48 -0
  66. iop/cls/IOP/Service/WSGI.cls +310 -0
  67. iop/cls/IOP/Test.cls +85 -0
  68. iop/cls/IOP/Utils.cls +378 -0
  69. iop/wsgi/handlers.py +104 -0
  70. iris_pex_embedded_python-3.2.1b2.dist-info/METADATA +90 -0
  71. iris_pex_embedded_python-3.2.1b2.dist-info/RECORD +139 -0
  72. {iris_pex_embedded_python-2.3.27b2.dist-info → iris_pex_embedded_python-3.2.1b2.dist-info}/WHEEL +1 -1
  73. iris_pex_embedded_python-3.2.1b2.dist-info/entry_points.txt +2 -0
  74. {iris_pex_embedded_python-2.3.27b2.dist-info → iris_pex_embedded_python-3.2.1b2.dist-info}/top_level.txt +1 -1
  75. grongier/pex/_business_operation.py +0 -70
  76. grongier/pex/_business_process.py +0 -215
  77. iris/__init__.py +0 -60
  78. iris/__init__.pyi +0 -236
  79. iris/iris_ipm.py +0 -40
  80. iris/iris_ipm.pyi +0 -17
  81. iris_pex_embedded_python-2.3.27b2.dist-info/METADATA +0 -1384
  82. iris_pex_embedded_python-2.3.27b2.dist-info/RECORD +0 -113
  83. iris_pex_embedded_python-2.3.27b2.dist-info/entry_points.txt +0 -2
  84. {grongier/pex → iop}/_pickle_message.py +0 -0
  85. {iris_pex_embedded_python-2.3.27b2.dist-info → iris_pex_embedded_python-3.2.1b2.dist-info}/LICENSE +0 -0
@@ -0,0 +1,71 @@
1
+ import importlib
2
+ from typing import Any, List, Optional, Union, Tuple
3
+ from iop._business_host import _BusinessHost
4
+
5
+ class _BusinessOperation(_BusinessHost):
6
+ """Business operation component that handles outbound communication.
7
+
8
+ Responsible for sending messages to external systems. Can optionally use an
9
+ adapter to handle the outbound messaging protocol.
10
+ """
11
+
12
+ DISPATCH: List[Tuple[str, str]] = []
13
+ Adapter: Any = None
14
+ adapter: Any = None
15
+
16
+ def on_message(self, request: Any) -> Any:
17
+ """Handle incoming messages.
18
+
19
+ Process messages received from other production components and either
20
+ send to external system or forward to another component.
21
+
22
+ Args:
23
+ request: The incoming message
24
+
25
+ Returns:
26
+ Response message
27
+ """
28
+ return self.OnMessage(request)
29
+
30
+ def on_keepalive(self) -> None:
31
+ """
32
+ Called when the server sends a keepalive message.
33
+ """
34
+ return
35
+
36
+ def _set_iris_handles(self, handle_current: Any, handle_partner: Any) -> None:
37
+ """For internal use only."""
38
+ self.iris_handle = handle_current
39
+ if type(handle_partner).__module__.find('iris') == 0:
40
+ if handle_partner._IsA("Grongier.PEX.OutboundAdapter") or handle_partner._IsA("IOP.OutboundAdapter"):
41
+ module = importlib.import_module(handle_partner.GetModule())
42
+ handle_partner = getattr(module, handle_partner.GetClassname())()
43
+ self.Adapter = self.adapter = handle_partner
44
+ return
45
+
46
+ def _dispatch_on_init(self, host_object: Any) -> None:
47
+ """For internal use only."""
48
+ self._create_dispatch()
49
+ self.on_init()
50
+ return
51
+
52
+ @_BusinessHost.input_deserialzer
53
+ @_BusinessHost.output_serialzer
54
+ def _dispatch_on_message(self, request: Any) -> Any:
55
+ """For internal use only."""
56
+ return self._dispach_message(request)
57
+
58
+ def OnMessage(self, request: Any) -> Any:
59
+ """DEPRECATED : use on_message
60
+ Called when the business operation receives a message from another production component.
61
+ Typically, the operation will either send the message to the external system or forward it to a business process or another business operation.
62
+ If the operation has an adapter, it uses the Adapter.invoke() method to call the method on the adapter that sends the message to the external system.
63
+ If the operation is forwarding the message to another production component, it uses the SendRequestAsync() or the SendRequestSync() method
64
+
65
+ Parameters:
66
+ request: An instance of either a subclass of Message or of IRISObject containing the incoming message for the business operation.
67
+
68
+ Returns:
69
+ The response object
70
+ """
71
+ return
@@ -0,0 +1,220 @@
1
+ from typing import Any, List, Optional, Union
2
+ from iop._business_host import _BusinessHost
3
+
4
+ class _BusinessProcess(_BusinessHost):
5
+ """Business process component that contains routing and transformation logic.
6
+
7
+ A business process can receive messages from services, other processes, or operations.
8
+ It can modify messages, transform formats, and route based on content.
9
+ """
10
+
11
+ DISPATCH: List[tuple] = []
12
+ PERSISTENT_PROPERTY_LIST: Optional[List[str]] = None
13
+
14
+ def on_message(self, request: Any) -> Any:
15
+ """Handle incoming messages.
16
+
17
+ Args:
18
+ request: The incoming message
19
+
20
+ Returns:
21
+ Response message
22
+ """
23
+ return self.on_request(request)
24
+
25
+ def on_request(self, request: Any) -> Any:
26
+ """Process initial requests sent to this component.
27
+
28
+ Args:
29
+ request: The incoming request message
30
+
31
+ Returns:
32
+ Response message
33
+ """
34
+ return self.OnRequest(request)
35
+
36
+ def on_response(self, request: Any, response: Any, call_request: Any, call_response: Any, completion_key: str) -> Any:
37
+ """Handle responses to messages sent by this component.
38
+
39
+ Args:
40
+ request: The initial request message
41
+ response: The response message
42
+ call_request: The request sent to the target
43
+ call_response: The incoming response
44
+ completion_key: The completion key specified in the outgoing SendAsync() method
45
+
46
+ Returns:
47
+ Response message
48
+ """
49
+ return self.OnResponse(request, response, call_request, call_response, completion_key)
50
+
51
+ def on_complete(self, request: Any, response: Any) -> Any:
52
+ """Called after all responses to requests sent by this component have been handled.
53
+
54
+ Args:
55
+ request: The initial request message
56
+ response: The response message
57
+
58
+ Returns:
59
+ Response message
60
+ """
61
+ return self.OnComplete(request, response)
62
+
63
+ @_BusinessHost.input_serialzer_param(0,'response')
64
+ def reply(self, response: Any) -> None:
65
+ """Send the specified response to the production component that sent the initial request.
66
+
67
+ Args:
68
+ response: The response message
69
+ """
70
+ return self.iris_handle.dispatchReply(response)
71
+
72
+ @_BusinessHost.input_serialzer_param(1,'request')
73
+ def send_request_async(self, target: str, request: Any, response_required: bool=True, completion_key: Optional[str]=None, description: Optional[str]=None) -> None:
74
+ """Send the specified message to the target business process or business operation asynchronously.
75
+
76
+ Args:
77
+ target: The name of the business process or operation to receive the request
78
+ request: The message to send to the target
79
+ response_required: Whether a response is required
80
+ completion_key: A string that will be returned with the response if the maximum time is exceeded
81
+ description: An optional description property in the message header
82
+
83
+ Raises:
84
+ TypeError: If request is not of type Message or IRISObject
85
+ """
86
+ if response_required:
87
+ response_required = 1
88
+ else:
89
+ response_required = 0
90
+ return self.iris_handle.dispatchSendRequestAsync(target, request, response_required, completion_key, description)
91
+
92
+ def set_timer(self, timeout: Union[int, str], completion_key: Optional[str]=None) -> None:
93
+ """Specify the maximum time the business process will wait for responses.
94
+
95
+ Args:
96
+ timeout: The maximum time to wait for responses
97
+ completion_key: A string that will be returned with the response if the maximum time is exceeded
98
+ """
99
+ self.iris_handle.dispatchSetTimer(timeout, completion_key)
100
+ return
101
+
102
+ def _set_iris_handles(self, handle_current: Any, handle_partner: Any) -> None:
103
+ """For internal use only."""
104
+ self.iris_handle = handle_current
105
+ return
106
+
107
+ def _save_persistent_properties(self, host_object: Any) -> None:
108
+ """For internal use only."""
109
+ if self.PERSISTENT_PROPERTY_LIST is None:
110
+ return
111
+ for prop in self.PERSISTENT_PROPERTY_LIST:
112
+ val = getattr(self, prop, None)
113
+ typ = val.__class__.__name__
114
+ if typ in ["str", "int", "float", "bool", "bytes"]:
115
+ try:
116
+ host_object.setPersistentProperty(prop, val)
117
+ except:
118
+ pass
119
+ return
120
+
121
+ def _restore_persistent_properties(self, host_object: Any) -> None:
122
+ """For internal use only."""
123
+ if self.PERSISTENT_PROPERTY_LIST is None:
124
+ return
125
+ for prop in self.PERSISTENT_PROPERTY_LIST:
126
+ try:
127
+ val = host_object.getPersistentProperty(prop)
128
+ setattr(self, prop, val)
129
+ except:
130
+ pass
131
+ return
132
+
133
+ def _dispatch_on_connected(self, host_object: Any) -> None:
134
+ """For internal use only."""
135
+ self.on_connected()
136
+ self._save_persistent_properties(host_object)
137
+ return
138
+
139
+ def _dispatch_on_init(self, host_object: Any) -> None:
140
+ """For internal use only."""
141
+ self._restore_persistent_properties(host_object)
142
+ self._create_dispatch()
143
+ self.on_init()
144
+ self._save_persistent_properties(host_object)
145
+ return
146
+
147
+ def _dispatch_on_tear_down(self, host_object: Any) -> None:
148
+ """For internal use only."""
149
+ self._restore_persistent_properties(host_object)
150
+ self.on_tear_down()
151
+ self._save_persistent_properties(host_object)
152
+ return
153
+
154
+ @_BusinessHost.input_deserialzer
155
+ @_BusinessHost.output_serialzer
156
+ def _dispatch_on_request(self, host_object: Any, request: Any) -> Any:
157
+ """For internal use only."""
158
+ self._restore_persistent_properties(host_object)
159
+ return_object = self._dispach_message(request)
160
+ self._save_persistent_properties(host_object)
161
+ return return_object
162
+
163
+ @_BusinessHost.input_deserialzer
164
+ @_BusinessHost.output_serialzer
165
+ def _dispatch_on_response(self, host_object: Any, request: Any, response: Any, call_request: Any, call_response: Any, completion_key: str) -> Any:
166
+ """For internal use only."""
167
+ self._restore_persistent_properties(host_object)
168
+ return_object = self.on_response(request, response, call_request, call_response, completion_key)
169
+ self._save_persistent_properties(host_object)
170
+ return return_object
171
+
172
+ @_BusinessHost.input_deserialzer
173
+ @_BusinessHost.output_serialzer
174
+ def _dispatch_on_complete(self, host_object: Any, request: Any, response: Any) -> Any:
175
+ """For internal use only."""
176
+ self._restore_persistent_properties(host_object)
177
+ return_object = self.on_complete(request, response)
178
+ self._save_persistent_properties(host_object)
179
+ return return_object
180
+
181
+ def OnRequest(self, request: Any) -> Any:
182
+ """
183
+ DEPRECATED: Use on_request.
184
+
185
+ Args:
186
+ request: The incoming request message
187
+
188
+ Returns:
189
+ Response message
190
+ """
191
+ return
192
+
193
+ def OnResponse(self, request: Any, response: Any, call_request: Any, call_response: Any, completion_key: str) -> Any:
194
+ """
195
+ DEPRECATED: Use on_response.
196
+
197
+ Args:
198
+ request: The initial request message
199
+ response: The response message
200
+ call_request: The request sent to the target
201
+ call_response: The incoming response
202
+ completion_key: The completion key specified in the outgoing SendAsync() method
203
+
204
+ Returns:
205
+ Response message
206
+ """
207
+ return response
208
+
209
+ def OnComplete(self, request: Any, response: Any) -> Any:
210
+ """
211
+ DEPRECATED: Use on_complete.
212
+
213
+ Args:
214
+ request: The initial request message
215
+ response: The response message
216
+
217
+ Returns:
218
+ Response message
219
+ """
220
+ return response
@@ -1,5 +1,5 @@
1
1
  import importlib
2
- from grongier.pex._business_host import _BusinessHost
2
+ from iop._business_host import _BusinessHost
3
3
 
4
4
  class _BusinessService(_BusinessHost):
5
5
  """ This class is responsible for receiving the data from external system and sending it to business processes or business operations in the production.
@@ -30,7 +30,7 @@ class _BusinessService(_BusinessHost):
30
30
  """ For internal use only. """
31
31
  self.iris_handle = handle_current
32
32
  if type(handle_partner).__module__.find('iris') == 0:
33
- if handle_partner._IsA("Grongier.PEX.InboundAdapter"):
33
+ if handle_partner._IsA("Grongier.PEX.InboundAdapter") or handle_partner._IsA("IOP.InboundAdapter"):
34
34
  module = importlib.import_module(handle_partner.GetModule())
35
35
  handle_partner = getattr(module, handle_partner.GetClassname())()
36
36
  self.Adapter = self.adapter = handle_partner
iop/_cli.py ADDED
@@ -0,0 +1,141 @@
1
+ import argparse
2
+ import json
3
+ import os
4
+ from importlib.metadata import version
5
+
6
+ from iop._director import _Director
7
+ from iop._utils import _Utils
8
+
9
+ def parse_args():
10
+ # parse arguments
11
+ main_parser = argparse.ArgumentParser()
12
+ parser = main_parser.add_mutually_exclusive_group()
13
+ parser.add_argument('-d', '--default', help='set the default production', nargs='?', const='not_set')
14
+ parser.add_argument('-l', '--list', help='list productions', action='store_true')
15
+ parser.add_argument('-s', '--start', help='start a production', nargs='?', const='not_set')
16
+ start = main_parser.add_argument_group('start arguments')
17
+ start.add_argument('-D', '--detach', help='start a production in detach mode', action='store_true')
18
+ parser.add_argument('-S', '--stop', help='stop a production', action='store_true')
19
+ parser.add_argument('-k', '--kill', help='kill a production', action='store_true')
20
+ parser.add_argument('-r', '--restart', help='restart a production', action='store_true')
21
+ parser.add_argument('-x', '--status', help='status a production', action='store_true')
22
+ parser.add_argument('-m', '-M', '--migrate', help='migrate production and classes with settings file')
23
+ parser.add_argument('-e', '--export', help='export a production', nargs='?', const='not_set')
24
+ parser.add_argument('-v', '--version', help='display version', action='store_true')
25
+ parser.add_argument('-L', '--log', help='display log', nargs='?', const='not_set')
26
+ parser.add_argument('-i', '--init', help='init the pex module in iris', nargs='?', const='not_set')
27
+ parser.add_argument('-t', '--test', help='test the pex module in iris', nargs='?', const='not_set')
28
+ test = main_parser.add_argument_group('test arguments')
29
+ # add classname argument
30
+ test.add_argument('-C', '--classname', help='test classname', nargs='?', const='not_set')
31
+ # body argument
32
+ test.add_argument('-B', '--body', help='test body', nargs='?', const='not_set')
33
+ return main_parser
34
+
35
+ def main(argv=None):
36
+ # build arguments
37
+ parser = parse_args()
38
+ args = parser.parse_args(argv)
39
+
40
+ if args.default:
41
+ # set default production
42
+ if args.default == 'not_set':
43
+ # display default production name
44
+ print(_Director.get_default_production())
45
+ else:
46
+ _Director.set_default_production(args.default)
47
+
48
+ elif args.list:
49
+ # display list of productions
50
+ dikt = _Director.list_productions()
51
+ print(json.dumps(dikt, indent=4))
52
+
53
+ elif args.start:
54
+ production_name = None
55
+ if args.start == 'not_set':
56
+ # start default production
57
+ production_name = _Director.get_default_production()
58
+ else:
59
+ # start production with name
60
+ production_name = args.start
61
+ if args.detach:
62
+ # start production in detach mode
63
+ _Director.start_production(production_name)
64
+ print(f"Production {production_name} started")
65
+ else:
66
+ _Director.start_production_with_log(production_name)
67
+
68
+ elif args.init:
69
+ if args.init == 'not_set':
70
+ # set arg to None
71
+ args.init = None
72
+ _Utils.setup(args.start)
73
+
74
+ elif args.kill:
75
+ # kill a production
76
+ _Director.shutdown_production()
77
+
78
+ elif args.restart:
79
+ # restart a production
80
+ _Director.restart_production()
81
+
82
+ elif args.migrate:
83
+ # check if migrate is absolute path
84
+ if os.path.isabs(args.migrate):
85
+ # migrate a production with absolute path
86
+ _Utils.migrate(args.migrate)
87
+ else:
88
+ # migrate a production with relative path
89
+ _Utils.migrate(os.path.join(os.getcwd(), args.migrate))
90
+
91
+ elif args.version:
92
+ # display version
93
+ print(version('iris-pex-embedded-python'))
94
+
95
+ elif args.log:
96
+ # display log
97
+ if args.log == 'not_set':
98
+ # display default production log
99
+ _Director.log_production()
100
+ else:
101
+ _Director.log_production_top(args.log)
102
+
103
+ elif args.stop:
104
+ # stop a production
105
+ _Director.stop_production()
106
+ print(f"Production {_Director.get_default_production()} stopped")
107
+
108
+ elif args.status:
109
+ dikt=_Director.status_production()
110
+ print(json.dumps(dikt, indent=4))
111
+
112
+ elif args.test:
113
+ classname = None
114
+ body = None
115
+ if args.test == 'not_set':
116
+ # set arg to None
117
+ args.test = None
118
+ if args.classname:
119
+ classname = args.classname
120
+ if args.body:
121
+ body = args.body
122
+ response = _Director.test_component(args.test, classname=classname, body=body)
123
+ print(response)
124
+
125
+ elif args.export:
126
+ if args.export == 'not_set':
127
+ # export default production
128
+ args.export=_Director.get_default_production()
129
+
130
+ dikt = _Utils.export_production(args.export)
131
+ print(json.dumps(dikt, indent=4))
132
+
133
+ else:
134
+ # display help
135
+ parser.print_help()
136
+ print()
137
+ print("Default production : " + _Director.get_default_production())
138
+
139
+
140
+ if __name__ == '__main__':
141
+ main()