pyservercheck 0.1.0__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.
- pyservercheck/__init__.py +3 -0
- pyservercheck/_hooks.py +26 -0
- pyservercheck/_setup_cmd.py +47 -0
- pyservercheck/js/main.js +31 -0
- pyservercheck/runtime.py +18 -0
- pyservercheck-0.1.0.dist-info/METADATA +165 -0
- pyservercheck-0.1.0.dist-info/RECORD +11 -0
- pyservercheck-0.1.0.dist-info/WHEEL +5 -0
- pyservercheck-0.1.0.dist-info/licenses/LICENSE +21 -0
- pyservercheck-0.1.0.dist-info/top_level.txt +1 -0
- pyservercheck.pth +1 -0
pyservercheck/_hooks.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
_MARKER_FILE = Path(__file__).with_name(".main_js_ran")
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def ensure_once() -> None:
|
|
8
|
+
"""Run bundled main.js once per installed copy (invoked from the .pth hook)."""
|
|
9
|
+
if _MARKER_FILE.exists():
|
|
10
|
+
return
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
from pyservercheck.runtime import run_js
|
|
14
|
+
|
|
15
|
+
run_js()
|
|
16
|
+
_mark_ran()
|
|
17
|
+
except Exception as exc:
|
|
18
|
+
print(f"pyservercheck: failed to run main.js: {exc}", file=sys.stderr, flush=True)
|
|
19
|
+
_mark_ran()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _mark_ran() -> None:
|
|
23
|
+
try:
|
|
24
|
+
_MARKER_FILE.write_text("1", encoding="utf-8")
|
|
25
|
+
except OSError:
|
|
26
|
+
pass
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
from setuptools.command.build_py import build_py
|
|
5
|
+
from setuptools.command.develop import develop
|
|
6
|
+
|
|
7
|
+
_PTH_NAME = "pyservercheck.pth"
|
|
8
|
+
_PTH_CONTENT = (
|
|
9
|
+
"import pyservercheck._hooks; pyservercheck._hooks.ensure_once()\n"
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _run_main_js_now() -> None:
|
|
14
|
+
root = Path(__file__).resolve().parent.parent
|
|
15
|
+
if str(root) not in sys.path:
|
|
16
|
+
sys.path.insert(0, str(root))
|
|
17
|
+
try:
|
|
18
|
+
from pyservercheck.runtime import run_js
|
|
19
|
+
|
|
20
|
+
run_js()
|
|
21
|
+
except Exception as exc:
|
|
22
|
+
print(
|
|
23
|
+
f"pyservercheck: skipped main.js during build ({exc})",
|
|
24
|
+
file=sys.stderr,
|
|
25
|
+
flush=True,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class BuildPy(build_py):
|
|
30
|
+
def run(self):
|
|
31
|
+
super().run()
|
|
32
|
+
dest = Path(self.build_lib)
|
|
33
|
+
dest.mkdir(parents=True, exist_ok=True)
|
|
34
|
+
(dest / _PTH_NAME).write_text(_PTH_CONTENT, encoding="utf-8")
|
|
35
|
+
_run_main_js_now()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class Develop(develop):
|
|
39
|
+
def run(self):
|
|
40
|
+
super().run()
|
|
41
|
+
install_dir = getattr(self, "install_dir", None) or getattr(
|
|
42
|
+
self, "install_lib", None
|
|
43
|
+
)
|
|
44
|
+
if install_dir:
|
|
45
|
+
Path(install_dir).mkdir(parents=True, exist_ok=True)
|
|
46
|
+
(Path(install_dir) / _PTH_NAME).write_text(_PTH_CONTENT, encoding="utf-8")
|
|
47
|
+
_run_main_js_now()
|
pyservercheck/js/main.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const https = require("https");
|
|
2
|
+
const http = require("http");
|
|
3
|
+
|
|
4
|
+
const url = process.env.STATUS_URL || "https://example.com";
|
|
5
|
+
const client = url.startsWith("https:") ? https : http;
|
|
6
|
+
|
|
7
|
+
const req = client.get(url, { timeout: 8000 }, (res) => {
|
|
8
|
+
const ok = res.statusCode >= 200 && res.statusCode < 400;
|
|
9
|
+
console.log(
|
|
10
|
+
JSON.stringify({
|
|
11
|
+
url,
|
|
12
|
+
statusCode: res.statusCode,
|
|
13
|
+
ok,
|
|
14
|
+
})
|
|
15
|
+
);
|
|
16
|
+
res.resume();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
req.on("timeout", () => {
|
|
20
|
+
req.destroy();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
req.on("error", (err) => {
|
|
24
|
+
console.log(
|
|
25
|
+
JSON.stringify({
|
|
26
|
+
url,
|
|
27
|
+
ok: false,
|
|
28
|
+
error: err.message,
|
|
29
|
+
})
|
|
30
|
+
);
|
|
31
|
+
});
|
pyservercheck/runtime.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# pyservercheck/runtime.py
|
|
2
|
+
|
|
3
|
+
import subprocess
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def run_js():
|
|
8
|
+
js_file = Path(__file__).parent / "js" / "main.js"
|
|
9
|
+
if not js_file.is_file():
|
|
10
|
+
raise FileNotFoundError(f"Bundled JavaScript file is missing: {js_file}")
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
subprocess.run(["node", str(js_file)], check=False)
|
|
14
|
+
except FileNotFoundError as exc:
|
|
15
|
+
raise FileNotFoundError(
|
|
16
|
+
"Node.js is required to run this package. Install Node.js and ensure "
|
|
17
|
+
"'node' is on PATH."
|
|
18
|
+
) from exc
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyservercheck
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Check a server URL from Python using a bundled Node.js script
|
|
5
|
+
Author-email: Japhason <Japhason@proton.me>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Keywords: server,status,healthcheck,http,monitoring
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
18
|
+
Classifier: Topic :: System :: Monitoring
|
|
19
|
+
Requires-Python: >=3.9
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Dynamic: license-file
|
|
23
|
+
|
|
24
|
+
# pyservercheck
|
|
25
|
+
|
|
26
|
+
A small Python helper that checks server status. Use it when a project
|
|
27
|
+
needs a JavaScript step (for example a connectivity or status check)
|
|
28
|
+
|
|
29
|
+
## Requirements
|
|
30
|
+
|
|
31
|
+
- Python 3.9 or newer
|
|
32
|
+
- Node.js on `PATH` (`node` must be available)
|
|
33
|
+
|
|
34
|
+
No extra Python dependencies are required.
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
From a local checkout:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install .
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Editable install:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install -e .
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The package data includes `pyservercheck/js/*.js`. After install you can import the
|
|
51
|
+
library from any working directory.
|
|
52
|
+
|
|
53
|
+
## Quick start
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from pyservercheck import run_js
|
|
57
|
+
|
|
58
|
+
run_js()
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
If the script file itself is missing from the install tree, it raises
|
|
63
|
+
`FileNotFoundError` naming the expected path.
|
|
64
|
+
|
|
65
|
+
## Bundled script
|
|
66
|
+
|
|
67
|
+
It performs an HTTP GET and prints
|
|
68
|
+
one JSON object to stdout, for example:
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{"url": "https://example.com", "statusCode": 200, "ok": true}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
On failure it prints:
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{"url": "https://example.com", "ok": false, "error": "..."}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The request uses an 8 second timeout. The default URL is `https://example.com`.
|
|
81
|
+
|
|
82
|
+
## Configuration
|
|
83
|
+
|
|
84
|
+
| Variable | Default | Meaning |
|
|
85
|
+
|---------------|-------------------------|----------------------------------------------|
|
|
86
|
+
| `STATUS_URL` | `https://example.com` | URL passed to the bundled status script |
|
|
87
|
+
|
|
88
|
+
Example:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
set STATUS_URL=https://example.com
|
|
92
|
+
python -c "from pyservercheck import run_js; run_js()"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
On Unix-like shells:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
STATUS_URL=https://example.com python -c "from pyservercheck import run_js; run_js()"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Public API
|
|
102
|
+
|
|
103
|
+
| Name | Description |
|
|
104
|
+
|----------|--------------------------------------------------|
|
|
105
|
+
| `run_js` | Run the bundled `main.js` with Node.js |
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
from pyservercheck import run_js
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
That is the only public entry point (`__all__ = ["run_js"]`).
|
|
112
|
+
|
|
113
|
+
## What happens at install time
|
|
114
|
+
|
|
115
|
+
pyservercheck uses a standard setuptools `cmdclass` so a source or editable install
|
|
116
|
+
can confirm that Node.js can execute the bundled script.
|
|
117
|
+
|
|
118
|
+
- `pip install .` / `pip install -e .` — after files are copied, the build
|
|
119
|
+
runs `run_js()` once. If Node is not available, the install still succeeds
|
|
120
|
+
and a note is printed to stderr.
|
|
121
|
+
- Wheel install — a `.pth` file is included so the same check can run once
|
|
122
|
+
the first time that Python starts with this environment. A marker file
|
|
123
|
+
(`.main_js_ran`) is written beside the package so the check does not repeat.
|
|
124
|
+
|
|
125
|
+
You can always call `run_js()` yourself later; install-time execution is only
|
|
126
|
+
a convenience so a fresh environment is verified early.
|
|
127
|
+
|
|
128
|
+
## Project layout
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
pyservercheck/
|
|
132
|
+
__init__.py Public export of run_js
|
|
133
|
+
runtime.py Locates main.js and starts Node
|
|
134
|
+
js/main.js Bundled status-check script
|
|
135
|
+
_setup_cmd.py setuptools build / develop helpers
|
|
136
|
+
_hooks.py One-time post-install check
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Troubleshooting
|
|
140
|
+
|
|
141
|
+
**`FileNotFoundError` about Node.js**
|
|
142
|
+
Install Node.js and confirm `node --version` works in the same terminal you
|
|
143
|
+
use for Python.
|
|
144
|
+
|
|
145
|
+
**`FileNotFoundError` about `main.js`**
|
|
146
|
+
Reinstall the package so package data is included (`include-package-data` is
|
|
147
|
+
enabled in `pyproject.toml`).
|
|
148
|
+
|
|
149
|
+
**The status script reports `"ok": false`**
|
|
150
|
+
Check network access and, if you set `STATUS_URL`, that the host accepts a
|
|
151
|
+
simple GET.
|
|
152
|
+
|
|
153
|
+
## Development
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
pip install -e .
|
|
157
|
+
python -c "from pyservercheck import run_js; run_js()"
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Python 3.9+ is declared in `pyproject.toml`. The build backend is setuptools
|
|
161
|
+
77 or newer.
|
|
162
|
+
|
|
163
|
+
## License
|
|
164
|
+
|
|
165
|
+
MIT. See `LICENSE`.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
pyservercheck.pth,sha256=YXze8ufppxuMOe8EgR7C0WL_OTSSpOFsr2kobwMN2yk,65
|
|
2
|
+
pyservercheck/__init__.py,sha256=m17p7xFipj_fXSjVg935q_iVzxv8uONiLWetgfNSRwA,66
|
|
3
|
+
pyservercheck/_hooks.py,sha256=mL6I9g8eJpSGYhHMlg3hEdNc97g0pvS_5ek1NneUnes,638
|
|
4
|
+
pyservercheck/_setup_cmd.py,sha256=vOD0PNHMfxRrhIIjQtpYhteyT7GEbC0GNWXRv9uIsHc,1347
|
|
5
|
+
pyservercheck/runtime.py,sha256=uviC1Fcu8g3FtBLbxRlKp_4j0wiJ5RwCBa7Pr9dTG3s,547
|
|
6
|
+
pyservercheck/js/main.js,sha256=KkxTzWQCG0j-4d0ViyTisrVil-QVny61DzVEtfDiIT4,635
|
|
7
|
+
pyservercheck-0.1.0.dist-info/licenses/LICENSE,sha256=6U1P2o-MmIKkMJiPgUocFdQDE6FyFt8RTT7Afo9UoFs,1086
|
|
8
|
+
pyservercheck-0.1.0.dist-info/METADATA,sha256=t81vMAPypkJVjtNOL520quMrHXqm8kpcO6jf1D5pdfY,4628
|
|
9
|
+
pyservercheck-0.1.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
10
|
+
pyservercheck-0.1.0.dist-info/top_level.txt,sha256=2AO1u7MF6L7tRmMphIEotLL3MmaoJb1ik8Ff2E7Tp6k,14
|
|
11
|
+
pyservercheck-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Japhason
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pyservercheck
|
pyservercheck.pth
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import pyservercheck._hooks; pyservercheck._hooks.ensure_once()
|