Cykl: Automatyzacja procesów z n8n — od danych do AI w jednym narzędziu · Część 8/26

Lista zadań i pipeline'y w Pythonie: makefile/invoke/fabric

Kacper Sieradziński
Kacper Sieradziński20 stycznia 2025 · 5 min czytania
Streszczenie
  • Po co tworzyć listę zadań w projekcie Python?
  • Makefile w projekcie Python
  • Pipeline w Makefile
  • Invoke - lista zadań w Pythonie
Lista zadań i pipeline'y w Pythonie: makefile/invoke/fabric

Lista zadań i pipeline'y w Pythonie: makefile/invoke/fabric

Lista zadań i pipeline’y w Pythonie pomagają uporządkować powtarzalne komendy w projekcie. Zamiast za każdym razem wpisywać długie polecenia do testów, formatowania, lintowania, budowania paczki albo wdrożenia, możesz przygotować jeden zestaw prostych komend, z którego korzysta cały zespół.

To szczególnie ważne w większych projektach Pythonowych. Jeśli każdy programista uruchamia testy inaczej, instaluje zależności inną komendą i wdraża aplikację według własnych notatek, szybko pojawiają się błędy. Pipeline porządkuje proces: definiuje, co ma się wydarzyć, w jakiej kolejności i jaką komendą.

W tym artykule poznasz trzy praktyczne podejścia: Makefile, invokefabric. Zobaczysz, jak tworzyć lokalne zadania, jak budować proste pipeline’y, jak automatyzować deployment i jak ustandaryzować pracę z projektem Python.

Kurs · 24 lekcje8h 14m
Kurs

Kurs Python od podstaw — PyStart

Zacznij programować w Pythonie od zera. Praktyczny kurs wideo z ćwiczeniami — bez wcześniejszego doświadczenia.

  • 24 lekcje wideo + 80 ćwiczeń
  • Realne bazy z e-commerce
  • Społeczność i code-review
699 zł
Zacznij kurs Pythona

Po co tworzyć listę zadań w projekcie Python?

W każdym projekcie powtarzają się podobne czynności:

  • instalacja zależności,
  • uruchamianie testów,
  • formatowanie kodu,
  • sprawdzanie jakości kodu,
  • czyszczenie plików tymczasowych,
  • budowanie paczki,
  • generowanie dokumentacji,
  • uruchamianie aplikacji lokalnie,
  • wdrażanie kodu na serwer,
  • tworzenie backupu.

Bez listy zadań te komendy często są zapisane w dokumentacji, historii terminala albo pamięci jednej osoby. To ryzykowne. Wystarczy zmiana w konfiguracji i część zespołu zaczyna pracować na nieaktualnych poleceniach.

Lista zadań rozwiązuje ten problem. Zamiast pamiętać:

Bash
1 pytest tests/ --cov=app --cov-report=html

możesz uruchomić:

Bash
1 make test

albo:

Bash
1 invoke test

To prostsze, mniej podatne na błędy i łatwiejsze do wdrożenia w zespole.

Makefile w projekcie Python

Makefile to klasyczne narzędzie do automatyzacji komend. Jest popularne nie tylko w Pythonie, ale też w wielu innych językach i projektach infrastrukturalnych. Jego największą zaletą jest prostota: definiujesz nazwę zadania i komendy, które mają się wykonać.

Przykładowy Makefile dla projektu Python:

MAKEFILE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 .PHONY: help install test lint format clean run help: @echo "Dostępne komendy:" @echo "make install - instalacja zależności" @echo "make test - uruchomienie testów" @echo "make lint - sprawdzenie jakości kodu" @echo "make format - formatowanie kodu" @echo "make clean - czyszczenie plików tymczasowych" @echo "make run - uruchomienie aplikacji" install: pip install -r requirements.txt test: pytest tests/ lint: flake8 . black --check . format: black . clean: find . -type d -name "__pycache__" -exec rm -rf {} + find . -type f -name "*.pyc" -delete rm -rf .pytest_cache .coverage htmlcov build dist *.egg-info run: python main.py

