Skip to content

Commit 0db1dea

Browse files
authored
Merge pull request #1 from kuberhealthy/codex/add-github-actions-for-build-validation
feat: add Python client package and CI
2 parents 52cf1cd + c807f78 commit 0db1dea

File tree

7 files changed

+122
-37
lines changed

7 files changed

+122
-37
lines changed

.github/workflows/build.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Build
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
jobs:
8+
build:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@v3
12+
- uses: actions/setup-python@v4
13+
with:
14+
python-version: "3.x"
15+
- name: Build package
16+
run: |
17+
python -m pip install --upgrade pip
18+
pip install build
19+
python -m build
20+
- name: Build example container
21+
run: |
22+
make build IMG=kuberhealthy-client:test

.github/workflows/publish.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Publish
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
jobs:
8+
publish:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@v3
12+
- uses: actions/setup-python@v4
13+
with:
14+
python-version: "3.x"
15+
- name: Build package
16+
run: |
17+
python -m pip install --upgrade pip
18+
pip install build
19+
python -m build
20+
- name: Publish to PyPI
21+
uses: pypa/gh-action-pypi-publish@release/v1
22+
with:
23+
user: __token__
24+
password: ${{ secrets.PYPI_API_TOKEN }}
25+
- name: Attach artifacts to release
26+
uses: softprops/action-gh-release@v1
27+
with:
28+
files: dist/*

Dockerfile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
FROM python:3.11-alpine
22

33
WORKDIR /app
4-
COPY client.py .
4+
COPY kuberhealthy_client kuberhealthy_client
5+
COPY example example
56

6-
CMD ["python3", "/app/client.py"]
7+
CMD ["python3", "/app/example/client.py"]

README.md

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,34 @@
11
# Python Kuberhealthy Client
22

3-
This directory contains a minimal Python application that demonstrates how to
4-
report status back to [Kuberhealthy](https://github.com/kuberhealthy/kuberhealthy).
5-
The example loads the `KH_REPORTING_URL` and `KH_RUN_UUID` environment variables
6-
provided to checker pods and includes commented calls to `report_ok` and
7-
`report_error`.
3+
This repository provides a small Python library for reporting check results back to [Kuberhealthy](https://github.com/kuberhealthy/kuberhealthy). It also includes a runnable example program and container configuration.
4+
5+
## Installing
6+
7+
Install the client into your own project:
8+
9+
```bash
10+
pip install kuberhealthy-client
11+
```
12+
13+
The library exposes two helpers:
14+
15+
```python
16+
from kuberhealthy_client import report_ok, report_error
17+
18+
# Environment variables KH_REPORTING_URL and KH_RUN_UUID are read automatically.
19+
report_ok()
20+
report_error("something went wrong")
21+
```
22+
23+
Both functions accept optional `url` and `run_uuid` keyword arguments if you prefer to supply values directly.
824

925
## Running the example
1026

1127
Set the `KH_REPORTING_URL` and `KH_RUN_UUID` environment variables, add your
12-
check logic to `client.py`, and then run:
28+
check logic to `example/client.py`, and then run:
1329

1430
```bash
15-
python3 client.py
31+
python3 example/client.py
1632
```
1733

1834
Within the `main` function, uncomment either `report_ok()` or
@@ -30,9 +46,8 @@ make push IMG=myrepo/example-check:latest
3046

3147
## Using in your own checks
3248

33-
1. Add your check logic to `client.py` by replacing the placeholder in `main`.
34-
Call `report_ok()` when the check succeeds or `report_error("message")`
35-
when it fails.
49+
1. Add your check logic to `example/client.py` or your own script. Call `report_ok()`
50+
when the check succeeds or `report_error("message")` when it fails.
3651
2. Build and push your image as shown above.
3752
3. Create a `KuberhealthyCheck` resource pointing at your image and apply it to any
3853
cluster where Kuberhealthy runs:

example/client.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/usr/bin/env python3
2+
"""Example Kuberhealthy client using the :mod:`kuberhealthy_client` package."""
3+
4+
from kuberhealthy_client import report_ok, report_error
5+
6+
7+
def main() -> None:
8+
"""Run the example client."""
9+
# INSERT YOUR CHECK LOGIC HERE
10+
# report_ok()
11+
# report_error("something went wrong")
12+
pass
13+
14+
15+
if __name__ == "__main__":
16+
main()
Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
1-
#!/usr/bin/env python3
2-
"""Example Kuberhealthy client in Python."""
1+
"""Lightweight client for reporting check results to Kuberhealthy."""
2+
3+
from __future__ import annotations
34

45
import json
56
import os
67
import urllib.request
7-
8+
from typing import Optional
89

910
KH_REPORTING_URL = "KH_REPORTING_URL"
1011
KH_RUN_UUID = "KH_RUN_UUID"
1112

12-
1313
def _get_env(name: str) -> str:
1414
"""Return the value of the environment variable *name* or raise an error."""
1515
value = os.getenv(name)
1616
if not value:
1717
raise EnvironmentError(f"{name} must be set")
1818
return value
1919

20-
21-
def _post_status(payload: dict) -> None:
20+
def _post_status(payload: dict, *, url: Optional[str] = None, run_uuid: Optional[str] = None) -> None:
2221
"""Send *payload* to the Kuberhealthy reporting URL."""
23-
url = _get_env(KH_REPORTING_URL)
24-
run_uuid = _get_env(KH_RUN_UUID)
22+
url = url or _get_env(KH_REPORTING_URL)
23+
run_uuid = run_uuid or _get_env(KH_RUN_UUID)
2524
data = json.dumps(payload).encode("utf-8")
2625
request = urllib.request.Request(
2726
url,
@@ -31,24 +30,12 @@ def _post_status(payload: dict) -> None:
3130
with urllib.request.urlopen(request, timeout=10) as response: # nosec B310
3231
response.read()
3332

34-
35-
def report_ok() -> None:
33+
def report_ok(*, url: Optional[str] = None, run_uuid: Optional[str] = None) -> None:
3634
"""Report a successful check to Kuberhealthy."""
37-
_post_status({"OK": True, "Errors": []})
35+
_post_status({"OK": True, "Errors": []}, url=url, run_uuid=run_uuid)
3836

39-
40-
def report_error(message: str) -> None:
37+
def report_error(message: str, *, url: Optional[str] = None, run_uuid: Optional[str] = None) -> None:
4138
"""Report a failure to Kuberhealthy with *message* as the error."""
42-
_post_status({"OK": False, "Errors": [message]})
43-
44-
45-
def main() -> None:
46-
"""Run the example client."""
47-
# INSERT YOUR CHECK LOGIC HERE
48-
# report_ok()
49-
# report_error("something went wrong")
50-
pass
51-
39+
_post_status({"OK": False, "Errors": [message]}, url=url, run_uuid=run_uuid)
5240

53-
if __name__ == "__main__":
54-
main()
41+
__all__ = ["report_ok", "report_error", "KH_REPORTING_URL", "KH_RUN_UUID"]

pyproject.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[build-system]
2+
requires = ["setuptools>=61.0"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "kuberhealthy-client"
7+
version = "0.1.0"
8+
description = "Python client for reporting check results to Kuberhealthy"
9+
readme = "README.md"
10+
authors = [{name = "Kuberhealthy"}]
11+
license = {text = "Apache-2.0"}
12+
requires-python = ">=3.8"
13+
14+
[tool.setuptools.packages.find]
15+
where = ["."]
16+
include = ["kuberhealthy_client"]

0 commit comments

Comments
 (0)