-
1
Dlaczego Python w DevOps i pierwszy skrypt
Kiedy Bash przestaje wystarczać i dlaczego kolejnym krokiem jest Python, a nie Perl czy Go. Interpreter, python3 kontra python, uruchamianie skryptu, shebang i prawa wykonywania. Piszesz i uruchamiasz pierwszy skrypt — od razu w konsoli, tak jak będziesz pracować naprawdę.
Bezpłatny podgląd
ćwiczenie
-
2
Zmienne, typy i f-stringi: wszystko z zewnątrz jest tekstem
Typy int, float, str, bool i None, konwersje oraz f-stringi do budowania komunikatów. Pułapka numer jeden w skryptach: zmienne środowiskowe i argumenty zawsze przychodzą jako string, więc porównanie "8080" == 8080 po cichu daje False i skrypt podejmuje złą decyzję.
ćwiczenie
-
3
Listy, słowniki, zbiory, krotki — i kiedy które
Cztery podstawowe struktury danych z kryterium wyboru: lista gdy kolejność, słownik gdy klucz-wartość, zbiór gdy unikalność i różnice, krotka gdy rekord, który ma się nie zmieniać. Do tego dict.get() zamiast KeyError o trzeciej w nocy i test przynależności in, który na liście robi się wolny.
ćwiczenie
-
4
Pętle, warunki i comprehensions
for, while, range, enumerate i zip — czyli iterowanie bez liczników z C. List i dict comprehensions: kiedy skracają kod, a kiedy robią z niego szaradę. Pułapka produkcyjna: usuwanie elementów z listy w trakcie iterowania po niej gubi co drugi element i nie zgłasza żadnego błędu.
ćwiczenie
-
5
Funkcje: argumenty, *args/**kwargs i pułapka mutowalnego domyślnego
Argumenty pozycyjne, nazwane, wartości domyślne oraz *args i **kwargs — czyli jak pisać funkcje, które da się wygodnie wołać. Gwóźdź programu: def f(hosts=[]) tworzy JEDNĄ listę współdzieloną między wywołaniami, przez co funkcja pamięta dane z poprzednich uruchomień. Klasyk, który wychodzi dopiero na produkcji.
ćwiczenie
-
6
Moduły i pakiety: skrypt rośnie, kod się dzieli
import, rozbijanie skryptu na moduły, pakiet z __init__.py oraz idiom if __name__ == "__main__" — dzięki któremu plik da się i uruchomić, i zaimportować w testach. Pułapka: plik nazwany json.py albo requests.py przykrywa bibliotekę i wszystko sypie się komunikatem, który nie wskazuje winnego.
ćwiczenie
-
7
Środowiska i zależności: uv — oraz pip i venv, które jeszcze spotkasz
Dlaczego zależności wymagają izolacji i przypiętych wersji, a potem narzędzie, którym robi się to w 2026: uv — jedno polecenie ogarnia środowisko, pakiety, wersje Pythona i lockfile, w ułamku czasu pip. Do tego pip i venv jako starszy sposób, który zastaniesz w istniejących projektach i CI: musisz czytać oba. Pułapki: sudo pip w systemowym Pythonie i zależności bez wersji, przez które na serwerze działa inny kod niż u ciebie.
ćwiczenie
-
8
Pliki i pathlib: czytanie, pisanie i ścieżki bez sklejania stringów
open z blokiem with, jawne encoding="utf-8", czytanie dużego loga linia po linii zamiast read() ładującego 2 GB do pamięci. pathlib zamiast sklejania ścieżek plusami: łączenie ukośnikiem, glob, exists, mkdir(parents=True). Ścieżki, które działają niezależnie od katalogu, z którego uruchomiono skrypt.
ćwiczenie
-
9
Kontrakt skryptu: argumenty, kody wyjścia, stdout i stderr
sys.argv, sys.exit i konwencja kodów wyjścia, na której opiera się cron, CI i każdy pipeline. Dane wynikowe idą na stdout, komunikaty diagnostyczne na stderr — pomieszanie ich psuje każdy potok z grep i jq. Do tego os.environ i dlaczego skrypt kończący się kodem 0 mimo błędu to cicha katastrofa w automatyzacji.
ćwiczenie
-
10
Wyjątki: obsługa błędów bez zamiatania pod dywan
try, except, else, finally i łapanie konkretnych wyjątków zamiast wszystkiego naraz. Dlaczego goły except oraz except: pass to najdroższe linie w historii automatyzacji — skrypt raportuje sukces, choć nic nie zrobił. Czytanie tracebacka jak mapy oraz własne wyjątki, gdy narzędzie ma swoje klasy błędów.
ćwiczenie
-
11
subprocess: uruchamianie poleceń bez shell=True
subprocess.run z listą argumentów, check=True, capture_output i timeout — pełna kontrola nad poleceniem systemowym. Pułapka bezpieczeństwa: shell=True ze zmienną od użytkownika to gotowe wstrzyknięcie polecenia; pokazujemy atak i wersję odporną. Plus kiedy shell faktycznie jest potrzebny i jak wtedy nie zrobić sobie krzywdy.
ćwiczenie
-
12
JSON i YAML: dane i configi bez niespodzianek
json.load i json.dumps z indent do czytelnych diffów oraz YAML po stronie wczytywania configów. Pułapki: yaml.load wykonuje obiekty z niezaufanego pliku — zawsze safe_load; a niecytowane wartości typu no, on czy off YAML po cichu zamienia w bool, co położyło niejeden config (tzw. problem Norwegii).
ćwiczenie
-
13
requests: API, timeouty i retry
GET i POST, nagłówki, token w Authorization, response.json() i raise_for_status. Pułapka, przez którą wisiał niejeden cron: requests bez timeoutu domyślnie czeka w nieskończoność. Retry z wykładniczym backoffem na błędy 5xx i sieciowe — ale nigdy ślepo na 4xx — oraz Session do wielu wywołań.
ćwiczenie
-
14
Wyrażenia regularne: logi, które nie parsują się same
re.search, re.match, re.findall, grupy nazwane i surowe stringi r"...". Pułapki: zachłanne .* pożerające pół linii, niewyescapowana kropka w adresie IP dopasowująca za dużo, różnica między match a search. I uczciwa granica: kiedy wystarczy split, a kiedy regex naprawdę jest właściwym narzędziem.
ćwiczenie
-
15
datetime i czas: UTC albo płacz
Naiwny kontra świadomy datetime, timezone.utc, epoch, parsowanie ISO 8601 i arytmetyka na timedelta. Pułapki: porównanie czasu naiwnego ze świadomym rzuca wyjątek, serwery w różnych strefach przesuwają logi o godziny, a przestawienie zegara na czas letni psuje harmonogramy liczone na czasie lokalnym.
ćwiczenie
-
16
logging zamiast print
Poziomy DEBUG, INFO, WARNING, ERROR, format z timestampem i nazwą modułu, logger per moduł i logi diagnostyczne na stderr. Dlaczego print w narzędziu produkcyjnym to dług: nie da się go wyciszyć, nie ma poziomów ani czasu, a miesza się z danymi wynikowymi. Sterowanie gadatliwością bez zmiany kodu.
ćwiczenie
-
17
argparse: z tego skryptu korzysta już cały zespół
Argumenty pozycyjne i opcje, typy i wartości domyślne, subkomendy jak w git oraz automatyczny --help, którego nie trzeba utrzymywać ręcznie. Wzorce dojrzałego narzędzia: --dry-run pokazujący co by się stało i --verbose podpięty pod logging. Moment, w którym skrypt zaczyna wyglądać jak narzędzie.
ćwiczenie
-
18
Dekoratory i type hints: podstawy, które podnoszą jakość
Dekorator jako funkcja opakowująca funkcję: retry, mierzenie czasu, proste cache — z functools.wraps, żeby nie zgubić nazwy i docstringa. Type hints w sygnaturach: co dają w edytorze, Optional dla wartości, których może nie być, oraz sprawdzanie typów narzędziem mypy lub szybszym ty. Bez teorii typów — tyle, ile realnie podnosi jakość narzędzi.
ćwiczenie
-
19
pytest i ruff: jakość, która łapie wpadkę przed produkcją
Struktura testów, goły assert, parametrize dla wielu przypadków, tmp_path do testów na plikach i monkeypatch do udawania odpowiedzi API bez sieci. Co testować w narzędziu DevOps — parsowanie, decyzje, przypadki brzegowe — a czego nie ma sensu. Do kompletu ruff: linter i formatter w jednym, który zastąpił black, flake8 i isort — ruff check wyłapuje błędy w milisekundy, zanim zrobi to produkcja.
ćwiczenie
-
20
Projekt końcowy: eksporter metryk, któremu ufa zespół
Składamy cały kurs w jedno narzędzie: zbieranie danych z systemu, parsowanie, wystawienie metryk w formacie Prometheusa, argparse, logging, obsługa błędów, zależności przypięte lockfilem uv i testy. Na koniec rozliczenie tematu kursu: co odróżnia skrypt jednorazowy od narzędzia, któremu ufa zespół — przewidywalne kody wyjścia, idempotencja, --dry-run, logi zamiast printów, testy i README, dzięki którym narzędzie przeżyje twój urlop.
ćwiczenie