Serwis w Pythonie postawiony obok WordPressa może być rozsądną decyzją architektoniczną. Może też zmienić jedną wdrażalną aplikację w system rozproszony z powodów sprowadzających się do preferencji językowych.
Właściwe pytanie nie brzmi, czy Python potrafi więcej niż PHP. Oba ekosystemy umożliwiają walidację danych, generowanie plików, wywoływanie API i pracę w tle. Trzeba ustalić, czy wąski, dobrze zdefiniowany proces korzysta z bibliotek, modelu wykonania albo kompetencji zespołu w Pythonie na tyle, aby uzasadnić kolejny runtime, wdrożenie, obszar awarii i granicę zaufania.
Po zbudowaniu produkcyjnych mostów WordPress + FastAPI wokół administracji WooCommerce okazało się, że ten koszt operacyjny ma większe znaczenie niż porównania frameworków. Python zasługiwał na miejsce, gdy pozostawał warsztatem do jednego zdefiniowanego zadania. Stawał się obciążeniem, gdy zaczynał dublować odpowiedzialności WordPressa.
W jednym mostku modele Pydantic łapały uszkodzone dane produktów, które PHP tolerowało przez miesiące, a openpyxl generował wieloarkuszowy XLSX trudny do odtworzenia w PHP. W innym asyncio utrzymywało kilkadziesiąt równoległych wywołań REST bez blokowania żądania z panelu, ale dopiero po ograniczeniu współbieżności, bo nasycenie PHP-FPM pojawiło się wcześniej niż limit po stronie Pythona. To uzasadniało Pythona. Dodatkowe wdrożenie, przechowywanie replay i testy kontraktu były ceną.
Kiedy osobny serwis w Pythonie ma sens
Najlepsi kandydaci mają jasne wejście, wyjście i właściciela:
- generowanie dużego albo mocno formatowanego pliku XLSX.
- walidacja i transformacja importowanego zbioru przed zapisem w WordPressie.
- wywołanie biblioteki danych lub ML typowej dla Pythona, np. pandas albo scikit-learn.
- koordynowanie długiego procesu operatorskiego, który nie powinien pozostawać w jednym żądaniu HTTP.
WordPress powinien pozostać źródłem prawdy dla produktów, zamówień, użytkowników, uprawnień i reguł biznesowych. Sidecar powinien tworzyć artefakt, zweryfikowaną propozycję albo wąsko zdefiniowane polecenie. „Zbudujmy lepszy panel w Pythonie” nie ma granic. „Sprawdź ten plik importu produktów i zwróć raport błędów” ma.
Przed dodaniem serwisu warto porównać go z rozwiązaniami natywnymi. Endpointy batch WooCommerce zmniejszają narzut żądań, ale nadal ograniczają paczkę do około 100 pozycji i wykonują osobne aktualizacje zamiast jednej transakcji bazy danych. Action Scheduler zapewnia obserwowalną kolejkę zadań WordPress dla pracy, którą można podzielić na ponawialne akcje. Razem często eliminują potrzebę osobnego runtimeu, zwłaszcza przy importach, które muszą pozostać idempotentne i odzyskiwalne.
Sidecar staje się przekonujący, gdy operacji nie da się sensownie podzielić, zależy od biblioteki typowej dla Pythona albo wymaga izolacji od limitów żądań WordPressa. Nawet wtedy korzyścią jest izolacja. Python nie jest automatycznie szybszy, a kod mocno obciążający CPU może nadal wymagać wielu procesów lub rozszerzeń natywnych.
Walidacja danych i kontrolowana współbieżność
W naszych projektach modele Pydantic nadawały kontraktowi danych jawną postać. Odrzucały uszkodzone dane produktów przed logiką biznesową i generowały użyteczną dokumentację schematu. Było to wartościowe, ale nie niedostępne dla PHP. Trasy REST WordPressa obsługują osobne callbacki walidacji i sanityzacji, a dojrzały kod PHP może egzekwować równie ścisłe schematy.
Przewagą była spójność na granicy integracji: jeden model opisywał dane akceptowane przez serwis w Pythonie, a testy kontraktowe sprawdzały, czy WordPress tworzy ten sam kształt. To ta sama zasada co zamiana walidacji w wykonywalną bramkę jakości zamiast konwencji, o której muszą pamiętać osoby robiące review.
Asynchroniczne I/O wymaga podobnej precyzji. Klient w Pythonie może utrzymywać kilka żądań REST WordPressa jednocześnie bez przydzielania osobnego wątku Pythona każdemu żądaniu. Nie usuwa jednak pracy po stronie WordPressa. Każde równoległe wywołanie nadal zużywa zasoby PHP i bazy danych.
Użytecznym wzorcem jest kontrolowana współbieżność:
- ogranicz liczbę żądań w locie za pomocą semafora.
- używaj paginacji lub tras batch zamiast setek pojedynczych wywołań.
- stosuj timeouty i ograniczoną liczbę ponowień.
- zwalniaj po odpowiedziach
429i5xx. - mierz nasycenie PHP-FPM i opóźnienie bazy przed zwiększeniem równoległości.
Jeden proces Pythona może sprawnie koordynować pracę. Nie zmieni źródłowego WordPressa w backend o nieograniczonej przepustowości.
Jak bezpiecznie ponawiać przerwane operacje
Gdy dwa systemy uczestniczą w jednym procesie, najgroźniejszym przypadkiem nie jest czysty błąd. Jest nim częściowy sukces: Python wygenerował plik, ale WordPress dostał timeout przed zapisaniem wyniku, albo WordPress przyjął aktualizację, a sidecar ją powtórzył, bo nie otrzymał odpowiedzi.
Proces należy zaprojektować jako maszynę stanów, a nie łańcuch wywołań HTTP:
- WordPress zapisuje job z
request_idwwp_optionsalbo własnej tabeli. - Sidecar zwraca
202 Acceptedz tym samymrequest_id. - Stany przechodzą jawnie:
pending→running→succeeded|failed. - Retry z tym samym
request_idodczytuje istniejący wynik albo bezpiecznie wznawia pracę. - Zapisy biznesowe idą przez wąski endpoint WordPress z deduplikacją.
Idempotencja jest ważniejsza niż dostarczenie dokładnie raz, którego HTTP i kolejki zadań nie zapewniają automatycznie. Powtórzone polecenie „ustaw cenę produktu na 20” może być bezpieczne. Powtórzone „odejmij 5 ze stanu magazynowego” nie jest bezpieczne bez identyfikatora operacji i deduplikacji.
Te same zasady własności dotyczą pracy w tle. Długie zadania potrzebują trwałego stanu uruchomienia i chronionych przejść, a nie transientu, który jedynie przypomina blokadę. Ten fragment projektu opisuje model blokady i trwałego stanu dla zadań WordPress.
Sposób uwierzytelniania zależy od rodzaju połączenia
Dla standardowych tras REST WordPressa Application Passwords są wbudowanym mechanizmem zdalnego uwierzytelniania. Używaj HTTPS, dedykowanego użytkownika z minimalnym zestawem uprawnień i poświadczenia, które można niezależnie unieważnić. Sprawdzają się przy wywołaniach sidecara do oficjalnych tras REST WordPressa albo WooCommerce. Własna przestrzeń nazw mostu zwykle wymaga osobnego tokena bearer albo schematu HMAC.
Dla własnej przestrzeni nazw mostu rozsądne są dwa popularne podejścia:
Bearer token o wysokiej entropii (losowy sekret). Jest prosty we wdrożeniu i rotacji. Jego uprawnienia ogranicza permission_callback endpointu, dlatego przestrzeń nazw powinna być wąska, a jeden sekret nie powinien otwierać całego API WooCommerce. Nie przekazuj sidecarowi kluczy REST WooCommerce (ck_/cs_). Otwierają całą powierzchnię /wc/v3 każdemu, kto je posiada. Uprawnienia mostu powinny być tak wąskie, jak wymaga funkcja.
Żądanie podpisane HMAC. Podpisuj kanoniczną reprezentację metody, ścieżki, znacznika czasu, request_id lub nonce oraz skrótu treści. Weryfikuj podpis porównaniem odpornym na analizę czasu. Odrzucaj stare znaczniki czasu i zapisuj każde zużyte request_id albo nonce w Redis, własnej tabeli albo opcji WordPress z TTL. Bez tego magazynu replay przechwycone wywołanie można wysłać ponownie w dozwolonym oknie czasowym. Samo sprawdzenie podpisu nie wystarczy.
HMAC nie usuwa potrzeby TLS, autoryzacji, rotacji ani przechowywania ochrony przed replay. Sam WordPress ostrzega, że jego wbudowane nonce nie zapewniają uwierzytelniania ani jednorazowej ochrony przed powtórzeniem. Własny nonce HMAC musi być faktycznie jednorazowy, jeśli projekt polega na tej właściwości.
Każdy endpoint WordPressa musi uwierzytelnić wywołującego i autoryzować operację. Trasa z permission_callback => '__return_true' jest publiczna niezależnie od kontroli wykonywanych gdzie indziej przez serwis w Pythonie.
Jeśli przeglądarka wywołuje sidecar bezpośrednio, powinna otrzymać krótkotrwały token przekazania ograniczony do konkretnego odbiorcy, a nie długowieczne poświadczenie między serwerami. CORS staje się wtedy potrzebny, ale CORS jest polityką przeglądarki, nie uwierzytelnianiem. Most działający wyłącznie serwer-serwer nie potrzebuje szerokiej listy CORS.
Drugi serwis oznacza dodatkowe obowiązki operacyjne
Widoczna aplikacja w Pythonie może być mała. Jej powierzchnia produkcyjna nie jest. Integracja dodaje:
- runtime albo kontener Pythona i nadzorcę procesu.
- budowanie zależności oraz aktualizacje bezpieczeństwa.
- konfigurację reverse proxy i timeoutów.
- sprawdzenia stanu, logi, metryki i alerty.
- dystrybucję oraz rotację sekretów.
- identyfikatory korelacji między PHP, Pythonem i zadaniami w tle.
- reguły backupu i odzyskiwania dla stanu należącego do sidecara.
Powstają też wersjonowane kontrakty. Niezależne wdrażanie WordPressa i Pythona oznacza, że jedna strona może wysłać dane, których druga już nie rozumie. Addytywne zmiany schematów, jawne wersje API, testy kompatybilności i plan rollbacku są ważniejsze niż wybór między FastAPI a Flaskiem.
Stan sesji i zadań wymaga jawnej decyzji o przechowywaniu. Jedna globalna operacja może zmieścić się w opcji WordPressa bez autoloadu. Wiele równoległych zadań zwykle uzasadnia własną tabelę z indeksowanym statusem, właścicielem i terminem wygaśnięcia. JSON na dysku jest dopuszczalny tylko dla jednego procesu na pojedynczym trwałym hoście. Redis lub Postgres ma sens, gdy wiele replik potrzebuje wspólnego stanu albo infrastruktura już istnieje. Żaden wybór nie jest poprawny zawsze.
Najważniejsze ograniczenie brzmi: stan ma jednego właściciela. Kopiowanie zmiennego stanu zadania do WordPressa i Pythona tworzy problem uzgadniania jeszcze przed wdrożeniem funkcji.
Najpierw wykorzystaj możliwości samego WordPressa
Sidecar zwykle nie jest dobrym pierwszym ruchem dla:
- jednego wolnego wywołania zewnętrznego API, które Action Scheduler może ponowić.
- własnych tras REST mapujących się bezpośrednio na API WordPressa.
- procesów mocno związanych z postami, terminami, polami ACF, użytkownikami lub hookami WooCommerce.
- zespołów, które nie mogą monitorować i wdrażać drugiego serwisu produkcyjnego.
Wolne zewnętrzne API nie uzasadnia automatycznie Pythona. Zacznij od kolejki w tle, aby żądanie administratora szybko się kończyło. Dodaj sidecar dopiero wtedy, gdy narzędzia dostępne w Pythonie, duża liczba operacji I/O albo silniejsza izolacja zmieniają rachunek ekonomiczny.
Głębokie operacje WordPressa to jeszcze wyraźniejszy sygnał, że sidecar nie pasuje. Odtwarzanie zachowania wp_insert_post(), taksonomii, hooków metadanych i cyklu życia WooCommerce przez REST tworzy długi ogon brakującej semantyki. Niech WordPress wykonuje te zapisy. Sidecar powinien wysłać polecenie albo zweryfikowany wynik, a nie udawać wnętrze WordPressa.
Który framework wybrać do integracji z WordPressem
FastAPI dobrze pasuje do tego wzorca, ponieważ typowane modele żądań, generowanie OpenAPI i obsługa async wspierają serwisy oparte na kontrakcie. Flask wystarcza dla małego synchronicznego mostu. Django może mieć sens, jeśli sidecar posiada rozbudowaną domenę i bazę danych, ale jest to też sygnał, aby sprawdzić, czy nadal mówimy o sidecarze.
Framework nie rozwiązuje ryzyk architektonicznych. Mała aplikacja FastAPI może nadal mieć zbyt szerokie uprawnienia, niebezpieczne ponowienia i stan rozdzielony między dwie bazy. Prosty endpoint Flask może być niezawodny, jeśli jego kontrakt i model awarii są zdyscyplinowane.
Serwis powinien być mały pod względem odpowiedzialności, nie tylko liczby linii:
- jeden powód do niezależnego wdrażania.
- brak zduplikowanego źródła prawdy.
- wąskie polecenia wracające do WordPressa.
- ograniczona współbieżność.
- obserwowalna i idempotentna obsługa awarii.
Kluczowa decyzja: który system jest za co odpowiedzialny
Użyj sidecara w Pythonie, gdy wąski proces wyraźnie korzysta z ekosystemu Pythona albo izolacji procesu, a zespół jest gotowy utrzymywać kolejny serwis. Rekord biznesowy i reguły specyficzne dla WordPressa pozostaw w WordPressie. Kontrakt API, ponowienia, uwierzytelnianie i ścieżkę odzyskiwania traktuj jako rdzeń funkcji.
Nie dodawaj Pythona dlatego, że PHP wydaje się niemodne albo demonstracja async wygląda czyściej. Serwis jest uzasadniony tylko wtedy, gdy odpowiedzialność zdjęta z WordPressa jest większa i stabilniejsza niż praca nad systemem rozproszonym, którą wprowadza.