oocana-python-executor 0.16.0__tar.gz → 0.16.1__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.
Files changed (19) hide show
  1. {oocana_python_executor-0.16.0 → oocana_python_executor-0.16.1}/PKG-INFO +1 -1
  2. {oocana_python_executor-0.16.0 → oocana_python_executor-0.16.1}/pyproject.toml +1 -1
  3. {oocana_python_executor-0.16.0 → oocana_python_executor-0.16.1}/python_executor/block.py +2 -2
  4. oocana_python_executor-0.16.1/python_executor/data.py +5 -0
  5. {oocana_python_executor-0.16.0 → oocana_python_executor-0.16.1}/python_executor/executor.py +17 -14
  6. {oocana_python_executor-0.16.0 → oocana_python_executor-0.16.1}/python_executor/hook.py +13 -15
  7. {oocana_python_executor-0.16.0 → oocana_python_executor-0.16.1}/python_executor/matplot/matplotlib_oomol/oomol.py +3 -3
  8. {oocana_python_executor-0.16.0 → oocana_python_executor-0.16.1}/python_executor/matplot/oomol_matplot_helper.py +4 -3
  9. {oocana_python_executor-0.16.0 → oocana_python_executor-0.16.1}/tests/test_cli.py +17 -0
  10. oocana_python_executor-0.16.0/python_executor/data.py +0 -5
  11. {oocana_python_executor-0.16.0 → oocana_python_executor-0.16.1}/python_executor/__init__.py +0 -0
  12. {oocana_python_executor-0.16.0 → oocana_python_executor-0.16.1}/python_executor/context.py +0 -0
  13. {oocana_python_executor-0.16.0 → oocana_python_executor-0.16.1}/python_executor/logger.py +0 -0
  14. {oocana_python_executor-0.16.0 → oocana_python_executor-0.16.1}/python_executor/matplot/matplotlib_oomol/__init__.py +0 -0
  15. {oocana_python_executor-0.16.0 → oocana_python_executor-0.16.1}/python_executor/secret.py +0 -0
  16. {oocana_python_executor-0.16.0 → oocana_python_executor-0.16.1}/python_executor/service.py +0 -0
  17. {oocana_python_executor-0.16.0 → oocana_python_executor-0.16.1}/python_executor/topic.py +0 -0
  18. {oocana_python_executor-0.16.0 → oocana_python_executor-0.16.1}/python_executor/utils.py +0 -0
  19. {oocana_python_executor-0.16.0 → oocana_python_executor-0.16.1}/tests/test_secret.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: oocana-python-executor
3
- Version: 0.16.0
3
+ Version: 0.16.1
4
4
  Summary: a client subscribe mqtt topic to execute oocana's block
5
5
  Author-Email: l1shen <lishen1635@gmail.com>, yleaf <11785335+leavesster@users.noreply.github.com>
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "oocana-python-executor"
3
- version = "0.16.0"
3
+ version = "0.16.1"
4
4
  authors = [
5
5
  { name = "l1shen", email = "lishen1635@gmail.com" },
6
6
  { name = "yleaf", email = "11785335+leavesster@users.noreply.github.com" },
@@ -4,7 +4,7 @@ from typing import Optional, TypedDict
4
4
  import inspect
5
5
  import traceback
6
6
  import logging
7
- from .data import store, vars, EXECUTOR_NAME
7
+ from .data import store, block_var, EXECUTOR_NAME
8
8
  from .context import createContext
9
9
  from .hook import ExitFunctionException
10
10
  import os
@@ -103,7 +103,7 @@ async def run_block(message, mainframe: Mainframe, session_dir: str, tmp_dir: st
103
103
  })
104
104
  return
105
105
 
106
- vars.set(context)
106
+ block_var.set(context)
107
107
 
108
108
  load_dir = payload.dir
109
109
 
@@ -0,0 +1,5 @@
1
+ from contextvars import ContextVar
2
+ from oocana import Context, EXECUTOR_NAME # noqa: F401
3
+
4
+ block_var: ContextVar[Context] = ContextVar('block-context')
5
+ store = {}
@@ -234,29 +234,32 @@ def main():
234
234
  parser.add_argument("--wait-for-client", help="wait for client to connect", default=False, action="store_true")
235
235
 
236
236
  try:
237
- args = parser.parse_args()
237
+ namespace, unknown_args = parser.parse_known_args()
238
238
  except Exception as e:
239
- print(f"parse args error: {e}")
239
+ hook.original_print(f"parse args error: {e}")
240
240
  # because we hook sys.exit in hook.py and raise a exception, the exit will be reset to 1.
241
241
  # parser origin exit code is 2. so we use 2 here.
242
- sys.exit(2)
242
+ hook.original_exit(2)
243
243
 
244
- address: str = args.address
245
- session_id: str = str(args.session_id)
246
- output: Literal["console", "file"] = args.output
247
- package: str | None = args.package
248
- session_dir: str = args.session_dir
249
- tmp_dir: str = args.tmp_dir
250
- identifier: str | None = args.identifier
244
+ address: str = namespace.address
245
+ session_id: str = str(namespace.session_id)
246
+ output: Literal["console", "file"] = namespace.output
247
+ package: str | None = namespace.package
248
+ session_dir: str = namespace.session_dir
249
+ tmp_dir: str = namespace.tmp_dir
250
+ identifier: str | None = namespace.identifier
251
251
 
252
252
  config_logger(session_id, identifier, output)
253
253
 
254
- if args.debug_port is not None and args.debug_port.isdigit():
254
+ if len(unknown_args) > 0:
255
+ logger.warning(f"receive unknown args: {unknown_args}")
256
+
257
+ if namespace.debug_port is not None and namespace.debug_port.isdigit():
255
258
  try:
