Python
Create a Python template#
- Go to Task Templates and click New Template.
- Select Python as the app type.
- Configure it:
| Field | Description |
|---|---|
| Name | A descriptive name for the template |
| Repository | The repository containing your .py script |
| Playbook / Script | Relative path to the script, e.g. scripts/deploy.py |
| Variable Groups | Variable groups whose values are injected as environment variables |
- Create, then Run.
Passing variables#
Variable group values arrive in the environment:
import os
target = os.environ.get("TARGET_HOST")
print(f"Deploying to {target}")Secrets from the Secrets tab work the same way and stay out of the task log.
Python version and dependencies#
Semaphore uses whichever python3 is on PATH in the execution environment. How you control that depends on your install:
| Install | How to control it |
|---|---|
| Package or binary | Install the required python3 on the host |
| Docker | Build a custom image with the version you need |
| Docker, extra packages only | Mount a requirements.txt at /etc/semaphore/requirements.txt — Semaphore runs pip3 install --upgrade -r on container start |
The requirements.txt route is shared with Ansible collections that need Python libraries; see Install.
If different templates need conflicting dependency sets, give them separate runners rather than fighting one shared environment.
Rules of the road#
- Scripts run non-interactively — nothing that waits on
input(). - Exit code
0is success; anything else fails the task. An uncaught exception exits non-zero, which is the behaviour you want. - Write progress to stdout: it becomes the streamed task log, and it is what someone reads at 3am.
Next steps#
- Shell / Bash — for the smaller jobs
- Runners — isolating dependency sets
- REST API — calling Semaphore from Python instead of the other way round