Pipenv - zarządzanie zależnościami i środowiskami wirtualnymi w Pythonie
Zależności
Programując w języku Python wcześniej niż później staniemy przed potrzebą skorzystania z zewnętrznych modułów bibliotek (zwanych też pakietami). Przed ich wykorzystaniem musimy je zainstalować (w odpowiednich wersjach) w środowisku Pythona, w którym będzie działał nasz program.
Możemy to zrobić ręcznie, poprzez pobranie kodu źródłowego dodatku, zbudowaniu go i zainstalowaniu w systemie. Jest to dość skomplikowany proces, gdyż musimy uwzględniać, że zewnętrzny pakiet będzie potrzebował innych zewnętrznych pakietów, które analogicznie będziemy musieli pobrać, zbudować i zainstalować.
Na szczęście Python daje nam kilka gotowych narzędzi ułatwiających proces instalacji zewnętrznych modułów wraz z ich zależnościami (setuptools, easy_install, pip, egg, wheel).
Środowiska wirtualne
Pracując przy kilku projektach równocześnie może okazać się, że potrzebujemy danego pakietu w różnych wersjach w różnych projektach. Tutaj z pomocą przychodzą nam wirtualne środowiska. Wirtualne środowisku pythona jest to odizolowany od systemu podsystem interpretera Python wraz własnym zestawem bibliotek, w którym można niezależnie instalować zewnętrzne moduły i uruchamiać własne programu. Programy uruchomione w takim środowisku korzystają tylko z komponentów i bibliotek w nim dostępnych.
I w tym miejscu również mamy do dyspozycji kilka narzędzi do zarządzania środowiskami wirtualnymi (pyenv, virtualenv, virtualenvwrapper, conda, venv)
Typowy proces pracy przy projekcie (pip + venv + requirements.txt)
Pokażę teraz w jaki sposób może przebiegać praca nad typowym projektem w Pythonie. Będziemy wykorzystywać Pythona w wersji co najmniej 3.4 (najlepiej w aktualnej obecnie wersji 3.7), gdyż począwszy od tej wersji mamy już wbudowany w środowisko Pythona program pip i nie musimy go dodatkowo instalować.
Zaczynamy od stworzenia środowiska wirtualnego dla projektu. Możemy to zrobić na wiele sposobów. Skorzystamy z modułu venv, który jest wbudowany w Pythona począwszy od wersji 3.3
gotowe środowisko wirtualne aktywujemy poprzez:
Korzystając z systemu Linux i powłoki fish w celu aktywowania środowiska wydajemy polecenie: source ~/venvs/myproject/bin/activate.fish, a w przypadku powłoki csh: source ~/venvs/myproject/bin/activate.csh
Przychodzi teraz pora na stworzenie katalogu dla projektu i edycję jego kodu w naszym ulubionym edytorze/IDE. Załóżmy, że będzie to projekt korzystający z frameworka flask. Zaczniemy banalnie:
Z powyższego kodu wynika, że będziemy potrzebowali moduł flask. Wydajemy więc w konsoli polecenie jego instalacji:
W wyniku wykonania tego polecenia zostanie w środowisku wirtualnym zainstalowany moduł flask w najnowszej wersji (w tym przypadku 1.0.2) wraz z innymi zależnościami.
Pip
domyślnie pobiera paczki modułów z adresu https://pypi.org
Gdy potrzebujemy innej wersji modułu flask
to musimy wyspecyfikować numer wersji do instalacji:
Mając zainstalowany moduł flask, wraz z modułami zależnymi powinnyśmy wygenerować plik z zależnościami, który w przyszłości umożliwi nam łatwiejszą instalację zależności w odpowiednich wersjach np. gdy kolejne osoby będą dołączać do grona developerów naszego projektu, albo gdy będziemy ten projekt publikować na serwerze produkcyjnym.
Mając tak przygotowany plik requirements.txt możemy w każdym momencie odtworzyć stan instalacji wszystkich zewnętrznych modułów w odpowiednich wersjach:
Dzięki takiemu sposobowi instalacji zależności nasz projekt będzie deterministyczny. Oznacza to, że niezależnie od momentu, w którym będziemy instalować zależności, zawsze otrzymamy w wyniku instalacji wszystkie moduły w wymaganych wersjach.
Rozważmy jeszcze hipotetyczną sytuację, że w pewnym momencie w jednym z modułów np. Jinja2 w wersji 2.10 wykryto lukę bezpieczeństwa (lub błąd), który usunięto w wersji 2.11. Edytujemy plik requirements.txt poprzez zmianę numeru wersji tego modułu, instalujemy ponownie zależności, uruchamiamy testy i jesteśmy gotowi na publikację projektu.
Warto jeszcze nadmienić, że bardzo częstą praktyką jest tworzenie w projekcie oddzielnych zestawów z zależnościami (plików) dla wersji developerskiej, produkcyjnej i dla testów.
Praca z pipenv
Narzędzie pipenv to swojego rodzaju połączenie pip i środowiska wirtualnego. Pipenv pozwala na łatwe zarządzanie środowiskami wirtualnymi i zależnościami wewnątrz nich. Dzięki temu narzędziu nie musimy już oddzielnie używać polecenia pip i venv/virtualenv - wystarczy jedno pelecenie: pipenv.
Pipenv do przechowywania informacji o zależnościach wykorzystuje pliki Pipfile oraz Pipfile.lock. W pliku Pipfile wykorzystywana jest składnia TOML do deklarowania zależności oraz ich źródeł. W pliku Pipfile.lock przechowywane są informacje o deterministycznym zestawie zależności, pozwalające na powtarzalny deployment projektu.
Pipenv jest zewnętrznym modułem Pythona, który instalujemy w globalnym środowisku Pythona:
Teraz dla porównania zrealizujemy ten sam proces pracy co w poprzednim podpunkcie ale z wykorzystaniem pipenv:
Wydaliśmy tylko polecenie instalacji modułu flask, a pipenv wykonał znacznie więcej pracy dla nas. Najpierw sprawdził, czy istniało już środowisko wirtualne (na podstawie nazwy katalogu z projektem). W tym przypadku nie istniało, więc pipenv go utworzył. Kolejnym etapem było utworzenie pliku Pipfile i instalacja zależności. Zobaczmy jak wygląda plik Pipfile po zakończeniu działania polecenia:
Przy instalacji modułu flask nie określiliśmy wersji do instalacji, więc została zainstalowana najnowsza, a w pliku Pifpile jako numer wersji wstawiony został symbol *. Instalacja modułu w konkretnej wersji może być zrealizowana w następujący sposób:
Jeśli potrzebujemy skorzystać z wersji modułu bezpośrednio z github, to mamy taką możliwość:
Aktywowanie utworzonego środowiska projektu odbywa się poprzez polecenie:
Możemy również uruchamiać programy w wirtualnym środowisku z poziomu środowiska globalnego (bez wcześniejszego aktywowania):
Korzystając z Pipenv nie musimy już tworzyć oddzielnych plików z zestawem zależności dla developmentu, produkcji, testów itp. W pliku Pipfile możemy tworzyć odpowiednie sekcje:
Możemy również w łatwy sposób zobaczyć jak wygląda drzewo zależności:
Odinstalowanie modułu umożliwia nam komenda:
Pipenv jako nowoczesne narzędzie umożliwia nam dwukierunkową współpracę z plikami requirements.txt. Jeśli potrzebować będziemy zainstalować zależności na podstawie pliku requirements.txt to możemy zrobić to poleceniem:
W drugą stronę, na podstawie zainstalowanych zależności możemy wygenerować plik requirements.txt:
Przedstawiłem tutaj zaledwie podstawy pracy z Pipenv, mając nadzieję na zachęcenia Was do poznania i wykorzystywania tego coraz bardziej popularnego narzędzia. Sam osobiście stosuję go od jakiegoś czasu w projektach i sprawdza się bardzo dobrze.
Zostaw komentarz