chalk-remote-call-python 0.0.0__tar.gz → 1.1.2__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.
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/PKG-INFO +11 -7
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/README.md +10 -6
- chalk_remote_call_python-1.1.2/chalk_remote_call/__init__.py +4 -0
- chalk_remote_call_python-1.1.2/chalk_remote_call/_version.py +1 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call/cli.py +20 -3
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call/handler_loader.py +19 -8
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call/server.py +15 -8
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call_python.egg-info/PKG-INFO +11 -7
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call_python.egg-info/SOURCES.txt +2 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/pyproject.toml +3 -0
- chalk_remote_call_python-1.1.2/tests/test_handler_loader.py +99 -0
- chalk_remote_call_python-0.0.0/chalk_remote_call/__init__.py +0 -6
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call/__main__.py +0 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call/_gen/__init__.py +0 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call/_gen/chalk/__init__.py +0 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call/_gen/chalk/runtime/__init__.py +0 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call/_gen/chalk/runtime/v1/__init__.py +0 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call/_gen/chalk/runtime/v1/remote_python_call_pb2.py +0 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call/_gen/chalk/runtime/v1/remote_python_call_pb2_grpc.py +0 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call/_native.pyi +0 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call/arrow_utils.py +0 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call/input_transform.py +0 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call/servicer.py +0 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call_python.egg-info/dependency_links.txt +0 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call_python.egg-info/entry_points.txt +0 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call_python.egg-info/requires.txt +0 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call_python.egg-info/top_level.txt +0 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/setup.cfg +0 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/setup.py +0 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/tests/test_arrow_utils.py +0 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/tests/test_end_to_end.py +0 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/tests/test_error_paths.py +0 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/tests/test_input_transform.py +0 -0
- {chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/tests/test_servicer.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: chalk-remote-call-python
|
|
3
|
-
Version:
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: Chalk remote call Python runtime interface client
|
|
5
5
|
Author: Chalk AI, Inc.
|
|
6
6
|
Project-URL: Homepage, https://chalk.ai
|
|
@@ -65,15 +65,18 @@ def handler(event: dict[str, pa.Array], context: dict) -> pa.Array:
|
|
|
65
65
|
|
|
66
66
|
Args:
|
|
67
67
|
event: dict mapping column names to pyarrow.Array values.
|
|
68
|
-
context: dict with request metadata
|
|
69
|
-
- "peer": remote address string
|
|
70
|
-
- "metadata": dict of gRPC headers
|
|
68
|
+
context: dict with request metadata
|
|
71
69
|
|
|
72
70
|
Returns:
|
|
73
71
|
A pyarrow.Array, pyarrow.RecordBatch, pyarrow.Table, list, dict, or scalar.
|
|
74
72
|
The framework auto-converts the result to Arrow IPC for the response.
|
|
75
73
|
"""
|
|
76
74
|
return pc.multiply(event["x"], event["y"])
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def on_shutdown():
|
|
78
|
+
"""Optional -- runs once after the server stops accepting requests."""
|
|
79
|
+
print("Releasing resources...")
|
|
77
80
|
```
|
|
78
81
|
|
|
79
82
|
### 2. Start the server
|
|
@@ -97,6 +100,7 @@ python -m chalk_remote_call --handler my_handler.handler
|
|
|
97
100
|
| `--host` | `CHALK_REMOTE_CALL_HOST` | `[::]` | Host to bind to |
|
|
98
101
|
| `--workers` | `CHALK_REMOTE_CALL_WORKERS` | `10` | Tokio runtime worker threads |
|
|
99
102
|
| `--on-startup` | | | Dotted path to a startup function |
|
|
103
|
+
| `--on-shutdown` | | | Dotted path to a shutdown function |
|
|
100
104
|
| `--log-level` | | `INFO` | `DEBUG`, `INFO`, `WARNING`, or `ERROR` |
|
|
101
105
|
|
|
102
106
|
### Environment variables
|
|
@@ -115,12 +119,12 @@ WORKDIR /app
|
|
|
115
119
|
RUN pip install chalk-remote-call-python
|
|
116
120
|
|
|
117
121
|
# Copy your handler code
|
|
118
|
-
COPY my_handler.py
|
|
122
|
+
COPY my_handler.py /app
|
|
119
123
|
|
|
120
|
-
# The server listens on port 6666 by default
|
|
121
124
|
EXPOSE 6666
|
|
122
125
|
|
|
123
|
-
ENTRYPOINT ["chalk-remote-call"
|
|
126
|
+
ENTRYPOINT ["chalk-remote-call"]
|
|
127
|
+
CMD ["--handler", "handler.handler"]
|
|
124
128
|
```
|
|
125
129
|
|
|
126
130
|
Build and run:
|
|
@@ -32,15 +32,18 @@ def handler(event: dict[str, pa.Array], context: dict) -> pa.Array:
|
|
|
32
32
|
|
|
33
33
|
Args:
|
|
34
34
|
event: dict mapping column names to pyarrow.Array values.
|
|
35
|
-
context: dict with request metadata
|
|
36
|
-
- "peer": remote address string
|
|
37
|
-
- "metadata": dict of gRPC headers
|
|
35
|
+
context: dict with request metadata
|
|
38
36
|
|
|
39
37
|
Returns:
|
|
40
38
|
A pyarrow.Array, pyarrow.RecordBatch, pyarrow.Table, list, dict, or scalar.
|
|
41
39
|
The framework auto-converts the result to Arrow IPC for the response.
|
|
42
40
|
"""
|
|
43
41
|
return pc.multiply(event["x"], event["y"])
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def on_shutdown():
|
|
45
|
+
"""Optional -- runs once after the server stops accepting requests."""
|
|
46
|
+
print("Releasing resources...")
|
|
44
47
|
```
|
|
45
48
|
|
|
46
49
|
### 2. Start the server
|
|
@@ -64,6 +67,7 @@ python -m chalk_remote_call --handler my_handler.handler
|
|
|
64
67
|
| `--host` | `CHALK_REMOTE_CALL_HOST` | `[::]` | Host to bind to |
|
|
65
68
|
| `--workers` | `CHALK_REMOTE_CALL_WORKERS` | `10` | Tokio runtime worker threads |
|
|
66
69
|
| `--on-startup` | | | Dotted path to a startup function |
|
|
70
|
+
| `--on-shutdown` | | | Dotted path to a shutdown function |
|
|
67
71
|
| `--log-level` | | `INFO` | `DEBUG`, `INFO`, `WARNING`, or `ERROR` |
|
|
68
72
|
|
|
69
73
|
### Environment variables
|
|
@@ -82,12 +86,12 @@ WORKDIR /app
|
|
|
82
86
|
RUN pip install chalk-remote-call-python
|
|
83
87
|
|
|
84
88
|
# Copy your handler code
|
|
85
|
-
COPY my_handler.py
|
|
89
|
+
COPY my_handler.py /app
|
|
86
90
|
|
|
87
|
-
# The server listens on port 6666 by default
|
|
88
91
|
EXPOSE 6666
|
|
89
92
|
|
|
90
|
-
ENTRYPOINT ["chalk-remote-call"
|
|
93
|
+
ENTRYPOINT ["chalk-remote-call"]
|
|
94
|
+
CMD ["--handler", "handler.handler"]
|
|
91
95
|
```
|
|
92
96
|
|
|
93
97
|
Build and run:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.1.2"
|
|
@@ -5,7 +5,7 @@ import logging
|
|
|
5
5
|
import os
|
|
6
6
|
import sys
|
|
7
7
|
|
|
8
|
-
from chalk_remote_call.handler_loader import
|
|
8
|
+
from chalk_remote_call.handler_loader import load_function, load_handler
|
|
9
9
|
from chalk_remote_call.input_transform import parse_input_args
|
|
10
10
|
from chalk_remote_call.server import serve
|
|
11
11
|
|
|
@@ -42,6 +42,11 @@ def main() -> None:
|
|
|
42
42
|
default=None,
|
|
43
43
|
help="Dotted path to a startup function (e.g. my_module.setup)",
|
|
44
44
|
)
|
|
45
|
+
parser.add_argument(
|
|
46
|
+
"--on-shutdown",
|
|
47
|
+
default=None,
|
|
48
|
+
help="Dotted path to a shutdown function (e.g. my_module.cleanup)",
|
|
49
|
+
)
|
|
45
50
|
parser.add_argument(
|
|
46
51
|
"--log-level",
|
|
47
52
|
default="INFO",
|
|
@@ -57,7 +62,7 @@ def main() -> None:
|
|
|
57
62
|
|
|
58
63
|
# Load handler
|
|
59
64
|
try:
|
|
60
|
-
handler, auto_startup = load_handler(args.handler)
|
|
65
|
+
handler, auto_startup, auto_shutdown = load_handler(args.handler)
|
|
61
66
|
except Exception as e:
|
|
62
67
|
print(f"Error loading handler: {e}", file=sys.stderr)
|
|
63
68
|
sys.exit(1)
|
|
@@ -66,13 +71,24 @@ def main() -> None:
|
|
|
66
71
|
on_startup = None
|
|
67
72
|
if args.on_startup:
|
|
68
73
|
try:
|
|
69
|
-
on_startup =
|
|
74
|
+
on_startup = load_function(args.on_startup, label="Startup")
|
|
70
75
|
except Exception as e:
|
|
71
76
|
print(f"Error loading startup function: {e}", file=sys.stderr)
|
|
72
77
|
sys.exit(1)
|
|
73
78
|
elif auto_startup is not None:
|
|
74
79
|
on_startup = auto_startup
|
|
75
80
|
|
|
81
|
+
# Determine shutdown function
|
|
82
|
+
on_shutdown = None
|
|
83
|
+
if args.on_shutdown:
|
|
84
|
+
try:
|
|
85
|
+
on_shutdown = load_function(args.on_shutdown, label="Shutdown")
|
|
86
|
+
except Exception as e:
|
|
87
|
+
print(f"Error loading shutdown function: {e}", file=sys.stderr)
|
|
88
|
+
sys.exit(1)
|
|
89
|
+
elif auto_shutdown is not None:
|
|
90
|
+
on_shutdown = auto_shutdown
|
|
91
|
+
|
|
76
92
|
# Parse input args
|
|
77
93
|
arg_names = parse_input_args()
|
|
78
94
|
|
|
@@ -82,5 +98,6 @@ def main() -> None:
|
|
|
82
98
|
port=args.port,
|
|
83
99
|
workers=args.workers,
|
|
84
100
|
on_startup=on_startup,
|
|
101
|
+
on_shutdown=on_shutdown,
|
|
85
102
|
arg_names=arg_names,
|
|
86
103
|
)
|
|
@@ -5,12 +5,14 @@ from collections.abc import Callable
|
|
|
5
5
|
from typing import Any
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
def load_handler(
|
|
8
|
+
def load_handler(
|
|
9
|
+
dotted_path: str,
|
|
10
|
+
) -> tuple[Callable[..., Any], Callable[[], None] | None, Callable[[], None] | None]:
|
|
9
11
|
"""Load a handler function from a dotted module path.
|
|
10
12
|
|
|
11
|
-
Returns (handler_fn, on_startup_fn_or_None).
|
|
12
|
-
The on_startup
|
|
13
|
-
|
|
13
|
+
Returns (handler_fn, on_startup_fn_or_None, on_shutdown_fn_or_None).
|
|
14
|
+
The on_startup/on_shutdown functions are auto-discovered if the handler's
|
|
15
|
+
module defines top-level callables with those names.
|
|
14
16
|
"""
|
|
15
17
|
if "." not in dotted_path:
|
|
16
18
|
raise ValueError(f"Handler path must be a dotted path like 'my_module.handler', got: {dotted_path!r}")
|
|
@@ -27,13 +29,22 @@ def load_handler(dotted_path: str) -> tuple[Callable[..., Any], Callable[[], Non
|
|
|
27
29
|
if on_startup is not None and not callable(on_startup):
|
|
28
30
|
on_startup = None
|
|
29
31
|
|
|
30
|
-
|
|
32
|
+
on_shutdown = getattr(module, "on_shutdown", None)
|
|
33
|
+
if on_shutdown is not None and not callable(on_shutdown):
|
|
34
|
+
on_shutdown = None
|
|
31
35
|
|
|
36
|
+
return handler, on_startup, on_shutdown
|
|
32
37
|
|
|
33
|
-
|
|
34
|
-
|
|
38
|
+
|
|
39
|
+
def load_function(dotted_path: str, label: str = "Function") -> Callable[[], None]:
|
|
40
|
+
"""Load a callable from a dotted module path.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
dotted_path: e.g. 'my_module.setup'
|
|
44
|
+
label: Human-readable label for error messages (e.g. "Startup", "Shutdown").
|
|
45
|
+
"""
|
|
35
46
|
if "." not in dotted_path:
|
|
36
|
-
raise ValueError(f"
|
|
47
|
+
raise ValueError(f"{label} path must be a dotted path like 'my_module.func', got: {dotted_path!r}")
|
|
37
48
|
|
|
38
49
|
module_path, func_name = dotted_path.rsplit(".", 1)
|
|
39
50
|
module = importlib.import_module(module_path)
|
{chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call/server.py
RENAMED
|
@@ -16,6 +16,7 @@ def serve(
|
|
|
16
16
|
port: int = 6666,
|
|
17
17
|
workers: int = 10,
|
|
18
18
|
on_startup: Callable[[], None] | None = None,
|
|
19
|
+
on_shutdown: Callable[[], None] | None = None,
|
|
19
20
|
arg_names: list[str] | None = None,
|
|
20
21
|
) -> None:
|
|
21
22
|
"""Start the gRPC server implementing RemoteCallService.
|
|
@@ -26,6 +27,7 @@ def serve(
|
|
|
26
27
|
port: The port to bind to.
|
|
27
28
|
workers: Number of worker threads for the tokio runtime.
|
|
28
29
|
on_startup: Optional startup hook called before the server starts accepting requests.
|
|
30
|
+
on_shutdown: Optional shutdown hook called after the server stops accepting requests.
|
|
29
31
|
arg_names: Parsed CHALK_INPUT_ARGS column names, or None.
|
|
30
32
|
"""
|
|
31
33
|
# Run startup hook before starting the Rust server
|
|
@@ -34,11 +36,16 @@ def serve(
|
|
|
34
36
|
on_startup()
|
|
35
37
|
|
|
36
38
|
logger.info("Starting server on %s:%d", host, port)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
try:
|
|
40
|
+
start_server(
|
|
41
|
+
handler=handler,
|
|
42
|
+
process_fn=process_batches,
|
|
43
|
+
host=host,
|
|
44
|
+
port=port,
|
|
45
|
+
workers=workers,
|
|
46
|
+
arg_names=arg_names,
|
|
47
|
+
)
|
|
48
|
+
finally:
|
|
49
|
+
if on_shutdown is not None:
|
|
50
|
+
logger.info("Running shutdown hook...")
|
|
51
|
+
on_shutdown()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: chalk-remote-call-python
|
|
3
|
-
Version:
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: Chalk remote call Python runtime interface client
|
|
5
5
|
Author: Chalk AI, Inc.
|
|
6
6
|
Project-URL: Homepage, https://chalk.ai
|
|
@@ -65,15 +65,18 @@ def handler(event: dict[str, pa.Array], context: dict) -> pa.Array:
|
|
|
65
65
|
|
|
66
66
|
Args:
|
|
67
67
|
event: dict mapping column names to pyarrow.Array values.
|
|
68
|
-
context: dict with request metadata
|
|
69
|
-
- "peer": remote address string
|
|
70
|
-
- "metadata": dict of gRPC headers
|
|
68
|
+
context: dict with request metadata
|
|
71
69
|
|
|
72
70
|
Returns:
|
|
73
71
|
A pyarrow.Array, pyarrow.RecordBatch, pyarrow.Table, list, dict, or scalar.
|
|
74
72
|
The framework auto-converts the result to Arrow IPC for the response.
|
|
75
73
|
"""
|
|
76
74
|
return pc.multiply(event["x"], event["y"])
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def on_shutdown():
|
|
78
|
+
"""Optional -- runs once after the server stops accepting requests."""
|
|
79
|
+
print("Releasing resources...")
|
|
77
80
|
```
|
|
78
81
|
|
|
79
82
|
### 2. Start the server
|
|
@@ -97,6 +100,7 @@ python -m chalk_remote_call --handler my_handler.handler
|
|
|
97
100
|
| `--host` | `CHALK_REMOTE_CALL_HOST` | `[::]` | Host to bind to |
|
|
98
101
|
| `--workers` | `CHALK_REMOTE_CALL_WORKERS` | `10` | Tokio runtime worker threads |
|
|
99
102
|
| `--on-startup` | | | Dotted path to a startup function |
|
|
103
|
+
| `--on-shutdown` | | | Dotted path to a shutdown function |
|
|
100
104
|
| `--log-level` | | `INFO` | `DEBUG`, `INFO`, `WARNING`, or `ERROR` |
|
|
101
105
|
|
|
102
106
|
### Environment variables
|
|
@@ -115,12 +119,12 @@ WORKDIR /app
|
|
|
115
119
|
RUN pip install chalk-remote-call-python
|
|
116
120
|
|
|
117
121
|
# Copy your handler code
|
|
118
|
-
COPY my_handler.py
|
|
122
|
+
COPY my_handler.py /app
|
|
119
123
|
|
|
120
|
-
# The server listens on port 6666 by default
|
|
121
124
|
EXPOSE 6666
|
|
122
125
|
|
|
123
|
-
ENTRYPOINT ["chalk-remote-call"
|
|
126
|
+
ENTRYPOINT ["chalk-remote-call"]
|
|
127
|
+
CMD ["--handler", "handler.handler"]
|
|
124
128
|
```
|
|
125
129
|
|
|
126
130
|
Build and run:
|
|
@@ -4,6 +4,7 @@ setup.py
|
|
|
4
4
|
chalk_remote_call/__init__.py
|
|
5
5
|
chalk_remote_call/__main__.py
|
|
6
6
|
chalk_remote_call/_native.pyi
|
|
7
|
+
chalk_remote_call/_version.py
|
|
7
8
|
chalk_remote_call/arrow_utils.py
|
|
8
9
|
chalk_remote_call/cli.py
|
|
9
10
|
chalk_remote_call/handler_loader.py
|
|
@@ -25,5 +26,6 @@ chalk_remote_call_python.egg-info/top_level.txt
|
|
|
25
26
|
tests/test_arrow_utils.py
|
|
26
27
|
tests/test_end_to_end.py
|
|
27
28
|
tests/test_error_paths.py
|
|
29
|
+
tests/test_handler_loader.py
|
|
28
30
|
tests/test_input_transform.py
|
|
29
31
|
tests/test_servicer.py
|
|
@@ -52,6 +52,9 @@ Changelog = "https://docs.chalk.ai/docs/changelog"
|
|
|
52
52
|
[project.scripts]
|
|
53
53
|
chalk-remote-call = "chalk_remote_call.cli:main"
|
|
54
54
|
|
|
55
|
+
[tool.setuptools.dynamic]
|
|
56
|
+
version = {attr = "chalk_remote_call._version.__version__"}
|
|
57
|
+
|
|
55
58
|
[tool.setuptools.packages.find]
|
|
56
59
|
where = ["."]
|
|
57
60
|
include = ["chalk_remote_call*"]
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"""Tests for handler_loader: load_handler and load_function."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import types
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
9
|
+
from chalk_remote_call.handler_loader import load_function, load_handler
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _make_module(name: str, **attrs: object) -> types.ModuleType:
|
|
13
|
+
"""Create a throwaway module with the given attributes."""
|
|
14
|
+
mod = types.ModuleType(name)
|
|
15
|
+
for k, v in attrs.items():
|
|
16
|
+
setattr(mod, k, v)
|
|
17
|
+
return mod
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# ---------------------------------------------------------------------------
|
|
21
|
+
# load_function
|
|
22
|
+
# ---------------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class TestLoadFunction:
|
|
26
|
+
def test_missing_dot_raises(self):
|
|
27
|
+
with pytest.raises(ValueError, match="dotted path"):
|
|
28
|
+
load_function("nodot", label="Test")
|
|
29
|
+
|
|
30
|
+
def test_nonexistent_module_raises(self):
|
|
31
|
+
with pytest.raises(ModuleNotFoundError):
|
|
32
|
+
load_function("nonexistent_module_xyz.func", label="Test")
|
|
33
|
+
|
|
34
|
+
def test_nonexistent_attr_raises(self):
|
|
35
|
+
with pytest.raises(AttributeError, match="no attribute"):
|
|
36
|
+
load_function("os.nonexistent_func_xyz", label="Test")
|
|
37
|
+
|
|
38
|
+
def test_not_callable_raises(self):
|
|
39
|
+
with pytest.raises(TypeError, match="not callable"):
|
|
40
|
+
load_function("os.sep", label="Test")
|
|
41
|
+
|
|
42
|
+
def test_loads_callable(self):
|
|
43
|
+
fn = load_function("os.path.exists", label="Test")
|
|
44
|
+
assert callable(fn)
|
|
45
|
+
|
|
46
|
+
def test_label_appears_in_error(self):
|
|
47
|
+
with pytest.raises(ValueError, match="Shutdown"):
|
|
48
|
+
load_function("nodot", label="Shutdown")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
# ---------------------------------------------------------------------------
|
|
52
|
+
# load_handler — auto-discovery of on_startup / on_shutdown
|
|
53
|
+
# ---------------------------------------------------------------------------
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class TestLoadHandlerAutoDiscovery:
|
|
57
|
+
def test_discovers_on_startup(self, monkeypatch):
|
|
58
|
+
startup = lambda: None # noqa: E731
|
|
59
|
+
mod = _make_module("fake_mod", handler=lambda e, c: e, on_startup=startup)
|
|
60
|
+
monkeypatch.setitem(__import__("sys").modules, "fake_mod", mod)
|
|
61
|
+
|
|
62
|
+
_handler, on_startup, on_shutdown = load_handler("fake_mod.handler")
|
|
63
|
+
assert on_startup is startup
|
|
64
|
+
assert on_shutdown is None
|
|
65
|
+
|
|
66
|
+
def test_discovers_on_shutdown(self, monkeypatch):
|
|
67
|
+
shutdown = lambda: None # noqa: E731
|
|
68
|
+
mod = _make_module("fake_mod", handler=lambda e, c: e, on_shutdown=shutdown)
|
|
69
|
+
monkeypatch.setitem(__import__("sys").modules, "fake_mod", mod)
|
|
70
|
+
|
|
71
|
+
_handler, on_startup, on_shutdown = load_handler("fake_mod.handler")
|
|
72
|
+
assert on_startup is None
|
|
73
|
+
assert on_shutdown is shutdown
|
|
74
|
+
|
|
75
|
+
def test_discovers_both(self, monkeypatch):
|
|
76
|
+
startup = lambda: None # noqa: E731
|
|
77
|
+
shutdown = lambda: None # noqa: E731
|
|
78
|
+
mod = _make_module("fake_mod", handler=lambda e, c: e, on_startup=startup, on_shutdown=shutdown)
|
|
79
|
+
monkeypatch.setitem(__import__("sys").modules, "fake_mod", mod)
|
|
80
|
+
|
|
81
|
+
_handler, on_startup, on_shutdown = load_handler("fake_mod.handler")
|
|
82
|
+
assert on_startup is startup
|
|
83
|
+
assert on_shutdown is shutdown
|
|
84
|
+
|
|
85
|
+
def test_ignores_non_callable(self, monkeypatch):
|
|
86
|
+
mod = _make_module("fake_mod", handler=lambda e, c: e, on_startup="not callable", on_shutdown=42)
|
|
87
|
+
monkeypatch.setitem(__import__("sys").modules, "fake_mod", mod)
|
|
88
|
+
|
|
89
|
+
_handler, on_startup, on_shutdown = load_handler("fake_mod.handler")
|
|
90
|
+
assert on_startup is None
|
|
91
|
+
assert on_shutdown is None
|
|
92
|
+
|
|
93
|
+
def test_neither_defined(self, monkeypatch):
|
|
94
|
+
mod = _make_module("fake_mod", handler=lambda e, c: e)
|
|
95
|
+
monkeypatch.setitem(__import__("sys").modules, "fake_mod", mod)
|
|
96
|
+
|
|
97
|
+
_handler, on_startup, on_shutdown = load_handler("fake_mod.handler")
|
|
98
|
+
assert on_startup is None
|
|
99
|
+
assert on_shutdown is None
|
{chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call/__main__.py
RENAMED
|
File without changes
|
{chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call/_gen/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call/_native.pyi
RENAMED
|
File without changes
|
{chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call/arrow_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
{chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/chalk_remote_call/servicer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{chalk_remote_call_python-0.0.0 → chalk_remote_call_python-1.1.2}/tests/test_input_transform.py
RENAMED
|
File without changes
|
|
File without changes
|