Appka, která bude na povel klikat za vás [zdarma]

Appka, která bude na povel klikat za vás [zdarma]

Taky vás někdy napadlo vytvořit si robota, který bude pracovat za vás? A který by se ideálně spouštěl v pravidelných intervalech? V tomto článku proberu postup, jak si vytvořit jednoduchou appku, která poběží na always free AWS cloudu.

Při brouzdání na twitteru jsem narazil na super tweet od Jakuba Čížka, který píše články pro Živě.cz a zmiňuje možnost vyzkoušet si serverless python. Doporučuji ho sledovat na twitteru, je to takový novodobý kutil.

V tu chvíli se mi zrodila myšlenka si vytvořit taky svou appku, měl jsem nápad na vytvoření webové automatizace, která by mi uvolnila ruku v mé pracovní rutině. Tímto článkem bych chtěl předejít dlouhým debuggováním, kterým jsem si sám prošel a zjednodušit tak cestu pro automatizaci. Zároveň ukázat cestu, jak si usnadnit workflow pomocí GPT.

Výběr serverless řešení

Existuje x služeb, které AWS nabízí v kategorii Always Free, nyní budu popisovat AWS Lambda. Samozřejmě mají své limity a kapacity, ale pro osobní účely naprosto dostačujicí.

Terminologie a trocha teorie (nutné, jinak se ztratíte):

  • Function - funkce je prostředí, kde si můžete nechat rozběhnout kód podobně jako ve VS code editoru
  • Layer - jedná se o nadstavbu pro Function, slouží pro instalaci libraries nebo dalších dependencies, které jsou potřeba pro rozběhnutí kódu. V našem případě python knihovny. Note: namísto command instalace slouží právě tyto layery.
  • Bucket - možnost, kde se dají ukládat soubory > 50 MB. Některé .zip files je potřeba ukládat přes S3 Bucket, není to nic jiného než storage. Vygeneruje dokonce URL, z které se dá daný soubor stáhnout nebo napojit na další AWS služby.

Jak to funguje?

  1. Je potřeba si založit AWS account, který si napárujete na kreditku. Pozor, dojde sice ke stržení 1 dolaru, ale během několika pracovních dnů je částka vrácena zpět na účet. I když je služba free, je potřeba projít tímto krokem.
  2. Přejít na service AWS Lambda a kutilství může začít:) Vytvořit si první funkci, první layers a zkoušet testovat kód, jestli funguje správně.
Serverless Function, FaaS Serverless - AWS Lambda - AWS
AWS Lambda is a serverless compute service for running code without having to provision or manage servers. You pay only for the compute time you consume.

Návod a doporučení, jak si vytvořit první automatizaci

Prerequisites:

  • jednoduchá práce s terminálem
  • benefitem je VS code nebo jiný obdobný nástroj
  • promptování s gpt

Nejprve odkážu na tento návod na YT, který popisuje celý postup a z kterého také čerpám. Pro automatizaci se využívá Selenium, který se používá zejména pro testování appek, ale dá se využít i pro automatizaci, jelikož testy jsou ve své podstatě také automatizované.

Odkládám cheat sheet na terminál:

Ponaučení při vytváření automatice

Jakmile budete začínat s terminálem, je důležité si zvolit správnou verzi pythonu. Novější verze nemusí být kompatabilní se Seleniem nebo Chromedriverem, odzkoušenou cestu mám (v době psaní článku) přes Python 3.7 (stejná verze je i ve videu), zkoušel jsem i novější 3.9, ale AWSku se to nelíbilo.

Jakmile půjdete vytvářet appku, je potřeba si dát pozor, aby verze pythonu seděla s vytvořenou Function a Layers. Konkrétně při selectu Compatible Runtimes.

