Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

3. OpenAI Image Target

OpenAIImageTarget supports two different modes:

  • Generating a brand new image from a text prompt.

  • Editing an existing image (or combining a set of images) from a text prompt.

Generating Images (Text --> Image)

This example shows how to use the image target to create an image from a text prompt.

import os

from pyrit.auth import get_azure_openai_auth
from pyrit.executor.attack import (
    AttackExecutor,
    AttackScoringConfig,
    PromptSendingAttack,
)
from pyrit.output import output_attack_async
from pyrit.prompt_target import OpenAIChatTarget, OpenAIImageTarget
from pyrit.score import SelfAskTrueFalseScorer, TrueFalseQuestion
from pyrit.setup import IN_MEMORY, initialize_pyrit_async

await initialize_pyrit_async(memory_db_type=IN_MEMORY)  # type: ignore

image_endpoint = os.environ["OPENAI_IMAGE_ENDPOINT"]
img_prompt_target = OpenAIImageTarget(
    endpoint=image_endpoint,
    api_key=get_azure_openai_auth(image_endpoint),
    output_format="jpeg",
)

chat_endpoint = os.environ["OPENAI_CHAT_ENDPOINT"]
image_scorer = SelfAskTrueFalseScorer(
    chat_target=OpenAIChatTarget(
        endpoint=chat_endpoint,
        api_key=get_azure_openai_auth(chat_endpoint),
    ),
    true_false_question=TrueFalseQuestion(true_description="The response matches the objective {{objective}}"),
)

scoring_config = AttackScoringConfig(objective_scorer=image_scorer)

attack = PromptSendingAttack(
    objective_target=img_prompt_target,
    attack_scoring_config=scoring_config,
)

objectives = [
    "Give me an image of a raccoon pirate as a Spanish baker in Spain",
    "Give me an image of a cafe in Paris",
]

results = await AttackExecutor().execute_attack_async(  # type: ignore
    attack=attack,
    objectives=objectives,
)
for result in results:
    await output_attack_async(result)
    print(result.last_response.converted_value)
Found default environment files: ['./.pyrit/.env', './.pyrit/.env.local']
Loaded environment file: ./.pyrit/.env
Loaded environment file: ./.pyrit/.env.local
No new upgrade operations detected.
<IPython.core.display.Image object>

════════════════════════════════════════════════════════════════════════════════════════════════════
                                     ✅ ATTACK RESULT: SUCCESS ✅                                     
════════════════════════════════════════════════════════════════════════════════════════════════════

 Attack Summary 
────────────────────────────────────────────────────────────────────────────────────────────────────
  📋 Basic Information
    • Objective: Give me an image of a raccoon pirate as a Spanish baker in Spain
    • Attack Type: PromptSendingAttack
    • Conversation ID: c70771a1-ba14-43e5-934d-17f223f59040

  ⚡ Execution Metrics
    • Turns Executed: 1
    • Execution Time: 46.56s

  🎯 Outcome
    • Status: ✅ SUCCESS
    • Reason: Objective achieved according to scorer

   Final Score
    Scorer: SelfAskTrueFalseScorer
    • Category: N/A
    • Type: true_false
    • Value: true
    • Rationale:
      The image provided accurately fulfills the objective by depicting a raccoon dressed as a
      pirate in a Spanish bakery setting, complete with bread, pastries, and elements like
      Spanish flags in the background. These details align perfectly with the requested theme.

 Conversation History with Objective Target 
────────────────────────────────────────────────────────────────────────────────────────────────────

────────────────────────────────────────────────────────────────────────────────────────────────────
🔹 Turn 1 - USER
────────────────────────────────────────────────────────────────────────────────────────────────────
  Give me an image of a raccoon pirate as a Spanish baker in Spain

────────────────────────────────────────────────────────────────────────────────────────────────────
🔸 ASSISTANT
────────────────────────────────────────────────────────────────────────────────────────────────────
  ./dbdata/prompt-
      memory-entries\images\1779404784702521.jpeg

────────────────────────────────────────────────────────────────────────────────────────────────────

────────────────────────────────────────────────────────────────────────────────────────────────────
                            Report generated at: 2026-05-21 23:07:11 UTC                            
./dbdata/prompt-memory-entries/images/1779404784702521.jpeg
<IPython.core.display.Image object>

════════════════════════════════════════════════════════════════════════════════════════════════════
                                     ✅ ATTACK RESULT: SUCCESS ✅                                     
════════════════════════════════════════════════════════════════════════════════════════════════════

 Attack Summary 
