Yandex.Cloud жана Python'дун серверсиз функцияларын колдонуу менен Алиса үчүн абалды көрсөтүү жөндөмүн түзүү

Жаңылыктардан баштайлы. Кечээ Yandex.Cloud серверсиз эсептөө сервисин ишке киргизгенин жарыялады Yandex Cloud функциялары. Бул деген: сиз кызматыңыз үчүн кодду гана жазасыз (мисалы, веб-тиркеме же чатбот), булут өзү иштеген жерде виртуалдык машиналарды түзүп, тейлейт, ал тургай жүк көбөйсө, аларды кайталайт. Сиз такыр ойлонуш керек эмес, бул абдан ыңгайлуу. Ал эми төлөм эсептөө убактысы үчүн гана.

Бирок айрымдары такыр төлөбөй коюшу мүмкүн. Булар иштеп чыгуучулар Алисанын тышкы жөндөмдөрү, башкача айтканда, чатботтор ага орнотулган. Ар бир иштеп чыгуучу мындай жөндөмдү жаза алат, кабыл алат жана каттай алат жана бүгүнкү күндөн баштап көндүмдөрдү хостингдин кереги жок - жөн гана өз кодун формада булутка жүктөңүз ошол эле серверсиз функция.

Бирок бир нече нюанстар бар. Биринчиден, сиздин пит кодуңуз кээ бир көз карандылыктарды талап кылышы мүмкүн жана аларды Булутка сүйрөө анчалык деле маанилүү эмес. Экинчиден, кандайдыр бир кадимки чатбот диалогдун абалын бир жерде сакташы керек (демек, абалы); Серверсиз функцияда муну жасоонун эң оңой жолу кайсы? Үчүнчүдөн, кантип Элис үчүн тез жана ыплас жөндөмдү же нөл эмес сюжети бар ботторду кантип жаза аласыз? Макала, чынында, бул нюанстар жөнүндө.

Yandex.Cloud жана Python'дун серверсиз функцияларын колдонуу менен Алиса үчүн абалды көрсөтүү жөндөмүн түзүү

Моралдык даярдык

Чыдабагандар үчүн: Функцияны булутка жүктөөдөн мурун мен керектүү көз карандылыктарды makefile менен чогултам, диалогдун абалын Yandex Object Storage'де сактайм (ал S3 API колдойт) жана диалогду башкаруу үчүн өз китепканамды колдоном. tgalice. Акырында билинет мындай демо чеберчилик. Эми мунун баарын бир аз майда-чүйдөсүнө чейин карап көрөлү.

Бир аз чыдамы жоктор үчүн, менин татаалдык жөнүндө окуяга киришүүдөн мурун, мен жөнөкөй нерседен баштоону сунуштайм. Тактап айтканда, бир файлдуу echobot функциясын түзүп, катталып, аны Dialogs иштеп чыгуучу консолунда сынап көрүңүз; чоо-жайы - in Диалогдор блогу и Булут документтери. Ошондо гана башталат.

Бул жерде эмне үчүн күрөшүп жатканыбызды дароо сезгиңиз келсе, Алисадан сураңыз."IT гороскоп" жөндөмүн иштетүү'. Төмөнкүгө окшош диалог болушу керек:

Алиса: Салам! Сиз "IT Horoscope" чеберчилигиндесиз. Жылдыздар сизге эмнени убада кылып жатканын билүү үчүн "Баштоо" деп айтыңыз.
Колдонуучу: Баштоо
A: Сураныч, атыңызды айтыңыз
Ю: Васисуалий
А: Эми мага туулган жылыңды айт. Төрт гана сан, ашыкча эч нерсе жок.
Ю: экинчи
Ж: Кайталап көрүңүз. Туулган жылыңызды киргизиңиз - төрт сан.
Ю: 2002
Улуу! Эми туулган айыңызды атаңыз.
Ю: февраль
Улуу! Акырында мага туулган күнүңүздү айтыңыз – жөн гана сан, бир же эки цифра.
Ю: 18
А: Рахмат, Васисуалий! Азыр биз билебиз: сиз 17 жаштасыз жана Суу Суучулсуз. Албетте, сен бактылуусуң! Жылдыздар сага мындай дейт: а что говорят звёзды, вы узнаете, запустив навык.