Při orientaci v prostředí jsem měl tendenci hledat terminál i tam. Není vyloženě potřeba, stačí klikat na Test tlačítko a po několika iteracích ladit kód. Test by mohli přejmenovat na Run, protože plní stejnou funkci:) Deploy pak slouží pro nasazení kódu na produkci, ze kterého se provadí testy.

Příklad python kódu pro odzkoušení, jestli appka funguje správně:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

def main(event, context):
    options = Options()
    options.binary_location = '/opt/headless-chromium'
    options.add_argument('--headless')
    options.add_argument('--no-sandbox')
    options.add_argument('--single-process')
    options.add_argument('--disable-dev-shm-usage')

    driver = webdriver.Chrome('/opt/chromedriver',chrome_options=options)
    driver.get('<https://www.google.com/>')

    driver.close();
    driver.quit();

    response = {
        "statusCode": 200,
        "body": "Appka úspěšně nainstalována!"
    }

    return response

Také je dobré si dát pozor na metodu procesu v podobě Handler name, jelikož bez správného pojmenování se nemusí dohledat jednotlivé moduly definované v kódu. Můj příklad:

Handler: main.main

Jakmile se podaří rozeběhnout základní kód je čas se pustit do psaní automatizace. Pro tuto část se mi nejvíce osvědčil moje pravá ruka GPT. Svoji automatizaci jsem stavěl na interním CMSku, kdy mě nebavilo neustále spouštět jedno tlačítlo (build). Jeden klik = řádek kódu, který za vás provede appka. Pokud je stránka za loginem, je potřeba automatizaci vybudouvat od přihlášení k účtu. Princip kódu je takový, že se vyhledá dané místo na stránce pomocí HTML kódu a následně se provede určitá akce (klik, vyplnění formuláře atd.).

Názorný příklad moji automatizace:

def main(event, context):
    options = Options()
    options.binary_location = '/opt/headless-chromium'
    options.add_argument('--headless')
    options.add_argument('--no-sandbox')
    options.add_argument('--single-process')
    options.add_argument('--disable-dev-shm-usage')

    driver = webdriver.Chrome('/opt/chromedriver',chrome_options=options)
   
    #here i can insert selenium code
    driver.get("<https://URL.com>")
    sso_button = driver.find_element(By.XPATH, "//button[contains(text(), 'Button SSO')]")
    sso_button.click()

    # Fill in the username and password fields
    ###username_field = driver.find_element(By.XPATH, "//input[@placeholder='Username or email address']")
    username_field = driver.find_element(By.ID, "UserName")
    username_field.send_keys("ZDE JE USERNAME")
    password_field = driver.find_element(By.ID, "Password")
    password_field.send_keys("HESLO NEREKNU")

    # Click the "Log in" button
    login_button = driver.find_element(By.XPATH, "//button[@type='submit']")
    login_button.click()
    driver.implicitly_wait(5)
    # Click on the "Configuration" link
    config_menu_item = driver.find_element(By.XPATH, "//span[@class='title' and text()='Configuration']")
    config_menu_item.click()

    driver.implicitly_wait(5)

    deploy_menu_item = driver.find_element(By.XPATH, "//span[@class='title' and text()='Deployment']")
    deploy_menu_item.click()
    
    driver.implicitly_wait(5)
    
    azure_menu_item = driver.find_element(By.XPATH, "//span[@class='title' and text()='Azure release']")
    azure_menu_item.click()

    css_selector = "a[href='/blabla/blabla']"

    # Find the button by XPath and click it
    stage_button = driver.find_element(By.CSS_SELECTOR, css_selector)
    stage_button.click()

    driver.close();
    driver.quit();

Test, test, test a appka je na světě. Pokud chcete jít dál a appku spouštět dle určitého patternu nebo časovat spuštění appky, slouží pro to opět služba od AWS Amazon EventBridge: https://aws.amazon.com/eventbridge/. Vytvoříte si pravidlo, kdy a kde se má spustit appka a následně provede proces za vás.

Budu rád za sdílení a zpětnou vazbu:)