256
259
  import debugpy
257
- debugpy.listen(int(args.debug_port))
258
- logger.info(f"debugpy listen on port {args.debug_port}")
259
- if args.wait_for_client:
260
+ debugpy.listen(int(namespace.debug_port))
261
+ logger.info(f"debugpy listen on port {namespace.debug_port}")
262
+ if namespace.wait_for_client:
260
263
  logger.info("wait for client to connect")
261
264
  debugpy.wait_for_client()
262
265
  logger.info("client connected")
@@ -3,7 +3,7 @@ from builtins import exit as global_exit
3
3
  from typing import TypeAlias, Any
4
4
  import sys
5
5
  import builtins
6
- from .data import vars, EXECUTOR_NAME
6
+ from .data import block_var, EXECUTOR_NAME
7
7
  import logging
8
8
 
9
9
  logger = logging.getLogger(EXECUTOR_NAME)
@@ -18,27 +18,25 @@ original_print = print
18
18
  _ExitCode: TypeAlias = str | int | None
19
19
 
20
20
  def sys_exit(status: _ExitCode = None) -> None:
21
- raise ExitFunctionException(status)
21
+ if block_var.get(None) is not None:
22
+ raise ExitFunctionException(status)
23
+ else:
24
+ original_exit(status)
22
25
 
23
26
  def sys_global_exit(status: _ExitCode = None) -> None:
24
- raise ExitFunctionException(status)
27
+ if block_var.get(None) is not None:
28
+ raise ExitFunctionException(status)
29
+ else:
30
+ original_global_exit(status)
25
31
 
26
32
  def global_print(*values: object, sep: str | None = " ", end: str | None = "\n", file: Any | None = None, flush: bool = False) -> None:
27
-
28
- context = None # 初始化 context 变量
29
- try:
30
- context = vars.get()
31
- except LookupError:
32
- # 这个 logger 不会上报到 root handle 中,所以即使 root logger 的 Handler 里面有 print 函数,也不会导致递归调用
33
- logger.warning("print called outside of block")
34
- except Exception as e:
35
- logger.error(f"print error: {e}")
36
-
37
- if context is not None:
33
+
34
+ block_ctx = block_var.get(None)
35
+ if block_ctx is not None:
38
36
  try:
39
37
  msg_sep = sep or " "
40
38
  msg = msg_sep.join(map(str, values))
41
- context.report_log(msg)
39
+ block_ctx.report_log(msg)
42
40
  except Exception as e:
43
41
  logger.error(f"transform print message to context log error: {e}")
44
42
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  from matplotlib.backend_bases import Gcf # type: ignore
4
4
  from matplotlib.backends.backend_agg import FigureCanvasAgg # type: ignore
5
- from python_executor.data import vars
5
+ from python_executor.data import block_var
6
6
 
7
7
  FigureCanvas = FigureCanvasAgg
8
8
 
@@ -10,8 +10,8 @@ def show(*args, **kwargs):
10
10
  import sys
11
11
  from io import BytesIO
12
12
  from base64 import b64encode
13
- if vars is not None:
14
- context = vars.get()
13
+ context = block_var.get(None)
14
+ if context is not None:
15
15
  images = []
16
16
  for figmanager in Gcf.get_all_fig_managers():
17
17
  buffer = BytesIO()
@@ -1,4 +1,4 @@
1
- from python_executor.data import vars
1
+ from python_executor.data import block_var
2
2
 
3
3
  def add_matplot_module():
4
4
  import sys
@@ -13,6 +13,7 @@ def import_helper(logger):
13
13
  matplotlib.use('module://matplotlib_oomol') # matplotlib_oomol.py 文件所在目录加入 PYTHONPATH
14
14
  except:
15
15
  logger.error("import matplotlib failed")
16
+ return
16
17
 
17
18
  # matplotlib 主题替换
18
19
  try:
@@ -34,8 +35,8 @@ def import_helper(logger):
34
35
 
35
36
  class OomolRenderer(ExternalRenderer):
36
37
  def render(self, fig_dict):
37
- if vars:
38
- context = vars.get()
38
+ context = block_var.get(None)
39
+ if context is not None:
39
40
 
40
41
  import re
41
42
  from plotly.io import to_html # type: ignore
@@ -35,6 +35,23 @@ class TestExecutorCLI(unittest.TestCase):
35
35
  process.send_signal(signal.SIGINT)
36
36
 
37
37
  process.wait()
38
+
39
+ def test_cli_addition_args(self):
40
+ cli_command = [sys.executable, "-u", "-m", "python_executor.executor", "--session-id", "test-session", "--session-dir", "/tmp", "--tmp-dir", "/tmp", "--echo", "Hello World!"]
41
+
42
+ print("Starting CLI tool... in", executor_parent_dir)
43
+
44
+ process = subprocess.Popen(cli_command, cwd=executor_parent_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
45
+
46
+ time.sleep(3)
47
+
48
+ code = process.poll()
49
+
50
+ self.assertIsNone(code, f"CLI tool failed to start or exit with code {code}")
51
+
52
+ process.send_signal(signal.SIGINT)
53
+
54
+ process.wait()
38
55
 
39
56
  def test_cli_fail(self):
40
57
  cli_command = [sys.executable, "-u", "-m", "python_executor.executor"]
@@ -1,5 +0,0 @@
1
- from contextvars import ContextVar
2
- from oocana import Context, EXECUTOR_NAME
3
-
4
- vars: ContextVar[Context] = ContextVar('context')
5
- store = {}