Sytuacja kobiet w IT w 2024 roku
22.05.20207 min
Shaked Zychlinski

Shaked ZychlinskiAlgorithm EngineerTaboola

Jak stworzyć pakiet Pythona i wysłać go do PyPI

Dowiedz się, jak przekształcić swój nieużywany kod w pakiet Python w 6 krokach oraz jak opublikować go później na PyPI.

Jak stworzyć pakiet Pythona i wysłać go do PyPI

Wielu z Was napisało pewnie kiedyś kod, który został przez Was uznany za bezużyteczny i leży odłogiem gdzieś na Waszych komputerach. Prawda jest taka, że nie jesteśmy w stanie przewidzieć, co się może przydać innym. Ja sam kiedyś myślałem w taki właśnie sposób — do momentu, w którym napisałem swój pierwszy artykuł związany z Data Science o nazwie The Search for Categorical Correlation

Stworzyłem wtedy i upubliczniłem swój pierwszy pakiet o nazwie Dython (narzędzia Danych dla pYTHONA), który opracowałem właśnie na potrzeby tego artykułu. Szczerze myślałem, że nikomu się to nie przyda, ale na poziomie 1,5 tysiąca pobrań miesięcznie uświadomiłem sobie, że nie wiem tak naprawdę, co się komu może przydać. 

Zachęcam więc do dzielenia się swoim kodem i pomagania innym programistom. Pozwól, że pokażę Ci, jak to osiągnąć w zaledwie 6 krokach. Do roboty!  

Zanim zaczniemy: czyszczenie kodu i kontrola wersji

Myślę, że to dosyć oczywiste, ale chciałbym się jednak upewnić, że wszyscy się rozumiemy. Programiści dzielą się na dwa typy: ci, którzy piszą czytelny kod, i ci, które używają zmiennych o nazwach x, x1, x2, yx itp.

Jeśli należysz do pierwszej grupy, możesz przejść dalej, jeśli do drugiej — czas przejść do tej pierwszej. Pamiętaj, że inne osoby będą czytać Twój kod, więc upewnij się, że jest on czytelny. Nadawaj sensowne nazwy, rozbijaj długie funkcje na metody jednokierunkowe o krótkim kodzie itp.

Zakładam też, że używasz jakiegoś narzędzia do kontroli wersji — najprawdopodobniej Githuba. Chociaż nie jest to wymagane, to jednak wysoce zalecane. Jeśli nigdy wcześniej nie korzystałeś z GitHuba, warto poświęcić kilka minut i dowiedzieć się, jak to zrobić — sprawdź oficjalny samouczek lub ten artykuł i zacznij.

Krok 1: Ustal swoje API

Pierwszym krokiem w przekształcaniu kodu w pakiet jest zdecydowanie, w jaki sposób użytkownicy powinni go używać — i umożliwić im importowanie. Podzielimy to na dwa działania:


#1: Metody publiczne i prywatne

Twój kod prawdopodobnie składa się z kilku funkcji i metod, ale nie wszystkie są do wykorzystania przez użytkowników — niektóre to funkcje wewnętrzne, które powinny być używane tylko przez Twój kod.

Ponieważ Python nie obsługuje metod prywatnych, konwencja polega na oznaczaniu ich podkreślnikiem: def_private_function(). Zmień nazwy wszystkich swoich funkcji wewnętrznych w taki sposób, aby użytkownicy mogli łatwo zrozumieć, czemu służą, a czemu nie. 

Wskazówka: możesz użyć specjalnej zmiennej __all__, aby dokładnie określić, które funkcje mają zostać ujawnione, a które nie, gdy użytkownicy korzystają z from your_package import *. Sprawdź ten wątek na StackOverflow, aby dowiedzieć się więcej.


#2: Dodanie __init__.py

Jeśli Twój kod składa się z kilku modułów (plików), które wyglądają tak:

your_package
  |-- module1.py
  |-- module2.py

Musisz dodać kolejny plik __init__.py do swojego pakietu, aby Python zinterpretował katalog your_package jako pakiet Pythona. Oznacza to, że teraz powinno to wyglądać tak:

your_package
  |-- __init__.py
  |-- module1.py
  |-- module2.py

Na początku możesz stworzyć pusty plik, ale musisz go mieć pod ręką, aby można było zrobić from your_package import module1.