Użycie:

Bash
1 2 3 4 5 6 make install make test make lint make format make clean make run

Dzięki temu nowe osoby w projekcie nie muszą znać wszystkich szczegółów. Wystarczy, że wpiszą make help i zobaczą dostępne komendy.

Pipeline w Makefile

Makefile pozwala też tworzyć zadania złożone, czyli takie, które uruchamiają kilka kroków w odpowiedniej kolejności.

Przykład:

MAKEFILE
1 2 3 4 5 6 7 8 9 10 .PHONY: check build release check: lint test @echo "Kod przeszedł lint i testy." build: clean python -m build release: check build @echo "Projekt gotowy do wydania."

W tym przypadku:

Bash
1 make release

uruchomi najpierw lint, potem test, potem clean, następnie build, a na końcu komunikat z zadania release.

To prosty pipeline lokalny. Możesz go wykorzystać przed commitem, przed pull requestem albo przed publikacją paczki.

Invoke - lista zadań w Pythonie

invoke to narzędzie do definiowania zadań w samym Pythonie. Jeśli nie chcesz pisać Makefile albo wolisz mieć większą kontrolę nad logiką, invoke jest bardzo dobrym wyborem.

Instalacja:

Bash
1 pip install invoke

Tworzysz plik tasks.py:

Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 from invoke import task @task def test(ctx): """Uruchamia testy.""" ctx.run("pytest tests/") @task def lint(ctx): """Sprawdza jakość kodu.""" ctx.run("flake8 .") ctx.run("black --check .") @task def format(ctx): """Formatuje kod.""" ctx.run("black .") @task def clean(ctx): """Czyści pliki tymczasowe.""" ctx.run("rm -rf build dist *.egg-info .pytest_cache .coverage htmlcov") ctx.run("find . -type d -name '__pycache__' -exec rm -rf {} +", warn=True) @task def run(ctx): """Uruchamia aplikację.""" ctx.run("python main.py")

Użycie:

Bash
1 2 3 4 5 invoke test invoke lint invoke format invoke clean invoke run

Możesz też używać skróconej formy:

Bash
1 inv test

invoke dobrze pasuje do projektów Pythonowych, bo zadania są zwykłymi funkcjami. Możesz dodawać warunki, argumenty, logikę i obsługę błędów.

Zadania z argumentami w invoke

Dużą zaletą invoke jest możliwość przekazywania parametrów do zadań.

Przykład zadania uruchamiającego testy dla wybranego katalogu:

Python
1 2 3 4 5 6 7 8 9 10 11 from invoke import task @task def test(ctx, path="tests/"): """Uruchamia testy dla wybranej ścieżki.""" ctx.run(f"pytest {path}") @task def coverage(ctx): """Uruchamia testy z raportem pokrycia.""" ctx.run("pytest tests/ --cov=app --cov-report=html")

Użycie:

Bash
1 2 3 invoke test invoke test --path=tests/unit/ invoke coverage

To wygodne, gdy chcesz mieć jedną komendę, ale różne warianty jej uruchomienia.

Pipeline zadań w invoke

Newsletter · co środę

Python co tydzień — newsletter dla programistów

Otrzymuj codzienne ćwiczenia, ciekawostki z ekosystemu Pythona i wskazówki do rozmów rekrutacyjnych.

2 312 czytelników · ⭐ 4,8

W invoke możesz definiować zależności między zadaniami za pomocą prepost.

Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 from invoke import task @task def clean(ctx): """Czyści pliki tymczasowe.""" ctx.run("rm -rf build dist *.egg-info") @task def lint(ctx): """Sprawdza jakość kodu.""" ctx.run("flake8 .") ctx.run("black --check .") @task def test(ctx): """Uruchamia testy.""" ctx.run("pytest tests/") @task def build(ctx): """Buduje paczkę.""" ctx.run("python -m build") @task(pre=[clean, lint, test], post=[build]) def release(ctx): """Kompletny proces wydania.""" print("Rozpoczynam proces wydania.")

