pyrit.scenario.ScenarioCompositeStrategy#

class ScenarioCompositeStrategy(*, strategies: Sequence[ScenarioStrategy])[source]#

Bases: object

Represents a composition of one or more attack strategies.

This class encapsulates a collection of ScenarioStrategy instances along with an auto-generated descriptive name, making it easy to represent both single strategies and composed multi-strategy attacks.

The name is automatically derived from the strategies: - Single strategy: Uses the strategy’s value (e.g., “base64”) - Multiple strategies: Generates “ComposedStrategy(base64, rot13)”

Example

>>> # Single strategy composition
>>> single = ScenarioCompositeStrategy(strategies=[FoundryStrategy.Base64])
>>> print(single.name)  # "base64"
>>>
>>> # Multi-strategy composition
>>> composed = ScenarioCompositeStrategy(strategies=[
...     FoundryStrategy.Base64,
...     FoundryStrategy.ROT13
... ])
>>> print(composed.name)  # "ComposedStrategy(base64, rot13)"
__init__(*, strategies: Sequence[ScenarioStrategy]) None[source]#

Initialize a ScenarioCompositeStrategy.

The name is automatically generated based on the strategies.

Parameters:

strategies (Sequence[ScenarioStrategy]) – The sequence of strategies in this composition. Must contain at least one strategy.

Raises:

ValueError – If strategies list is empty.

Example

>>> # Single strategy
>>> composite = ScenarioCompositeStrategy(strategies=[FoundryStrategy.Base64])
>>> print(composite.name)  # "base64"
>>>
>>> # Multiple strategies
>>> composite = ScenarioCompositeStrategy(strategies=[
...     FoundryStrategy.Base64,
...     FoundryStrategy.Atbash
... ])
>>> print(composite.name)  # "ComposedStrategy(base64, atbash)"

Methods

__init__(*, strategies)

Initialize a ScenarioCompositeStrategy.

extract_single_strategy_values(composites, ...)

Extract strategy values from single-strategy composites.

get_composite_name(strategies)

Generate a descriptive name for a composition of strategies.

normalize_compositions(compositions, *, ...)

Normalize strategy compositions by expanding aggregates while preserving concrete compositions.

Attributes

is_single_strategy

Check if this composition contains only a single strategy.

name

Get the name of the composite strategy.

strategies

Get the list of strategies in this composition.

static extract_single_strategy_values(composites: Sequence[ScenarioCompositeStrategy], *, strategy_type: type[T]) Set[str][source]#

Extract strategy values from single-strategy composites.

This is a helper method for scenarios that don’t support composition and need to filter or map strategies by their values. It flattens the composites into a simple set of strategy values.

This method enforces that all composites contain only a single strategy. If any composite contains multiple strategies, a ValueError is raised.

Parameters:
  • composites (Sequence[ScenarioCompositeStrategy]) – List of composite strategies. Each composite must contain only a single strategy.

  • strategy_type (type[T]) – The strategy enum type to filter by.

Returns:

Set of strategy values (e.g., {“base64”, “rot13”, “morse_code”}).

Return type:

Set[str]

Raises:

ValueError – If any composite contains multiple strategies.

static get_composite_name(strategies: Sequence[ScenarioStrategy]) str[source]#

Generate a descriptive name for a composition of strategies.

For single strategies, returns the strategy’s value. For multiple strategies, generates a name like “ComposedStrategy(base64, rot13)”.

Parameters:

strategies (Sequence[ScenarioStrategy]) – The strategies to generate a name for.

Returns:

The generated composite name.

Return type:

str

Raises:

ValueError – If strategies is empty.

Example

>>> # Single strategy
>>> name = ScenarioCompositeStrategy.get_composite_name([FoundryStrategy.Base64])
>>> # Returns: "base64"
>>>
>>> # Multiple strategies
>>> name = ScenarioCompositeStrategy.get_composite_name([
...     FoundryStrategy.Base64,
...     FoundryStrategy.Atbash
... ])
>>> # Returns: "ComposedStrategy(base64, atbash)"
property is_single_strategy: bool#

Check if this composition contains only a single strategy.

property name: str#

Get the name of the composite strategy.

static normalize_compositions(compositions: List[ScenarioCompositeStrategy], *, strategy_type: type[T]) List[ScenarioCompositeStrategy][source]#

Normalize strategy compositions by expanding aggregates while preserving concrete compositions.

Aggregate strategies are expanded into their constituent individual strategies. Each aggregate expansion creates separate single-strategy compositions. Concrete strategy compositions are preserved together as single compositions.

This method also validates compositions according to the strategy’s rules via validate_composition().

Parameters:
  • compositions (List[ScenarioCompositeStrategy]) – List of composite strategies to normalize.

  • strategy_type (type[T]) – The strategy enum type to use for normalization and validation.

Returns:

Normalized list of composite strategies with aggregates expanded.

Return type:

List[ScenarioCompositeStrategy]

Raises:

ValueError – If compositions is empty, contains empty compositions, mixes aggregates with concrete strategies in the same composition, has multiple aggregates in one composition, or violates validate_composition() rules.

Example:

# Aggregate expands to individual strategies
[ScenarioCompositeStrategy(strategies=[EASY])]
-> [ScenarioCompositeStrategy(strategies=[Base64]),
    ScenarioCompositeStrategy(strategies=[ROT13]), ...]

# Concrete composition preserved
[ScenarioCompositeStrategy(strategies=[Base64, Atbash])]
-> [ScenarioCompositeStrategy(strategies=[Base64, Atbash])]

# Error: Cannot mix aggregate with concrete in same composition
[ScenarioCompositeStrategy(strategies=[EASY, Base64])] -> ValueError
property strategies: List[ScenarioStrategy]#

Get the list of strategies in this composition.