Маселе мындай жөнөкөй диалогду сактап калуу үчүн колдонуучунун атын жана туулган күнүн эстеп калуу керек, ал эми серверсиз функция чөйрөсүндө бул маанилүү эмес. Контекстти RAMда же дискте файл катары сактоо мүмкүн эмес, анткени Yandex.Cloud бир эле учурда бир нече виртуалдык машиналарда функцияны иштетип, алардын ортосунда өз каалоосу боюнча которула алат. Тышкы сактагычтын кандайдыр бир түрүн колдонушуңуз керек болот. Object Storage түздөн-түз Yandex.Cloud'та (б.а., балким, тез) кыйла арзан жана жөнөкөй сактагыч катары тандалган. Акысыз альтернатива катары, мисалы, бекер бөлүккө аракет кыла аласыз Булуттуу Монга алыс жерде. Object Storage (S3 интерфейсин колдойт) жана Mongo үчүн ыңгайлуу Python орогучтары бар.

Дагы бир көйгөй - Object Storage, MongoDB жана башка маалыматтар базасына же маалымат дүкөнүнө кирүү үчүн сизге функция кодуңуз менен бирге Yandex Функцияларына жүктөлүшү керек болгон кээ бир тышкы көз карандылыктар керек. Жана мен муну ыңгайлуу кылгым келет. Тилекке каршы, бул толугу менен ыңгайлуу болбойт (Heroku сыяктуу), бирок чөйрөнү куруу үчүн сценарий жазуу менен кээ бир негизги ыңгайлуулукту түзсө болот (файл түзүү).

Гороскоп чеберчилигин кантип ишке киргизүү керек

  1. Даярдаңыз: Linux менен бир машинага өтүңүз. Негизи, сиз Windows менен да иштей аласыз, бирок андан кийин makefileди ишке киргизүү менен кандайдыр бир сыйкырчылык кылышыңыз керек болот. Кандай болбосун, сизге жок дегенде Python 3.6 орнотулган болушу керек.
  2. Аны Githubдан клондоңуз гороскоп чеберчилигинин мисалы.
  3. Y.Cloud'та катталуу: https://cloud.yandex.ru
  4. Өзүңүзгө эки чака түзүңүз Object сактоо, аларды каалаган ат менен атаңыз {BUCKET NAME} и tgalice-test-cold-storage (бул экинчи ат азыр катуу коддолгон main.py менин мисалым). Биринчи чака жайгаштыруу үчүн гана керек болот, экинчиси - диалог абалын сактоо үчүн.
  5. Түзүү кызмат эсеби, ага роль бер editor, жана ал үчүн статикалык эсептик дайындарды алыңыз {KEY ID} и {KEY VALUE} — биз аларды диалогдун абалын жазуу үчүн колдонобуз. Мунун баары Ya.Cloud функциясы Ya.Cloud сактагычына кире алышы үчүн керек. Бир күнү, мен ишенем, авторизация автоматтык түрдө болот, бирок азыр ушундай.
  6. (Милдеттүү эмес) орнотуу буйрук сабынын интерфейси yc. Функцияны веб-интерфейс аркылуу да түзө аласыз, бирок CLI жакшы, анткени анда бардык инновациялар тезирээк пайда болот.
  7. Эми сиз чындыгында көз карандылыктын жыйындысын даярдай аласыз: аны чеберчиликтин мисалы менен папкадан буйрук сабында иштетиңиз make all. Папкада бир топ китепканалар (негизинен, адаттагыдай, керексиз) орнотулат dist.
  8. Объект сактагычына кол менен куюңуз (чакага {BUCKET NAME}) мурунку кадамда алынган архив dist.zip. Кааласаңыз, муну буйрук сабынан жасай аласыз, мисалы, колдонуу AWS CLI.
  9. Веб интерфейси аркылуу же утилитаны колдонуу менен серверсиз функцияны түзүңүз yc. Утилита үчүн буйрук төмөнкүдөй болот:

