Przejdź do treści

Kontrakt skryptu

Ta strona opisuje umowę między Twoim kodem a agentem, który go uruchamia: skąd czytać dane, gdzie zapisywać wyniki, co decyduje o statusie uruchomienia i co zastaniesz w środowisku. Trzymanie się tych zasad jest jedynym warunkiem, żeby automatyzacja działała przewidywalnie.

Skrót tego kontraktu znajdziesz również w panelu, nad listą plików pakietu, w rozwijanej sekcji Jak przygotować skrypt.

Rozwinięta sekcja Jak przygotować skrypt

Ta strona dotyczy agenta webowego

Opisane niżej środowisko odnosi się do automatyzacji o trybie Skrypt Python i agencie wykonującym Web. Agent windowsowy buduje środowisko w inny sposób i rządzi się osobnymi zasadami - dla niego ta sekcja w panelu w ogóle się nie pokazuje.


1. Szkielet skryptu

Poniższy plik zawiera komplet konwencji w jednym miejscu - odczyt danych wejściowych, zapis wyników, użycie zmiennych i wywołanie funkcji głównej.

import os
from pathlib import Path

OUTPUT = Path(os.environ.get("OUTPUT_DIR", "output"))
OUTPUT.mkdir(parents=True, exist_ok=True)


def main():
    # Pliki wgrane jako dane wejściowe leżą w ./input/
    for source in Path("input").glob("*"):
        print("wejscie:", source.name)

    # Zmienne i sekrety ze scenariusza przychodzą jako zwykłe zmienne środowiskowe
    erp_url = os.environ["ERP_URL"]

    # Wszystko, co ma trafić do artefaktów uruchomienia, zapisz do OUTPUT
    (OUTPUT / "raport.txt").write_text(f"gotowe: {erp_url}", encoding="utf-8")


# Bez tego wywołania skrypt tylko zdefiniowałby funkcje i nic by się nie wykonało
if __name__ == "__main__":
    main()

2. Punkt wejścia

Uruchamiany jest wyłącznie plik oznaczony w pakiecie jako punkt wejścia.

  • Punkt wejścia może leżeć w podkatalogu. Skrypt startuje w miejscu, w którym się znajduje, więc importy sąsiedzkie i pakietowe działają tak samo jak lokalnie.
  • Bez oznaczonego punktu wejścia uruchomienie zostanie odrzucone.
  • Skrypt musi coś wywołać. Plik z samymi definicjami funkcji zakończyłby się kodem 0, więc agent odmawia jego uruchomienia: przebieg kończy się niepowodzeniem z opisem przyczyny, zamiast zielonym statusem procesu, który nic nie zrobił.
  • Plik leżący w katalogu z __init__.py uruchamiany jest jako moduł pakietu, więc importy względne również się rozwiązują.

3. Katalogi robocze

Wszystkie ścieżki w kontrakcie są względne katalogu roboczego uruchomienia.

Katalog Rola
input/ Pliki wgrane jako dane wejściowe uruchomienia. Czytaj je ścieżką względną.
output/ Wszystko, co ma trafić do artefaktów uruchomienia.

Zmienna środowiskowa OUTPUT_DIR wskazuje katalog artefaktów wprost, a zawartość ./output jest do niego kopiowana przed wysyłką - działają więc obie drogi. Posługiwanie się zmienną jest pewniejsze:

OUTPUT = Path(os.environ.get("OUTPUT_DIR", "output"))
OUTPUT.mkdir(parents=True, exist_ok=True)

Pliki zapisane poza tymi katalogami przepadają

Plik zapisany pod ścieżką bezwzględną albo w katalogu domowym użytkownika nie zostanie zebrany i zniknie razem ze środowiskiem uruchomienia. To najczęstsza przyczyna sytuacji „robot zadziałał, ale nie ma wyników".


4. Wynik uruchomienia

4.1. Kod wyjścia jest źródłem prawdy

Status uruchomienia bierze się z kodu wyjścia procesu:

Kod wyjścia Status
0 Sukces
cokolwiek innego Niepowodzenie

4.2. Błędy biznesowe

Nie każde niepowodzenie jest awarią robota. Faktura odrzucona przez ERP, kontrahent bez numeru NIP, brak dokumentu w systemie źródłowym - to niepowodzenia biznesowe, które warto odróżnić od błędu technicznego.

