kimsia
kimsia5mo ago

[Solved] Browser automation self-hosted: python example for initial login

i have a use case where i need to login to substack manually using my username and password. then followed by my TOTP MFA code. once that's done, i want the rest of the browser automation take over in terms of downloading invoices. I found https://www.windmill.dev/docs/advanced/browser_automation but the examples are all not python. I used claude and tried
import os
from playwright.sync_api import sync_playwright
import wmill

# You can import any PyPi package.
# See here for more info: https://www.windmill.dev/docs/advanced/dependencies_in_python

# you can use typed resources by doing a type alias to dict
# postgresql = dict


def main():
with sync_playwright() as p:
browser = p.chromium.launch(executable_path="/usr/bin/chromium")

page = browser.new_page()
page.goto("https://google.com")

title = page.title()

browser.close()

return title
import os
from playwright.sync_api import sync_playwright
import wmill

# You can import any PyPi package.
# See here for more info: https://www.windmill.dev/docs/advanced/dependencies_in_python

# you can use typed resources by doing a type alias to dict
# postgresql = dict


def main():
with sync_playwright() as p:
browser = p.chromium.launch(executable_path="/usr/bin/chromium")

page = browser.new_page()
page.goto("https://google.com")

title = page.title()

browser.close()

return title
what happens is
Error: BrowserType.launch: Failed to launch chromium because executable doesn't exist at /usr/bin/chromium
File "/tmp/windmill/wk-default-6f5cff974f78-sYQ4l/019102ae-1ce1-eea8-9b82-0fc2d2ee6b6b/u/kimsia/browser_automate_playwright.py", line 14, in main
browser = p.chromium.launch(executable_path="/usr/bin/chromium")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: BrowserType.launch: Failed to launch chromium because executable doesn't exist at /usr/bin/chromium
File "/tmp/windmill/wk-default-6f5cff974f78-sYQ4l/019102ae-1ce1-eea8-9b82-0fc2d2ee6b6b/u/kimsia/browser_automate_playwright.py", line 14, in main
browser = p.chromium.launch(executable_path="/usr/bin/chromium")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I am running locally using docker in my macOS laptop M1 how do i solve this? I am on the Pro Plan trial period.
11 Replies
Hugo
Hugo5mo ago
Do you have a worker with chromium installed ?
kimsia
kimsiaOP5mo ago
how does that work? do i install it inside the docker image provided by windmill or it's another docker image?
Hugo
Hugo5mo ago
you can uncomment windmill_worker_reports inside the docker compose, it's a worker with the worker group chromium which will install chromium on start
kimsia
kimsiaOP5mo ago
import os
from playwright.sync_api import sync_playwright
import wmill
import sys

# You can import any PyPi package.
# See here for more info: https://www.windmill.dev/docs/advanced/dependencies_in_python

# you can use typed resources by doing a type alias to dict
# postgresql = dict


def main():
try:
with sync_playwright() as p:
browser = p.chromium.launch(
# Remove the executable_path argument
headless=True # Ensure headless mode for Docker environment
)

page = browser.new_page()
page.goto("https://google.com")

title = page.title()

browser.close()

return title
except Exception as e:
print(f"An error occurred: {e}", file=sys.stderr)
return None
import os
from playwright.sync_api import sync_playwright
import wmill
import sys

# You can import any PyPi package.
# See here for more info: https://www.windmill.dev/docs/advanced/dependencies_in_python

# you can use typed resources by doing a type alias to dict
# postgresql = dict


def main():
try:
with sync_playwright() as p:
browser = p.chromium.launch(
# Remove the executable_path argument
headless=True # Ensure headless mode for Docker environment
)

page = browser.new_page()
page.goto("https://google.com")

title = page.title()

browser.close()

return title
except Exception as e:
print(f"An error occurred: {e}", file=sys.stderr)
return None
this is my script when i run it, i get
job=01910d2f-d996-b117-fd0f-896649c60d29 tag=python3 worker=wk-default-d71bb81e0834-pU5Az hostname=d71bb81e0834


--- PYTHON CODE EXECUTION ---

An error occurred: BrowserType.launch: Executable doesn't exist at /root/.cache/ms-playwright/chromium-1124/chrome-linux/chrome
╔════════════════════════════════════════════════════════════╗
║ Looks like Playwright was just installed or updated. ║
║ Please run the following command to download new browsers: ║
║ ║
║ playwright install ║
║ ║
║ <3 Playwright Team ║
╚════════════════════════════════════════════════════════════╝
job=01910d2f-d996-b117-fd0f-896649c60d29 tag=python3 worker=wk-default-d71bb81e0834-pU5Az hostname=d71bb81e0834


--- PYTHON CODE EXECUTION ---

An error occurred: BrowserType.launch: Executable doesn't exist at /root/.cache/ms-playwright/chromium-1124/chrome-linux/chrome
╔════════════════════════════════════════════════════════════╗
║ Looks like Playwright was just installed or updated. ║
║ Please run the following command to download new browsers: ║
║ ║
║ playwright install ║
║ ║
║ <3 Playwright Team ║
╚════════════════════════════════════════════════════════════╝
kimsia
kimsiaOP5mo ago
No description
kimsia
kimsiaOP5mo ago
given my original idea which is that i need to login to substack manually using my username and password. then followed by my TOTP MFA code. once that's done, i want the rest of the browser automation take over in terms of downloading invoices. is that even possible in windmill self-host?
Hugo
Hugo5mo ago
I will investigate tomorrow, typescript should work though
kimsia
kimsiaOP5mo ago
thank you. i am more familiar with python
Hugo
Hugo5mo ago
for your use case, you could try using an approval step in a flow, but you need to find a way to save the browser state in the first step so that you can restart from there in the next step
kimsia
kimsiaOP5mo ago
I don’t understand what you said Can we do a simpler version even if it’s only a fraction of what I said I wanted to do? How about just make chromium worker fetch something from a public web page first when using python? i got the chromium worker going for python
from playwright.sync_api import sync_playwright


def main():
with sync_playwright() as p:
browser = p.chromium.launch(executable_path="/usr/bin/chromium")
page = browser.new_page()
page.goto("https://google.com")

title = page.title()

browser.close()

return title


if __name__ == "__main__":
print(main())
from playwright.sync_api import sync_playwright


def main():
with sync_playwright() as p:
browser = p.chromium.launch(executable_path="/usr/bin/chromium")
page = browser.new_page()
page.goto("https://google.com")

title = page.title()

browser.close()

return title


if __name__ == "__main__":
print(main())
Thank you i will create a separate thread about my bigger question of how to interact with the chromium for login
Hugo
Hugo5mo ago
nice! sorry hadn't had time to look at it