yc serverless function version create
    --function-name=horoscope
    --environment=AWS_ACCESS_KEY_ID={KEY ID},AWS_SECRET_ACCESS_KEY={KEY VALUE}
    --runtime=python37
    --package-bucket-name={BUCKET NAME}
    --package-object-name=dist.zip
    --entrypoint=main.alice_handler
    --memory=128M
    --execution-timeout=3s

Функцияны кол менен түзүүдө бардык параметрлер бир эле жол менен толтурулат.

Эми сиз жараткан функцияны иштеп чыгуучунун консолу аркылуу текшерип, андан кийин чеберчиликти өркүндөтүп, жарыялоого болот.

Yandex.Cloud жана Python'дун серверсиз функцияларын колдонуу менен Алиса үчүн абалды көрсөтүү жөндөмүн түзүү

Капоттун астында эмне бар

Makefile чындыгында көз карандылыктарды орнотуу жана аларды архивге салуу үчүн абдан жөнөкөй скриптти камтыйт dist.zip, болжол менен мындай:

mkdir -p dist/
pip3 install -r requirements.txt --target dist/ 
cp main.py dist/main.py
cp form.yaml dist/form.yaml
cd dist && zip --exclude '*.pyc' -r ../dist.zip ./*

Калгандары китепканага оролгон бир нече жөнөкөй куралдар tgalice. Колдонуучунун маалыматтарын толтуруу процесси конфигурацияда сүрөттөлөт form.yaml:

form_name: 'horoscope_form'
start:
  regexp: 'старт|нач(ать|ни)'
  suggests:
    - Старт
fields:
  - name: 'name'
    question: Пожалуйста, назовите своё имя.
  - name: 'year'
    question: Теперь скажите мне год вашего рождения. Только четыре цифры, ничего лишнего.
    validate_regexp: '^[0-9]{4}$'
    validate_message: Пожалуйста, попробуйте ещё раз. Назовите год вашего рождения - четыре цифры.
  - name: 'month'
    question: Замечательно! Теперь назовите месяц вашего рождения.
    options:
      - январь
     ...
      - декабрь
    validate_message: То, что вы назвали, не похоже на месяц. Пожалуйста, назовите месяц вашего рождения, без других слов.
  - name: 'day'
    question: Отлично! Наконец, назовите мне дату вашего рождения - только число, всего одна или две цифры.
    validate_regexp: '[0123]?d$'
    validate_message: Пожалуйста, попробуйте ещё раз. Вам нужно назвать число своего рождения (например, двадцатое); это одна или две цифры.

Бул конфигурацияны талдоо жана акыркы натыйжаны эсептөө ишин Python классы өзүнө алат

class CheckableFormFiller(tgalice.dialog_manager.form_filling.FormFillingDialogManager):
    SIGNS = {
        'январь': 'Козерог',
        ...
    }

    def handle_completed_form(self, form, user_object, ctx):
        response = tgalice.dialog_manager.base.Response(
            text='Спасибо, {}! Теперь мы знаем: вам {} лет, и вы {}. n'
                 'Вот это вам, конечно, повезло! Звёзды говорят вам: {}'.format(
                form['fields']['name'],
                2019 - int(form['fields']['year']),
                self.SIGNS[form['fields']['month']],
                random.choice(FORECASTS),
            ),
            user_object=user_object,
        )
        return response

Тагыраак айтканда, базалык класс FormFillingDialogManager "форманы" толтуруу жана бала класс ыкмасы менен алектенет handle_completed_form ага даяр болгондо эмне кылуу керектигин айтат.

Бул диалогдун негизги агымынан тышкары, колдонуучу да саламдашуу керек, ошондой эле "жардам" буйругун колдонуу менен жардам берип, "чыгуу" буйругун колдонуу менен чеберчиликтен бошотулушу керек. Муну жасоо үчүн tgalice Шаблон да бар, андыктан диалогдун бардык менеджери бөлүктөрдөн турат:

dm = tgalice.dialog_manager.CascadeDialogManager(
    tgalice.dialog_manager.GreetAndHelpDialogManager(
        greeting_message=DEFAULT_MESSAGE,
        help_message=DEFAULT_MESSAGE,
        exit_message='До свидания, приходите в навык "Айтишный гороскоп" ещё!'
    ),
    CheckableFormFiller(`form.yaml`, default_message=DEFAULT_MESSAGE)
)

CascadeDialogManager Ал жөнөкөй иштейт: ал өз кезегинде диалогдун учурдагы абалына өзүнүн бардык компоненттерин колдонууга аракет кылат жана биринчи ылайыктуусун тандап алат.

Диалог менеджери ар бир билдирүүгө жооп катары Python объектисин кайтарат. Response, андан кийин жөнөкөй текстке, же Алиса же Telegramдагы билдирүүгө айландырылат - бот кайда иштеп жатканына жараша; ал ошондой эле сакталышы керек болгон диалогдун өзгөргөн абалын камтыйт. Бул ашкананы башка класс башкарат, DialogConnector, ошондуктан Яндекс Функцияларында чеберчиликти ишке киргизүү үчүн түз скрипт төмөнкүдөй көрүнөт:

...
session = boto3.session.Session()
s3 = session.client(
    service_name='s3',
    endpoint_url='https://storage.yandexcloud.net',
    aws_access_key_id=os.environ['AWS_ACCESS_KEY_ID'],
    aws_secret_access_key=os.environ['AWS_SECRET_ACCESS_KEY'],
    region_name='ru-central1',
)
storage = tgalice.session_storage.S3BasedStorage(s3_client=s3, bucket_name='tgalice-test-cold-storage')
connector = tgalice.dialog_connector.DialogConnector(dialog_manager=dm, storage=storage)
alice_handler = connector.serverless_alice_handler

Көрүнүп тургандай, бул коддун көбү Object Storage S3 интерфейсине байланышты түзөт. Бул байланыш түз кантип колдонуларын окуй аласыз tgalice кодунда.
Акыркы сап функцияны түзөт alice_handler — ошол эле параметрди койгондо Yandex.Cloudка тарткыла деп айтканбыз --entrypoint=main.alice_handler.

Чындыгында, баары ушул. Чогултуу үчүн Makefiles, контекстти сактоо үчүн S3 сыяктуу Object Storage жана Python китепканасы tgalice. Python'дун серверсиз функциялары жана экспрессивдүүлүгү менен айкалышып, бул адамдын дени сак жөндөмүн өнүктүрүү үчүн жетиштүү.

Түзүү эмне үчүн зарыл болгон деп сурасаңыз болот tgalice? JSON файлдарын суроо-талаптан жоопко жана сактагычтан эстутумга жана кайра өткөрүүчү бардык кызыксыз код анда жатат. Ошондой эле үзгүлтүксүз коддуу тиркеме бар, "Февраль" "Февралга" окшош экенин түшүнүү функциясы жана жакырлар үчүн башка NLU. Менин оюмча, бул жетиштүү болушу керек, ошондуктан сиз yaml файлдарындагы көндүмдөрдүн прототиптерин техникалык деталдарга алаксыбай элестете аласыз.

Эгер сиз олуттуураак NLUну кааласаңыз, аны өз чеберчилигиңизге тиркөөңүз болот Даам же ДепПавлов, бирок аларды орнотуу дап менен кошумча бийлерди талап кылат, айрыкча серверсиз. Эгер сиз такыр коддоону каалабасаңыз, анда визуалдык конструкторду колдонушуңуз керек Aimylogic. Tgalice түзүп жатканда, мен кандайдыр бир ортоңку жол жөнүндө ойлондум. Келгиле, мындан эмне болорун карап көрөлү.

Макул, эми кошул Алиса жөндөмдөрүн иштеп чыгуучу чатыокуу документтештирүү, жана сонун жаратат көндүмдөр!

Source: www.habr.com

Комментарий кошуу