iris-pex-embedded-python 3.5.5b4__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 (91) hide show
  1. grongier/__init__.py +0 -0
  2. grongier/cls/Grongier/PEX/BusinessOperation.cls +8 -0
  3. grongier/cls/Grongier/PEX/BusinessProcess.cls +13 -0
  4. grongier/cls/Grongier/PEX/BusinessService.cls +8 -0
  5. grongier/cls/Grongier/PEX/Common.cls +10 -0
  6. grongier/cls/Grongier/PEX/Director.cls +10 -0
  7. grongier/cls/Grongier/PEX/Duplex/Operation.cls +4 -0
  8. grongier/cls/Grongier/PEX/Duplex/Process.cls +13 -0
  9. grongier/cls/Grongier/PEX/Duplex/Service.cls +4 -0
  10. grongier/cls/Grongier/PEX/InboundAdapter.cls +8 -0
  11. grongier/cls/Grongier/PEX/Message.cls +13 -0
  12. grongier/cls/Grongier/PEX/OutboundAdapter.cls +8 -0
  13. grongier/cls/Grongier/PEX/PickleMessage.cls +13 -0
  14. grongier/cls/Grongier/PEX/PrivateSession/Duplex.cls +8 -0
  15. grongier/cls/Grongier/PEX/PrivateSession/Message/Ack.cls +14 -0
  16. grongier/cls/Grongier/PEX/PrivateSession/Message/Poll.cls +14 -0
  17. grongier/cls/Grongier/PEX/PrivateSession/Message/Start.cls +14 -0
  18. grongier/cls/Grongier/PEX/PrivateSession/Message/Stop.cls +14 -0
  19. grongier/cls/Grongier/PEX/Test.cls +10 -0
  20. grongier/cls/Grongier/PEX/Utils.cls +10 -0
  21. grongier/cls/Grongier/Service/WSGI.cls +4 -0
  22. grongier/pex/__init__.py +24 -0
  23. grongier/pex/__main__.py +4 -0
  24. grongier/pex/_business_host.py +1 -0
  25. grongier/pex/_cli.py +4 -0
  26. grongier/pex/_common.py +1 -0
  27. grongier/pex/_director.py +1 -0
  28. grongier/pex/_utils.py +1 -0
  29. grongier/pex/wsgi/handlers.py +104 -0
  30. iop/__init__.py +25 -0
  31. iop/__main__.py +4 -0
  32. iop/_async_request.py +67 -0
  33. iop/_business_host.py +256 -0
  34. iop/_business_operation.py +75 -0
  35. iop/_business_process.py +224 -0
  36. iop/_business_service.py +63 -0
  37. iop/_cli.py +247 -0
  38. iop/_common.py +334 -0
  39. iop/_debugpy.py +187 -0
  40. iop/_decorators.py +49 -0
  41. iop/_director.py +301 -0
  42. iop/_dispatch.py +136 -0
  43. iop/_generator_request.py +30 -0
  44. iop/_inbound_adapter.py +34 -0
  45. iop/_iris.py +8 -0
  46. iop/_log_manager.py +100 -0
  47. iop/_message.py +40 -0
  48. iop/_message_validator.py +49 -0
  49. iop/_outbound_adapter.py +23 -0
  50. iop/_private_session_duplex.py +103 -0
  51. iop/_private_session_process.py +41 -0
  52. iop/_remote.py +91 -0
  53. iop/_serialization.py +199 -0
  54. iop/_utils.py +671 -0
  55. iop/cls/IOP/BusinessOperation.cls +35 -0
  56. iop/cls/IOP/BusinessProcess.cls +156 -0
  57. iop/cls/IOP/BusinessService.cls +40 -0
  58. iop/cls/IOP/Common.cls +569 -0
  59. iop/cls/IOP/Director.cls +70 -0
  60. iop/cls/IOP/Duplex/Operation.cls +29 -0
  61. iop/cls/IOP/Duplex/Process.cls +229 -0
  62. iop/cls/IOP/Duplex/Service.cls +9 -0
  63. iop/cls/IOP/Generator/Message/Ack.cls +31 -0
  64. iop/cls/IOP/Generator/Message/Poll.cls +31 -0
  65. iop/cls/IOP/Generator/Message/Start.cls +15 -0
  66. iop/cls/IOP/Generator/Message/StartPickle.cls +15 -0
  67. iop/cls/IOP/Generator/Message/Stop.cls +32 -0
  68. iop/cls/IOP/InboundAdapter.cls +22 -0
  69. iop/cls/IOP/Message/JSONSchema.cls +125 -0
  70. iop/cls/IOP/Message.cls +754 -0
  71. iop/cls/IOP/OutboundAdapter.cls +36 -0
  72. iop/cls/IOP/PickleMessage.cls +58 -0
  73. iop/cls/IOP/PrivateSession/Duplex.cls +260 -0
  74. iop/cls/IOP/PrivateSession/Message/Ack.cls +32 -0
  75. iop/cls/IOP/PrivateSession/Message/Poll.cls +32 -0
  76. iop/cls/IOP/PrivateSession/Message/Start.cls +31 -0
  77. iop/cls/IOP/PrivateSession/Message/Stop.cls +48 -0
  78. iop/cls/IOP/Projection.cls +49 -0
  79. iop/cls/IOP/Service/Remote/Handler.cls +30 -0
  80. iop/cls/IOP/Service/Remote/Rest/v1.cls +97 -0
  81. iop/cls/IOP/Service/WSGI.cls +310 -0
  82. iop/cls/IOP/Test.cls +85 -0
  83. iop/cls/IOP/Utils.cls +503 -0
  84. iop/cls/IOP/Wrapper.cls +58 -0
  85. iop/wsgi/handlers.py +104 -0
  86. iris_pex_embedded_python-3.5.5b4.dist-info/METADATA +91 -0
  87. iris_pex_embedded_python-3.5.5b4.dist-info/RECORD +91 -0
  88. iris_pex_embedded_python-3.5.5b4.dist-info/WHEEL +5 -0
  89. iris_pex_embedded_python-3.5.5b4.dist-info/entry_points.txt +2 -0
  90. iris_pex_embedded_python-3.5.5b4.dist-info/licenses/LICENSE +21 -0
  91. iris_pex_embedded_python-3.5.5b4.dist-info/top_level.txt +2 -0
