quapp-hpc 0.0.1.dev5__tar.gz → 0.0.1.dev6__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 (30) hide show
  1. {quapp_hpc-0.0.1.dev5/quapp_hpc.egg-info → quapp_hpc-0.0.1.dev6}/PKG-INFO +1 -1
  2. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/pyproject.toml +2 -2
  3. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6/quapp_hpc.egg-info}/PKG-INFO +1 -1
  4. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/quapp_hpc.egg-info/SOURCES.txt +3 -1
  5. quapp_hpc-0.0.1.dev6/quapp_hpc.egg-info/top_level.txt +2 -0
  6. quapp_hpc-0.0.1.dev6/quapp_slurm_hpc/__init__.py +0 -0
  7. quapp_hpc-0.0.1.dev6/quapp_slurm_hpc/runner.py +112 -0
  8. quapp_hpc-0.0.1.dev5/quapp_hpc.egg-info/top_level.txt +0 -1
  9. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/LICENSE +0 -0
  10. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/README.md +0 -0
  11. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/quapp_hpc/__init__.py +0 -0
  12. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/quapp_hpc/component/__init__.py +0 -0
  13. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/quapp_hpc/component/backend/__init__.py +0 -0
  14. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/quapp_hpc/component/backend/hpc_invocation.py +0 -0
  15. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/quapp_hpc/component/backend/slurm_job_fetching.py +0 -0
  16. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/quapp_hpc/factory/__init__.py +0 -0
  17. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/quapp_hpc/factory/hpc_device_factory.py +0 -0
  18. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/quapp_hpc/factory/hpc_handler_factory.py +0 -0
  19. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/quapp_hpc/factory/hpc_provider_factory.py +0 -0
  20. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/quapp_hpc/handler/__init__.py +0 -0
  21. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/quapp_hpc/handler/invocation_handler.py +0 -0
  22. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/quapp_hpc/handler/job_fetching_handler.py +0 -0
  23. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/quapp_hpc/model/__init__.py +0 -0
  24. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/quapp_hpc/model/device/__init__.py +0 -0
  25. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/quapp_hpc/model/device/slurm_device.py +0 -0
  26. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/quapp_hpc/model/provider/__init__.py +0 -0
  27. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/quapp_hpc/model/provider/slurm_provider.py +0 -0
  28. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/quapp_hpc.egg-info/dependency_links.txt +0 -0
  29. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/quapp_hpc.egg-info/requires.txt +0 -0
  30. {quapp_hpc-0.0.1.dev5 → quapp_hpc-0.0.1.dev6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quapp-hpc
3
- Version: 0.0.1.dev5
3
+ Version: 0.0.1.dev6
4
4
  Summary: Quapp HPC library — Slurm integration for Quapp Platform
5
5
  Author-email: "CITYNOW Co. Ltd." <corp@citynow.vn>
6
6
  License: The MIT License (MIT)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "quapp-hpc"
7
- version = "0.0.1.dev5"
7
+ version = "0.0.1.dev6"
8
8
  description = "Quapp HPC library — Slurm integration for Quapp Platform"
9
9
  readme = "README.md"
10
10
  authors = [{ name = "CITYNOW Co. Ltd.", email = "corp@citynow.vn" }]
@@ -26,7 +26,7 @@ requires-python = ">=3.10,<3.13"
26
26
  dev = ["black", "bumpver", "isort", "pip-tools", "pytest"]
27
27
 
28
28
  [tool.setuptools.packages.find]
29
- include = ["quapp_hpc*"]
29
+ include = ["quapp_hpc*", "quapp_slurm_hpc*"]
30
30
  exclude = ["*.md", "*.yml", "*.yaml", "*.toml", "tests*", ".gitignore"]
31
31
 
32
32
  [project.urls]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quapp-hpc
3
- Version: 0.0.1.dev5
3
+ Version: 0.0.1.dev6
4
4
  Summary: Quapp HPC library — Slurm integration for Quapp Platform
5
5
  Author-email: "CITYNOW Co. Ltd." <corp@citynow.vn>
6
6
  License: The MIT License (MIT)
@@ -22,4 +22,6 @@ quapp_hpc/model/__init__.py
22
22
  quapp_hpc/model/device/__init__.py
23
23
  quapp_hpc/model/device/slurm_device.py
24
24
  quapp_hpc/model/provider/__init__.py
25
- quapp_hpc/model/provider/slurm_provider.py
25
+ quapp_hpc/model/provider/slurm_provider.py
26
+ quapp_slurm_hpc/__init__.py
27
+ quapp_slurm_hpc/runner.py
@@ -0,0 +1,2 @@
1
+ quapp_hpc
2
+ quapp_slurm_hpc
File without changes
@@ -0,0 +1,112 @@
1
+ """CLI runner — invoked by the sbatch script inside the Apptainer container.
2
+
3
+ The Java SlurmPlatformManager generates a sbatch script that runs:
4
+
5
+ apptainer exec docker://<image> python -m quapp_slurm_hpc.runner \
6
+ --input-file /data/jobs/<jobId>/input.json \
7
+ --output-file /data/jobs/<jobId>/output.json \
8
+ --handler-dir /home/app/function
9
+
10
+ This module:
11
+ 1. Reads the invocation input from --input-file (JSON written by the sbatch script).
12
+ 2. Loads handler.py from --handler-dir.
13
+ 3. Calls handler.processing(invocation_input) → bash script string.
14
+ 4. Executes the bash script, captures stdout / stderr / exit_code.
15
+ 5. Calls handler.post_processing(raw_result) if it exists.
16
+ 6. Writes the final result dict to --output-file.
17
+ """
18
+ import argparse
19
+ import importlib.util
20
+ import json
21
+ import subprocess
22
+ import sys
23
+ import tempfile
24
+ import traceback
25
+ from pathlib import Path
26
+ from types import ModuleType
27
+
28
+
29
+ def _load_handler(handler_dir: str) -> ModuleType:
30
+ handler_path = Path(handler_dir) / "handler.py"
31
+ if not handler_path.exists():
32
+ raise FileNotFoundError(
33
+ f"handler.py not found in {handler_dir!r}. "
34
+ "Ensure the function image was built with the handler in /home/app/function."
35
+ )
36
+ if str(handler_dir) not in sys.path:
37
+ sys.path.insert(0, str(handler_dir))
38
+ spec = importlib.util.spec_from_file_location("handler", handler_path)
39
+ module = importlib.util.module_from_spec(spec)
40
+ spec.loader.exec_module(module)
41
+ return module
42
+
43
+
44
+ def _run_script(script: str) -> dict:
45
+ """Write script to a temp file and execute it with bash, capturing output."""
46
+ with tempfile.NamedTemporaryFile(
47
+ mode="w", suffix=".sh", delete=False, encoding="utf-8"
48
+ ) as f:
49
+ f.write(script)
50
+ tmp_path = f.name
51
+ try:
52
+ result = subprocess.run(
53
+ ["bash", tmp_path],
54
+ capture_output=True,
55
+ text=True,
56
+ )
57
+ return {
58
+ "exit_code": result.returncode,
59
+ "stdout": result.stdout,
60
+ "stderr": result.stderr,
61
+ }
62
+ finally:
63
+ Path(tmp_path).unlink(missing_ok=True)
64
+
65
+
66
+ def main() -> None:
67
+ parser = argparse.ArgumentParser(
68
+ description="Quapp HPC runner — executes handler.py inside an Apptainer container"
69
+ )
70
+ parser.add_argument("--input-file", required=True, help="Path to input JSON file")
71
+ parser.add_argument("--output-file", required=True, help="Path to write output JSON")
72
+ parser.add_argument("--handler-dir", required=True, help="Directory containing handler.py")
73
+ args = parser.parse_args()
74
+
75
+ output: dict = {}
76
+ try:
77
+ with open(args.input_file, encoding="utf-8") as f:
78
+ invocation_input = json.load(f)
79
+
80
+ handler = _load_handler(args.handler_dir)
81
+
82
+ if not hasattr(handler, "processing"):
83
+ raise AttributeError(
84
+ "handler.py must define a processing(invocation_input: dict) -> str function"
85
+ )
86
+
87
+ script = handler.processing(invocation_input)
88
+ if not isinstance(script, str):
89
+ raise TypeError(
90
+ f"handler.processing() must return a str (bash script), got {type(script).__name__}"
91
+ )
92
+
93
+ raw_result = _run_script(script)
94
+
95
+ if hasattr(handler, "post_processing"):
96
+ output = handler.post_processing(raw_result)
97
+ else:
98
+ output = raw_result
99
+
100
+ except Exception:
101
+ output = {
102
+ "exit_code": 1,
103
+ "stdout": "",
104
+ "stderr": traceback.format_exc(),
105
+ }
106
+
107
+ with open(args.output_file, "w", encoding="utf-8") as f:
108
+ json.dump(output, f)
109
+
110
+
111
+ if __name__ == "__main__":
112
+ main()
@@ -1 +0,0 @@
1
- quapp_hpc
File without changes
File without changes
File without changes