triangulum 0.40.2__py3-none-any.whl

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.
triangulum/__init__.py ADDED
@@ -0,0 +1,13 @@
1
+ """Python bindings for the Triangulum validation layer."""
2
+
3
+ from triangulum.errors import BunNotFound, Error, TriangulumFailed
4
+ from triangulum.validation import Diagnostic, Result, Validation
5
+
6
+ __all__ = [
7
+ "BunNotFound",
8
+ "Diagnostic",
9
+ "Error",
10
+ "Result",
11
+ "TriangulumFailed",
12
+ "Validation",
13
+ ]
triangulum/errors.py ADDED
@@ -0,0 +1,13 @@
1
+ """Exceptions raised by triangulum."""
2
+
3
+
4
+ class Error(Exception):
5
+ """Base class for every triangulum error."""
6
+
7
+
8
+ class TriangulumFailed(Error):
9
+ """The bun subprocess exited with a failure."""
10
+
11
+
12
+ class BunNotFound(Error):
13
+ """No bun executable is available to run the entrypoints with."""
triangulum/executor.py ADDED
@@ -0,0 +1,73 @@
1
+ """Runs the bundled TypeScript entrypoints through bun."""
2
+
3
+ import base64
4
+ import shutil
5
+ import subprocess
6
+ from pathlib import Path
7
+
8
+ from triangulum.errors import BunNotFound, TriangulumFailed
9
+
10
+ JS_DIR = Path(__file__).parent / "js"
11
+
12
+ # Platform wheels embed the matching bun binary here, see hatch_build.py. The
13
+ # pure python wheel does not, and falls back to bun on PATH.
14
+ BUNDLED_BUN = Path(__file__).parent / "exe" / "bun"
15
+
16
+
17
+ def bun():
18
+ """Path to the bun executable to run the entrypoints with."""
19
+ if BUNDLED_BUN.is_file():
20
+ return str(BUNDLED_BUN)
21
+
22
+ found = shutil.which("bun")
23
+ if found is None:
24
+ raise BunNotFound(
25
+ "No bundled bun binary found and no 'bun' on PATH. Install bun "
26
+ "(https://bun.sh) or use a platform specific triangulum wheel."
27
+ )
28
+
29
+ return found
30
+
31
+
32
+ def run_ts_triangulum(entrypoint, payload):
33
+ """Run ``entrypoint`` with ``payload`` on stdin and return its stdout."""
34
+ process = subprocess.run(
35
+ [bun(), "run", str(entrypoint)],
36
+ input=payload,
37
+ capture_output=True,
38
+ text=True,
39
+ check=False,
40
+ )
41
+
42
+ if process.returncode != 0:
43
+ if process.returncode < 0:
44
+ status_info = f"SIGNAL: {-process.returncode}"
45
+ else:
46
+ status_info = f"STATUS: {process.returncode}"
47
+
48
+ raise TriangulumFailed(
49
+ f"{status_info}\n\nOUT:\n{process.stdout}\n\nERR:\n{process.stderr}"
50
+ )
51
+
52
+ return process.stdout
53
+
54
+
55
+ def _encode(message):
56
+ return base64.b64encode(message.SerializeToString()).decode("ascii")
57
+
58
+
59
+ def serialize_input(flow, function_definitions, data_types):
60
+ """Serialize the protobuf messages into the entrypoint's stdin format.
61
+
62
+ One base64 encoded message per line, the three groups separated by an empty
63
+ line. Mirrors ``Triangulum::Validation#serialize_input`` in the ruby gem.
64
+ """
65
+ lines = [_encode(flow), ""]
66
+
67
+ lines += [_encode(fd) for fd in function_definitions]
68
+ lines.append("")
69
+
70
+ lines += [_encode(dt) for dt in data_types]
71
+ lines.append("")
72
+
73
+ return "\n".join(lines)
triangulum/js/.gitkeep ADDED
File without changes