Wskazówka: kod w __init__.py jest wykonywany po zaimportowaniu pakietu, a to pozwala robić różne fajne rzeczy. Możesz, na przykład, użyć __init__.py, aby skrócić swoje API.

Powiedzmy, że najważniejszą metodą Twojego kodu to imp_func z module1. Możesz zezwolić użytkownikom na importowanie jej taką składnią from your_package import imp_func zamiast from your_package.module1 import imp_func, poprzez dodanie:

from .module1 import imp_func

do swojego pliku __init__.py.

Krok 2: Dokumentuj

Istnieją dwa rodzaje dokumentacji, które musisz dodać:


#1: Docstrings

Każda funkcja w bibliotece powinna mieć swój doc-string, który podsumowuje, na czym ona polega. Co powinno zostać zawarte:

  • Podsumowanie: prostym językiem wyjaśnij co Twoja funkcja ma robić
  • Parametry: wyjaśnij, jakie są parametry i typy parametrów, których oczekuje funkcja
  • Zwracana wartość: wyjaśnij, co funkcja zwraca
  • Przykład: chociaż nie jest to konieczne, zawsze warto dodać przykład użycia


Oto przykład: 

def my_sum(x, y):     
    """calculates the sum of x and y.     
    Parameters:     
       x (int): a number
       y (int): another number    
    Returns:     
       int: sum of x and y
    """      
   
   return x+y

Tutaj możesz dowiedzieć się więcej o formatach doc-strings.


#2: Read-Me

Plik Read-Me to podsumowanie tego, czego dotyczy Twój pakiet. Po umieszczeniu na górze katalogu pakietu GitHub używa go jako „strony domowej” pakietu, wyświetlanej odwiedzającym jako pierwsza rzecz, którą widzą.

Dobry Read-Me zawiera opis pakietu, informacje o instalacji (w tym wymagania) i kilka przykładów, opisujących podstawowe użycie pakietu. Pliki Read-Me są zwykle zapisywane w Markdown (o którym możesz dowiedzieć się więcej tutaj), to dlatego zwykle nazywają się README.md.

Krok 3: Licencja

Ponieważ kod zostanie upubliczniony, należy dołączyć do niego licencję, wyjaśniającą innym użytkownikom, w jaki sposób powinni go używać. Najlepsze są licencja MIT lub licencja Apache 2.0.

GitHub może Ci pomóc w wybraniu Licencji. Gdy klikniesz opcję License, do Twojego repozytorium dodany zostanie plik LICENSE. Jeśli nie chcesz używać GitHuba, to możesz dodać plik ręcznie.

Krok 4: Porządki

W tym momencie Twój pakiet powinien wyglądać tak:

your_package  
  |-- README.md 
  |-- LICENSE
  |-- __init__.py
  |-- module1.py
  |-- module2.py

Teraz dodamy plik, który zbuduje instalowalny pakiet Python z twojego kodu. W tym celu musisz dodać nowy plik o nazwie setup.py i zmienić kolejność plików w następujący sposób:

your_package 
  |-- setup.py 
  |-- README.md 
  |-- LICENSE
  |-- your_package
        |-- __init__.py
        |-- module1.py
        |-- module2.py

Plik instalacyjny określa wszystko, co instalator Python powinien wiedzieć. Bardzo prosty plik, do skopiowania, wygląda następująco:

import pathlib
from setuptools import setup, find_packages

HERE = pathlib.Path(__file__).parent

VERSION = '0.1.0'
PACKAGE_NAME = 'your_package'
AUTHOR = 'You'
AUTHOR_EMAIL = '[email protected]'
URL = 'https://github.com/you/your_package'

LICENSE = 'Apache License 2.0'
DESCRIPTION = 'Describe your package in one sentence'
LONG_DESCRIPTION = (HERE / "README.md").read_text()
LONG_DESC_TYPE = "text/markdown"

INSTALL_REQUIRES = [
      'numpy',
      'pandas'
]

setup(name=PACKAGE_NAME,
      version=VERSION,
      description=DESCRIPTION,
      long_description=LONG_DESCRIPTION,
      long_description_content_type=LONG_DESC_TYPE,
      author=AUTHOR,
      license=LICENSE,
      author_email=AUTHOR_EMAIL,
      url=URL,
      install_requires=INSTALL_REQUIRES,
      packages=find_packages()
      )

