Project Oxygen & Ideo-LabIDEO LAB Dashboard 2026

Toolbox Dev — Ideo-Lab

PyTaskRunner — Runner CLI de tñches (mini “Makefile Python”)

Centralise tes scripts de build/test/deploy/backup dans tasks.py et exécute-les via pytask. Dépendances, .env, exécution shell streaming, dry-run, et parallélisme best-effort.

v0.1.0  ‱  Python 3.10+

À quoi ça sert ?

PyTaskRunner sert Ă  organiser et exĂ©cuter des “tĂąches projet” rĂ©currentes : build, tests, lint, release, backup, jobs d’ops, scripts de maintenance, etc. L’idĂ©e : au lieu d’avoir 25 scripts Ă©parpillĂ©s, tu Ă©cris des fonctions Python annotĂ©es et tu les exĂ©cutes via une commande unique pytask.

Pourquoi c’est utile (en vrai) :
  • Tu standardises la maniĂšre de lancer les tĂąches (local, CI, serveur)
  • Tu factorises dĂ©pendances + ordre d’exĂ©cution (ex : deploy dĂ©pend de build et test)
  • Tu peux activer --dry pour vĂ©rifier sans exĂ©cuter
  • Tu charges automatiquement un .env pour secrets/config locale (API_KEY, HOST, etc.)
  • Tu gardes du Python : conditions, boucles, gĂ©nĂ©ration de commandes, etc.

Dépendances & Orchestration

DĂ©finis une tĂąche deploy qui dĂ©pend de build et test. PyTaskRunner garantit l’ordre.

@task(deps=[...])toposortcycle detection

Shell streaming

sh() exĂ©cute une commande et laisse le stdout/stderr “en live” (parfait pour pytest, rsync, docker).

subprocesscheck=Truerc handling

.env intégré

Charge un .env local et expose ctx.env pour tes tùches (sans dépendance python-dotenv).

load_dotenvctx.envoverride control

Comparaison (PyTaskRunner vs scripts dispersés)

ProblĂšme courantSans runnerAvec PyTaskRunner
Ordre build/test/deploydocs + “faut penser à
”deps=["build","test"] (automatique)
Secrets & configenv bricolé / export manuel.env chargé + ctx.env
Lisibilité / maintenancebash + scripts multiples1 fichier tasks.py versionnable/testable
Dry-runsouvent absent--dry (validation safe)
Philosophie : petit, stable, sans dĂ©pendances. PyTaskRunner ne remplace pas un CI/CD, il sert Ă  standardiser l’exĂ©cution des tĂąches projet et Ă  Ă©viter les scripts “one-shot” oubliĂ©s.

Installation (.whl)

PyTaskRunner est livré en wheel (installation rapide dans ton venv). Une fois installé, tu obtiens la commande pytask.

Télécharger le Wheel (pytaskrunner v0.1.0)

/static/toolbox/pytaskrunner-0.1.0-py3-none-any.whl

Commande d’installation

# venv activé
pip install /chemin/local/pytaskrunner-0.1.0-py3-none-any.whl

Vérifier que la CLI est disponible

pytask --help
pytask list
Si “pytask: command not found” :
  • vĂ©rifie que ton venv est bien activĂ©
  • ou lance via python -m pytaskrunner (option alternative si tu ajoutes un entrypoint plus tard)

Quickstart (5 minutes)

Étape 1 — CrĂ©e un fichier tasks.py Ă  la racine

from pytaskrunner import task, sh

@task(desc="Run unit tests")
def test(ctx):
    sh("pytest -q")

@task(desc="Build wheel")
def build(ctx):
    sh("python -m build")

@task(desc="Deploy (example)", deps=["build", "test"])
def deploy(ctx):
    sh("echo Deploying...")

Étape 2 — Liste les tñches

pytask list
RĂ©sultat →Tasks: build, deploy (deps=[build,test]), test

Étape 3 — ExĂ©cute une tĂąche simple

pytask run test

Étape 4 — ExĂ©cute une tĂąche avec deps

pytask run deploy
RĂ©sultat →build → test → deploy (dans cet ordre)

Étape 5 — Dry-run pour valider sans exĂ©cuter

pytask run deploy --dry
RĂ©sultat →DRY-RUN: skipped execution of build/test/deploy
Une fois ce schéma en place, tu peux remplacer progressivement tes scripts dispersés par des tùches bien nommées.

