workpeg 0.4.1__tar.gz → 0.4.3__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.
- {workpeg-0.4.1/src/workpeg.egg-info → workpeg-0.4.3}/PKG-INFO +1 -1
- {workpeg-0.4.1 → workpeg-0.4.3}/pyproject.toml +1 -1
- {workpeg-0.4.1 → workpeg-0.4.3}/src/workpeg/run.py +3 -1
- {workpeg-0.4.1 → workpeg-0.4.3}/src/workpeg/submit.py +4 -4
- workpeg-0.4.3/src/workpeg/utils.py +10 -0
- {workpeg-0.4.1 → workpeg-0.4.3/src/workpeg.egg-info}/PKG-INFO +1 -1
- {workpeg-0.4.1 → workpeg-0.4.3}/src/workpeg.egg-info/SOURCES.txt +3 -1
- {workpeg-0.4.1 → workpeg-0.4.3}/tests/test_run.py +67 -14
- {workpeg-0.4.1 → workpeg-0.4.3}/tests/test_submit.py +5 -5
- workpeg-0.4.3/tests/test_utils.py +46 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/LICENSE +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/MANIFEST.in +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/README.md +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/setup.cfg +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/src/workpeg/__init__.py +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/src/workpeg/build.py +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/src/workpeg/cli.py +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/src/workpeg/config.py +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/src/workpeg/context.py +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/src/workpeg/create_new.py +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/src/workpeg/runtime.py +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/src/workpeg/templates/__init__.py +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/src/workpeg/templates/functions/Dockerfile +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/src/workpeg/templates/functions/LICENSE +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/src/workpeg/templates/functions/README.md +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/src/workpeg/templates/functions/app/__init__.py +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/src/workpeg/templates/functions/app/main.py +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/src/workpeg/templates/functions/requirements.txt +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/src/workpeg.egg-info/dependency_links.txt +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/src/workpeg.egg-info/entry_points.txt +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/src/workpeg.egg-info/requires.txt +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/src/workpeg.egg-info/top_level.txt +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/tests/test_build.py +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/tests/test_cli.py +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/tests/test_context.py +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/tests/test_create_new.py +0 -0
- {workpeg-0.4.1 → workpeg-0.4.3}/tests/test_runtime.py +0 -0
|
@@ -27,7 +27,7 @@ def run_with_docker(
|
|
|
27
27
|
cfg.get("build", {}).get("image") or project_path.name
|
|
28
28
|
)
|
|
29
29
|
|
|
30
|
-
cmd = ["docker", "run", "
|
|
30
|
+
cmd = ["docker", "run", "-d"]
|
|
31
31
|
|
|
32
32
|
if name:
|
|
33
33
|
cmd += ["--name", name]
|
|
@@ -38,6 +38,8 @@ def run_with_docker(
|
|
|
38
38
|
if network:
|
|
39
39
|
cmd += ["--network", network]
|
|
40
40
|
|
|
41
|
+
cmd += ["--restart", "unless-stopped"]
|
|
42
|
+
|
|
41
43
|
cmd.append(image)
|
|
42
44
|
|
|
43
45
|
subprocess.run(cmd, check=True)
|
|
@@ -106,7 +106,7 @@ def submit_bundle(
|
|
|
106
106
|
api_base: str,
|
|
107
107
|
peg_id: str,
|
|
108
108
|
token: str,
|
|
109
|
-
|
|
109
|
+
branch_id: str,
|
|
110
110
|
version: str,
|
|
111
111
|
bundle_bytes: bytes,
|
|
112
112
|
timeout_s: int = 60,
|
|
@@ -117,7 +117,7 @@ def submit_bundle(
|
|
|
117
117
|
"bundle": ("bundle.tar.gz", bundle_bytes, "application/gzip"),
|
|
118
118
|
}
|
|
119
119
|
data = {
|
|
120
|
-
"
|
|
120
|
+
"branch_id": branch_id,
|
|
121
121
|
"version": version,
|
|
122
122
|
}
|
|
123
123
|
headers = {
|
|
@@ -144,7 +144,7 @@ def main(argv=None) -> None:
|
|
|
144
144
|
parser.add_argument(
|
|
145
145
|
"ref",
|
|
146
146
|
help="Function reference in the form <branch_name>:<version>"
|
|
147
|
-
" (e.g.,
|
|
147
|
+
" (e.g., main:1.0.0)")
|
|
148
148
|
parser.add_argument("--api", default=os.environ.get(API_ENV,
|
|
149
149
|
DEFAULT_API_BASE), help="API base URL")
|
|
150
150
|
parser.add_argument("--path", default=os.environ.get(PATH_ENV,
|
|
@@ -173,7 +173,7 @@ def main(argv=None) -> None:
|
|
|
173
173
|
api_base=args.api,
|
|
174
174
|
peg_id=str(peg_id),
|
|
175
175
|
token=token,
|
|
176
|
-
|
|
176
|
+
branch_id=branch_name,
|
|
177
177
|
version=version,
|
|
178
178
|
bundle_bytes=bundle_bytes,
|
|
179
179
|
timeout_s=args.timeout,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
def get_hook_urn(hook_name: str) -> str:
|
|
2
|
+
# move to workpeg SDK
|
|
3
|
+
"""Convert a hook name to a valid Python method name."""
|
|
4
|
+
# remove "custom." prefix if it exists
|
|
5
|
+
urn = hook_name[len("custom."):] if str(
|
|
6
|
+
hook_name).startswith("custom.") else str(hook_name)
|
|
7
|
+
|
|
8
|
+
urn = urn.replace(":", "_").lower()
|
|
9
|
+
|
|
10
|
+
return f"http://{urn}:8000"
|
|
@@ -11,6 +11,7 @@ src/workpeg/create_new.py
|
|
|
11
11
|
src/workpeg/run.py
|
|
12
12
|
src/workpeg/runtime.py
|
|
13
13
|
src/workpeg/submit.py
|
|
14
|
+
src/workpeg/utils.py
|
|
14
15
|
src/workpeg.egg-info/PKG-INFO
|
|
15
16
|
src/workpeg.egg-info/SOURCES.txt
|
|
16
17
|
src/workpeg.egg-info/dependency_links.txt
|
|
@@ -30,4 +31,5 @@ tests/test_context.py
|
|
|
30
31
|
tests/test_create_new.py
|
|
31
32
|
tests/test_run.py
|
|
32
33
|
tests/test_runtime.py
|
|
33
|
-
tests/test_submit.py
|
|
34
|
+
tests/test_submit.py
|
|
35
|
+
tests/test_utils.py
|
|
@@ -38,14 +38,19 @@ def test_run_with_docker_builds_first(monkeypatch, tmp_path):
|
|
|
38
38
|
|
|
39
39
|
monkeypatch.setattr(run.subprocess, "run", fake_run)
|
|
40
40
|
|
|
41
|
-
run.run_with_docker(
|
|
41
|
+
run.run_with_docker(
|
|
42
|
+
path=str(project),
|
|
43
|
+
build_first=True,
|
|
44
|
+
network="workpeg_net",
|
|
45
|
+
)
|
|
42
46
|
|
|
43
47
|
assert len(calls) == 1
|
|
44
48
|
cmd, check = calls[0]
|
|
45
49
|
assert cmd == [
|
|
46
|
-
"docker", "run", "
|
|
50
|
+
"docker", "run", "-d",
|
|
47
51
|
"-p", "9000:9000",
|
|
48
52
|
"--network", "workpeg_net",
|
|
53
|
+
"--restart", "unless-stopped",
|
|
49
54
|
"built-image",
|
|
50
55
|
]
|
|
51
56
|
assert check is True
|
|
@@ -55,7 +60,8 @@ def test_run_with_docker_no_build(monkeypatch, tmp_path):
|
|
|
55
60
|
project = tmp_path / "demo"
|
|
56
61
|
project.mkdir()
|
|
57
62
|
(project / "workpeg.json").write_text(
|
|
58
|
-
'{"build": {"image": "configured-image"},
|
|
63
|
+
'{"build": {"image": "configured-image"}, '
|
|
64
|
+
'"runtime": {"docker": {"port": 8000}}}'
|
|
59
65
|
)
|
|
60
66
|
|
|
61
67
|
calls = []
|
|
@@ -65,13 +71,18 @@ def test_run_with_docker_no_build(monkeypatch, tmp_path):
|
|
|
65
71
|
|
|
66
72
|
monkeypatch.setattr(run.subprocess, "run", fake_run)
|
|
67
73
|
|
|
68
|
-
run.run_with_docker(
|
|
74
|
+
run.run_with_docker(
|
|
75
|
+
path=str(project),
|
|
76
|
+
build_first=False,
|
|
77
|
+
network="bridge",
|
|
78
|
+
)
|
|
69
79
|
|
|
70
80
|
cmd, check = calls[0]
|
|
71
81
|
assert cmd == [
|
|
72
|
-
"docker", "run", "
|
|
82
|
+
"docker", "run", "-d",
|
|
73
83
|
"-p", "8000:8000",
|
|
74
84
|
"--network", "bridge",
|
|
85
|
+
"--restart", "unless-stopped",
|
|
75
86
|
"configured-image",
|
|
76
87
|
]
|
|
77
88
|
assert check is True
|
|
@@ -80,10 +91,18 @@ def test_run_with_docker_no_build(monkeypatch, tmp_path):
|
|
|
80
91
|
def test_run_main_with_docker(monkeypatch):
|
|
81
92
|
called = {}
|
|
82
93
|
|
|
83
|
-
def fake_run_with_docker(
|
|
94
|
+
def fake_run_with_docker(
|
|
95
|
+
path=".",
|
|
96
|
+
build_first=True,
|
|
97
|
+
network=None,
|
|
98
|
+
expose=True,
|
|
99
|
+
name=None,
|
|
100
|
+
):
|
|
84
101
|
called["path"] = path
|
|
85
102
|
called["build_first"] = build_first
|
|
86
103
|
called["network"] = network
|
|
104
|
+
called["expose"] = expose
|
|
105
|
+
called["name"] = name
|
|
87
106
|
|
|
88
107
|
monkeypatch.setattr(run, "run_with_docker", fake_run_with_docker)
|
|
89
108
|
|
|
@@ -93,6 +112,8 @@ def test_run_main_with_docker(monkeypatch):
|
|
|
93
112
|
"path": "/tmp/demo",
|
|
94
113
|
"build_first": False,
|
|
95
114
|
"network": None,
|
|
115
|
+
"expose": True,
|
|
116
|
+
"name": None,
|
|
96
117
|
}
|
|
97
118
|
|
|
98
119
|
|
|
@@ -118,10 +139,18 @@ def test_run_main_uses_config_default(monkeypatch, tmp_path):
|
|
|
118
139
|
|
|
119
140
|
called = {}
|
|
120
141
|
|
|
121
|
-
def fake_run_with_docker(
|
|
142
|
+
def fake_run_with_docker(
|
|
143
|
+
path=".",
|
|
144
|
+
build_first=True,
|
|
145
|
+
network=None,
|
|
146
|
+
expose=True,
|
|
147
|
+
name=None,
|
|
148
|
+
):
|
|
122
149
|
called["path"] = path
|
|
123
150
|
called["build_first"] = build_first
|
|
124
151
|
called["network"] = network
|
|
152
|
+
called["expose"] = expose
|
|
153
|
+
called["name"] = name
|
|
125
154
|
|
|
126
155
|
monkeypatch.setattr(run, "run_with_docker", fake_run_with_docker)
|
|
127
156
|
|
|
@@ -131,16 +160,26 @@ def test_run_main_uses_config_default(monkeypatch, tmp_path):
|
|
|
131
160
|
"path": str(project),
|
|
132
161
|
"build_first": True,
|
|
133
162
|
"network": None,
|
|
163
|
+
"expose": True,
|
|
164
|
+
"name": None,
|
|
134
165
|
}
|
|
135
166
|
|
|
136
167
|
|
|
137
168
|
def test_run_main_with_docker_and_network(monkeypatch):
|
|
138
169
|
called = {}
|
|
139
170
|
|
|
140
|
-
def fake_run_with_docker(
|
|
171
|
+
def fake_run_with_docker(
|
|
172
|
+
path=".",
|
|
173
|
+
build_first=True,
|
|
174
|
+
network=None,
|
|
175
|
+
expose=True,
|
|
176
|
+
name=None,
|
|
177
|
+
):
|
|
141
178
|
called["path"] = path
|
|
142
179
|
called["build_first"] = build_first
|
|
143
180
|
called["network"] = network
|
|
181
|
+
called["expose"] = expose
|
|
182
|
+
called["name"] = name
|
|
144
183
|
|
|
145
184
|
monkeypatch.setattr(run, "run_with_docker", fake_run_with_docker)
|
|
146
185
|
|
|
@@ -154,6 +193,8 @@ def test_run_main_with_docker_and_network(monkeypatch):
|
|
|
154
193
|
"path": "/tmp/demo",
|
|
155
194
|
"build_first": True,
|
|
156
195
|
"network": "workpeg_net",
|
|
196
|
+
"expose": True,
|
|
197
|
+
"name": None,
|
|
157
198
|
}
|
|
158
199
|
|
|
159
200
|
|
|
@@ -171,12 +212,17 @@ def test_run_with_docker_no_expose(monkeypatch, tmp_path):
|
|
|
171
212
|
|
|
172
213
|
monkeypatch.setattr(run.subprocess, "run", fake_run)
|
|
173
214
|
|
|
174
|
-
run.run_with_docker(
|
|
215
|
+
run.run_with_docker(
|
|
216
|
+
path=str(project),
|
|
217
|
+
build_first=False,
|
|
218
|
+
expose=False,
|
|
219
|
+
)
|
|
175
220
|
|
|
176
221
|
assert len(calls) == 1
|
|
177
222
|
cmd, check = calls[0]
|
|
178
223
|
assert cmd == [
|
|
179
|
-
"docker", "run", "
|
|
224
|
+
"docker", "run", "-d",
|
|
225
|
+
"--restart", "unless-stopped",
|
|
180
226
|
"demo",
|
|
181
227
|
]
|
|
182
228
|
assert check is True
|
|
@@ -196,12 +242,17 @@ def test_run_with_docker_expose(monkeypatch, tmp_path):
|
|
|
196
242
|
|
|
197
243
|
monkeypatch.setattr(run.subprocess, "run", fake_run)
|
|
198
244
|
|
|
199
|
-
run.run_with_docker(
|
|
245
|
+
run.run_with_docker(
|
|
246
|
+
path=str(project),
|
|
247
|
+
build_first=False,
|
|
248
|
+
expose=True,
|
|
249
|
+
)
|
|
200
250
|
|
|
201
251
|
cmd, check = calls[0]
|
|
202
252
|
assert cmd == [
|
|
203
|
-
"docker", "run", "
|
|
253
|
+
"docker", "run", "-d",
|
|
204
254
|
"-p", "9000:9000",
|
|
255
|
+
"--restart", "unless-stopped",
|
|
205
256
|
"demo",
|
|
206
257
|
]
|
|
207
258
|
assert check is True
|
|
@@ -232,8 +283,9 @@ def test_run_with_docker_with_name(monkeypatch, tmp_path):
|
|
|
232
283
|
cmd, check = calls[0]
|
|
233
284
|
|
|
234
285
|
assert cmd == [
|
|
235
|
-
"docker", "run", "
|
|
286
|
+
"docker", "run", "-d",
|
|
236
287
|
"--name", "foo",
|
|
288
|
+
"--restart", "unless-stopped",
|
|
237
289
|
"demo",
|
|
238
290
|
]
|
|
239
291
|
assert check is True
|
|
@@ -264,9 +316,10 @@ def test_run_with_docker_name_and_network(monkeypatch, tmp_path):
|
|
|
264
316
|
cmd, check = calls[0]
|
|
265
317
|
|
|
266
318
|
assert cmd == [
|
|
267
|
-
"docker", "run", "
|
|
319
|
+
"docker", "run", "-d",
|
|
268
320
|
"--name", "foo",
|
|
269
321
|
"--network", "workpeg_net",
|
|
322
|
+
"--restart", "unless-stopped",
|
|
270
323
|
"demo",
|
|
271
324
|
]
|
|
272
325
|
assert check is True
|
|
@@ -155,7 +155,7 @@ def test_submit_bundle_success_builds_request(mock_post):
|
|
|
155
155
|
api_base="https://repo.workpeg.com",
|
|
156
156
|
peg_id="peg-123",
|
|
157
157
|
token="jwt-token",
|
|
158
|
-
|
|
158
|
+
branch_id="fn_echo",
|
|
159
159
|
version="1.0.0",
|
|
160
160
|
bundle_bytes=b"tgz-bytes",
|
|
161
161
|
timeout_s=60,
|
|
@@ -168,7 +168,7 @@ def test_submit_bundle_success_builds_request(mock_post):
|
|
|
168
168
|
|
|
169
169
|
assert args[0] == "https://repo.workpeg.com/api/pegs/peg-123/functions/"
|
|
170
170
|
assert kwargs["headers"]["Authorization"] == "Bearer jwt-token"
|
|
171
|
-
assert kwargs["data"] == {"
|
|
171
|
+
assert kwargs["data"] == {"branch_id": "fn_echo", "version": "1.0.0"}
|
|
172
172
|
assert "files" in kwargs
|
|
173
173
|
file_tuple = kwargs["files"]["bundle"]
|
|
174
174
|
assert file_tuple[0] == "bundle.tar.gz"
|
|
@@ -189,7 +189,7 @@ def test_submit_bundle_http_error_json(mock_post):
|
|
|
189
189
|
api_base="https://repo.workpeg.com",
|
|
190
190
|
peg_id="peg-123",
|
|
191
191
|
token="jwt-token",
|
|
192
|
-
|
|
192
|
+
branch_id="fn_echo",
|
|
193
193
|
version="1.0.0",
|
|
194
194
|
bundle_bytes=b"tgz-bytes",
|
|
195
195
|
)
|
|
@@ -209,7 +209,7 @@ def test_submit_bundle_http_error_non_json(mock_post):
|
|
|
209
209
|
api_base="https://repo.workpeg.com",
|
|
210
210
|
peg_id="peg-123",
|
|
211
211
|
token="jwt-token",
|
|
212
|
-
|
|
212
|
+
branch_id="fn_echo",
|
|
213
213
|
version="1.0.0",
|
|
214
214
|
bundle_bytes=b"tgz-bytes",
|
|
215
215
|
)
|
|
@@ -265,7 +265,7 @@ def test_main_happy_path_uses_default_api_base(
|
|
|
265
265
|
_, kwargs = mock_submit_bundle.call_args
|
|
266
266
|
assert kwargs["api_base"] == "https://repo.workpeg.com"
|
|
267
267
|
assert kwargs["peg_id"] == "peg-123"
|
|
268
|
-
assert kwargs["
|
|
268
|
+
assert kwargs["branch_id"] == "fn_echo"
|
|
269
269
|
assert kwargs["version"] == "1.0.0"
|
|
270
270
|
assert kwargs["token"] == token
|
|
271
271
|
assert isinstance(kwargs["bundle_bytes"], (bytes, bytearray))
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from unittest import TestCase
|
|
2
|
+
|
|
3
|
+
from workpeg.utils import get_hook_urn
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TestGetHookUrn(TestCase):
|
|
7
|
+
|
|
8
|
+
def test_returns_hook_urn(self):
|
|
9
|
+
result = get_hook_urn("mail_sanitizer:v1")
|
|
10
|
+
|
|
11
|
+
self.assertEqual(
|
|
12
|
+
result,
|
|
13
|
+
"http://mail_sanitizer_v1:8000",
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
def test_removes_custom_prefix(self):
|
|
17
|
+
result = get_hook_urn("custom.mail_sanitizer:v1")
|
|
18
|
+
|
|
19
|
+
self.assertEqual(
|
|
20
|
+
result,
|
|
21
|
+
"http://mail_sanitizer_v1:8000",
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
def test_lowercases_hook_name(self):
|
|
25
|
+
result = get_hook_urn("Mail_Sanitizer:V1")
|
|
26
|
+
|
|
27
|
+
self.assertEqual(
|
|
28
|
+
result,
|
|
29
|
+
"http://mail_sanitizer_v1:8000",
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
def test_replaces_colon_with_underscore(self):
|
|
33
|
+
result = get_hook_urn("calendar:1.1")
|
|
34
|
+
|
|
35
|
+
self.assertEqual(
|
|
36
|
+
result,
|
|
37
|
+
"http://calendar_1.1:8000",
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
def test_handles_hook_without_version(self):
|
|
41
|
+
result = get_hook_urn("mailer")
|
|
42
|
+
|
|
43
|
+
self.assertEqual(
|
|
44
|
+
result,
|
|
45
|
+
"http://mailer:8000",
|
|
46
|
+
)
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|