iop/_cli.py ADDED
@@ -0,0 +1,247 @@
1
+ from __future__ import annotations
2
+ import argparse
3
+ import json
4
+ import logging
5
+ import os
6
+ from dataclasses import dataclass
7
+ from enum import Enum, auto
8
+ import sys
9
+ from typing import Optional, Callable
10
+ from importlib.metadata import version
11
+
12
+ from ._director import _Director
13
+ from ._utils import _Utils
14
+
15
+
16
+ class CommandType(Enum):
17
+ DEFAULT = auto()
18
+ LIST = auto()
19
+ START = auto()
20
+ STOP = auto()
21
+ KILL = auto()
22
+ RESTART = auto()
23
+ STATUS = auto()
24
+ TEST = auto()
25
+ VERSION = auto()
26
+ EXPORT = auto()
27
+ MIGRATE = auto()
28
+ LOG = auto()
29
+ INIT = auto()
30
+ HELP = auto()
31
+ UPDATE = auto()
32
+
33
+ @dataclass
34
+ class CommandArgs:
35
+ """Container for parsed command arguments"""
36
+ default: Optional[str] = None
37
+ list: bool = False
38
+ start: Optional[str] = None
39
+ detach: bool = False
40
+ stop: bool = False
41
+ kill: bool = False
42
+ restart: bool = False
43
+ status: bool = False
44
+ migrate: Optional[str] = None
45
+ export: Optional[str] = None
46
+ version: bool = False
47
+ log: Optional[str] = None
48
+ init: Optional[str] = None
49
+ test: Optional[str] = None
50
+ classname: Optional[str] = None
51
+ body: Optional[str] = None
52
+ namespace: Optional[str] = None
53
+ force_local: bool = False
54
+ update: bool = False
55
+
56
+ class Command:
57
+ def __init__(self, args: CommandArgs):
58
+ self.args = args
59
+
60
+ if self.args.namespace and self.args.namespace != 'not_set':
61
+ # set environment variable IRISNAMESPACE
62
+ os.environ['IRISNAMESPACE'] = self.args.namespace
63
+
64
+ def _has_primary_command(self) -> bool:
65
+ return any([
66
+ self.args.default,
67
+ self.args.list,
68
+ self.args.start,
69
+ self.args.stop,
70
+ self.args.kill,
71
+ self.args.restart,
72
+ self.args.status,
73
+ self.args.test,
74
+ self.args.version,
75
+ self.args.export,
76
+ self.args.migrate,
77
+ self.args.log,
78
+ self.args.init,
79
+ self.args.update,
80
+ ])
81
+
82
+ def execute(self) -> None:
83
+ if self.args.namespace == 'not_set' and not self._has_primary_command():
84
+ print(os.getenv('IRISNAMESPACE', 'not set'))
85
+ return
86
+
87
+ command_type = self._determine_command_type()
88
+ command_handlers = {
89
+ CommandType.DEFAULT: self._handle_default,
90
+ CommandType.LIST: self._handle_list,
91
+ CommandType.START: self._handle_start,
92
+ CommandType.STOP: self._handle_stop,
93
+ CommandType.KILL: self._handle_kill,
94
+ CommandType.RESTART: self._handle_restart,
95
+ CommandType.STATUS: self._handle_status,
96
+ CommandType.TEST: self._handle_test,
97
+ CommandType.VERSION: self._handle_version,
98
+ CommandType.EXPORT: self._handle_export,
99
+ CommandType.MIGRATE: self._handle_migrate,
100
+ CommandType.LOG: self._handle_log,
101
+ CommandType.INIT: self._handle_init,
102
+ CommandType.HELP: self._handle_help,
103
+ CommandType.UPDATE: self._handle_update,
104
+ }
105
+ handler = command_handlers.get(command_type)
106
+ if handler:
107
+ handler()
108
+
109
+ def _determine_command_type(self) -> CommandType:
110
+ if self.args.default: return CommandType.DEFAULT
111
+ if self.args.list: return CommandType.LIST
112
+ if self.args.start: return CommandType.START
113
+ if self.args.stop: return CommandType.STOP
114
+ if self.args.kill: return CommandType.KILL
115
+ if self.args.restart: return CommandType.RESTART
116
+ if self.args.status: return CommandType.STATUS
117
+ if self.args.test: return CommandType.TEST
118
+ if self.args.version: return CommandType.VERSION
119
+ if self.args.export: return CommandType.EXPORT
120
+ if self.args.migrate: return CommandType.MIGRATE
121
+ if self.args.log: return CommandType.LOG
122
+ if self.args.init: return CommandType.INIT
123
+ if self.args.update: return CommandType.UPDATE
124
+ return CommandType.HELP
125
+
126
+ def _handle_default(self) -> None:
127
+ if self.args.default == 'not_set':
128
+ print(_Director.get_default_production())
129
+ elif self.args.default is not None:
130
+ _Director.set_default_production(self.args.default)
131
+
132
+ def _handle_list(self) -> None:
133
+ dikt = _Director.list_productions()
134
+ print(json.dumps(dikt, indent=4))
135
+
136
+ def _handle_start(self) -> None:
137
+ production_name = self.args.start if self.args.start != 'not_set' else _Director.get_default_production()
138
+ if self.args.detach:
139
+ _Director.start_production(production_name)
140
+ print(f"Production {production_name} started")
141
+ else:
142
+ _Director.start_production_with_log(production_name)
143
+
144
+ def _handle_stop(self) -> None:
145
+ _Director.stop_production()
146
+ print(f"Production {_Director.get_default_production()} stopped")
147
+
148
+ def _handle_kill(self) -> None:
149
+ _Director.shutdown_production()
150
+
151
+ def _handle_restart(self) -> None:
152
+ _Director.restart_production()
153
+
154
+ def _handle_status(self) -> None:
155
+ print(json.dumps(_Director.status_production(), indent=4))
156
+
157
+ def _handle_update(self) -> None:
158
+ _Director.update_production()
159
+
160
+ def _handle_test(self) -> None:
161
+ test_name = None if self.args.test == 'not_set' else self.args.test
162
+ response = _Director.test_component(
163
+ test_name,
164
+ classname=self.args.classname if self.args.classname != 'not_set' else None,
165
+ body=self.args.body if self.args.body != 'not_set' else None
166
+ )
167
+ print(response)
168
+
169
+ def _handle_version(self) -> None:
170
+ print(version('iris-pex-embedded-python'))
171
+
172
+ def _handle_export(self) -> None:
173
+ export_name = _Director.get_default_production() if self.args.export == 'not_set' else self.args.export
174
+ print(json.dumps(_Utils.export_production(export_name), indent=4))
175
+
176
+ def _handle_migrate(self) -> None:
177
+ migrate_path = self.args.migrate
178
+ if migrate_path is not None:
179
+ if not os.path.isabs(migrate_path):
180
+ migrate_path = os.path.join(os.getcwd(), migrate_path)
181
+ _Utils.migrate_remote(migrate_path, force_local=self.args.force_local)
182
+
183
+ def _handle_log(self) -> None:
184
+ if self.args.log == 'not_set':
185
+ print(_Director.log_production())
186
+ elif self.args.log is not None:
187
+ print(_Director.log_production_top(int(self.args.log)))
188
+
189
+ def _handle_init(self) -> None:
190
+ _Utils.setup(None)
191
+
192
+ def _handle_help(self) -> None:
193
+ create_parser().print_help()
194
+ try:
195
+ print(f"\nDefault production: {_Director.get_default_production()}")
196
+ print(f"\nNamespace: {os.getenv('IRISNAMESPACE','not set')}")
197
+ except Exception:
198
+ logging.warning("Could not retrieve default production.")
199
+
200
+ def create_parser() -> argparse.ArgumentParser:
201
+ """Create and configure argument parser"""
202
+ main_parser = argparse.ArgumentParser()
203
+ parser = main_parser.add_mutually_exclusive_group()
204
+
205
+ # Main commands
206
+ parser.add_argument('-d', '--default', help='set the default production', nargs='?', const='not_set')
207
+ parser.add_argument('-l', '--list', help='list productions', action='store_true')
208
+ parser.add_argument('-s', '--start', help='start a production', nargs='?', const='not_set')
209
+ parser.add_argument('-S', '--stop', help='stop a production', action='store_true')
210
+ parser.add_argument('-k', '--kill', help='kill a production', action='store_true')
211
+ parser.add_argument('-r', '--restart', help='restart a production', action='store_true')
212
+ parser.add_argument('-x', '--status', help='status a production', action='store_true')
213
+ parser.add_argument('-m', '-M', '--migrate', help='migrate production and classes with settings file')
214
+ parser.add_argument('-e', '--export', help='export a production', nargs='?', const='not_set')
215
+ parser.add_argument('-v', '--version', help='display version', action='store_true')
216
+ parser.add_argument('-L', '--log', help='display log', nargs='?', const='not_set')
217
+ parser.add_argument('-i', '--init', help='init the pex module in iris', nargs='?', const='not_set')
218
+ parser.add_argument('-t', '--test', help='test the pex module in iris', nargs='?', const='not_set')
219
+ parser.add_argument('-u', '--update', help='update a production', action='store_true')
220
+
221
+ # Command groups
222
+ start = main_parser.add_argument_group('start arguments')
223
+ start.add_argument('-D', '--detach', help='start a production in detach mode', action='store_true')
224
+
225
+ test = main_parser.add_argument_group('test arguments')
226
+ test.add_argument('-C', '--classname', help='test classname', nargs='?', const='not_set')
227
+ test.add_argument('-B', '--body', help='test body', nargs='?', const='not_set')
228
+
229
+ migrate = main_parser.add_argument_group('migrate arguments')
230
+ migrate.add_argument('--force-local', help='force local migration, skip remote even if REMOTE_SETTINGS is present', action='store_true')
231
+
232
+ namespace = main_parser.add_argument_group('namespace arguments')
233
+ namespace.add_argument('-n', '--namespace', help='set namespace', nargs='?', const='not_set')
234
+
235
+ return main_parser
236
+
237
+ def main(argv=None) -> None:
238
+ parser = create_parser()
239
+ args = parser.parse_args(argv)
240
+ cmd_args = CommandArgs(**vars(args))
241
+
242
+ command = Command(cmd_args)
243
+ command.execute()
244
+ sys.exit(0)
245
+
246
+ if __name__ == '__main__':
247
+ main()
iop/_common.py ADDED
@@ -0,0 +1,334 @@
1
+ import abc
2
+ import inspect
3
+ import traceback
4
+ from typing import Any, ClassVar, List, Optional, Tuple
5
+
6
+ from . import _iris
7
+ from ._log_manager import LogManager, logging
8
+ from ._debugpy import debugpython
9
+
10
+ class _Common(metaclass=abc.ABCMeta):
11
+ """Base class that defines common methods for all component types.
12
+
13
+ Provides core functionality like initialization, teardown, connection handling
14
+ and message type checking that is shared across component types.
15
+ """
16
+
17
+ INFO_URL: ClassVar[str]
18
+ ICON_URL: ClassVar[str]
19
+ iris_handle: Any = None
20
+ _log_to_console: bool = False
21
+ _logger: Optional[logging.Logger] = None
22
+
23
+ @staticmethod
24
+ def get_adapter_type() -> Optional[str]:
25
+ """Get the adapter type for this component. Override in subclasses."""
26
+ return None
27
+
28
+ @property
29
+ def logger(self) -> logging.Logger:
30
+ if self._logger is None:
31
+ self._logger = LogManager.get_logger(self.__class__.__name__,self.log_to_console)
32
+ return self._logger
33
+
34
+ @logger.setter
35
+ def logger(self, value: logging.Logger) -> None:
36
+ self._logger = value
37
+
38
+ @property
39
+ def log_to_console(self) -> bool:
40
+ return self._log_to_console
41
+
42
+ @log_to_console.setter
43
+ def log_to_console(self, value: bool) -> None:
44
+ self._log_to_console = value
45
+ self.logger = LogManager.get_logger(self.__class__.__name__,value)
46
+
47
+ # Lifecycle methods
48
+ def on_init(self) -> None:
49
+ """Initialize component when started."""
50
+ pass
51
+
52
+ def on_tear_down(self) -> None:
53
+ """Clean up component before termination."""
54
+ pass
55
+
56
+ def on_connected(self) -> None:
57
+ """Handle component connection/reconnection."""
58
+ pass
59
+
60
+ # Internal dispatch methods
61
+ def _dispatch_on_connected(self, host_object: Any) -> None:
62
+ self.on_connected()
63
+
64
+ def _dispatch_on_init(self, host_object: Any) -> None:
65
+ """Initialize component when started."""
66
+ self.on_init()
67
+
68
+ def _dispatch_on_tear_down(self, host_object: Any) -> None:
69
+ self.on_tear_down()
70
+
71
+ def _set_iris_handles(self, handle_current: Any, handle_partner: Any) -> None:
72
+ """Internal method to set IRIS handles."""
73
+ pass
74
+
75
+ def _debugpy(self, host) -> None:
76
+ """Set up debugpy for debugging."""
77
+ if debugpython is not None:
78
+ debugpython(self=self, host_object=host)
79
+
80
+ # Component information methods
81
+ @classmethod
82
+ def _get_info(cls) -> List[str]:
83
+ """Get component configuration information.
84
+
85
+ Returns information used to display in Production config UI including:
86
+ - Superclass
87
+ - Description
88
+ - InfoURL
89
+ - IconURL
90
+ - Adapter type (for Business Services/Operations)
91
+ """
92
+ ret = []
93
+ desc = ""
94
+ info_url = ""
95
+ icon_url = ""
96
+ super_class = ""
97
+ adapter = ""
98
+ try:
99
+ # Get tuple of the class's base classes and loop through them until we find one of the PEX component classes
100
+ classes = inspect.getmro(cls)
101
+ for cl in classes:
102
+ classname = str(cl)[7:-1]
103
+ if classname in ["'iop.BusinessService'","'iop.BusinessOperation'","'iop.DuplexOperation'","'iop.DuplexService'",
104
+ "'grongier.pex.BusinessService'","'grongier.pex.BusinessOperation'","'grongier.pex.DuplexOperation'","'grongier.pex.DuplexService'"] :
105
+ # Remove the apostrophes and set as super_class, then find if it uses an adapter
106
+ super_class = classname[1:-1]
107
+ adapter = cls.get_adapter_type()
108
+ if adapter is None:
109
+ # for retro-compatibility
110
+ adapter = cls.getAdapterType() # type: ignore
111
+ break
112
+ elif classname in ["'iop.BusinessProcess'","'iop.DuplexProcess'","'iop.InboundAdapter'","'iop.OutboundAdapter'",
113
+ "'grongier.pex.BusinessProcess'","'grongier.pex.DuplexProcess'","'grongier.pex.InboundAdapter'","'grongier.pex.OutboundAdapter'"] :
114
+ # Remove the apostrophes and set as super_class
115
+ super_class = classname[1:-1]
116
+ break
117
+
118
+ if ""==super_class:
119
+ return []
120
+ ret.append(super_class)
121
+
122
+ # Get the class documentation, if any
123
+ class_desc = inspect.getdoc(cls)
124
+ super_desc = inspect.getdoc(classes[1])
125
+ if class_desc!=super_desc:
126
+ desc = class_desc
127
+ ret.append(str(desc))
128
+
129
+ info_url = inspect.getattr_static(cls,"INFO_URL","")
130
+ icon_url = inspect.getattr_static(cls,"ICON_URL","")
131
+
132
+ ret.append(info_url)
133
+ ret.append(icon_url)
134
+
135
+ if ""!=adapter:
136
+ ret.append(adapter)
137
+ except Exception as e:
138
+ raise e
139
+ return ret
140
+
141
+ @classmethod
142
+ def _get_properties(cls) -> List[List[Any]]:
143
+ """Get component properties for Production configuration.
144
+
145
+ Returns list of property definitions containing:
146
+ - Property name
147
+ - Data type
148
+ - Default value
149
+ - Required flag
150
+ - Category
151
+ - Description
152
+
153
+ Only includes non-private class attributes and properties.
154
+ """
155
+ ret = []
156
+ try:
157
+ # getmembers() returns all the members of an obj
158
+ for member in inspect.getmembers(cls):
159
+ # remove private and protected functions
160
+ if not member[0].startswith('_'):
161
+ # remove other methods and functions
162
+ if not inspect.ismethod(member[1]) and not inspect.isfunction(member[1]) and not inspect.isclass(member[1]):
163
+ if member[0] not in ('INFO_URL','ICON_URL','PERSISTENT_PROPERTY_LIST'
164
+ ,'log_to_console','logger','iris_handle'
165
+ ,'DISPATCH','adapter','Adapter','buffer'
166
+ ,'BusinessHost','business_host','business_host_python'):
167
+ name = member[0]
168
+ req = 0
169
+ cat = "Additional"
170
+ desc = ""
171
+ # get value, set to "" if None or a @property
172
+ val = member[1]
173
+ if isinstance(val,property) or (val is None):
174
+ val = ""
175
+ dt = str(type(val))[8:-2]
176
+ # get datatype from attribute definition, default to String
177
+ data_type = {'int':'Integer','float':'Numeric','complex':'Numeric','bool':'Boolean'}.get(dt,'String')
178
+ # if the user has created a attr_info function, then check the annotation on the return from that for more information about this attribute
179
+ if hasattr(cls,name + '_info') :
180
+ func = getattr(cls,name+'_info')
181
+ if callable(func) :
182
+ annotations = func.__annotations__['return']
183
+ if annotations is not None:
184
+ if bool(annotations.get("ExcludeFromSettings")) :
185
+ # don't add this attribute to the settings list
186
+ continue
187
+ req = bool(annotations.get("IsRequired"))
188
+ cat = annotations.get("Category","Additional")
189
+ desc = annotations.get("Description")
190
+ dt = annotations.get("DataType")
191
+ # only override DataType found
192
+ if (dt is not None) and ("" != dt):
193
+ data_type = {int:'Integer',float:'Number',complex:'Number',bool:'Boolean',str:'String'}.get(dt,str(dt))
194
+ default = func()
195
+ if default is not None:
196
+ val = default
197
+ # create list of information for this specific property
198
+ info = []
199
+ info.append(name) # Name
200
+ info.append(data_type) # DataType
201
+ info.append(val) # Default Value
202
+ info.append(req) # Required
203
+ info.append(cat) # Category
204
+ info.append(desc) # Description
205
+ # add this property to the list
206
+ ret.append(info)
207
+ except:
208
+ pass
209
+ return ret
210
+
211
+ # Logging methods
212
+ def _log(self) -> Tuple[str, Optional[str]]:
213
+ """Get class and method name for logging.
214
+
215
+ Returns:
216
+ Tuple of (class_name, method_name)
217
+ """
218
+ current_class = self.__class__.__name__
219
+ current_method = None
220
+ try:
221
+ frame = traceback.extract_stack()[-4]
222
+ current_method = frame.name
223
+ except:
224
+ pass
225
+ return current_class, current_method
226
+
227
+ def _logging(self, message: str, level: int, to_console: Optional[bool] = None) -> None:
228
+ """Write log entry.
229
+
230
+ Args:
231
+ message: Message to log
232
+ level: Log level
233
+ to_console: If True, log to console instead of IRIS
234
+ """
235
+ current_class, current_method = self._log()
236
+ if to_console is None:
237
+ to_console = self.log_to_console
238
+ if level == logging.DEBUG:
239
+ self.logger.debug(message, extra={'to_console': to_console, 'class_name': current_class, 'method_name': current_method})
240
+ elif level == logging.INFO:
241
+ self.logger.info(message, extra={'to_console': to_console, 'class_name': current_class, 'method_name': current_method})
242
+ elif level == logging.CRITICAL:
243
+ self.logger.critical(message, extra={'to_console': to_console, 'class_name': current_class, 'method_name': current_method})
244
+ elif level == logging.WARNING:
245
+ self.logger.warning(message, extra={'to_console': to_console, 'class_name': current_class, 'method_name': current_method})
246
+ elif level == logging.ERROR:
247
+ self.logger.error(message, extra={'to_console': to_console, 'class_name': current_class, 'method_name': current_method})
248
+
249
+ def trace(self, message: str, to_console: Optional[bool] = None) -> None:
250
+ """Write trace log entry.
251
+
252
+ Args:
253
+ message: Message to log
254
+ to_console: If True, log to console instead of IRIS
255
+ """
256
+ self._logging(message, logging.DEBUG, to_console)
257
+
258
+ def log_info(self, message: str, to_console: Optional[bool] = None) -> None:
259
+ """Write info log entry.
260
+
261
+ Args:
262
+ message: Message to log
263
+ to_console: If True, log to console instead of IRIS
264
+ """
265
+ self._logging(message, logging.INFO, to_console)
266
+
267
+ def log_alert(self, message: str, to_console: Optional[bool] = None) -> None:
268
+ """Write alert log entry.
269
+
270
+ Args:
271
+ message: Message to log
272
+ to_console: If True, log to console instead of IRIS
273
+ """
274
+ self._logging(message, logging.CRITICAL, to_console)
275
+
276
+ def log_warning(self, message: str, to_console: Optional[bool] = None) -> None:
277
+ """Write warning log entry.
278
+
279
+ Args:
280
+ message: Message to log
281
+ to_console: If True, log to console instead of IRIS
282
+ """
283
+ self._logging(message, logging.WARNING, to_console)
284
+
285
+ def log_error(self, message: str, to_console: Optional[bool] = None) -> None:
286
+ """Write error log entry.
287
+
288
+ Args:
289
+ message: Message to log
290
+ to_console: If True, log to console instead of IRIS
291
+ """
292
+ self._logging(message, logging.ERROR, to_console)
293
+
294
+ def log_assert(self, message: str) -> None:
295
+ """Write a log entry of type "assert". Log entries can be viewed in the management portal.
296
+
297
+ Parameters:
298
+ message: a string that is written to the log.
299
+ """
300
+ iris = _iris.get_iris()
301
+ current_class, current_method = self._log()
302
+ iris.cls("Ens.Util.Log").LogAssert(current_class, current_method, message)
303
+
304
+ def LOGINFO(self, message: str) -> None:
305
+ """DEPRECATED: Use log_info."""
306
+ return self.log_info(message=message)
307
+
308
+ def LOGALERT(self, message: str) -> None:
309
+ """DEPRECATED: Use log_alert."""
310
+ return self.log_alert(message)
311
+
312
+ def LOGWARNING(self, message: str) -> None:
313
+ """DEPRECATED: Use log_warning."""
314
+ return self.log_warning(message)
315
+
316
+ def LOGERROR(self, message: str) -> None:
317
+ """DEPRECATED: Use log_error."""
318
+ return self.log_error(message)
319
+
320
+ def LOGASSERT(self, message: str) -> None:
321
+ """DEPRECATED: Use log_assert."""
322
+ return self.log_assert(message)
323
+
324
+ def OnInit(self) -> None:
325
+ """DEPRECATED: Use on_init."""
326
+ return
327
+
328
+ def OnTearDown(self) -> None:
329
+ """DEPRECATED: Use on_tear_down."""
330
+ return
331
+
332
+ def OnConnected(self) -> None:
333
+ """DEPRECATED: Use on_connected."""
334
+ return