Skip to content

Commit 374ca1a

Browse files
committed
Merge remote-tracking branch 'origin/main' into rlundeen2-cleanup-initializers
# Conflicts: # pyrit/registry/class_registries/initializer_registry.py # pyrit/setup/initialization.py # tests/unit/registry/test_initializer_registry.py # tests/unit/setup/test_technique_initializer.py
2 parents e0df568 + b818290 commit 374ca1a

40 files changed

Lines changed: 1049 additions & 2683 deletions

doc/code/registry/0_registry.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ PyRIT has two registry patterns for different use cases:
1818
| **Class Registry** | Classes (type[T]) | Components instantiated with user-provided parameters |
1919
| **Instance Registry** | Pre-configured instances | Components requiring complex setup before use |
2020

21-
## Common API (RegistryProtocol)
21+
## Common API
2222

23-
Both registry types implement `RegistryProtocol`, sharing a consistent interface:
23+
Registries share a consistent interface for discovery and introspection:
2424

2525
| Method | Description |
2626
|--------|-------------|
@@ -29,14 +29,17 @@ Both registry types implement `RegistryProtocol`, sharing a consistent interface
2929
| `list_metadata()` | Get descriptive metadata for all items |
3030
| `reset_instance()` | Reset the singleton (useful for testing) |
3131

32-
This protocol enables writing code that works with any registry type:
32+
This makes it easy to write code that inspects any registry:
3333

3434
```python
35-
from pyrit.registry import RegistryProtocol
35+
from pyrit.registry import ScenarioRegistry
3636

37-
def show_registry_contents(registry: RegistryProtocol) -> None:
37+
def show_registry_contents(registry) -> None:
3838
for name in registry.get_names():
3939
print(name)
40+
41+
42+
show_registry_contents(ScenarioRegistry.get_registry_singleton())
4043
```
4144

4245