Oprócz edytowania danych osobowych musisz pamiętać o dwóch rzeczach:

  • Wersja: za każdym razem, gdy wydasz nową wersję PyPI, musisz podbić numer wersji
  • Wymagania instalatora: jest to lista wszystkich zewnętrznych zależności Twojego pakietu. Upewnij się, że wszystko zostało wymienione, aby Python zainstalował je wraz z Twoim pakietem.

Krok 5: Utwórz konto na PyPI

Jesteśmy już prawie na miejscu! Przejdź do pypi.org i utwórz konto. Będziesz go potrzebował do przesłania swojej nowej biblioteki.

Krok 6: Buduj i wysyłaj w świat

Już prawie skończyliśmy. Pozostało uruchomienie komend, które zbudują instalowalny pakiet Pythona z twojego kodu oraz prześlą go do PyPI.

Zanim zaczniemy, musimy zainstalować twine, który pozwoli nam na wgranie pakietu do PyPI. Oto, jak to zrobić:

pip install twine

Następnie utworzymy instalowalny pakiet. Przejdź do katalogu, w którym znajduje się plik setup.py i uruchom:

python setup.py sdist bdist_wheel

Utworzy to kilka nowych katalogów, takich jak dist, build i your_package.egg-info. Zależy nam głównie na dist, ponieważ zawiera pliki instalacyjne, które chcemy wrzucić na PyPI.

Znajdziesz tam dwa pliki: skompresowany plik tar i plik wheel.

Wskazówka: dodaj te katalogi do pliku .gitignore, aby zapobiec wypychaniu plików instalacyjnych do repozytorium (dowiedz się więcej o .gitignore).

Następnie sprawdź, czy utworzone pliki dystrybucyjne są prawidłowe, uruchamiając:

twine check dist/*

Czas wgrać paczkę do PyPI. Zalecam wdrożenie najpierw w domenie testowej PyPI, abyś mógł sprawdzić, czy wszystko jest OK. Zrób to za pomocą:

twine upload --repository-url https://test.pypi.org/legacy/ dist/*

Przejdź do test.pypi.org i sprawdź, czy wszystko jest, jak należy. Jeśli tak, to przejdźmy do prawdziwego PyPI:

twine upload dist/*

To tyle. Od teraz każdy może zainstalować pakiet za pomocą pip install. Dobra robota!

Wskazówka: możesz ułatwić sobie życie za pomocą skryptu Bash, który zbuduje, sprawdzi i wdroży pakiet za pomocą jednego polecenia. Utwórz nowy plik o nazwie build_deploy.sh w tym samym katalogu, co setup.py. Skopiuj i wklej następujący kod do tego pliku:

rm -r dist ;
python setup.py sdist bdist_wheel ;
if twine check dist/* ; then
  if [ "$1" = "--test" ] ; then
    twine upload --repository-url https://test.pypi.org/legacy/ dist/*
  else
    twine upload dist/* ;
  fi
fi

Teraz wystarczy jedynie uruchomić z katalogu, którym znajduje się ten plik:

./build_deploy.sh

Możesz również uruchomić:

./build_deploy.sh --test

aby przesłać go na testową domenę. Pamiętaj, że musisz dodać skryptowi uprawnienia do wykonywania przed uruchomieniem go po raz pierwszy. Uruchom chmod + x build_deploy.sh w katalogu, w którym znajduje się plik.

Napisz artykuł

Twój kod jest teraz dostępny dla wszystkich, ale ludzie nadal o nim nie wiedzą. Jak możesz im dać o nim znać?

Napisz artykuł, w którym opisujesz, dlaczego tworzysz taki kod oraz do czego można go używać. Podziel się swoją historią, a może zaoszczędzisz komuś sporo czasu.

Podsumowanie

Udostępnianie swojego kodu może wydawać się straszne, gdy robi się to po raz pierwszy, bo mamy wątpliwości, czy komuś się w ogóle przyda i nie wiemy, jak to zrobić. Mam nadzieję, że ten artykuł Ci pomoże. Dobra robota i witaj w społeczności open source!

<p>Loading...</p>