Skip to content

Install Python deps via apt so the root service can import them (#74) - #75

Open
cuneytozseker wants to merge 1 commit into
mainfrom
fix/setup-deps-for-root-service
Open

Install Python deps via apt so the root service can import them (#74)#75
cuneytozseker wants to merge 1 commit into
mainfrom
fix/setup-deps-for-root-service

Conversation

@cuneytozseker

Copy link
Copy Markdown
Owner

Fixes #74.

The bug

TinyProgrammer does not run out of the box on a fresh Pi install.

setup.sh installed three of its Python dependencies as the invoking (unprivileged) user:

pip3 install --quiet --break-system-packages requests flask python-dotenv

On Bookworm that lands in ~/<user>/.local/lib/python3.11/site-packages. But tinyprogrammer.service sets User=root and runs /usr/bin/python3 .../main.py, and root's sys.path includes /root/.local/... — never the installing user's. So import flask fails and the app never starts.

pygame and PIL were unaffected only because they already came from apt in the same script and are therefore installed system-wide. That is exactly why flask is the module people see in the log.

Because the unit sets Restart=on-failure with RestartSec=5, this doesn't fail once and stop — it crash-loops every five seconds, which reads as a display problem unless you happen to check /var/log/tinyprogrammer.log.

The fix

Move all of the Python dependencies to apt so everything is installed system-wide and root can resolve it. This keeps User=root and the framebuffer assumptions in the service unit unchanged, and drops the --break-system-packages workaround entirely.

In place of the pip step, setup.sh now verifies the imports as root — the same user the service runs as, so this class of bug cannot ship silently again:

sudo python3 -c 'import pygame, PIL, numpy, flask, requests, dotenv'

Also: python3-numpy was never installed

While scoping this I found a second gap. setup.sh never installed numpy at all, and neither did the README's manual instructions — it is in requirements.txt, but setup.sh hand-lists packages rather than reading that file.

display/framebuffer.py:13 imports numpy at module level, on the core Pi render path (rgb888_to_rgb565, rgb888_to_xrgb8888), as does display/color_adjustment.py:8 which framebuffer.py imports. A missing numpy is a startup crash, not a degraded feature.

It has been resolving until now only as a transitive dependency of python3-pygame. That is accidental, so python3-numpy is now requested explicitly.

Alternative considered

@krs-novice's own fix — keeping User=root and dropping to the user for main.py via runuser — also works, and is more careful than it first appears: it leaves the two ExecStartPre lines running as root, and the first of those (echo 0 > /sys/class/graphics/fbcon/cursor_blink) has no - prefix, so it would fail the whole unit if it couldn't write. A plain switch to User=<user> would break that and would additionally need the user in the video group for /dev/fb0.

I went the apt route because it is the smaller diff and leaves the documented root/framebuffer model intact.

Testing

bash -n setup.sh passes. Not yet verified on hardware — this needs one run on a Pi to confirm the apt package names resolve and the check passes:

apt-cache policy python3-flask python3-requests python3-dotenv python3-numpy
sudo python3 -c 'import pygame, PIL, numpy, flask, requests, dotenv'

Reported by @krs-novice in #74.

Generated with Claude Code

https://claude.ai/code/session_018hU2w7FyVR7WDegE8sWeAM

setup.sh installed requests, flask and python-dotenv with `pip3 --user`,
which lands in the invoking user's ~/.local. tinyprogrammer.service runs
as root, whose sys.path never includes that directory, so main.py died
with "No module named flask" and systemd restart-looped it every 5s.

pygame and PIL were unaffected only because they already came from apt.

Move all of them to apt so everything is installed system-wide, and add
an explicit root import check in place of the pip step — the service
user is the one that has to resolve these, so that is the user to test.

Also add python3-numpy, which was never installed at all despite
display/framebuffer.py importing it at module level on the Pi render
path. It resolved until now only as a transitive dependency of
python3-pygame.

Reported-by: krs-novice

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018hU2w7FyVR7WDegE8sWeAM
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Suggestion] Install Documentation update, re flask module

1 participant