Użycie:

Bash
1 invoke release

Taki pipeline uruchomi czyszczenie, lint, testy, główne zadanie release, a potem build. Dzięki temu proces wydania jest powtarzalny i mniej zależny od pamięci osoby, która go wykonuje.

Fabric - automatyzacja zadań zdalnych

fabric służy do automatyzacji zadań wykonywanych na zdalnych serwerach. Jest przydatny przy prostych deploymentach, restartowaniu usług, aktualizacji kodu, tworzeniu backupów albo wykonywaniu komend przez SSH.

Instalacja:

Bash
1 pip install fabric

Przykładowy fabfile.py:

Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from fabric import task @task def deploy(c): """Wdraża aplikację na serwerze.""" c.run("cd /var/www/myapp && git pull origin main") c.run("cd /var/www/myapp && source venv/bin/activate && pip install -r requirements.txt") c.run("sudo systemctl restart myapp") @task def backup(c): """Tworzy backup bazy danych.""" c.run("pg_dump mydb > /tmp/mydb_backup.sql") @task def logs(c): """Pokazuje logi aplikacji.""" c.run("sudo journalctl -u myapp -n 100 --no-pager")

Użycie:

Bash
1 2 3 fab -H user@example.com deploy fab -H user@example.com backup fab -H user@example.com logs

Fabric sprawdza się wtedy, gdy chcesz mieć prosty, powtarzalny sposób wykonywania zadań administracyjnych na serwerze bez ręcznego logowania się przez SSH i wpisywania wielu komend.

Deployment z Fabric krok po kroku

Prosty proces wdrożenia może obejmować pobranie zmian z Gita, instalację zależności, migracje bazy i restart aplikacji.

Python
1 2 3 4 5 6 7 8 9 10 11 12 from fabric import task APP_DIR = "/var/www/myapp" @task def deploy(c): """Pełny deployment aplikacji Python.""" c.run(f"cd {APP_DIR} && git pull origin main") c.run(f"cd {APP_DIR} && venv/bin/pip install -r requirements.txt") c.run(f"cd {APP_DIR} && venv/bin/python manage.py migrate") c.run("sudo systemctl restart myapp") c.run("sudo systemctl status myapp --no-pager")

Uruchomienie:

Bash
1 fab -H user@server.com deploy

To nadal prosty deployment, ale już znacznie bardziej uporządkowany niż ręczne wykonywanie tych samych kroków na serwerze.

Makefile, invoke czy fabric - co wybrać?

Każde z tych narzędzi ma inne zastosowanie.

Makefile jest dobry, gdy chcesz mieć proste, standardowe komendy dostępne z terminala. Sprawdza się w wielu projektach i jest łatwy do zrozumienia.

invoke jest dobry, gdy chcesz pisać zadania w Pythonie, przekazywać argumenty, dodawać logikę i budować bardziej elastyczne pipeline’y lokalne.

fabric jest dobry, gdy zadania mają wykonywać się na zdalnym serwerze przez SSH.

W praktyce możesz używać ich razem. Na przykład:

  • Makefile jako główny interfejs dla programisty,
  • invoke do bardziej złożonej logiki lokalnej,
  • fabric do deploymentu i zadań serwerowych.

Przykład: make deploy może wewnętrznie uruchamiać fab deploy.

Przykładowa struktura projektu Python z zadaniami

Prosty projekt może wyglądać tak:

1 2 3 4 5 6 7 8 9 10 11 my_project/ ├── app/ │ └── main.py ├── tests/ │ └── test_main.py ├── tasks.py ├── fabfile.py ├── Makefile ├── requirements.txt ├── pyproject.toml └── README.md

W takim układzie:

  • Makefile daje szybkie komendy,
  • tasks.py zawiera zadania invoke,
  • fabfile.py zawiera zadania zdalne,
  • requirements.txt lub pyproject.toml opisuje zależności,
  • README.md dokumentuje sposób pracy z projektem.