Exemples concrets (dev, ops, Django)

1) Tasks “Dev” classiques (lint / tests / format)

from pytaskrunner import task, sh

@task(desc="Format code")
def fmt(ctx):
    sh("ruff format .")

@task(desc="Lint")
def lint(ctx):
    sh("ruff check .")

@task(desc="Tests", deps=["lint"])
def test(ctx):
    sh("pytest -q")

2) Wheel + Release local

Centralise build + vérifications + génération artefacts.

@task(desc="Build dist")
def build(ctx):
    sh("python -m build")

@task(desc="Check dist")
def check(ctx):
    sh("python -m pip install -U twine")
    sh("twine check dist/*")

@task(desc="Release local", deps=["build", "check"])
def release(ctx):
    sh("ls -lh dist")

3) Django : migrations / collectstatic / runserver

@task(desc="Django migrate")
def migrate(ctx):
    sh("python manage.py migrate")

@task(desc="Collect static")
def collectstatic(ctx):
    sh("python manage.py collectstatic --noinput")

@task(desc="Run dev server", deps=["migrate"])
def run(ctx):
    sh("python manage.py runserver 0.0.0.0:8000")

4) Ops : backup PostgreSQL (env via .env)

Exemple : dans .env : PGHOST, PGUSER, PGDATABASE, BACKUP_DIR.

@task(desc="Backup Postgres")
def pg_backup(ctx):
    host = ctx.env.get("PGHOST","localhost")
    user = ctx.env.get("PGUSER","postgres")
    db   = ctx.env.get("PGDATABASE","app")
    out  = ctx.env.get("BACKUP_DIR","./backups")
    sh(f"mkdir -p {out}")
    sh(f"pg_dump -h {host} -U {user} {db} | gzip > {out}/{db}.sql.gz")
Remarque : sh() stream le stdout/stderr. Pour des secrets, privilĂ©gie env plutĂŽt que l’inline.

5) Télécharger/Sync artefacts (rsync)

@task(desc="Sync dist to server", deps=["build"])
def sync(ctx):
    host = ctx.env.get("DEPLOY_HOST","myserver")
    sh(f"rsync -av dist/ {host}:/srv/releases/")

6) Exemple de sortie attendue (logs)

# pytask run deploy
[12:01:03] INFO Running task: build — Build wheel
... build output ...
[12:01:07] OK   Done: build (4.12s)
[12:01:07] INFO Running task: test — Run unit tests
... pytest output ...
[12:01:15] OK   Done: test (7.88s)
[12:01:15] INFO Running task: deploy — Deploy (example)
Deploying...
[12:01:15] OK   Done: deploy (0.12s)

Avancé (deps, jobs, patterns, piÚges)

Dépendances : rÚgles & erreurs

PyTaskRunner calcule un ordre via tri topologique. En cas de cycle (A dĂ©pend de B et B dĂ©pend de A), l’exĂ©cution Ă©choue volontairement.

Erreurs typiques :
  • Task inconnue dans deps → “Unknown task”
  • Cycle de dĂ©pendances → “Cycle detected”
  • Commande shell rc!=0 → stop (fail-fast) + code retour non zĂ©ro

Jobs parallĂšles (-j) best-effort

Si plusieurs dĂ©pendances sont indĂ©pendantes, PyTaskRunner peut les lancer en parallĂšle. Attention : si deux tĂąches touchent les mĂȘmes fichiers, tu peux crĂ©er des race conditions.

pytask run deploy -j 4
Conseil : rĂ©serve le parallel Ă  des tĂąches “read-only” (lint/test) ou Ă  des steps rĂ©ellement indĂ©pendants.

Pattern recommandé : tùches petites + composables

PatternPourquoi
tùches courtes (lint, test, build)plus faciles à réutiliser comme deps (ex: deploy dépend de build+test)
tĂąches “meta” (ci, release)juste des deps, pas de logique compliquĂ©e
utiliser .env pour config localeévite hardcode, simplifie usage multi-env

Trucs utiles Ă  ajouter en V2 (si tu veux)

  • Arguments de task : pytask run backup -- --full (pass-through args)
  • Hooks : pre=["lint"] / post=["report"]
  • Capture output optionnelle (pour logs structurĂ©s)
  • Affichage “plan” d’exĂ©cution (graph deps)