doc/code/registry/1_class_registry.ipynb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"source": [
88
"# Listing Available Classes\n",
99
"\n",
10-
"Use `get_names()` to see what's available, or `list_metadata()` for detailed information."
10+
"Use `get_class_names()` to see what's available, or `get_all_registered_class_metadata()` for detailed information."
1111
]
1212
},
1313
{
@@ -36,11 +36,11 @@
3636
"registry = ScenarioRegistry.get_registry_singleton()\n",
3737
"\n",
3838
"# Get all registered names\n",
39-
"names = registry.get_names()\n",
39+
"names = registry.get_class_names()\n",
4040
"print(f\"Available scenarios: {names[:5]}...\") # Show first 5\n",
4141
"\n",
4242
"# Get detailed metadata\n",
43-
"metadata = registry.list_metadata()\n",
43+
"metadata = registry.get_all_registered_class_metadata()\n",
4444
"for item in metadata[:2]: # Show first 2\n",
4545
" print(f\"\\n{item.class_name}:\")\n",
4646
" print(f\" Description: {item.class_description[:80]}...\")"
@@ -226,11 +226,11 @@
226226
"initializer_registry = InitializerRegistry.get_registry_singleton()\n",
227227
"\n",
228228
"# Get all registered names\n",
229-
"initializer_names = initializer_registry.get_names()\n",
229+
"initializer_names = initializer_registry.get_class_names()\n",
230230
"print(f\"Available initializers: {initializer_names[:5]}...\") # Show first 5\n",
231231
"\n",
232232
"# Get detailed metadata\n",
233-
"for init_item in initializer_registry.list_metadata()[:2]: # Show first 2\n",
233+
"for init_item in initializer_registry.get_all_registered_class_metadata()[:2]: # Show first 2\n",
234234
" print(f\"\\n{init_item.registry_name}:\")\n",
235235
" print(f\" Class: {init_item.class_name}\")\n",
236236
" print(f\" Description: {init_item.class_description[:80]}...\")"

doc/code/registry/1_class_registry.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,19 @@
1111
# %% [markdown]
1212
# # Listing Available Classes
1313
#
14-
# Use `get_names()` to see what's available, or `list_metadata()` for detailed information.
14+
# Use `get_class_names()` to see what's available, or `get_all_registered_class_metadata()` for detailed information.
1515

1616
# %%
1717
from pyrit.registry import ScenarioRegistry
1818

1919
registry = ScenarioRegistry.get_registry_singleton()
2020

2121
# Get all registered names
22-
names = registry.get_names()
22+
names = registry.get_class_names()
2323
print(f"Available scenarios: {names[:5]}...") # Show first 5
2424

2525
# Get detailed metadata
26-
metadata = registry.list_metadata()
26+
metadata = registry.get_all_registered_class_metadata()
2727
for item in metadata[:2]: # Show first 2
2828
print(f"\n{item.class_name}:")
2929
print(f" Description: {item.class_description[:80]}...")
@@ -92,11 +92,11 @@
9292
initializer_registry = InitializerRegistry.get_registry_singleton()
9393

9494
# Get all registered names
95-
initializer_names = initializer_registry.get_names()
95+
initializer_names = initializer_registry.get_class_names()
9696
print(f"Available initializers: {initializer_names[:5]}...") # Show first 5
9797

9898
# Get detailed metadata
99-
for init_item in initializer_registry.list_metadata()[:2]: # Show first 2
99+
for init_item in initializer_registry.get_all_registered_class_metadata()[:2]: # Show first 2
100100
print(f"\n{init_item.registry_name}:")
101101
print(f" Class: {init_item.class_name}")
102102
print(f" Description: {init_item.class_description[:80]}...")

pyrit/backend/services/initializer_service.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ async def list_initializers_async(
6969
Returns:
7070
ListRegisteredInitializersResponse with paginated initializer summaries.
7171
"""
72-
all_metadata = self._registry.list_metadata()
72+
all_metadata = self._registry.get_all_registered_class_metadata()
7373
all_summaries = [_metadata_to_registered_initializer(m) for m in all_metadata]
7474

7575
page, has_more = self._paginate(items=all_summaries, cursor=cursor, limit=limit)
@@ -90,7 +90,7 @@ async def get_initializer_async(self, *, initializer_name: str) -> RegisteredIni
9090
Returns:
9191
RegisteredInitializer if found, None otherwise.
9292
"""
93-
all_metadata = self._registry.list_metadata()
93+
all_metadata = self._registry.get_all_registered_class_metadata()
9494
for metadata in all_metadata:
9595
if metadata.registry_name == initializer_name:
9696
return _metadata_to_registered_initializer(metadata)

pyrit/backend/services/scenario_run_service.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,13 +227,13 @@ async def _run_initializers_async(self, *, request: RunScenarioRequest) -> None:
227227

228228
initializer_registry = InitializerRegistry.get_registry_singleton()
229229
for initializer_name in request.initializers:
230+
initializer_params = (request.initializer_args or {}).get(initializer_name)
230231
try:
231-
initializer_class = initializer_registry.get_class(initializer_name)
232+
instance = initializer_registry.create_and_configure(
233+
initializer_name, initializer_params=initializer_params
234+
)
232235
except KeyError as e:
233236
raise ValueError(f"Initializer not found: {e}") from None
234-
instance = initializer_class()
235-
if request.initializer_args and initializer_name in request.initializer_args:
236-
instance.set_params_from_args(args=request.initializer_args[initializer_name])
237237
await instance.initialize_async()
238238

239239
def _resolve_target(self, *, request: RunScenarioRequest) -> "PromptTarget":

pyrit/registry/__init__.py

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,61 +3,45 @@
33

44
"""Registry module for PyRIT class and object registries."""
55

6-
from pyrit.registry.base import RegistryProtocol
7-
from pyrit.registry.class_registries import (
8-
BaseClassRegistry,
9-
ClassEntry,
10-
InitializerMetadata,
11-
InitializerRegistry,
12-
)
136
from pyrit.registry.components import (
147
AttackTechniqueMetadata,
158
AttackTechniqueRegistry,
169
ConverterMetadata,
1710
ConverterRegistry,
11+
InitializerMetadata,
12+
InitializerRegistry,
1813
ScenarioMetadata,
1914
ScenarioRegistry,
2015
ScorerMetadata,
2116
ScorerRegistry,
2217
TargetMetadata,
2318
TargetRegistry,
2419
)
25-
from pyrit.registry.discovery import (
26-
discover_in_directory,
27-
discover_in_package,
28-
discover_subclasses_in_loaded_modules,
29-
)
20+
from pyrit.registry.discovery import discover_in_directory
3021
from pyrit.registry.instance_registry import (
3122
DefaultInstanceRegistry,
3223
InstanceRegistry,
33-
SupportsInstances,
34-
)
35-
from pyrit.registry.object_registries import (
36-
BaseInstanceRegistry,
3724
RegistryEntry,
25+
SupportsInstances,
3826
)
3927
from pyrit.registry.registry import Registry
28+
from pyrit.registry.registry_metadata import RegistryMetadata
4029
from pyrit.registry.tag_query import TagQuery
4130

4231
__all__ = [
4332
"AttackTechniqueRegistry",
4433
"AttackTechniqueMetadata",
45-
"BaseClassRegistry",
46-
"BaseInstanceRegistry",
4734
"ConverterRegistry",
4835
"ConverterMetadata",
4936
"DefaultInstanceRegistry",
5037
"InstanceRegistry",
5138
"Registry",
39+
"RegistryMetadata",
5240
"SupportsInstances",
53-
"ClassEntry",
5441
"discover_in_directory",
55-
"discover_in_package",
56-
"discover_subclasses_in_loaded_modules",
5742
"InitializerMetadata",
5843
"InitializerRegistry",
5944
"RegistryEntry",
60-
"RegistryProtocol",
6145
"ScenarioMetadata",
6246
"ScenarioRegistry",
6347
"ScorerRegistry",

0 commit comments

Comments
 (0)