Powrót do strony głównej

Zarządzanie dialogami w Pythonie za pomocą konfiguracji JSON

Przegląd biblioteki dialog-engine do deklaratywnego opisu wieloetapowych dialogów w Pythonie. Artykuł omawia mechanizm warunkowej widoczności, kontekstową nawigację, integrację z aiogram 3 i narzędzia CLI do walidacji konfiguracji.

Wizardy i ankiety w Pythonie: deklaratywna nawigacja
Advertisement 728x90

# Zarządzanie wieloetapowymi dialogami w Pythonie za pomocą konfiguracji JSON

Rozwój ankiet, onboardingów i skomplikowanych wizardów często prowadzi do nagromadzenia logiki warunkowej, którą trudno utrzymywać i skalować. Biblioteka dialog-engine oferuje deklaratywną alternatywę: struktura dialogu, reguły widoczności pól i nawigacja są opisane w JSON lub YAML. Silnik samodzielnie oblicza dostępne kroki na podstawie kontekstu sesji, eliminując konieczność pisania zagnieżdżonych konstrukcji dla każdego scenariusza.

Deklaratywny sposób budowania wizardów

Tradycyjna implementacja formularzy krokowych wymaga jawnego zarządzania stanem. Programista ręcznie śledzi bieżący etap, sprawdza warunki przejścia i formuje interfejs. Przy zmianie logiki biznesowej lub dodaniu nowych gałęzi kod szybko się komplikuje, zamieniając w spaghetti z if i match. dialog-engine odwraca ten proces: dialog staje się zbiorem danych, a nie sekwencją instrukcji.

Plik konfiguracyjny zawiera tablicę kroków. Każdy element definiuje identyfikator, typ wejścia, tekst i opcjonalne parametry walidacji. Silnik nie interpretuje typów pól — text, choice, photo lub niestandardowe wartości pozostają na poziomie konwencji między konfiguracją a warstwą wyświetlania. Dzięki temu ten sam plik można wykorzystać dla bota Telegram, interfejsu webowego lub narzędzia konsolowego.

Google AdInline article slot
{
  "steps": [
    { "id": "name", "type": "text", "text": "What is your name?" },
    { "id": "plan", "type": "choice", "text": "Choose a plan",
      "choices": { "free": "Free", "pro": "Professional" } },
    { "id": "company_inn", "type": "text", "text": "Enter the company tax ID",
      "show_when": { "field": "plan", "equals": "pro" } },
    { "id": "confirm", "type": "text", "text": "Is everything correct? Sending!" }
  ]
}

Instalacja rdzenia nie wymaga zewnętrznych zależności. Dodatkowe moduły podłącza się w miarę potrzeb za pomocą extras, co zachowuje lekką wagę podstawowej dystrybucji.

pip install dialog-engine
pip install dialog-engine[validation,yaml,aiogram]

Mechanizm warunkowej widoczności i nawigacji

Kluczową cechą silnika jest routowanie zależne od kontekstu. Zamiast hardkodowanych przejść używa się słownika z odpowiedziami użytkownika. Na jego podstawie obliczane są indeksy następnego i poprzedniego widocznego kroku. Ukryte etapy są automatycznie pomijane w pasku postępu i logice nawigacji, co gwarantuje poprawny licznik pozycji typu „krok 2 z 3”.

Warunki widoczności określa się za pomocą pól show_when i skip_when. Obsługiwane są podstawowe operatory porównania i sprawdzania istnienia, a także złożone reguły any_of i all_of do realizacji skomplikowanej logiki biznesowej. Reguły można zagnieżdżać bez ograniczeń głębokości.

Google AdInline article slot
{
  "skip_when": {
    "any_of": [
      { "field": "plan", "equals": "free" },
      { "field": "age", "lt": 18 }
    ]
  }
}

Python API dostarcza metody do pracy z indeksami i pozycjami. Pozwala to precyzyjnie kontrolować stan sesji bez ręcznego przeszukiwania warunków.

