iris-pex-embedded-python 3.7.2b1__tar.gz → 3.7.2b2__tar.gz
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.
- {iris_pex_embedded_python-3.7.2b1/src/iris_pex_embedded_python.egg-info → iris_pex_embedded_python-3.7.2b2}/PKG-INFO +1 -1
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/pyproject.toml +1 -1
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/pex/__init__.py +9 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/__init__.py +9 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_cli.py +29 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_common.py +240 -78
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_local.py +1 -1
- iris_pex_embedded_python-3.7.2b2/src/iop/_polling_business_service.py +6 -0
- iris_pex_embedded_python-3.7.2b2/src/iop/_settings.py +188 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_utils.py +219 -17
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/Utils.cls +21 -1
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2/src/iris_pex_embedded_python.egg-info}/PKG-INFO +1 -1
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iris_pex_embedded_python.egg-info/SOURCES.txt +2 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/LICENSE +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/README.md +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/setup.cfg +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/setup.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/__init__.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/cls/Grongier/PEX/BusinessOperation.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/cls/Grongier/PEX/BusinessProcess.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/cls/Grongier/PEX/BusinessService.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/cls/Grongier/PEX/Common.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/cls/Grongier/PEX/Director.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/cls/Grongier/PEX/Duplex/Operation.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/cls/Grongier/PEX/Duplex/Process.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/cls/Grongier/PEX/Duplex/Service.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/cls/Grongier/PEX/InboundAdapter.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/cls/Grongier/PEX/Message.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/cls/Grongier/PEX/OutboundAdapter.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/cls/Grongier/PEX/PickleMessage.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/cls/Grongier/PEX/PrivateSession/Duplex.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/cls/Grongier/PEX/PrivateSession/Message/Ack.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/cls/Grongier/PEX/PrivateSession/Message/Poll.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/cls/Grongier/PEX/PrivateSession/Message/Start.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/cls/Grongier/PEX/PrivateSession/Message/Stop.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/cls/Grongier/PEX/Test.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/cls/Grongier/PEX/Utils.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/cls/Grongier/Service/WSGI.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/pex/__main__.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/pex/_business_host.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/pex/_cli.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/pex/_common.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/pex/_director.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/pex/_utils.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/pex/wsgi/handlers.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/__main__.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_async_request.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_business_host.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_business_operation.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_business_process.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_business_service.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_debugpy.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_decorators.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_director.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_director_protocol.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_dispatch.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_generator_request.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_inbound_adapter.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_iris.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_log_manager.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_message.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_message_validator.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_outbound_adapter.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_persistent_message.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_private_session_duplex.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_private_session_process.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_remote.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/_serialization.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/BusinessOperation.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/BusinessProcess.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/BusinessService.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/Common.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/Director.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/Duplex/Operation.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/Duplex/Process.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/Duplex/Service.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/Generator/Message/Ack.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/Generator/Message/Poll.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/Generator/Message/Start.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/Generator/Message/StartPickle.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/Generator/Message/Stop.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/InboundAdapter.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/Message/JSONSchema.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/Message.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/OutboundAdapter.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/PickleMessage.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/PrivateSession/Duplex.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/PrivateSession/Message/Ack.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/PrivateSession/Message/Poll.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/PrivateSession/Message/Start.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/PrivateSession/Message/Stop.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/Projection.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/Service/Remote/Handler.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/Service/Remote/Rest/v1.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/Service/WSGI.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/Test.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/cls/IOP/Wrapper.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iop/wsgi/handlers.py +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iris_pex_embedded_python.egg-info/dependency_links.txt +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iris_pex_embedded_python.egg-info/entry_points.txt +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iris_pex_embedded_python.egg-info/requires.txt +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/iris_pex_embedded_python.egg-info/top_level.txt +0 -0
{iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-3.7.2b2}/src/grongier/pex/__init__.py
RENAMED
|
@@ -6,11 +6,16 @@ from iop._inbound_adapter import _InboundAdapter
|
|
|
6
6
|
from iop._message import _Message
|
|
7
7
|
from iop._message import _PickleMessage
|
|
8
8
|
from iop._outbound_adapter import _OutboundAdapter
|
|
9
|
+
from iop._polling_business_service import _PollingBusinessServiceMixin
|
|
9
10
|
from iop._persistent_message import Field as Field
|
|
10
11
|
from iop._persistent_message import Model as Model
|
|
11
12
|
from iop._persistent_message import _PersistentMessage
|
|
12
13
|
from iop._private_session_duplex import _PrivateSessionDuplex
|
|
13
14
|
from iop._private_session_process import _PrivateSessionProcess
|
|
15
|
+
from iop._settings import Category as Category
|
|
16
|
+
from iop._settings import Setting as Setting
|
|
17
|
+
from iop._settings import controls as controls
|
|
18
|
+
from iop._settings import setting as setting
|
|
14
19
|
from iop._utils import _Utils
|
|
15
20
|
|
|
16
21
|
|
|
@@ -30,6 +35,10 @@ class BusinessService(_BusinessService):
|
|
|
30
35
|
pass
|
|
31
36
|
|
|
32
37
|
|
|
38
|
+
class PollingBusinessService(_PollingBusinessServiceMixin, BusinessService):
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
|
|
33
42
|
class BusinessOperation(_BusinessOperation):
|
|
34
43
|
pass
|
|
35
44
|
|
|
@@ -10,11 +10,16 @@ from iop._message import (
|
|
|
10
10
|
_PydanticPickleMessage,
|
|
11
11
|
)
|
|
12
12
|
from iop._outbound_adapter import _OutboundAdapter
|
|
13
|
+
from iop._polling_business_service import _PollingBusinessServiceMixin
|
|
13
14
|
from iop._persistent_message import Field as Field
|
|
14
15
|
from iop._persistent_message import Model as Model
|
|
15
16
|
from iop._persistent_message import _PersistentMessage
|
|
16
17
|
from iop._private_session_duplex import _PrivateSessionDuplex
|
|
17
18
|
from iop._private_session_process import _PrivateSessionProcess
|
|
19
|
+
from iop._settings import Category as Category
|
|
20
|
+
from iop._settings import Setting as Setting
|
|
21
|
+
from iop._settings import controls as controls
|
|
22
|
+
from iop._settings import setting as setting
|
|
18
23
|
from iop._utils import _Utils
|
|
19
24
|
|
|
20
25
|
|
|
@@ -34,6 +39,10 @@ class BusinessService(_BusinessService):
|
|
|
34
39
|
pass
|
|
35
40
|
|
|
36
41
|
|
|
42
|
+
class PollingBusinessService(_PollingBusinessServiceMixin, BusinessService):
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
|
|
37
46
|
class BusinessOperation(_BusinessOperation):
|
|
38
47
|
pass
|
|
39
48
|
|
|
@@ -13,6 +13,7 @@ from importlib.metadata import version
|
|
|
13
13
|
from ._local import _LocalDirector
|
|
14
14
|
from ._remote import _RemoteDirector, get_remote_settings
|
|
15
15
|
from ._director_protocol import DirectorProtocol
|
|
16
|
+
from ._utils import _Utils
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
class CommandType(Enum):
|
|
@@ -57,6 +58,7 @@ class CommandArgs:
|
|
|
57
58
|
force_local: bool = False
|
|
58
59
|
remote_settings: Optional[str] = None
|
|
59
60
|
update: bool = False
|
|
61
|
+
migration_plan: bool = False
|
|
60
62
|
|
|
61
63
|
|
|
62
64
|
class Command:
|
|
@@ -252,7 +254,27 @@ class Command:
|
|
|
252
254
|
if migrate_path is not None:
|
|
253
255
|
if not os.path.isabs(migrate_path):
|
|
254
256
|
migrate_path = os.path.join(os.getcwd(), migrate_path)
|
|
257
|
+
mode = "REMOTE" if self._is_remote else "LOCAL"
|
|
258
|
+
if self.args.migration_plan:
|
|
259
|
+
print(
|
|
260
|
+
_Utils.explain_migration(
|
|
261
|
+
migrate_path, mode=mode, namespace=self.director.namespace
|
|
262
|
+
)
|
|
263
|
+
)
|
|
264
|
+
return
|
|
265
|
+
if self._is_remote:
|
|
266
|
+
print(
|
|
267
|
+
_Utils.explain_migration(
|
|
268
|
+
migrate_path, mode=mode, namespace=self.director.namespace
|
|
269
|
+
)
|
|
270
|
+
)
|
|
255
271
|
self.director.migrate(migrate_path)
|
|
272
|
+
if self._is_remote:
|
|
273
|
+
print(
|
|
274
|
+
_Utils.format_migration_success(
|
|
275
|
+
migrate_path, namespace=self.director.namespace
|
|
276
|
+
)
|
|
277
|
+
)
|
|
256
278
|
|
|
257
279
|
def _handle_log(self) -> None:
|
|
258
280
|
if self.args.log == "not_set":
|
|
@@ -406,6 +428,13 @@ def create_parser() -> argparse.ArgumentParser:
|
|
|
406
428
|
help="force local mode, skip remote even if REMOTE_SETTINGS or IOP_URL is present",
|
|
407
429
|
action="store_true",
|
|
408
430
|
)
|
|
431
|
+
migrate.add_argument(
|
|
432
|
+
"--dry-run",
|
|
433
|
+
"--explain",
|
|
434
|
+
dest="migration_plan",
|
|
435
|
+
help="show the migration plan and validation messages without writing to IRIS",
|
|
436
|
+
action="store_true",
|
|
437
|
+
)
|
|
409
438
|
|
|
410
439
|
remote = main_parser.add_argument_group("remote arguments")
|
|
411
440
|
remote.add_argument(
|
|
@@ -1,11 +1,143 @@
|
|
|
1
1
|
import abc
|
|
2
2
|
import inspect
|
|
3
3
|
import traceback
|
|
4
|
-
from
|
|
4
|
+
from enum import Enum
|
|
5
|
+
from types import UnionType
|
|
6
|
+
from typing import (
|
|
7
|
+
Annotated,
|
|
8
|
+
Any,
|
|
9
|
+
ClassVar,
|
|
10
|
+
List,
|
|
11
|
+
Optional,
|
|
12
|
+
Tuple,
|
|
13
|
+
Union,
|
|
14
|
+
get_args,
|
|
15
|
+
get_origin,
|
|
16
|
+
get_type_hints,
|
|
17
|
+
)
|
|
5
18
|
|
|
6
19
|
from . import _iris
|
|
7
|
-
from ._log_manager import LogManager, logging
|
|
8
20
|
from ._debugpy import debugpython
|
|
21
|
+
from ._log_manager import LogManager, logging
|
|
22
|
+
from ._settings import Setting
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
_NO_VALUE = object()
|
|
26
|
+
|
|
27
|
+
_EXCLUDED_SETTING_NAMES = {
|
|
28
|
+
"INFO_URL",
|
|
29
|
+
"ICON_URL",
|
|
30
|
+
"PERSISTENT_PROPERTY_LIST",
|
|
31
|
+
"log_to_console",
|
|
32
|
+
"logger",
|
|
33
|
+
"iris_handle",
|
|
34
|
+
"DISPATCH",
|
|
35
|
+
"adapter",
|
|
36
|
+
"Adapter",
|
|
37
|
+
"buffer",
|
|
38
|
+
"BusinessHost",
|
|
39
|
+
"business_host",
|
|
40
|
+
"business_host_python",
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
_PYTHON_TYPE_TO_IRIS = {
|
|
44
|
+
int: "Integer",
|
|
45
|
+
float: "Numeric",
|
|
46
|
+
complex: "Numeric",
|
|
47
|
+
bool: "Boolean",
|
|
48
|
+
str: "String",
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
_SIMPLE_TYPE_NAMES = {
|
|
52
|
+
"int": "Integer",
|
|
53
|
+
"integer": "Integer",
|
|
54
|
+
"float": "Numeric",
|
|
55
|
+
"complex": "Numeric",
|
|
56
|
+
"number": "Numeric",
|
|
57
|
+
"numeric": "Numeric",
|
|
58
|
+
"bool": "Boolean",
|
|
59
|
+
"boolean": "Boolean",
|
|
60
|
+
"str": "String",
|
|
61
|
+
"string": "String",
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _string_metadata(value: Any) -> str:
|
|
66
|
+
if value is None:
|
|
67
|
+
return ""
|
|
68
|
+
if isinstance(value, Enum):
|
|
69
|
+
return str(value.value)
|
|
70
|
+
return str(value)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _type_hints_with_extras(cls) -> dict[str, Any]:
|
|
74
|
+
try:
|
|
75
|
+
return get_type_hints(cls, include_extras=True)
|
|
76
|
+
except Exception:
|
|
77
|
+
hints: dict[str, Any] = {}
|
|
78
|
+
for base in reversed(inspect.getmro(cls)):
|
|
79
|
+
hints.update(getattr(base, "__annotations__", {}))
|
|
80
|
+
return hints
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _unwrap_annotated(data_type: Any) -> tuple[Any, tuple[Any, ...]]:
|
|
84
|
+
if get_origin(data_type) is Annotated:
|
|
85
|
+
args = get_args(data_type)
|
|
86
|
+
if args:
|
|
87
|
+
return args[0], args[1:]
|
|
88
|
+
return data_type, ()
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _setting_from_annotation(data_type: Any) -> tuple[Any, Optional[Setting]]:
|
|
92
|
+
data_type, metadata = _unwrap_annotated(data_type)
|
|
93
|
+
setting = None
|
|
94
|
+
for item in metadata:
|
|
95
|
+
if isinstance(item, Setting):
|
|
96
|
+
setting = item
|
|
97
|
+
return data_type, setting
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def _unwrap_optional(data_type: Any) -> Any:
|
|
101
|
+
origin = get_origin(data_type)
|
|
102
|
+
if origin in (Union, UnionType):
|
|
103
|
+
args = [arg for arg in get_args(data_type) if arg is not type(None)]
|
|
104
|
+
if len(args) == 1:
|
|
105
|
+
return args[0]
|
|
106
|
+
return data_type
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def _iris_data_type(data_type: Any) -> Optional[str]:
|
|
110
|
+
if data_type is None or data_type == "":
|
|
111
|
+
return None
|
|
112
|
+
|
|
113
|
+
data_type, _ = _unwrap_annotated(data_type)
|
|
114
|
+
data_type = _unwrap_optional(data_type)
|
|
115
|
+
|
|
116
|
+
if data_type is Any or data_type is object:
|
|
117
|
+
return "String"
|
|
118
|
+
|
|
119
|
+
if isinstance(data_type, str):
|
|
120
|
+
data_type = data_type.strip()
|
|
121
|
+
return _SIMPLE_TYPE_NAMES.get(data_type.lower(), data_type)
|
|
122
|
+
|
|
123
|
+
if data_type in _PYTHON_TYPE_TO_IRIS:
|
|
124
|
+
return _PYTHON_TYPE_TO_IRIS[data_type]
|
|
125
|
+
|
|
126
|
+
origin = get_origin(data_type)
|
|
127
|
+
if origin in _PYTHON_TYPE_TO_IRIS:
|
|
128
|
+
return _PYTHON_TYPE_TO_IRIS[origin]
|
|
129
|
+
if origin is not None:
|
|
130
|
+
return "String"
|
|
131
|
+
|
|
132
|
+
return None
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def _is_setting_member(name: str, value: Any) -> bool:
|
|
136
|
+
if name.startswith("_") or name in _EXCLUDED_SETTING_NAMES:
|
|
137
|
+
return False
|
|
138
|
+
return not (
|
|
139
|
+
inspect.ismethod(value) or inspect.isfunction(value) or inspect.isclass(value)
|
|
140
|
+
)
|
|
9
141
|
|
|
10
142
|
|
|
11
143
|
class _Common(metaclass=abc.ABCMeta):
|
|
@@ -168,87 +300,117 @@ class _Common(metaclass=abc.ABCMeta):
|
|
|
168
300
|
- Required flag
|
|
169
301
|
- Category
|
|
170
302
|
- Description
|
|
303
|
+
- Control/editor context
|
|
171
304
|
|
|
172
305
|
Only includes non-private class attributes and properties.
|
|
173
306
|
"""
|
|
174
307
|
ret = []
|
|
175
308
|
try:
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
309
|
+
annotations = _type_hints_with_extras(cls)
|
|
310
|
+
members = dict(inspect.getmembers(cls))
|
|
311
|
+
|
|
312
|
+
names = [
|
|
313
|
+
name
|
|
314
|
+
for name, value in members.items()
|
|
315
|
+
if _is_setting_member(name, value)
|
|
316
|
+
]
|
|
317
|
+
for name in annotations:
|
|
318
|
+
if (
|
|
319
|
+
name in names
|
|
320
|
+
or name.startswith("_")
|
|
321
|
+
or name in _EXCLUDED_SETTING_NAMES
|
|
322
|
+
):
|
|
323
|
+
continue
|
|
324
|
+
value = members.get(name, _NO_VALUE)
|
|
325
|
+
if value is not _NO_VALUE and not _is_setting_member(name, value):
|
|
326
|
+
continue
|
|
327
|
+
names.append(name)
|
|
328
|
+
|
|
329
|
+
for name in names:
|
|
330
|
+
member_exists = name in members
|
|
331
|
+
val = members.get(name, "")
|
|
332
|
+
annotated_type, annotated_setting = _setting_from_annotation(
|
|
333
|
+
annotations.get(name)
|
|
334
|
+
)
|
|
335
|
+
value_setting = val if isinstance(val, Setting) else None
|
|
336
|
+
setting_info = value_setting or annotated_setting
|
|
337
|
+
|
|
338
|
+
if setting_info is not None and setting_info.exclude:
|
|
339
|
+
continue
|
|
340
|
+
|
|
341
|
+
req = bool(setting_info.required) if setting_info is not None else False
|
|
342
|
+
cat = setting_info.category if setting_info is not None else ""
|
|
343
|
+
desc = setting_info.description if setting_info is not None else ""
|
|
344
|
+
control = setting_info.control if setting_info is not None else ""
|
|
345
|
+
|
|
346
|
+
if value_setting is not None:
|
|
347
|
+
val = value_setting.default if value_setting.has_default else ""
|
|
348
|
+
elif (
|
|
349
|
+
not member_exists
|
|
350
|
+
and annotated_setting is not None
|
|
351
|
+
and annotated_setting.has_default
|
|
352
|
+
):
|
|
353
|
+
val = annotated_setting.default
|
|
354
|
+
elif not member_exists:
|
|
355
|
+
val = ""
|
|
356
|
+
|
|
357
|
+
if isinstance(val, property) or (val is None):
|
|
358
|
+
val = ""
|
|
359
|
+
|
|
360
|
+
if setting_info is not None and setting_info.iris_type:
|
|
361
|
+
data_type = setting_info.iris_type
|
|
362
|
+
else:
|
|
363
|
+
data_type_source = (
|
|
364
|
+
setting_info.data_type
|
|
365
|
+
if setting_info is not None and setting_info.data_type
|
|
366
|
+
else annotated_type
|
|
367
|
+
)
|
|
368
|
+
data_type = _iris_data_type(data_type_source)
|
|
369
|
+
if data_type is None:
|
|
370
|
+
data_type = _iris_data_type(type(val)) or "String"
|
|
371
|
+
|
|
372
|
+
# Legacy attr_info() support. Values supplied here keep working
|
|
373
|
+
# and can also provide the new control/editor context field.
|
|
374
|
+
if hasattr(cls, name + "_info"):
|
|
375
|
+
func = getattr(cls, name + "_info")
|
|
376
|
+
if callable(func):
|
|
377
|
+
info_annotations = getattr(func, "__annotations__", {}).get(
|
|
378
|
+
"return"
|
|
379
|
+
)
|
|
380
|
+
if info_annotations is not None:
|
|
381
|
+
if bool(info_annotations.get("ExcludeFromSettings")):
|
|
382
|
+
continue
|
|
383
|
+
req = bool(info_annotations.get("IsRequired", req))
|
|
384
|
+
cat = _string_metadata(
|
|
385
|
+
info_annotations.get("Category", cat)
|
|
386
|
+
)
|
|
387
|
+
desc = _string_metadata(
|
|
388
|
+
info_annotations.get("Description", desc)
|
|
389
|
+
)
|
|
390
|
+
control = _string_metadata(
|
|
391
|
+
info_annotations.get(
|
|
392
|
+
"Control",
|
|
393
|
+
info_annotations.get("EditorContext", control),
|
|
394
|
+
)
|
|
395
|
+
)
|
|
396
|
+
dt = info_annotations.get("DataType")
|
|
397
|
+
if (dt is not None) and ("" != dt):
|
|
398
|
+
data_type = _iris_data_type(dt) or str(dt)
|
|
399
|
+
default = func()
|
|
400
|
+
if default is not None:
|
|
401
|
+
val = default
|
|
402
|
+
|
|
403
|
+
ret.append(
|
|
404
|
+
[
|
|
405
|
+
name, # Name
|
|
406
|
+
data_type, # DataType
|
|
407
|
+
val, # Default Value
|
|
408
|
+
req, # Required
|
|
409
|
+
_string_metadata(cat), # Category
|
|
410
|
+
_string_metadata(desc), # Description
|
|
411
|
+
_string_metadata(control), # Control/editor context
|
|
412
|
+
]
|
|
413
|
+
)
|
|
252
414
|
except Exception:
|
|
253
415
|
pass
|
|
254
416
|
return ret
|
|
@@ -95,7 +95,7 @@ class _LocalDirector(_DirectorProtocol):
|
|
|
95
95
|
# ------------------------------------------------------------------
|
|
96
96
|
|
|
97
97
|
def migrate(self, path: str) -> None:
|
|
98
|
-
_Utils.migrate(path)
|
|
98
|
+
_Utils.migrate(path, mode="LOCAL", namespace=self.namespace)
|
|
99
99
|
|
|
100
100
|
# ------------------------------------------------------------------
|
|
101
101
|
# Metadata
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
_MISSING = object()
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Category(str, Enum):
|
|
9
|
+
"""Common IRIS production setting categories for Management Portal grouping."""
|
|
10
|
+
|
|
11
|
+
INFO = "Info"
|
|
12
|
+
BASIC = "Basic"
|
|
13
|
+
CONNECTION = "Connection"
|
|
14
|
+
ADDITIONAL = "Additional"
|
|
15
|
+
ALERTING = "Alerting"
|
|
16
|
+
DEV = "Dev"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _string_value(value: Any) -> str:
|
|
20
|
+
if isinstance(value, Enum):
|
|
21
|
+
return str(value.value)
|
|
22
|
+
return str(value)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class Setting:
|
|
26
|
+
"""Metadata for an IRIS production setting."""
|
|
27
|
+
|
|
28
|
+
def __init__(
|
|
29
|
+
self,
|
|
30
|
+
default: Any = _MISSING,
|
|
31
|
+
*,
|
|
32
|
+
data_type: Any = None,
|
|
33
|
+
iris_type: str | None = None,
|
|
34
|
+
category: str | Category | None = None,
|
|
35
|
+
required: bool = False,
|
|
36
|
+
description: str = "",
|
|
37
|
+
control: str | None = None,
|
|
38
|
+
exclude: bool = False,
|
|
39
|
+
):
|
|
40
|
+
self.default = default
|
|
41
|
+
self.data_type = data_type
|
|
42
|
+
self.iris_type = iris_type
|
|
43
|
+
self.category = _string_value(category) if category is not None else None
|
|
44
|
+
self.required = required
|
|
45
|
+
self.description = description or ""
|
|
46
|
+
self.control = control or ""
|
|
47
|
+
self.exclude = exclude
|
|
48
|
+
self.name = ""
|
|
49
|
+
|
|
50
|
+
def __set_name__(self, owner, name):
|
|
51
|
+
self.name = name
|
|
52
|
+
|
|
53
|
+
def __get__(self, instance, owner=None):
|
|
54
|
+
if instance is None:
|
|
55
|
+
return self
|
|
56
|
+
if self.name in instance.__dict__:
|
|
57
|
+
return instance.__dict__[self.name]
|
|
58
|
+
if self.default is _MISSING:
|
|
59
|
+
return None
|
|
60
|
+
return self.default
|
|
61
|
+
|
|
62
|
+
def __set__(self, instance, value):
|
|
63
|
+
instance.__dict__[self.name] = value
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def has_default(self) -> bool:
|
|
67
|
+
return self.default is not _MISSING
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def setting(default: Any = _MISSING, **kwargs) -> Setting:
|
|
71
|
+
return Setting(default, **kwargs)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class _Controls:
|
|
75
|
+
"""Helpers for IRIS production setting editor controls."""
|
|
76
|
+
|
|
77
|
+
@staticmethod
|
|
78
|
+
def raw(value: str) -> str:
|
|
79
|
+
"""Return an advanced IRIS editor context string unchanged."""
|
|
80
|
+
return value
|
|
81
|
+
|
|
82
|
+
@staticmethod
|
|
83
|
+
def selector(
|
|
84
|
+
context: str | None = None, *, multi_select: bool | None = None, **params
|
|
85
|
+
) -> str:
|
|
86
|
+
"""Build an IRIS selector editor context from a context search string."""
|
|
87
|
+
query = []
|
|
88
|
+
if multi_select is not None:
|
|
89
|
+
query.append(f"multiSelect={1 if multi_select else 0}")
|
|
90
|
+
if context:
|
|
91
|
+
if not (context.startswith("{") and context.endswith("}")):
|
|
92
|
+
context = "{" + context + "}"
|
|
93
|
+
query.append(f"context={context}")
|
|
94
|
+
for key, value in params.items():
|
|
95
|
+
if value is not None:
|
|
96
|
+
query.append(f"{key}={value}")
|
|
97
|
+
return "selector" + (f"?{'&'.join(query)}" if query else "")
|
|
98
|
+
|
|
99
|
+
@staticmethod
|
|
100
|
+
def production_item(
|
|
101
|
+
*,
|
|
102
|
+
targets: bool = True,
|
|
103
|
+
production_name: str = "@productionId",
|
|
104
|
+
multi_select: bool = False,
|
|
105
|
+
) -> str:
|
|
106
|
+
"""Select production items, normally target components, from a production."""
|
|
107
|
+
context = (
|
|
108
|
+
"Ens.ContextSearch/ProductionItems?"
|
|
109
|
+
f"targets={1 if targets else 0}&productionName={production_name}"
|
|
110
|
+
)
|
|
111
|
+
return _Controls.selector(context, multi_select=multi_select or None)
|
|
112
|
+
|
|
113
|
+
@staticmethod
|
|
114
|
+
def partner() -> str:
|
|
115
|
+
"""Select a partner setting value."""
|
|
116
|
+
return "partnerSelector"
|
|
117
|
+
|
|
118
|
+
@staticmethod
|
|
119
|
+
def rule() -> str:
|
|
120
|
+
"""Select an IRIS rule definition."""
|
|
121
|
+
return "ruleSelector"
|
|
122
|
+
|
|
123
|
+
@staticmethod
|
|
124
|
+
def credentials() -> str:
|
|
125
|
+
"""Select an IRIS credentials entry."""
|
|
126
|
+
return "credentialsSelector"
|
|
127
|
+
|
|
128
|
+
@staticmethod
|
|
129
|
+
def directory() -> str:
|
|
130
|
+
"""Select a directory path."""
|
|
131
|
+
return "directorySelector"
|
|
132
|
+
|
|
133
|
+
@staticmethod
|
|
134
|
+
def file() -> str:
|
|
135
|
+
"""Select a file path."""
|
|
136
|
+
return "fileSelector"
|
|
137
|
+
|
|
138
|
+
@staticmethod
|
|
139
|
+
def dtl() -> str:
|
|
140
|
+
"""Select an IRIS DTL data transformation."""
|
|
141
|
+
return "dtlSelector"
|
|
142
|
+
|
|
143
|
+
@staticmethod
|
|
144
|
+
def schedule() -> str:
|
|
145
|
+
"""Select an IRIS schedule."""
|
|
146
|
+
return "scheduleSelector"
|
|
147
|
+
|
|
148
|
+
@staticmethod
|
|
149
|
+
def ssl_config() -> str:
|
|
150
|
+
"""Select an IRIS SSL/TLS configuration."""
|
|
151
|
+
return "sslConfigSelector"
|
|
152
|
+
|
|
153
|
+
@staticmethod
|
|
154
|
+
def bpl() -> str:
|
|
155
|
+
"""Select an IRIS BPL business process."""
|
|
156
|
+
return "bplSelector"
|
|
157
|
+
|
|
158
|
+
@staticmethod
|
|
159
|
+
def character_set() -> str:
|
|
160
|
+
"""Select an IRIS character set."""
|
|
161
|
+
return _Controls.selector("Ens.ContextSearch/CharacterSets")
|
|
162
|
+
|
|
163
|
+
charset = character_set
|
|
164
|
+
|
|
165
|
+
@staticmethod
|
|
166
|
+
def framing(*, host: str = "@currHostId", prop: str = "Framing") -> str:
|
|
167
|
+
"""Select a display-list value such as the current host framing option."""
|
|
168
|
+
return _Controls.selector(
|
|
169
|
+
f"Ens.ContextSearch/getDisplayList?host={host}&prop={prop}"
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
@staticmethod
|
|
173
|
+
def local_interface() -> str:
|
|
174
|
+
"""Select a configured TCP local interface."""
|
|
175
|
+
return _Controls.selector("Ens.ContextSearch/TCPLocalInterfaces")
|
|
176
|
+
|
|
177
|
+
@staticmethod
|
|
178
|
+
def schema_category(host: str) -> str:
|
|
179
|
+
"""Select a schema category for the specified host expression."""
|
|
180
|
+
return _Controls.selector(f"Ens.ContextSearch/SchemaCategories?host={host}")
|
|
181
|
+
|
|
182
|
+
@staticmethod
|
|
183
|
+
def search_table(host: str) -> str:
|
|
184
|
+
"""Select a search table class for the specified host expression."""
|
|
185
|
+
return _Controls.selector(f"Ens.ContextSearch/SearchTableClasses?host={host}")
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
controls = _Controls()
|