Przykładowy Makefile jako warstwa nad invoke

Możesz też użyć Makefile jako prostego skrótu do zadań invoke.

MAKEFILE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 .PHONY: install test lint format clean release install: pip install -r requirements.txt test: invoke test lint: invoke lint format: invoke format clean: invoke clean release: invoke release

Dzięki temu osoby, które wolą make, używają make test, a złożona logika nadal pozostaje w Pythonowym pliku tasks.py.

Automatyzacja jakości kodu

Pipeline w projekcie Python powinien zwykle obejmować kontrolę jakości kodu. Najczęściej używa się narzędzi takich jak black, ruff, flake8, mypypytest.

Przykład zadania qualityinvoke:

Python
1 2 3 4 5 6 7 8 9 from invoke import task @task def quality(ctx): """Uruchamia pełną kontrolę jakości kodu.""" ctx.run("black --check .") ctx.run("ruff check .") ctx.run("mypy app/") ctx.run("pytest tests/")

Użycie:

Bash
1 invoke quality

Taki zestaw możesz uruchamiać lokalnie przed commitem i później przenieść do CI/CD, np. GitHub Actions.

Dobre praktyki przy pipeline’ach w Pythonie

Dobrze przygotowana lista zadań powinna być prosta, przewidywalna i czytelna. Nie chodzi o to, żeby ukryć wszystko za skomplikowaną automatyzacją, ale żeby ułatwić codzienną pracę.

Najważniejsze praktyki:

  • trzymaj najczęstsze komendy w jednym miejscu,
  • dodaj zadanie help,
  • używaj krótkich i zrozumiałych nazw,
  • rozdziel zadania lokalne od zdalnych,
  • nie wpisuj haseł i tokenów w plikach z zadaniami,
  • sprawdzaj kod przed buildem,
  • uruchamiaj testy przed release,
  • czyść pliki tymczasowe przed budowaniem paczki,
  • dokumentuj komendy w README.md,
  • używaj tych samych komend lokalnie i w CI/CD.

Dzięki temu pipeline nie jest tylko dodatkiem, ale realnym elementem jakości projektu.

Podsumowanie

Kurs · 24 lekcje8h 14m
Kurs

Kurs Python dla początkujących — PyStart

Zacznij programować w Pythonie! Idealne dla osób bez doświadczenia. Praktyczne zadania, projekty i wsparcie społeczności.

  • 24 lekcje wideo + 80 ćwiczeń
  • Realne bazy z e-commerce
  • Społeczność i code-review
699 zł
Rozpocznij naukę

Lista zadań i pipeline’y w Pythonie pomagają standardyzować codzienną pracę z projektem. Zamiast pamiętać długie komendy, możesz uruchamiać proste polecenia typu make test, invoke lint albo fab deploy.

Do lokalnych komend dobrze sprawdzi się Makefile lub invoke. Do zadań zdalnych najlepszy będzie fabric. W większych projektach warto połączyć te narzędzia i stworzyć jeden powtarzalny workflow: instalacja, formatowanie, lint, testy, build i deployment.

Jeśli chcesz zacząć praktycznie, dodaj do projektu prosty Makefile z komendami install, test, lint, formatclean. To mała zmiana, która szybko porządkuje pracę i ułatwia późniejsze przejście do CI/CD.

➡️ Następny artykuł

Po opanowaniu zarządzania zadaniami naucz się automatyzować CI/CD:

Automatyzacja CI/CD w Pythonie: GitHub Actions — kompletny przewodnik po automatyzacji testów, kontroli jakości kodu i wdrożeń z poziomu GitHub Actions.

Część 9 z 26

Narzędzia do PDF w Pythonie: przegląd bibliotek

druga lekcja cyklu „Automatyzacja procesów z n8n — od danych do AI w jednym narzędziu"

Czytaj kolejny →