fix: use append (>>) instead of overwrite (>) for cron logs and add missing dependencies

- Fixed api/schema.py to generate cron jobs using '>> wecker.log' so logs aren't truncated.
- Added test_bugfix_default_command_uses_append_for_logs in tests/test_api.py to prevent regression.
- Added RPi.GPIO and pygame to pyproject.toml via 'uv add' to fix ModuleNotFoundError in cron jobs.
- Updated README.md to reflect that system python packages are no longer needed.
This commit is contained in:
Markus Graf
2026-05-11 22:08:57 +02:00
parent ff79224560
commit 64947deeb1
6 changed files with 81 additions and 6 deletions
-4
View File
@@ -21,10 +21,6 @@ This project uses Python 3 and `uv` for dependency management. To set up the env
uv sync
```
Note: The system also requires `python3-pygame` and `python3-rpi.gpio` which should be installed via system packages:
```bash
sudo apt-get install python3-pygame python3-rpi.gpio
```
## Wiring
-1
View File
@@ -1 +0,0 @@
17958
+1 -1
View File
@@ -49,7 +49,7 @@ class Mutation:
if command is None:
project_root = Path(__file__).parent.parent.absolute()
python_exec = sys.executable
command = f"cd {project_root} && {python_exec} wecker.py > wecker.log 2>&1"
command = f"cd {project_root} && {python_exec} wecker.py >> wecker.log 2>&1"
manager = get_manager()
new_id = manager.set_alarm(
+2
View File
@@ -6,8 +6,10 @@ readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"fastapi>=0.136.1",
"pygame>=2.6.1",
"python-crontab>=3.3.0",
"python-dotenv>=1.2.2",
"rpi-gpio>=0.7.1",
"strawberry-graphql>=0.315.3",
"uvicorn>=0.46.0",
]
+53
View File
@@ -40,6 +40,59 @@ def test_auth_invalid():
assert response.status_code == 401
def test_bugfix_default_command_uses_append_for_logs():
"""
Test for bugfix: Ensure the default command appends (>>) to wecker.log
instead of overwriting (>) it.
"""
from api.schema import Mutation
mutation = Mutation()
# Call the resolver directly without command to trigger default command generation
alarm = mutation.set_alarm(cron_expression="0 9 * * *")
# Verify the generated command string
command = alarm.command
assert ">> wecker.log 2>&1" in command, (
f"Command must use append '>>' syntax. Got: {command}"
)
assert "> wecker.log 2>&1" not in command.replace(">> wecker.log", "REPLACED"), (
"Command must not use overwrite '>'"
)
# Cleanup
mutation.delete_alarm(id=alarm.id)
def test_set_alarm_default_command_append():
headers = {"X-API-Key": "test-secret"}
mutation = """
mutation {
setAlarm(cronExpression: "0 9 * * *") {
id
command
}
}
"""
res = client.post("/graphql", json={"query": mutation}, headers=headers)
assert res.status_code == 200
data = res.json()["data"]["setAlarm"]
# Assert the command contains the correct append syntax (>>) and not just overwrite (>)
command = data["command"]
assert ">> wecker.log 2>&1" in command
assert "> wecker.log 2>&1" not in command.replace(">> wecker.log", "REPLACED")
# Cleanup so we don't break subsequent tests
alarm_id = data["id"]
mutation_delete = f"""
mutation {{
deleteAlarm(id: "{alarm_id}")
}}
"""
client.post("/graphql", json={"query": mutation_delete}, headers=headers)
def test_graphql_workflow():
headers = {"X-API-Key": "test-secret"}
Generated
+25
View File
@@ -243,6 +243,21 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/f6/d2/42dd53d0a85c27606f316d3aa5d2869c4e8470a5ed6dec30e4a1abe19192/pydantic_core-2.46.4-cp314-cp314t-win_arm64.whl", hash = "sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596", size = 2017325, upload-time = "2026-05-06T13:40:52.723Z" },
]
[[package]]
name = "pygame"
version = "2.6.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/49/cc/08bba60f00541f62aaa252ce0cfbd60aebd04616c0b9574f755b583e45ae/pygame-2.6.1.tar.gz", hash = "sha256:56fb02ead529cee00d415c3e007f75e0780c655909aaa8e8bf616ee09c9feb1f", size = 14808125, upload-time = "2024-09-29T13:41:34.698Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e1/91/718acf3e2a9d08a6ddcc96bd02a6f63c99ee7ba14afeaff2a51c987df0b9/pygame-2.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ae6039f3a55d800db80e8010f387557b528d34d534435e0871326804df2a62f2", size = 13090765, upload-time = "2024-09-29T14:27:02.377Z" },
{ url = "https://files.pythonhosted.org/packages/0e/c6/9cb315de851a7682d9c7568a41ea042ee98d668cb8deadc1dafcab6116f0/pygame-2.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2a3a1288e2e9b1e5834e425bedd5ba01a3cd4902b5c2bff8ed4a740ccfe98171", size = 12381704, upload-time = "2024-09-29T14:27:10.228Z" },
{ url = "https://files.pythonhosted.org/packages/9f/8f/617a1196e31ae3b46be6949fbaa95b8c93ce15e0544266198c2266cc1b4d/pygame-2.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27eb17e3dc9640e4b4683074f1890e2e879827447770470c2aba9f125f74510b", size = 13581091, upload-time = "2024-09-29T11:30:27.653Z" },
{ url = "https://files.pythonhosted.org/packages/3b/87/2851a564e40a2dad353f1c6e143465d445dab18a95281f9ea458b94f3608/pygame-2.6.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c1623180e70a03c4a734deb9bac50fc9c82942ae84a3a220779062128e75f3b", size = 14273844, upload-time = "2024-09-29T11:40:04.138Z" },
{ url = "https://files.pythonhosted.org/packages/85/b5/aa23aa2e70bcba42c989c02e7228273c30f3b44b9b264abb93eaeff43ad7/pygame-2.6.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef07c0103d79492c21fced9ad68c11c32efa6801ca1920ebfd0f15fb46c78b1c", size = 13951197, upload-time = "2024-09-29T11:40:06.785Z" },
{ url = "https://files.pythonhosted.org/packages/a6/06/29e939b34d3f1354738c7d201c51c250ad7abefefaf6f8332d962ff67c4b/pygame-2.6.1-cp313-cp313-win32.whl", hash = "sha256:3acd8c009317190c2bfd81db681ecef47d5eb108c2151d09596d9c7ea9df5c0e", size = 10249309, upload-time = "2024-09-29T11:10:23.329Z" },
{ url = "https://files.pythonhosted.org/packages/7e/11/17f7f319ca91824b86557e9303e3b7a71991ef17fd45286bf47d7f0a38e6/pygame-2.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:813af4fba5d0b2cb8e58f5d95f7910295c34067dcc290d34f1be59c48bd1ea6a", size = 10620084, upload-time = "2024-09-29T11:48:51.587Z" },
]
[[package]]
name = "pygments"
version = "2.20.0"
@@ -322,6 +337,12 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a", size = 22101, upload-time = "2026-03-01T16:00:25.09Z" },
]
[[package]]
name = "rpi-gpio"
version = "0.7.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/c4/0f/10b524a12b3445af1c607c27b2f5ed122ef55756e29942900e5c950735f2/RPi.GPIO-0.7.1.tar.gz", hash = "sha256:cd61c4b03c37b62bba4a5acfea9862749c33c618e0295e7e90aa4713fb373b70", size = 29090, upload-time = "2022-02-06T15:15:06.022Z" }
[[package]]
name = "ruff"
version = "0.15.12"
@@ -424,8 +445,10 @@ version = "0.1.0"
source = { virtual = "." }
dependencies = [
{ name = "fastapi" },
{ name = "pygame" },
{ name = "python-crontab" },
{ name = "python-dotenv" },
{ name = "rpi-gpio" },
{ name = "strawberry-graphql" },
{ name = "uvicorn" },
]
@@ -442,8 +465,10 @@ dev = [
[package.metadata]
requires-dist = [
{ name = "fastapi", specifier = ">=0.136.1" },
{ name = "pygame", specifier = ">=2.6.1" },
{ name = "python-crontab", specifier = ">=3.3.0" },
{ name = "python-dotenv", specifier = ">=1.2.2" },
{ name = "rpi-gpio", specifier = ">=0.7.1" },
{ name = "strawberry-graphql", specifier = ">=0.315.3" },
{ name = "uvicorn", specifier = ">=0.46.0" },
]