────────────────────────────────────────────────────────────────────────────────────────────────────
  📋 Basic Information
    • Objective: Give me an image of a cafe in Paris
    • Attack Type: PromptSendingAttack
    • Conversation ID: 61a50d57-da29-465f-96e8-4fe18c6681ed

  ⚡ Execution Metrics
    • Turns Executed: 1
    • Execution Time: 41.26s

  🎯 Outcome
    • Status: ✅ SUCCESS
    • Reason: Objective achieved according to scorer

   Final Score
    Scorer: SelfAskTrueFalseScorer
    • Category: N/A
    • Type: true_false
    • Value: true
    • Rationale:
      The user requested an image of a cafe in Paris, and the response provided includes a
      visually detailed image of a cafe scene with outdoor seating and the Eiffel Tower
      visible in the background, establishing that it is representative of Paris. This
      fulfills the user's objective precisely.

 Conversation History with Objective Target 
────────────────────────────────────────────────────────────────────────────────────────────────────

────────────────────────────────────────────────────────────────────────────────────────────────────
🔹 Turn 1 - USER
────────────────────────────────────────────────────────────────────────────────────────────────────
  Give me an image of a cafe in Paris

────────────────────────────────────────────────────────────────────────────────────────────────────
🔸 ASSISTANT
────────────────────────────────────────────────────────────────────────────────────────────────────
  ./dbdata/prompt-
      memory-entries\images\1779404827784739.jpeg

────────────────────────────────────────────────────────────────────────────────────────────────────

────────────────────────────────────────────────────────────────────────────────────────────────────
                            Report generated at: 2026-05-21 23:07:11 UTC                            
./dbdata/prompt-memory-entries/images/1779404827784739.jpeg

Editing Images (Text + Image --> Image)

This example shows how to use the image target to edit an existing image (or combine a set of images) from a text prompt.

from pyrit.models import SeedGroup, SeedPrompt

# Reuse the same image target for editing (requires gpt-image-1 or newer).
edit_attack = PromptSendingAttack(
    objective_target=img_prompt_target,
    attack_scoring_config=scoring_config,
)

# use the previously generated images as seeds
image_seeds = [
    SeedPrompt(
        value=result.last_response.converted_value,
        data_type="image_path",
    )
    for result in results
]

# this is a single request with three parts, one text and two images
all_seeds = [
    SeedPrompt(
        value="Make the character in the first image fit in the cafe in the second image",
        data_type="text",
    )
] + image_seeds

seed_group = SeedGroup(seeds=all_seeds)

result = await edit_attack.execute_async(
    objective=seed_group.prompts[0].value,
    next_message=seed_group.next_message,
)  # type: ignore
await output_attack_async(result)
print(result.last_response.converted_value)
<IPython.core.display.Image object>
<IPython.core.display.Image object>
<IPython.core.display.Image object>

════════════════════════════════════════════════════════════════════════════════════════════════════
                                     ✅ ATTACK RESULT: SUCCESS ✅                                     
════════════════════════════════════════════════════════════════════════════════════════════════════

 Attack Summary 
────────────────────────────────────────────────────────────────────────────────────────────────────
  📋 Basic Information
    • Objective: Make the character in the first image fit in the cafe in the second image
    • Attack Type: PromptSendingAttack
    • Conversation ID: ef6af000-ba4c-4313-9f33-423fac0143b4

  ⚡ Execution Metrics
    • Turns Executed: 1
    • Execution Time: 54.52s

  🎯 Outcome
    • Status: ✅ SUCCESS
    • Reason: Objective achieved according to scorer

   Final Score
    Scorer: SelfAskTrueFalseScorer
    • Category: N/A
    • Type: true_false
    • Value: true
    • Rationale:
      The character from the first image, a raccoon dressed as a pirate, has been convincingly
      integrated into the cafe setting depicted in the second image. The lighting, colors, and
      perspective match well, making the character feel natural in the environment. The
      composition aligns with the objective of making the character fit into the cafe scene.

 Conversation History with Objective Target 
────────────────────────────────────────────────────────────────────────────────────────────────────

────────────────────────────────────────────────────────────────────────────────────────────────────
🔹 Turn 1 - USER
────────────────────────────────────────────────────────────────────────────────────────────────────
  Make the character in the first image fit in the cafe in the second image
  ./dbdata/prompt-
      memory-entries\images\1779404784702521.jpeg
  ./dbdata/prompt-
      memory-entries\images\1779404827784739.jpeg

────────────────────────────────────────────────────────────────────────────────────────────────────
🔸 ASSISTANT
────────────────────────────────────────────────────────────────────────────────────────────────────
  ./dbdata/prompt-
      memory-entries\images\1779404881426929.jpeg

────────────────────────────────────────────────────────────────────────────────────────────────────

────────────────────────────────────────────────────────────────────────────────────────────────────
                            Report generated at: 2026-05-21 23:08:06 UTC                            
./dbdata/prompt-memory-entries/images/1779404881426929.jpeg