pyrit.scenarios.ScenarioStrategy#

class ScenarioStrategy(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]#

Bases: Enum

Base class for attack strategies with tag-based categorization and aggregation.

This class provides a pattern for defining attack strategies as enums where each strategy has a set of tags for flexible categorization. It supports aggregate tags (like “easy”, “moderate”, “difficult” or “fast”, “medium”) that automatically expand to include all strategies with that tag.

Tags: Flexible categorization system where strategies can have multiple tags (e.g., {“easy”, “converter”}, {“difficult”, “multi_turn”})

Subclasses should define their enum members with (value, tags) tuples and override the get_aggregate_tags() classmethod to specify which tags represent aggregates that should expand.

Convention: All subclasses should include ALL = (“all”, {“all”}) as the first aggregate member. The base class automatically handles expanding “all” to include all non-aggregate strategies.

The normalization process automatically: 1. Expands aggregate tags into their constituent strategies 2. Excludes the aggregate tag enum members themselves from the final set 3. Handles the special “all” tag by expanding to all non-aggregate strategies

__init__(*args, **kwds)#

Methods

get_aggregate_tags()

Get the set of tags that represent aggregate categories.

get_strategies_by_tag(tag)

Get all attack strategies that have a specific tag.

get_all_strategies()

Get all non-aggregate strategies for this strategy enum.

get_aggregate_strategies()

Get all aggregate strategies for this strategy enum.

normalize_strategies(strategies)

Normalize a set of attack strategies by expanding aggregate tags.

prepare_scenario_strategies([strategies, ...])

Prepare and normalize scenario strategies for use in a scenario.

supports_composition()

Indicate whether this strategy type supports composition.

validate_composition(strategies)

Validate whether the given strategies can be composed together.

Attributes

tags

Get the tags for this attack strategy.

classmethod get_aggregate_strategies() list[T][source]#

Get all aggregate strategies for this strategy enum.

This method returns only the aggregate markers (like ALL, EASY, MODERATE, DIFFICULT) that are used to group concrete strategies by tags.

Returns:

List of all aggregate strategies.

Return type:

list[T]

Example

>>> # Get all aggregate strategies for a strategy enum
>>> aggregates = FoundryStrategy.get_aggregate_strategies()
>>> # Returns: [ALL, EASY, MODERATE, DIFFICULT]
classmethod get_aggregate_tags() Set[str][source]#

Get the set of tags that represent aggregate categories.

Subclasses should override this method to specify which tags are aggregate markers (e.g., {“easy”, “moderate”, “difficult”} for complexity-based scenarios or {“fast”, “medium”} for speed-based scenarios).

The base class automatically includes “all” as an aggregate tag that expands to all non-aggregate strategies.

Returns:

Set of tags that represent aggregates.

Return type:

Set[str]

classmethod get_all_strategies() list[T][source]#

Get all non-aggregate strategies for this strategy enum.

This method returns all concrete attack strategies, excluding aggregate markers (like ALL, EASY, MODERATE, DIFFICULT) that are used for grouping.

Returns:

List of all non-aggregate strategies.

Return type:

list[T]

Example

>>> # Get all concrete strategies for a strategy enum
>>> all_strategies = FoundryStrategy.get_all_strategies()
>>> # Returns: [Base64, ROT13, Leetspeak, ..., Crescendo]
>>> # Excludes: ALL, EASY, MODERATE, DIFFICULT
classmethod get_strategies_by_tag(tag: str) Set[T][source]#

Get all attack strategies that have a specific tag.

This method returns concrete attack strategies (not aggregate markers) that include the specified tag.

Parameters:

tag (str) – The tag to filter by (e.g., “easy”, “converter”, “multi_turn”).

Returns:

Set of strategies that include the specified tag, excluding

any aggregate markers.

Return type:

Set[T]

classmethod normalize_strategies(strategies: Set[T]) Set[T][source]#

Normalize a set of attack strategies by expanding aggregate tags.

This method processes a set of strategies and expands any aggregate tags (like EASY, MODERATE, DIFFICULT or FAST, MEDIUM) into their constituent concrete strategies. The aggregate tag markers themselves are removed from the result.

The special “all” tag is automatically supported and expands to all non-aggregate strategies.

Parameters:

strategies (Set[T]) – The initial set of attack strategies, which may include aggregate tags.

Returns:

The normalized set of concrete attack strategies with aggregate tags

expanded and removed.

Return type:

Set[T]

classmethod prepare_scenario_strategies(strategies: Sequence[T | ScenarioCompositeStrategy] | None = None, *, default_aggregate: T | None = None) List[ScenarioCompositeStrategy][source]#

Prepare and normalize scenario strategies for use in a scenario.

This helper method simplifies scenario initialization by: 1. Handling None input with sensible defaults 2. Auto-wrapping bare ScenarioStrategy instances into ScenarioCompositeStrategy 3. Expanding aggregate tags (like EASY, ALL) into concrete strategies 4. Validating compositions according to the strategy’s rules

This eliminates boilerplate code in scenario __init__ methods.

Parameters:
  • strategies (Sequence[T | ScenarioCompositeStrategy] | None) – The strategies to prepare. Can be a mix of bare strategy enums and composite strategies. If None, uses default_aggregate to determine defaults.

  • default_aggregate (T | None) – The aggregate strategy to use when strategies is None. Common values: MyStrategy.ALL, MyStrategy.EASY. If None when strategies is None, raises ValueError.

Returns:

Normalized list of composite strategies ready for use.

Return type:

List[ScenarioCompositeStrategy]

Raises:

ValueError – If strategies is None and default_aggregate is None, or if compositions are invalid according to validate_composition().

classmethod supports_composition() bool[source]#

Indicate whether this strategy type supports composition.

By default, strategies do NOT support composition (only single strategies allowed). Subclasses that support composition (e.g., FoundryStrategy) should override this to return True and implement validate_composition() to enforce their specific rules.

Returns:

True if composition is supported, False otherwise.

Return type:

bool

property tags: set[str]#

Get the tags for this attack strategy.

Tags provide a flexible categorization system, allowing strategies to be classified along multiple dimensions (e.g., by complexity, type, or technique).

Returns:

The tags (e.g., {“easy”, “converter”, “encoding”}).

Return type:

set[str]

classmethod validate_composition(strategies: Sequence[T]) None[source]#

Validate whether the given strategies can be composed together.

The base implementation checks supports_composition() and raises an error if composition is not supported and multiple strategies are provided.

Subclasses that support composition should override this method to define their specific composition rules (e.g., “no more than one attack strategy”).

Parameters:

strategies (Sequence[T]) – The strategies to validate for composition.

Raises:

ValueError – If the composition is invalid according to the subclass’s rules. The error message should clearly explain what rule was violated.

Examples

# EncodingStrategy doesn’t support composition (uses default) >>> EncodingStrategy.validate_composition([EncodingStrategy.Base64, EncodingStrategy.ROT13]) ValueError: EncodingStrategy does not support composition. Each strategy must be used individually.

# FoundryStrategy allows composition but with rules >>> FoundryStrategy.validate_composition([FoundryStrategy.Crescendo, FoundryStrategy.MultiTurn]) ValueError: Cannot compose multiple attack strategies: [‘crescendo’, ‘multi_turn’]