W obrazie agenta jest preinstalowany pakiet testto. Wystarczy go zaimportować:

from testto import report_business_error

report_business_error(
    "INVOICE_REJECTED",                       # własny kod błędu (dowolny łańcuch)
    "Faktura odrzucona przez ERP (brak PO)",  # komunikat widoczny w panelu
    retryable=False,                          # podpowiedź dla automatycznych ponowień
    data={"invoice_id": "FV/2026/07/123"},    # opcjonalny ładunek
)

Wywołanie zapisuje plik wyniku i kończy proces błędem. Platforma oznaczy uruchomienie statusem Błąd biznesowy wraz z Twoim kodem i komunikatem.

Parametry:

Parametr Znaczenie
pierwszy argument Kod błędu. Używany również przez politykę automatycznego ponawiania.
drugi argument Komunikat pokazywany w panelu.
retryable Podpowiedź dla polityki ponawiania: czy ten błąd ma sens ponawiać.
data Opcjonalny słownik z dodatkowym kontekstem.

Kod wyjścia wygrywa z plikiem wyniku

Uruchomienie zakończone kodem 0 jest zawsze sukcesem, a plik wyniku zostaje zignorowany. Jeśli zgłaszasz błąd biznesowy samodzielnie, bez pakietu testto, pamiętaj o zakończeniu skryptu kodem różnym od zera.

Wariant bez importu

Nie chcesz zależności od pakietu testto? Zapisz samodzielnie plik output/testto_result.json i zakończ skrypt kodem różnym od zera. Platforma odczyta z niego kod błędu, komunikat i flagę retryable.


5. Zmienne i sekrety

Zmienne zdefiniowane w zakładce Zmienne i sekrety docierają do skryptu jako zwykłe zmienne środowiskowe:

erp_url = os.environ["ERP_URL"]
haslo = os.environ["ERP_PASSWORD"]

Wartość sekretu nie jest zapisywana przy automatyzacji - agent pobiera ją tuż przed startem i zasłania w dzienniku przebiegu. Szczegóły opisuje strona Zmienne i sekrety.


6. Środowisko

Element Co zastaniesz
Python Wersja 3.11 wraz z pip. Instalacja zależności odbywa się dla użytkownika uruchamiającego proces.
Przeglądarka Jest w obrazie. chromium.launch(headless=True) działa bez wskazywania ścieżki do binarki.
Pakiet testto Preinstalowany - służy do zgłaszania błędów biznesowych.

6.1. Przeglądarka

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()
    page.goto("https://example.com")
    browser.close()

Tryb headed nie ma ekranu do dyspozycji

Środowisko agenta nie udostępnia serwera graficznego. Skrypt wymagający pełnej przeglądarki z widocznym oknem musi uruchomić ją pod wirtualnym ekranem we własnym zakresie.


7. Limit czasu

Czas pracy robota ogranicza etap ROBOT_RUNNING. Wartość domyślna obowiązuje wszystkie automatyzacje, ale można ją nadpisać dla pojedynczego procesu w zakładce Ustawienia uruchomień.

Przekroczenie limitu kończy uruchomienie statusem TIMEOUT, a komunikat niesie wartość limitu, który został przekroczony.

Robot pracujący wiele godzin jest trudny w diagnozie i długo blokuje miejsce w kolejce. Jeśli proces z natury trwa długo, rozważ podzielenie go na kilka automatyzacji wywoływanych po kolei - łatwiej wtedy wskazać, na czym się zatrzymał, i powtórzyć tylko brakującą część.


8. Lista kontrolna przed pierwszym uruchomieniem

  1. [ ] Punkt wejścia oznaczony w pakiecie.
  2. [ ] Skrypt wywołuje funkcję główną, a nie tylko ją definiuje.
  3. [ ] Wyniki zapisywane do katalogu z OUTPUT_DIR, nie pod ścieżką bezwzględną.
  4. [ ] Zależności wypisane w requirements.txt albo w bloku pip: manifestu conda.
  5. [ ] Parametry i hasła odczytywane ze zmiennych środowiskowych, nie zapisane w kodzie.
  6. [ ] Niepowodzenia biznesowe zgłaszane przez report_business_error, nie zwykłym wyjątkiem.