ctx = {"plan": "free"}
next_idx = engine.next_index(1, ctx)
prev_idx = engine.previous_index(3, ctx)
pos = engine.effective_position(next_idx, ctx)
total = engine.effective_total(ctx)

if engine.is_last_visible(next_idx, ctx):
    # Complete dialog
    ...

Do trwałości sesji przewidziano klasę DialogSessionState, która serializuje bieżący indeks i kontekst do JSON. Ułatwia to przechowywanie stanu w Redis lub relacyjnych bazach danych między żądaniami użytkownika.

Integracja z aiogram 3 i obsługa callbacków

Rdzeń biblioteki jest agnostyczny wobec frameworków, ale dla ekosystemu Telegram przygotowano gotowe pomocniki. Generują one klawiatury inline, automatycznie oznaczają wybrane wartości i tworzą poprawne callback_data. Obsługa kliknięć jest typowana i oddziela logikę wyboru, pominięcia i powrotu.

Google AdInline article slot
from dialog_engine.integrations.aiogram import (
    build_step_keyboard,
    parse_choice_callback,
    is_named_callback,
    KeyboardCallbacks,
)

step = engine.get_step(current_index)
kb = build_step_keyboard(step, translate, show_back=True, current_value=ctx.get(step.id))
await message.answer(step.text, reply_markup=kb)

Rozbiór przychodzących callbacków odbywa się za pomocą parserów, które zwracają identyfikator kroku i wybrane wartość. Eliminuje to konieczność ręcznego parsowania stringów callback.data i zmniejsza ryzyko kolizji prefiksów.

@router.callback_query()
async def on_callback(callback: CallbackQuery):
    cb = KeyboardCallbacks()
    pair = parse_choice_callback(callback.data, cb)
    if pair:
        step_id, choice_key = pair
        ctx[step_id] = choice_key
        next_idx = engine.next_index(current_index, ctx)
        ...

Narzędzia CLI i walidacja konfiguracji

Obsługa deklaratywnych konfiguracji wymaga narzędzi analizy statycznej. Dostarczany CLI pozwala sprawdzać strukturę pliku pod kątem duplikatów identyfikatorów, uszkodzony linków i błędów składniowych przed uruchomieniem aplikacji. Tryb ścisły używa Pydantic do pełnej weryfikacji typów.

  • dialog-engine validate wizard.json — podstawowa weryfikacja struktury.
  • dialog-engine validate --strict wizard.json — walidacja przez Pydantic.
  • dialog-engine mermaid wizard.json — generowanie diagramu przejść do dokumentacji.
  • dialog-engine schema > dialog.schema.json — eksport JSON Schema do autouzupełniania w IDE.
  • dialog-engine init -o my-dialog.json — tworzenie szablonu nowego dialogu.

Wbudowanie walidacji w potok CI/CD gwarantuje, że niepoprawne konfiguracje nie trafią do produkcji. JSON Schema zapewnia podświetlenie składni i podpowiedzi w edytorach kodu, co obniża próg wejścia dla menedżerów produktów i analityków edytujących ankiety.

Co ważne

  • Dialog opisuje się deklaratywnie w JSON/YAML, co oddziela logikę biznesową od kodu aplikacji i pozwala edytować scenariusze bez wdrożenia.
  • Nawigacja i widoczność kroków obliczane są dynamicznie na podstawie kontekstu sesji, eliminując zagnieżdżone konstrukcje warunkowe.
  • Integracja z aiogram 3 dostarcza gotowe generatory klawiatur i typowane parsery callbacków, skracając ilość boilerplate-kodu.
  • Narzędzia CLI i JSON Schema zapewniają statyczną weryfikację konfiguracji i wygodną pracę w IDE.
  • Biblioteka dystrybuowana jest na licencji source-available: użycie w projektach dozwolone, modyfikacja i redystrybucja kodu źródłowego ograniczona.

— Editorial Team

Advertisement 728x90

Czytaj dalej