REFACTOR: Promote backend service & CLI client defaults to ClassVar - #1971
Closed
Roman Lutz (romanlutz) wants to merge 1 commit into
Closed
Conversation
Moves hard-coded `limit` defaults across `pyrit/backend/services/*.py` and `pyrit/cli/api_client.py` from method signatures (and one module-level constant in `scenario_run_service.py`) onto their owning class as `ClassVar` constants, using the sentinel-default pattern (`limit: int | None = None` + `if limit is None: limit = self.DEFAULT_LIST_LIMIT`). Also promotes the CLI client's `60.0` request timeout to `PyRITApiClient.DEFAULT_REQUEST_TIMEOUT`. No value changes. No behaviour changes. Verified: ruff / ty / pytest tests/unit/backend tests/unit/cli (876 passed). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Richard Lundeen (rlundeen2)
approved these changes
Jun 9, 2026
Contributor
Author
|
Closing per maintainer feedback on the constants-audit work. This PR introduced the sentinel-default pattern (changing Branch left intact in case any portion is worth cherry-picking later. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
REFACTOR: Promote backend service & CLI client defaults to ClassVar
PR B-6 of the constants-audit cleanup, following the pattern established
in #1964 (backend / registry / setup) and #1965 (prompt_converter).
What changed
Promotes hard-coded numeric defaults across
pyrit/backend/services/*.pyand
pyrit/cli/api_client.pyfrom method signatures (and one module-levelconstant) onto their owning class as
ClassVarconstants, per thestyle-guide rule
that constants live on the owning class, not at module scope.
Because Python signature defaults can't reference class attributes, the
defaults use the sentinel pattern:
Backend services (
pyrit/backend/services/)attack_service.pylist_attacks_async(limit=20)→AttackService.DEFAULT_LIST_LIMIT = 20initializer_service.pylist_initializers_async(limit=50)→InitializerService.DEFAULT_LIST_LIMIT = 50scenario_service.pylist_scenarios_async(limit=50)→ScenarioService.DEFAULT_LIST_LIMIT = 50scenario_run_service.pylist_runs(limit=100)→ScenarioRunService.DEFAULT_LIST_LIMIT = 100; module-level_DEFAULT_MAX_CONCURRENT_RUNS = 3→ScenarioRunService.DEFAULT_MAX_CONCURRENT_RUNS = 3(constructor +get_scenario_run_service()factory updated to reference it)target_service.pylist_targets_async(limit=50)→TargetService.DEFAULT_LIST_LIMIT = 50CLI client (
pyrit/cli/api_client.py)request_timeout=None⇒60.0literalPyRITApiClient.DEFAULT_REQUEST_TIMEOUT = 60.0list_scenarios_async(limit=200)PyRITApiClient.DEFAULT_LIST_LIMIT = 200list_initializers_async(limit=200)DEFAULT_LIST_LIMIT(same value)list_targets_async(limit=200)DEFAULT_LIST_LIMIT(same value)list_scenario_runs_async(limit=100)PyRITApiClient.DEFAULT_SCENARIO_RUNS_LIST_LIMIT = 100(different value, named specifically)Test update
tests/unit/backend/test_scenario_run_service.pyswapped the now-removedmodule-level
_DEFAULT_MAX_CONCURRENT_RUNSimport forScenarioRunService.DEFAULT_MAX_CONCURRENT_RUNS.Out of scope
pyrit/backend/middleware/,target_service.py:_AZURE_ML_SCOPE,converter_service.py:_DATA_TYPE_EXTENSION— already covered by REFACTOR: Promote single-class module constants to ClassVar (backend + registry + setup) #1964._CONVERTER_CLASS_REGISTRY,_TARGET_CLASS_REGISTRY),_SIMPLE_TYPES, hostname-suffix tuplesin
target_service.py— explicitly skipped per the audit rules(cross-module / import-time registries stay at module scope).
httpx.Timeout(connect=10.0, read=None, write=30.0, pool=10.0)inget_scenario_run_async— internal method-specific tuning, not aconfigurable default.
No behaviour change
Pure structural rename. Same literal values, just moved onto the owning
class. The sentinel pattern preserves the public signature behaviour
exactly: passing nothing still selects the documented default; passing
an explicit value (including the old default) still works.
Verification
uv run --link-mode=copy ruff check pyrit/backend/ pyrit/cli/ tests/unit/backend/ tests/unit/cli/✅ All checks passeduv run --link-mode=copy ty check pyrit/backend/ pyrit/cli/— only a single pre-existing diagnostic inscenario_run_service.py:505(updated_at=scenario_result.completion_timereported asdatetime | Nonevsdatetime); identical issue exists onmain(line shifted by the ClassVar additions), unrelated to this PRuv run --link-mode=copy pytest tests/unit/backend/ tests/unit/cli/ -x --no-header -q✅ 876 passed, 5 skipped