Browser automation agents with Pydantic AI and Playwright

pamelafox1 pts0 comments

Browser automation with Pydantic AI + Playwright

Thursday, August 20, 2026

Browser automation with Pydantic AI + Playwright

When we build agents, we often want to give them the ability to browse the web: open webpages, navigate from one page to the other, and read the content of a webpage. By combining Pydantic AI with the Playwright capability from Pydantic AI Harness, we can build agents that browse the web safely and programmatically.

Using Pydantic AI with Microsoft Foundry models

Pydantic AI is an open-source model-agnostic framework from Pydantic for building LLM-based applications and agents. It's type-safe and supports OpenTelemetry, making it a great choice for robust production applications.

We can use Pydantic-AI with Microsoft Foundry models using either API keys or Entra token-based authentication. When possible, we always recommend the keyless route, so that's what we'll demonstrate here.

We use the azure-identity package to authenticate with Entra, using either local or managed identity, and get back a token provider callback function for that credential:

from azure.identity.aio import AzureDeveloperCliCredential, get_bearer_token_provider

credential = AzureDeveloperCliCredential()<br>token_provider = get_bearer_token_provider(credential,<br>"https://cognitiveservices.azure.com/.default")

Then we use the OpenAI package to configure the model connection:

from openai import AsyncOpenAI

client = AsyncOpenAI(<br>base_url=os.environ["AZURE_OPENAI_ENDPOINT"] + "/openai/v1",<br>api_key=token_provider,<br>model = OpenAIChatModel(<br>model_name=os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT"],<br>provider=OpenAIProvider(openai_client=client),

Let's explain the options used above:

base_url: We point this at the OpenAI-compatible endpoint for our Foundry model. This endpoint works for Azure OpenAI models (like gpt-5.4, which this project deploys), and for cross-provider Foundry models that support the OpenAI v1 API, like Kimi-K2.7-Code. The base URL looks like "https://AZURE_OPENAI_SERVICE_NAME.openai.azure.com/openai/v1".

api_key: We pass in the token provider callback function that generates OAuth2 tokens using our Entra credential. If we were using API keys, we'd simply pass in the key string here instead.

model_name: We provide the name of the deployment, not the name of the model. Oftentimes, the deployment name is the same as the model, but not always - it depends on how you set it up in the Portal or infrastructure-as-code files. Notably, when using models on Foundry, you must always make an explicit deployment for the desired model, before you can use it.

Integrating Playwright capability

Playwright is a browser automation library. It was originally built for writing E2E tests to verify website correctness, and is still the best option for E2E tests today. Its browser automation capabilities also make it a powerful way to give an agent access to websites. When you yourself are developing a website, it's a great way to give the agent access to browse the website, do manual QA, and iterate on design improvements. We can also use Playwright to access other websites, as long as the website's terms permit programmatic access.

To integrate Pydantic AI with Playwright, we bring in the PlaywrightBrowser capability from pydantic-ai-harness, a library of additional capabilities for Pydantic AI agents.

from pydantic_ai_harness.playwright import PlaywrightBrowser

browser = PlaywrightBrowser(<br>allowed_domains=[website_hostname],<br>block_private_addresses=True,<br>headless=False,<br>max_content_tokens=30000,<br>action_timeout_ms=5_000,<br>navigation_timeout_ms=30_000,<br>screenshot_on_navigate=False,<br>auto_install_chromium=False,<br>Let's break down those parameters:

allowed_domains: Restricts top-level navigation and data-moving requests (like fetch and XHR) to the specified hostnames. This prevents unexpected navigation and data transfer, keeping the agent’s scenario targeted.

block_private_addresses: By default, this option is set to True to prevent navigation to localhost and private or reserved IP addresses, even when that address appears in allowed_domains. Set it to False only when the agent needs explicit access to a trusted locally deployed application.

headless: By default, Playwright will run in headless mode, which means that the browser window is not visible. When developing, I often set this to False, since it can be helpful to actually watch Playwright control the browser.

max_content_tokens: This option limits the amount of webpage text returned to the agent. This defaults to 4000 tokens, so I increased it to 30,000 tokens to allow for longer webpages. Keep in mind that the amount of content returned will increase the usage of the context window, affecting both performance and latency of subsequent LLM calls.

action_timeout_ms and navigation_timeout_ms: Actions like clicking or typing and page navigations get separate deadlines, since they fail for different reasons. A click on a selector that does not exist...

pydantic playwright browser openai from model

Related Articles