Source code for pyrit.prompt_target.playwright_target

# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.

from typing import TYPE_CHECKING, Protocol

from pyrit.models import (
    PromptRequestPiece,
    PromptRequestResponse,
    construct_response_from_request,
)
from pyrit.prompt_target.common.prompt_target import PromptTarget

# Avoid errors for users who don't have playwright installed
if TYPE_CHECKING:
    from playwright.async_api import Page
else:
    Page = None


class InteractionFunction(Protocol):
    """
    Defines the structure of interaction functions used with PlaywrightTarget.
    """

    async def __call__(self, page: "Page", request_piece: PromptRequestPiece) -> str: ...


[docs] class PlaywrightTarget(PromptTarget): """ PlaywrightTarget uses Playwright to interact with a web UI. Parameters: interaction_func (InteractionFunction): The function that defines how to interact with the page. page (Page): The Playwright page object to use for interaction. """
[docs] def __init__( self, *, interaction_func: InteractionFunction, page: "Page", ) -> None: super().__init__() self._interaction_func = interaction_func self._page = page
[docs] async def send_prompt_async(self, *, prompt_request: PromptRequestResponse) -> PromptRequestResponse: self._validate_request(prompt_request=prompt_request) if not self._page: raise RuntimeError( "Playwright page is not initialized. Please pass a Page object when initializing PlaywrightTarget." ) request_piece = prompt_request.request_pieces[0] try: text = await self._interaction_func(self._page, request_piece) except Exception as e: raise RuntimeError(f"An error occurred during interaction: {str(e)}") from e response_entry = construct_response_from_request(request=request_piece, response_text_pieces=[text]) return response_entry
def _validate_request(self, *, prompt_request: PromptRequestResponse) -> None: n_pieces = len(prompt_request.request_pieces) if n_pieces != 1: raise ValueError(f"This target only supports a single prompt request piece. Received: {n_pieces} pieces.") piece_type = prompt_request.request_pieces[0].converted_value_data_type if piece_type != "text": raise ValueError(f"This target only supports text prompt input. Received: {piece_type}.")