iris-pex-embedded-python 3.7.2b1__tar.gz → 4.0.0b1__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-4.0.0b1}/PKG-INFO +3 -1
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/pyproject.toml +13 -2
- iris_pex_embedded_python-4.0.0b1/src/iop/__init__.py +138 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/__main__.py +5 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/cli/__init__.py +1 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/cli/formatting.py +45 -0
- iris_pex_embedded_python-3.7.2b1/src/iop/_cli.py → iris_pex_embedded_python-4.0.0b1/src/iop/cli/main.py +97 -204
- iris_pex_embedded_python-4.0.0b1/src/iop/cli/parser.py +128 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/cli/types.py +57 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/Service/Remote/Rest/v1.cls +151 -5
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/Utils.cls +413 -8
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/Wrapper.cls +1 -1
- iris_pex_embedded_python-4.0.0b1/src/iop/components/__init__.py +16 -0
- iris_pex_embedded_python-3.7.2b1/src/iop/_async_request.py → iris_pex_embedded_python-4.0.0b1/src/iop/components/async_request.py +7 -7
- iris_pex_embedded_python-4.0.0b1/src/iop/components/business_host.py +319 -0
- iris_pex_embedded_python-3.7.2b1/src/iop/_business_operation.py → iris_pex_embedded_python-4.0.0b1/src/iop/components/business_operation.py +16 -33
- iris_pex_embedded_python-3.7.2b1/src/iop/_business_process.py → iris_pex_embedded_python-4.0.0b1/src/iop/components/business_process.py +28 -71
- iris_pex_embedded_python-3.7.2b1/src/iop/_business_service.py → iris_pex_embedded_python-4.0.0b1/src/iop/components/business_service.py +16 -30
- iris_pex_embedded_python-4.0.0b1/src/iop/components/common.py +498 -0
- iris_pex_embedded_python-3.7.2b1/src/iop/_debugpy.py → iris_pex_embedded_python-4.0.0b1/src/iop/components/debugpy.py +11 -11
- iris_pex_embedded_python-3.7.2b1/src/iop/_generator_request.py → iris_pex_embedded_python-4.0.0b1/src/iop/components/generator_request.py +4 -4
- iris_pex_embedded_python-3.7.2b1/src/iop/_inbound_adapter.py → iris_pex_embedded_python-4.0.0b1/src/iop/components/inbound_adapter.py +10 -18
- iris_pex_embedded_python-3.7.2b1/src/iop/_log_manager.py → iris_pex_embedded_python-4.0.0b1/src/iop/components/log_manager.py +1 -1
- iris_pex_embedded_python-3.7.2b1/src/iop/_outbound_adapter.py → iris_pex_embedded_python-4.0.0b1/src/iop/components/outbound_adapter.py +1 -1
- iris_pex_embedded_python-4.0.0b1/src/iop/components/polling_business_service.py +6 -0
- iris_pex_embedded_python-3.7.2b1/src/iop/_private_session_duplex.py → iris_pex_embedded_python-4.0.0b1/src/iop/components/private_session_duplex.py +7 -9
- iris_pex_embedded_python-3.7.2b1/src/iop/_private_session_process.py → iris_pex_embedded_python-4.0.0b1/src/iop/components/private_session_process.py +2 -2
- iris_pex_embedded_python-4.0.0b1/src/iop/components/settings.py +187 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/messages/__init__.py +7 -0
- iris_pex_embedded_python-3.7.2b1/src/iop/_message.py → iris_pex_embedded_python-4.0.0b1/src/iop/messages/base.py +15 -15
- iris_pex_embedded_python-3.7.2b1/src/iop/_decorators.py → iris_pex_embedded_python-4.0.0b1/src/iop/messages/decorators.py +3 -2
- iris_pex_embedded_python-3.7.2b1/src/iop/_dispatch.py → iris_pex_embedded_python-4.0.0b1/src/iop/messages/dispatch.py +19 -22
- iris_pex_embedded_python-3.7.2b1/src/iop/_persistent_message.py → iris_pex_embedded_python-4.0.0b1/src/iop/messages/persistent.py +16 -19
- iris_pex_embedded_python-3.7.2b1/src/iop/_serialization.py → iris_pex_embedded_python-4.0.0b1/src/iop/messages/serialization.py +21 -17
- iris_pex_embedded_python-3.7.2b1/src/iop/_message_validator.py → iris_pex_embedded_python-4.0.0b1/src/iop/messages/validation.py +4 -4
- iris_pex_embedded_python-4.0.0b1/src/iop/migration/__init__.py +1 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/migration/io.py +61 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/migration/plans.py +159 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/migration/utils.py +1135 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/production/__init__.py +29 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/production/actions.py +228 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/production/common.py +79 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/production/component.py +240 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/production/diff.py +321 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/production/import_.py +259 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/production/inspection.py +92 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/production/model.py +783 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/production/reconstruction.py +169 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/production/rendering.py +289 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/production/runtime.py +76 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/production/types.py +301 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/runtime/__init__.py +1 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/runtime/director.py +405 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/runtime/environment.py +59 -0
- iris_pex_embedded_python-3.7.2b1/src/iop/_iris.py → iris_pex_embedded_python-4.0.0b1/src/iop/runtime/iris.py +2 -2
- iris_pex_embedded_python-4.0.0b1/src/iop/runtime/local.py +126 -0
- iris_pex_embedded_python-3.7.2b1/src/iop/_director_protocol.py → iris_pex_embedded_python-4.0.0b1/src/iop/runtime/protocol.py +15 -7
- iris_pex_embedded_python-4.0.0b1/src/iop/runtime/remote/__init__.py +12 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/runtime/remote/client.py +90 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/runtime/remote/director.py +265 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/runtime/remote/migration.py +51 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/runtime/remote/settings.py +69 -0
- iris_pex_embedded_python-4.0.0b1/src/iop/runtime/remote/setup.py +72 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1/src/iris_pex_embedded_python.egg-info}/PKG-INFO +3 -1
- iris_pex_embedded_python-4.0.0b1/src/iris_pex_embedded_python.egg-info/SOURCES.txt +96 -0
- iris_pex_embedded_python-4.0.0b1/src/iris_pex_embedded_python.egg-info/entry_points.txt +2 -0
- iris_pex_embedded_python-4.0.0b1/src/iris_pex_embedded_python.egg-info/top_level.txt +1 -0
- iris_pex_embedded_python-3.7.2b1/setup.py +0 -3
- iris_pex_embedded_python-3.7.2b1/src/grongier/__init__.py +0 -0
- iris_pex_embedded_python-3.7.2b1/src/grongier/cls/Grongier/PEX/BusinessOperation.cls +0 -8
- iris_pex_embedded_python-3.7.2b1/src/grongier/cls/Grongier/PEX/BusinessProcess.cls +0 -13
- iris_pex_embedded_python-3.7.2b1/src/grongier/cls/Grongier/PEX/BusinessService.cls +0 -8
- iris_pex_embedded_python-3.7.2b1/src/grongier/cls/Grongier/PEX/Common.cls +0 -10
- iris_pex_embedded_python-3.7.2b1/src/grongier/cls/Grongier/PEX/Director.cls +0 -10
- iris_pex_embedded_python-3.7.2b1/src/grongier/cls/Grongier/PEX/Duplex/Operation.cls +0 -4
- iris_pex_embedded_python-3.7.2b1/src/grongier/cls/Grongier/PEX/Duplex/Process.cls +0 -13
- iris_pex_embedded_python-3.7.2b1/src/grongier/cls/Grongier/PEX/Duplex/Service.cls +0 -4
- iris_pex_embedded_python-3.7.2b1/src/grongier/cls/Grongier/PEX/InboundAdapter.cls +0 -8
- iris_pex_embedded_python-3.7.2b1/src/grongier/cls/Grongier/PEX/Message.cls +0 -13
- iris_pex_embedded_python-3.7.2b1/src/grongier/cls/Grongier/PEX/OutboundAdapter.cls +0 -8
- iris_pex_embedded_python-3.7.2b1/src/grongier/cls/Grongier/PEX/PickleMessage.cls +0 -13
- iris_pex_embedded_python-3.7.2b1/src/grongier/cls/Grongier/PEX/PrivateSession/Duplex.cls +0 -8
- iris_pex_embedded_python-3.7.2b1/src/grongier/cls/Grongier/PEX/PrivateSession/Message/Ack.cls +0 -14
- iris_pex_embedded_python-3.7.2b1/src/grongier/cls/Grongier/PEX/PrivateSession/Message/Poll.cls +0 -14
- iris_pex_embedded_python-3.7.2b1/src/grongier/cls/Grongier/PEX/PrivateSession/Message/Start.cls +0 -14
- iris_pex_embedded_python-3.7.2b1/src/grongier/cls/Grongier/PEX/PrivateSession/Message/Stop.cls +0 -14
- iris_pex_embedded_python-3.7.2b1/src/grongier/cls/Grongier/PEX/Test.cls +0 -10
- iris_pex_embedded_python-3.7.2b1/src/grongier/cls/Grongier/PEX/Utils.cls +0 -10
- iris_pex_embedded_python-3.7.2b1/src/grongier/cls/Grongier/Service/WSGI.cls +0 -4
- iris_pex_embedded_python-3.7.2b1/src/grongier/pex/__init__.py +0 -66
- iris_pex_embedded_python-3.7.2b1/src/grongier/pex/__main__.py +0 -4
- iris_pex_embedded_python-3.7.2b1/src/grongier/pex/_business_host.py +0 -1
- iris_pex_embedded_python-3.7.2b1/src/grongier/pex/_cli.py +0 -4
- iris_pex_embedded_python-3.7.2b1/src/grongier/pex/_common.py +0 -1
- iris_pex_embedded_python-3.7.2b1/src/grongier/pex/_director.py +0 -1
- iris_pex_embedded_python-3.7.2b1/src/grongier/pex/_utils.py +0 -1
- iris_pex_embedded_python-3.7.2b1/src/grongier/pex/wsgi/handlers.py +0 -104
- iris_pex_embedded_python-3.7.2b1/src/iop/__init__.py +0 -78
- iris_pex_embedded_python-3.7.2b1/src/iop/__main__.py +0 -5
- iris_pex_embedded_python-3.7.2b1/src/iop/_business_host.py +0 -322
- iris_pex_embedded_python-3.7.2b1/src/iop/_common.py +0 -416
- iris_pex_embedded_python-3.7.2b1/src/iop/_director.py +0 -333
- iris_pex_embedded_python-3.7.2b1/src/iop/_local.py +0 -106
- iris_pex_embedded_python-3.7.2b1/src/iop/_remote.py +0 -473
- iris_pex_embedded_python-3.7.2b1/src/iop/_utils.py +0 -710
- iris_pex_embedded_python-3.7.2b1/src/iop/cls/IOP/Service/WSGI.cls +0 -310
- iris_pex_embedded_python-3.7.2b1/src/iop/wsgi/handlers.py +0 -112
- iris_pex_embedded_python-3.7.2b1/src/iris_pex_embedded_python.egg-info/SOURCES.txt +0 -98
- iris_pex_embedded_python-3.7.2b1/src/iris_pex_embedded_python.egg-info/entry_points.txt +0 -2
- iris_pex_embedded_python-3.7.2b1/src/iris_pex_embedded_python.egg-info/top_level.txt +0 -2
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/LICENSE +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/README.md +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/setup.cfg +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/BusinessOperation.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/BusinessProcess.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/BusinessService.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/Common.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/Director.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/Duplex/Operation.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/Duplex/Process.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/Duplex/Service.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/Generator/Message/Ack.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/Generator/Message/Poll.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/Generator/Message/Start.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/Generator/Message/StartPickle.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/Generator/Message/Stop.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/InboundAdapter.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/Message/JSONSchema.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/Message.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/OutboundAdapter.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/PickleMessage.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/PrivateSession/Duplex.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/PrivateSession/Message/Ack.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/PrivateSession/Message/Poll.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/PrivateSession/Message/Start.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/PrivateSession/Message/Stop.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/Projection.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/Service/Remote/Handler.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iop/cls/IOP/Test.cls +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iris_pex_embedded_python.egg-info/dependency_links.txt +0 -0
- {iris_pex_embedded_python-3.7.2b1 → iris_pex_embedded_python-4.0.0b1}/src/iris_pex_embedded_python.egg-info/requires.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: iris_pex_embedded_python
|
|
3
|
-
Version:
|
|
3
|
+
Version: 4.0.0b1
|
|
4
4
|
Summary: Iris Interoperability based on Embedded Python
|
|
5
5
|
Author-email: grongier <guillaume.rongier@intersystems.com>
|
|
6
6
|
License: MIT License
|
|
@@ -37,6 +37,8 @@ Classifier: Operating System :: OS Independent
|
|
|
37
37
|
Classifier: Programming Language :: Python :: 3.10
|
|
38
38
|
Classifier: Programming Language :: Python :: 3.11
|
|
39
39
|
Classifier: Programming Language :: Python :: 3.12
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
41
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
40
42
|
Classifier: Topic :: Utilities
|
|
41
43
|
Requires-Python: >=3.10
|
|
42
44
|
Description-Content-Type: text/markdown
|
|
@@ -3,7 +3,7 @@ requires = ["setuptools", "wheel"]
|
|
|
3
3
|
|
|
4
4
|
[project]
|
|
5
5
|
name = "iris_pex_embedded_python"
|
|
6
|
-
version = "
|
|
6
|
+
version = "4.0.0b1"
|
|
7
7
|
description = "Iris Interoperability based on Embedded Python"
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
requires-python = ">=3.10"
|
|
@@ -20,6 +20,8 @@ classifiers = [
|
|
|
20
20
|
"Programming Language :: Python :: 3.10",
|
|
21
21
|
"Programming Language :: Python :: 3.11",
|
|
22
22
|
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Programming Language :: Python :: 3.13",
|
|
24
|
+
"Programming Language :: Python :: 3.14",
|
|
23
25
|
"Topic :: Utilities"
|
|
24
26
|
]
|
|
25
27
|
|
|
@@ -42,10 +44,11 @@ repository = "https://github.com/grongierisc/interoperability-embedded-python"
|
|
|
42
44
|
issues = "https://github.com/grongierisc/interoperability-embedded-python/issues"
|
|
43
45
|
|
|
44
46
|
[project.scripts]
|
|
45
|
-
iop = "iop.
|
|
47
|
+
iop = "iop.cli.main:main"
|
|
46
48
|
|
|
47
49
|
[tool.setuptools.packages.find]
|
|
48
50
|
where = ["src"]
|
|
51
|
+
include = ["iop*"]
|
|
49
52
|
exclude = ["tests*"]
|
|
50
53
|
|
|
51
54
|
[tool.setuptools.package-data]
|
|
@@ -59,3 +62,11 @@ markers = [
|
|
|
59
62
|
"e2e_local: end-to-end test requiring a local IRIS instance",
|
|
60
63
|
"e2e_remote: end-to-end test requiring a remote IRIS instance via REST API",
|
|
61
64
|
]
|
|
65
|
+
|
|
66
|
+
[tool.ruff]
|
|
67
|
+
target-version = "py310"
|
|
68
|
+
line-length = 88
|
|
69
|
+
|
|
70
|
+
[tool.ruff.lint]
|
|
71
|
+
select = ["E", "F", "I", "B", "UP"]
|
|
72
|
+
ignore = ["E501"]
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
from iop.components.business_operation import _BusinessOperation
|
|
2
|
+
from iop.components.business_process import _BusinessProcess
|
|
3
|
+
from iop.components.business_service import _BusinessService
|
|
4
|
+
from iop.components.inbound_adapter import _InboundAdapter
|
|
5
|
+
from iop.components.outbound_adapter import _OutboundAdapter
|
|
6
|
+
from iop.components.polling_business_service import _PollingBusinessServiceMixin
|
|
7
|
+
from iop.components.private_session_duplex import _PrivateSessionDuplex
|
|
8
|
+
from iop.components.private_session_process import _PrivateSessionProcess
|
|
9
|
+
from iop.components.settings import Category as Category
|
|
10
|
+
from iop.components.settings import Setting as Setting
|
|
11
|
+
from iop.components.settings import controls as controls
|
|
12
|
+
from iop.components.settings import setting as setting
|
|
13
|
+
from iop.messages.base import (
|
|
14
|
+
_Message,
|
|
15
|
+
_PickleMessage,
|
|
16
|
+
_PydanticMessage,
|
|
17
|
+
_PydanticPickleMessage,
|
|
18
|
+
)
|
|
19
|
+
from iop.messages.persistent import Field as Field
|
|
20
|
+
from iop.messages.persistent import Model as Model
|
|
21
|
+
from iop.messages.persistent import _PersistentMessage
|
|
22
|
+
from iop.migration.utils import _Utils
|
|
23
|
+
from iop.migration.utils import bind_component as bind_component
|
|
24
|
+
from iop.migration.utils import list_bindings as list_bindings
|
|
25
|
+
from iop.migration.utils import register_component as register_component
|
|
26
|
+
from iop.migration.utils import unbind_component as unbind_component
|
|
27
|
+
from iop.migration.utils import unregister_component as unregister_component
|
|
28
|
+
from iop.production import ComponentRef as ComponentRef
|
|
29
|
+
from iop.production import Port as Port
|
|
30
|
+
from iop.production import Production as Production
|
|
31
|
+
from iop.production import ProductionDiff as ProductionDiff
|
|
32
|
+
from iop.production import ProductionDiffEntry as ProductionDiffEntry
|
|
33
|
+
from iop.production import ProductionGraph as ProductionGraph
|
|
34
|
+
from iop.production import target as target
|
|
35
|
+
from iop.runtime.director import _Director
|
|
36
|
+
from iop.runtime.protocol import DirectorProtocol as DirectorProtocol
|
|
37
|
+
|
|
38
|
+
__all__ = [
|
|
39
|
+
"BusinessOperation",
|
|
40
|
+
"BusinessProcess",
|
|
41
|
+
"BusinessService",
|
|
42
|
+
"Category",
|
|
43
|
+
"ComponentRef",
|
|
44
|
+
"Director",
|
|
45
|
+
"DirectorProtocol",
|
|
46
|
+
"DuplexOperation",
|
|
47
|
+
"DuplexProcess",
|
|
48
|
+
"DuplexService",
|
|
49
|
+
"Field",
|
|
50
|
+
"InboundAdapter",
|
|
51
|
+
"Message",
|
|
52
|
+
"Model",
|
|
53
|
+
"OutboundAdapter",
|
|
54
|
+
"PersistentMessage",
|
|
55
|
+
"PickleMessage",
|
|
56
|
+
"PollingBusinessService",
|
|
57
|
+
"Port",
|
|
58
|
+
"Production",
|
|
59
|
+
"ProductionDiff",
|
|
60
|
+
"ProductionDiffEntry",
|
|
61
|
+
"ProductionGraph",
|
|
62
|
+
"PydanticMessage",
|
|
63
|
+
"PydanticPickleMessage",
|
|
64
|
+
"Setting",
|
|
65
|
+
"Utils",
|
|
66
|
+
"bind_component",
|
|
67
|
+
"controls",
|
|
68
|
+
"list_bindings",
|
|
69
|
+
"register_component",
|
|
70
|
+
"setting",
|
|
71
|
+
"target",
|
|
72
|
+
"unbind_component",
|
|
73
|
+
"unregister_component",
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class Utils(_Utils):
|
|
78
|
+
pass
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class InboundAdapter(_InboundAdapter):
|
|
82
|
+
pass
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class OutboundAdapter(_OutboundAdapter):
|
|
86
|
+
pass
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class BusinessService(_BusinessService):
|
|
90
|
+
pass
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class PollingBusinessService(_PollingBusinessServiceMixin, BusinessService):
|
|
94
|
+
pass
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class BusinessOperation(_BusinessOperation):
|
|
98
|
+
pass
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class BusinessProcess(_BusinessProcess):
|
|
102
|
+
pass
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class DuplexService(_PrivateSessionDuplex):
|
|
106
|
+
pass
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class DuplexOperation(_PrivateSessionDuplex):
|
|
110
|
+
pass
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class DuplexProcess(_PrivateSessionProcess):
|
|
114
|
+
pass
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class Message(_Message):
|
|
118
|
+
pass
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class PickleMessage(_PickleMessage):
|
|
122
|
+
pass
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class PydanticMessage(_PydanticMessage):
|
|
126
|
+
pass
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class PydanticPickleMessage(_PydanticPickleMessage):
|
|
130
|
+
pass
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class PersistentMessage(_PersistentMessage):
|
|
134
|
+
_iop_persistent_message_abstract = True
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class Director(_Director):
|
|
138
|
+
pass
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .main import main as main
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import dataclasses
|
|
4
|
+
import json
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def format_test_response(response: Any) -> str:
|
|
9
|
+
"""Pretty-print any test_component() return value."""
|
|
10
|
+
if isinstance(response, dict):
|
|
11
|
+
parts = []
|
|
12
|
+
if response.get("error"):
|
|
13
|
+
return f"Error: {response['error']}"
|
|
14
|
+
if response.get("classname"):
|
|
15
|
+
parts.append(f"classname: {response['classname']}")
|
|
16
|
+
body = response.get("body", "")
|
|
17
|
+
if body:
|
|
18
|
+
try:
|
|
19
|
+
parsed = json.loads(body)
|
|
20
|
+
parts.append("body:\n" + json.dumps(parsed, indent=4))
|
|
21
|
+
except (json.JSONDecodeError, TypeError):
|
|
22
|
+
parts.append(f"body: {body}")
|
|
23
|
+
if response.get("truncated"):
|
|
24
|
+
parts.append("(response body was truncated)")
|
|
25
|
+
return "\n".join(parts) if parts else str(response)
|
|
26
|
+
|
|
27
|
+
if isinstance(response, str):
|
|
28
|
+
if " : " in response:
|
|
29
|
+
classname_part, _, body_part = response.partition(" : ")
|
|
30
|
+
try:
|
|
31
|
+
parsed = json.loads(body_part)
|
|
32
|
+
return (
|
|
33
|
+
f"classname: {classname_part.strip()}\n"
|
|
34
|
+
f"body:\n{json.dumps(parsed, indent=4)}"
|
|
35
|
+
)
|
|
36
|
+
except (json.JSONDecodeError, TypeError):
|
|
37
|
+
pass
|
|
38
|
+
try:
|
|
39
|
+
return json.dumps(json.loads(response), indent=4)
|
|
40
|
+
except (json.JSONDecodeError, TypeError):
|
|
41
|
+
return response
|
|
42
|
+
|
|
43
|
+
if dataclasses.is_dataclass(response):
|
|
44
|
+
return json.dumps(dataclasses.asdict(response), indent=4)
|
|
45
|
+
return str(response)
|
|
@@ -1,62 +1,23 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
import json
|
|
4
4
|
import logging
|
|
5
|
-
import requests
|
|
6
5
|
import os
|
|
7
|
-
from dataclasses import dataclass
|
|
8
|
-
from enum import Enum, auto
|
|
9
6
|
import sys
|
|
10
|
-
from typing import Optional
|
|
11
7
|
from importlib.metadata import version
|
|
12
8
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
from
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
STATUS = auto()
|
|
26
|
-
TEST = auto()
|
|
27
|
-
VERSION = auto()
|
|
28
|
-
EXPORT = auto()
|
|
29
|
-
MIGRATE = auto()
|
|
30
|
-
LOG = auto()
|
|
31
|
-
INIT = auto()
|
|
32
|
-
HELP = auto()
|
|
33
|
-
UPDATE = auto()
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
@dataclass
|
|
37
|
-
class CommandArgs:
|
|
38
|
-
"""Container for parsed command arguments"""
|
|
39
|
-
|
|
40
|
-
default: Optional[str] = None
|
|
41
|
-
list: bool = False
|
|
42
|
-
start: Optional[str] = None
|
|
43
|
-
detach: bool = False
|
|
44
|
-
stop: bool = False
|
|
45
|
-
kill: bool = False
|
|
46
|
-
restart: bool = False
|
|
47
|
-
status: bool = False
|
|
48
|
-
migrate: Optional[str] = None
|
|
49
|
-
export: Optional[str] = None
|
|
50
|
-
version: bool = False
|
|
51
|
-
log: Optional[str] = None
|
|
52
|
-
init: Optional[str] = None
|
|
53
|
-
test: Optional[str] = None
|
|
54
|
-
classname: Optional[str] = None
|
|
55
|
-
body: Optional[str] = None
|
|
56
|
-
namespace: Optional[str] = None
|
|
57
|
-
force_local: bool = False
|
|
58
|
-
remote_settings: Optional[str] = None
|
|
59
|
-
update: bool = False
|
|
9
|
+
import requests
|
|
10
|
+
|
|
11
|
+
from ..migration import utils as migration_utils
|
|
12
|
+
from ..production import Production
|
|
13
|
+
from ..runtime.local import _LocalDirector
|
|
14
|
+
from ..runtime.protocol import DirectorProtocol
|
|
15
|
+
from ..runtime.remote import _RemoteDirector, get_remote_settings
|
|
16
|
+
from .formatting import format_test_response
|
|
17
|
+
from .parser import create_parser
|
|
18
|
+
from .types import CommandArgs, CommandType
|
|
19
|
+
|
|
20
|
+
_format_test_response = format_test_response
|
|
60
21
|
|
|
61
22
|
|
|
62
23
|
class Command:
|
|
@@ -112,12 +73,18 @@ class Command:
|
|
|
112
73
|
self.args.export,
|
|
113
74
|
self.args.migrate,
|
|
114
75
|
self.args.log,
|
|
76
|
+
self.args.queue,
|
|
115
77
|
self.args.init,
|
|
78
|
+
self.args.bindings,
|
|
79
|
+
self.args.unbind is not None,
|
|
116
80
|
self.args.update,
|
|
117
81
|
]
|
|
118
82
|
)
|
|
119
83
|
|
|
120
84
|
def execute(self) -> None:
|
|
85
|
+
if self.args.unused and not self.args.bindings:
|
|
86
|
+
raise ValueError("--unused can only be used with --bindings.")
|
|
87
|
+
|
|
121
88
|
if self.args.namespace == "not_set" and not self._has_primary_command():
|
|
122
89
|
print(os.getenv("IRISNAMESPACE", "not set"))
|
|
123
90
|
return
|
|
@@ -136,7 +103,10 @@ class Command:
|
|
|
136
103
|
CommandType.EXPORT: self._handle_export,
|
|
137
104
|
CommandType.MIGRATE: self._handle_migrate,
|
|
138
105
|
CommandType.LOG: self._handle_log,
|
|
106
|
+
CommandType.QUEUE: self._handle_queue,
|
|
139
107
|
CommandType.INIT: self._handle_init,
|
|
108
|
+
CommandType.BINDINGS: self._handle_bindings,
|
|
109
|
+
CommandType.UNBIND: self._handle_unbind,
|
|
140
110
|
CommandType.HELP: self._handle_help,
|
|
141
111
|
CommandType.UPDATE: self._handle_update,
|
|
142
112
|
}
|
|
@@ -169,8 +139,14 @@ class Command:
|
|
|
169
139
|
return CommandType.MIGRATE
|
|
170
140
|
if self.args.log:
|
|
171
141
|
return CommandType.LOG
|
|
142
|
+
if self.args.queue:
|
|
143
|
+
return CommandType.QUEUE
|
|
172
144
|
if self.args.init:
|
|
173
145
|
return CommandType.INIT
|
|
146
|
+
if self.args.bindings:
|
|
147
|
+
return CommandType.BINDINGS
|
|
148
|
+
if self.args.unbind is not None:
|
|
149
|
+
return CommandType.UNBIND
|
|
174
150
|
if self.args.update:
|
|
175
151
|
return CommandType.UPDATE
|
|
176
152
|
return CommandType.HELP
|
|
@@ -228,13 +204,13 @@ class Command:
|
|
|
228
204
|
filepath = body[1:]
|
|
229
205
|
if not os.path.isabs(filepath):
|
|
230
206
|
filepath = os.path.join(os.getcwd(), filepath)
|
|
231
|
-
with open(filepath,
|
|
207
|
+
with open(filepath, encoding="utf-8") as fh:
|
|
232
208
|
body = fh.read()
|
|
233
209
|
|
|
234
210
|
response = self.director.test_component(
|
|
235
211
|
test_name, classname=classname, body=body
|
|
236
212
|
)
|
|
237
|
-
print(
|
|
213
|
+
print(format_test_response(response))
|
|
238
214
|
|
|
239
215
|
def _handle_version(self) -> None:
|
|
240
216
|
print(version("iris-pex-embedded-python"))
|
|
@@ -245,14 +221,46 @@ class Command:
|
|
|
245
221
|
if self.args.export == "not_set"
|
|
246
222
|
else self.args.export
|
|
247
223
|
)
|
|
248
|
-
|
|
224
|
+
export_format = self.args.export_format or "json"
|
|
225
|
+
if export_format == "json":
|
|
226
|
+
print(json.dumps(self.director.export_production(export_name), indent=4))
|
|
227
|
+
return
|
|
228
|
+
|
|
229
|
+
production = Production.from_iris(export_name, director=self.director)
|
|
230
|
+
if export_format == "python":
|
|
231
|
+
print(production.to_python(), end="")
|
|
232
|
+
return
|
|
233
|
+
if export_format == "graph":
|
|
234
|
+
print(production.graph())
|
|
235
|
+
return
|
|
236
|
+
raise ValueError(f"Unsupported export format: {export_format}")
|
|
249
237
|
|
|
250
238
|
def _handle_migrate(self) -> None:
|
|
251
239
|
migrate_path = self.args.migrate
|
|
252
240
|
if migrate_path is not None:
|
|
253
241
|
if not os.path.isabs(migrate_path):
|
|
254
242
|
migrate_path = os.path.join(os.getcwd(), migrate_path)
|
|
243
|
+
mode = "REMOTE" if self._is_remote else "LOCAL"
|
|
244
|
+
if self.args.migration_plan:
|
|
245
|
+
print(
|
|
246
|
+
migration_utils.explain_migration(
|
|
247
|
+
migrate_path, mode=mode, namespace=self.director.namespace
|
|
248
|
+
)
|
|
249
|
+
)
|
|
250
|
+
return
|
|
251
|
+
if self._is_remote:
|
|
252
|
+
print(
|
|
253
|
+
migration_utils.explain_migration(
|
|
254
|
+
migrate_path, mode=mode, namespace=self.director.namespace
|
|
255
|
+
)
|
|
256
|
+
)
|
|
255
257
|
self.director.migrate(migrate_path)
|
|
258
|
+
if self._is_remote:
|
|
259
|
+
print(
|
|
260
|
+
migration_utils.format_migration_success(
|
|
261
|
+
migrate_path, namespace=self.director.namespace
|
|
262
|
+
)
|
|
263
|
+
)
|
|
256
264
|
|
|
257
265
|
def _handle_log(self) -> None:
|
|
258
266
|
if self.args.log == "not_set":
|
|
@@ -260,10 +268,43 @@ class Command:
|
|
|
260
268
|
elif self.args.log is not None:
|
|
261
269
|
self.director.log_production_top(int(self.args.log))
|
|
262
270
|
|
|
271
|
+
def _handle_queue(self) -> None:
|
|
272
|
+
production_name = (
|
|
273
|
+
self.director.get_default_production()
|
|
274
|
+
if self.args.queue == "not_set"
|
|
275
|
+
else self.args.queue
|
|
276
|
+
)
|
|
277
|
+
if not production_name or production_name == "Not defined":
|
|
278
|
+
print(
|
|
279
|
+
"Error: no production name provided and no default production is defined.",
|
|
280
|
+
file=sys.stderr,
|
|
281
|
+
)
|
|
282
|
+
sys.exit(1)
|
|
283
|
+
print(
|
|
284
|
+
json.dumps(
|
|
285
|
+
self.director.export_production_queue_info(production_name),
|
|
286
|
+
indent=4,
|
|
287
|
+
)
|
|
288
|
+
)
|
|
289
|
+
|
|
263
290
|
def _handle_init(self) -> None:
|
|
264
291
|
path = None if self.args.init == "not_set" else self.args.init
|
|
265
292
|
self.director.setup(path)
|
|
266
293
|
|
|
294
|
+
def _handle_bindings(self) -> None:
|
|
295
|
+
print(
|
|
296
|
+
json.dumps(
|
|
297
|
+
self.director.list_bindings(unused_only=self.args.unused),
|
|
298
|
+
indent=4,
|
|
299
|
+
)
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
def _handle_unbind(self) -> None:
|
|
303
|
+
if not self.args.unbind:
|
|
304
|
+
raise ValueError("IRIS class name is required.")
|
|
305
|
+
self.director.unbind_component(self.args.unbind)
|
|
306
|
+
print(f"Removed binding {self.args.unbind}.")
|
|
307
|
+
|
|
267
308
|
def _handle_help(self) -> None:
|
|
268
309
|
create_parser().print_help()
|
|
269
310
|
if self._is_remote:
|
|
@@ -275,154 +316,6 @@ class Command:
|
|
|
275
316
|
logging.warning("Could not retrieve default production.")
|
|
276
317
|
|
|
277
318
|
|
|
278
|
-
def _format_test_response(response) -> str:
|
|
279
|
-
"""Pretty-print any test_component() return value.
|
|
280
|
-
|
|
281
|
-
Handles three cases:
|
|
282
|
-
- dict : remote response with ``classname`` / ``body`` keys
|
|
283
|
-
- str : local response in ``"ClassName : {json}"`` format
|
|
284
|
-
- other : Python dataclass / object returned by the local director
|
|
285
|
-
"""
|
|
286
|
-
if isinstance(response, dict):
|
|
287
|
-
parts = []
|
|
288
|
-
if response.get("error"):
|
|
289
|
-
return f"Error: {response['error']}"
|
|
290
|
-
if response.get("classname"):
|
|
291
|
-
parts.append(f"classname: {response['classname']}")
|
|
292
|
-
body = response.get("body", "")
|
|
293
|
-
if body:
|
|
294
|
-
try:
|
|
295
|
-
parsed = json.loads(body)
|
|
296
|
-
parts.append("body:\n" + json.dumps(parsed, indent=4))
|
|
297
|
-
except (json.JSONDecodeError, TypeError):
|
|
298
|
-
parts.append(f"body: {body}")
|
|
299
|
-
if response.get("truncated"):
|
|
300
|
-
parts.append("(response body was truncated)")
|
|
301
|
-
return "\n".join(parts) if parts else str(response)
|
|
302
|
-
|
|
303
|
-
if isinstance(response, str):
|
|
304
|
-
# Try to detect the "ClassName : {json_body}" pattern from local mode
|
|
305
|
-
if " : " in response:
|
|
306
|
-
classname_part, _, body_part = response.partition(" : ")
|
|
307
|
-
try:
|
|
308
|
-
parsed = json.loads(body_part)
|
|
309
|
-
return (
|
|
310
|
-
f"classname: {classname_part.strip()}\n"
|
|
311
|
-
f"body:\n{json.dumps(parsed, indent=4)}"
|
|
312
|
-
)
|
|
313
|
-
except (json.JSONDecodeError, TypeError):
|
|
314
|
-
pass
|
|
315
|
-
# Plain string — try JSON pretty-print
|
|
316
|
-
try:
|
|
317
|
-
return json.dumps(json.loads(response), indent=4)
|
|
318
|
-
except (json.JSONDecodeError, TypeError):
|
|
319
|
-
return response
|
|
320
|
-
|
|
321
|
-
# Python dataclass / arbitrary object
|
|
322
|
-
try:
|
|
323
|
-
import dataclasses
|
|
324
|
-
|
|
325
|
-
if dataclasses.is_dataclass(response):
|
|
326
|
-
return json.dumps(dataclasses.asdict(response), indent=4)
|
|
327
|
-
except Exception:
|
|
328
|
-
pass
|
|
329
|
-
return str(response)
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
def create_parser() -> argparse.ArgumentParser:
|
|
333
|
-
"""Create and configure argument parser"""
|
|
334
|
-
main_parser = argparse.ArgumentParser(
|
|
335
|
-
epilog=(
|
|
336
|
-
"Remote mode: set IOP_URL (e.g. http://localhost:8080) to run all commands\n"
|
|
337
|
-
"against a remote IRIS instance via its REST API. Optional env vars:\n"
|
|
338
|
-
" IOP_USERNAME, IOP_PASSWORD, IOP_NAMESPACE (default: USER),\n"
|
|
339
|
-
" IOP_VERIFY_SSL (set to 0 to disable TLS verification).\n"
|
|
340
|
-
"Alternatively use -R /path/to/settings.py or set IOP_SETTINGS=\n"
|
|
341
|
-
"(file must contain a REMOTE_SETTINGS dict with at least 'url').\n"
|
|
342
|
-
"Use --force-local to suppress remote mode entirely."
|
|
343
|
-
),
|
|
344
|
-
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
345
|
-
)
|
|
346
|
-
parser = main_parser.add_mutually_exclusive_group()
|
|
347
|
-
|
|
348
|
-
# Main commands
|
|
349
|
-
parser.add_argument(
|
|
350
|
-
"-d", "--default", help="set the default production", nargs="?", const="not_set"
|
|
351
|
-
)
|
|
352
|
-
parser.add_argument("-l", "--list", help="list productions", action="store_true")
|
|
353
|
-
parser.add_argument(
|
|
354
|
-
"-s", "--start", help="start a production", nargs="?", const="not_set"
|
|
355
|
-
)
|
|
356
|
-
parser.add_argument("-S", "--stop", help="stop a production", action="store_true")
|
|
357
|
-
parser.add_argument("-k", "--kill", help="kill a production", action="store_true")
|
|
358
|
-
parser.add_argument(
|
|
359
|
-
"-r", "--restart", help="restart a production", action="store_true"
|
|
360
|
-
)
|
|
361
|
-
parser.add_argument(
|
|
362
|
-
"-x", "--status", help="status a production", action="store_true"
|
|
363
|
-
)
|
|
364
|
-
parser.add_argument(
|
|
365
|
-
"-m",
|
|
366
|
-
"-M",
|
|
367
|
-
"--migrate",
|
|
368
|
-
help="migrate production and classes with settings file",
|
|
369
|
-
)
|
|
370
|
-
parser.add_argument(
|
|
371
|
-
"-e", "--export", help="export a production", nargs="?", const="not_set"
|
|
372
|
-
)
|
|
373
|
-
parser.add_argument("-v", "--version", help="display version", action="store_true")
|
|
374
|
-
parser.add_argument("-L", "--log", help="display log", nargs="?", const="not_set")
|
|
375
|
-
parser.add_argument(
|
|
376
|
-
"-i", "--init", help="init the pex module in iris", nargs="?", const="not_set"
|
|
377
|
-
)
|
|
378
|
-
parser.add_argument(
|
|
379
|
-
"-t", "--test", help="test the pex module in iris", nargs="?", const="not_set"
|
|
380
|
-
)
|
|
381
|
-
parser.add_argument(
|
|
382
|
-
"-u", "--update", help="update a production", action="store_true"
|
|
383
|
-
)
|
|
384
|
-
|
|
385
|
-
# Command groups
|
|
386
|
-
start = main_parser.add_argument_group("start arguments")
|
|
387
|
-
start.add_argument(
|
|
388
|
-
"-D", "--detach", help="start a production in detach mode", action="store_true"
|
|
389
|
-
)
|
|
390
|
-
|
|
391
|
-
test = main_parser.add_argument_group("test arguments")
|
|
392
|
-
test.add_argument(
|
|
393
|
-
"-C", "--classname", help="test classname", nargs="?", const="not_set"
|
|
394
|
-
)
|
|
395
|
-
test.add_argument(
|
|
396
|
-
"-B",
|
|
397
|
-
"--body",
|
|
398
|
-
help="test body (JSON string or @path/to/file.json)",
|
|
399
|
-
nargs="?",
|
|
400
|
-
const="not_set",
|
|
401
|
-
)
|
|
402
|
-
|
|
403
|
-
migrate = main_parser.add_argument_group("migrate arguments")
|
|
404
|
-
migrate.add_argument(
|
|
405
|
-
"--force-local",
|
|
406
|
-
help="force local mode, skip remote even if REMOTE_SETTINGS or IOP_URL is present",
|
|
407
|
-
action="store_true",
|
|
408
|
-
)
|
|
409
|
-
|
|
410
|
-
remote = main_parser.add_argument_group("remote arguments")
|
|
411
|
-
remote.add_argument(
|
|
412
|
-
"-R",
|
|
413
|
-
"--remote-settings",
|
|
414
|
-
help="path to a settings.py containing REMOTE_SETTINGS (overrides IOP_SETTINGS env var)",
|
|
415
|
-
metavar="FILE",
|
|
416
|
-
)
|
|
417
|
-
|
|
418
|
-
namespace = main_parser.add_argument_group("namespace arguments")
|
|
419
|
-
namespace.add_argument(
|
|
420
|
-
"-n", "--namespace", help="set namespace", nargs="?", const="not_set"
|
|
421
|
-
)
|
|
422
|
-
|
|
423
|
-
return main_parser
|
|
424
|
-
|
|
425
|
-
|
|
426
319
|
def main(argv=None) -> None:
|
|
427
320
|
parser = create_parser()
|
|
428
321
|
args = parser.parse_args(argv)
|
|
@@ -443,7 +336,7 @@ def main(argv=None) -> None:
|
|
|
443
336
|
except requests.exceptions.HTTPError as exc:
|
|
444
337
|
print(f"Error: {exc}", file=sys.stderr)
|
|
445
338
|
sys.exit(1)
|
|
446
|
-
except RuntimeError as exc:
|
|
339
|
+
except (RuntimeError, ValueError) as exc:
|
|
447
340
|
print(f"Error: {exc}", file=sys.stderr)
|
|
448
341
|
sys.exit(1)
|
|
449
342
|
sys.exit(0)
|