Skip to content

Commit 606793e

Browse files
fix(typing): Type pagerduty module (#98075)
1 parent 1d57b68 commit 606793e

File tree

6 files changed

+67
-39
lines changed

6 files changed

+67
-39
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,6 @@ module = [
307307
"sentry.api.endpoints.organization_releases",
308308
"sentry.api.paginator",
309309
"sentry.db.postgres.base",
310-
"sentry.integrations.pagerduty.actions.form",
311310
"sentry.integrations.slack.message_builder.notifications.issues",
312311
"sentry.integrations.slack.webhooks.event",
313312
"sentry.issues.search",
@@ -418,6 +417,7 @@ module = [
418417
"sentry.integrations.jira_server.actions.*",
419418
"sentry.integrations.jira_server.utils.*",
420419
"sentry.integrations.models.integration_feature",
420+
"sentry.integrations.pagerduty.*",
421421
"sentry.integrations.project_management.*",
422422
"sentry.integrations.repository.*",
423423
"sentry.integrations.services.*",

src/sentry/integrations/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ def update_organization_config(self, data: MutableMapping[str, Any]) -> None:
414414
if org_integration is not None:
415415
self.org_integration = org_integration
416416

417-
def get_config_data(self) -> Mapping[str, str]:
417+
def get_config_data(self) -> Mapping[str, Any]:
418418
if not self.org_integration:
419419
return {}
420420
return self.org_integration.config

src/sentry/integrations/pagerduty/actions/form.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from sentry.integrations.pagerduty.metrics import record_event
1111
from sentry.integrations.services.integration import integration_service
1212
from sentry.integrations.types import ExternalProviders
13+
from sentry.utils.forms import set_field_choices
1314

1415

1516
def _validate_int_field(field: str, cleaned_data: Mapping[str, Any]) -> int | None:
@@ -29,28 +30,26 @@ class PagerDutyNotifyServiceForm(forms.Form):
2930
account = forms.ChoiceField(choices=(), widget=forms.Select())
3031
service = forms.ChoiceField(required=False, choices=(), widget=forms.Select())
3132

32-
def __init__(self, *args, **kwargs):
33-
integrations = [(i.id, i.name) for i in kwargs.pop("integrations")]
34-
services = kwargs.pop("services")
33+
def __init__(self, *args: Any, **kwargs: Any) -> None:
34+
self._integrations = [(i.id, i.name) for i in kwargs.pop("integrations")]
35+
self._services = kwargs.pop("services")
3536

3637
super().__init__(*args, **kwargs)
37-
if integrations:
38-
self.fields["account"].initial = integrations[0][0]
38+
if self._integrations:
39+
self.fields["account"].initial = self._integrations[0][0]
3940

40-
self.fields["account"].choices = integrations
41-
self.fields["account"].widget.choices = self.fields["account"].choices
41+
set_field_choices(self.fields["account"], self._integrations)
4242

43-
if services:
44-
self.fields["service"].initial = services[0][0]
43+
if self._services:
44+
self.fields["service"].initial = self._services[0][0]
4545

46-
self.fields["service"].choices = services
47-
self.fields["service"].widget.choices = self.fields["service"].choices
46+
set_field_choices(self.fields["service"], self._services)
4847

4948
def _validate_service(self, service_id: int, integration_id: int) -> None:
5049
with record_event(OnCallInteractionType.VALIDATE_SERVICE).capture() as lifecycle:
5150
params = {
52-
"account": dict(self.fields["account"].choices).get(integration_id),
53-
"service": dict(self.fields["service"].choices).get(service_id),
51+
"account": dict(self._integrations).get(integration_id),
52+
"service": dict(self._services).get(service_id),
5453
}
5554

5655
org_integrations = integration_service.get_organization_integrations(
@@ -77,11 +76,13 @@ def _validate_service(self, service_id: int, integration_id: int) -> None:
7776

7877
def clean(self) -> dict[str, Any] | None:
7978
cleaned_data = super().clean()
79+
if cleaned_data is None:
80+
return cleaned_data
8081

8182
integration_id = _validate_int_field("account", cleaned_data)
8283
service_id = _validate_int_field("service", cleaned_data)
8384

84-
if service_id:
85+
if service_id and integration_id:
8586
self._validate_service(service_id, integration_id)
8687

8788
return cleaned_data

src/sentry/integrations/pagerduty/actions/notification.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from __future__ import annotations
22

33
import logging
4-
from collections.abc import Sequence
5-
from typing import cast
4+
from collections.abc import Generator, Sequence
5+
from typing import Any, TypedDict, cast
66

77
import sentry_sdk
88

@@ -16,20 +16,30 @@
1616
from sentry.integrations.types import IntegrationProviderSlug
1717
from sentry.models.rule import Rule
1818
from sentry.rules.actions import IntegrationEventAction
19+
from sentry.rules.base import CallbackFuture
20+
from sentry.services.eventstore.models import GroupEvent
1921
from sentry.shared_integrations.exceptions import ApiError
22+
from sentry.types.rules import RuleFuture
2023
from sentry.utils.strings import truncatechars
2124

2225
logger = logging.getLogger("sentry.integrations.pagerduty")
2326

2427

28+
class PagerDutyService(TypedDict):
29+
id: int
30+
integration_key: str
31+
service_name: str
32+
integration_id: int
33+
34+
2535
class PagerDutyNotifyServiceAction(IntegrationEventAction):
2636
id = "sentry.integrations.pagerduty.notify_action.PagerDutyNotifyServiceAction"
2737
label = "Send a notification to PagerDuty account {account} and service {service} with {severity} severity"
2838
prompt = "Send a PagerDuty notification"
2939
provider = IntegrationProviderSlug.PAGERDUTY.value
3040
integration_key = "account"
3141

32-
def __init__(self, *args, **kwargs):
42+
def __init__(self, *args: Any, **kwargs: Any) -> None:
3343
super().__init__(*args, **kwargs)
3444
self.form_fields = {
3545
"account": {
@@ -49,7 +59,7 @@ def __init__(self, *args, **kwargs):
4959
},
5060
}
5161

52-
def _get_service(self):
62+
def _get_service(self) -> PagerDutyService | None:
5363
oi = self.get_organization_integration()
5464
if not oi:
5565
return None
@@ -58,7 +68,9 @@ def _get_service(self):
5868
return pds
5969
return None
6070

61-
def after(self, event, notification_uuid: str | None = None):
71+
def after(
72+
self, event: GroupEvent, notification_uuid: str | None = None
73+
) -> Generator[CallbackFuture]:
6274
integration = self.get_integration()
6375
log_context = {
6476
"organization_id": self.project.organization_id,
@@ -79,7 +91,7 @@ def after(self, event, notification_uuid: str | None = None):
7991
PagerdutySeverity, self.get_option("severity", default=PAGERDUTY_DEFAULT_SEVERITY)
8092
)
8193

82-
def send_notification(event, futures):
94+
def send_notification(event: GroupEvent, futures: Sequence[RuleFuture]) -> None:
8395
installation = integration.get_installation(self.project.organization_id)
8496
try:
8597
client = installation.get_keyring_client(self.get_option("service"))
@@ -147,7 +159,7 @@ def get_services(self) -> Sequence[tuple[int, str]]:
147159
for v in oi.config.get("pagerduty_services", [])
148160
]
149161

150-
def render_label(self):
162+
def render_label(self) -> str:
151163
s = self._get_service()
152164
if s:
153165
service_name = s["service_name"]

src/sentry/integrations/pagerduty/integration.py

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from __future__ import annotations
22

33
import logging
4-
from collections.abc import Mapping, Sequence
5-
from typing import Any
4+
from collections.abc import Mapping, MutableMapping, Sequence
5+
from typing import Any, TypedDict
66

77
import orjson
88
from django.db import router, transaction
@@ -73,6 +73,23 @@
7373
)
7474

7575

76+
class PagerDutyOrganizationConfig(TypedDict):
77+
name: str
78+
type: str
79+
label: str
80+
help: str
81+
addButtonText: str
82+
columnLabels: dict[str, str]
83+
columnKeys: list[str]
84+
confirmDeleteMessage: str
85+
86+
87+
class PagerDutyServiceConfig(TypedDict):
88+
service: str
89+
integration_key: str
90+
id: int
91+
92+
7693
class PagerDutyIntegration(IntegrationInstallation):
7794
def get_keyring_client(self, keyid: int | str) -> PagerDutyClient:
7895
org_integration = self.org_integration
@@ -89,11 +106,11 @@ def get_keyring_client(self, keyid: int | str) -> PagerDutyClient:
89106
integration_id=org_integration.integration_id, integration_key=integration_key
90107
)
91108

92-
def get_client(self):
109+
def get_client(self) -> None:
93110
raise NotImplementedError("Use get_keyring_client instead.")
94111

95-
def get_organization_config(self):
96-
fields = [
112+
def get_organization_config(self) -> list[PagerDutyOrganizationConfig]:
113+
return [
97114
{
98115
"name": "service_table",
99116
"type": "table",
@@ -106,9 +123,7 @@ def get_organization_config(self):
106123
}
107124
]
108125

109-
return fields
110-
111-
def update_organization_config(self, data):
126+
def update_organization_config(self, data: MutableMapping[str, Any]) -> None:
112127
if "service_table" in data:
113128
service_rows = data["service_table"]
114129
# validate fields
@@ -149,15 +164,15 @@ def update_organization_config(self, data):
149164
key = row["integration_key"]
150165
add_service(oi, integration_key=key, service_name=service_name)
151166

152-
def get_config_data(self):
167+
def get_config_data(self) -> Mapping[str, list[PagerDutyServiceConfig]]:
153168
service_list = []
154169
for s in self.services:
155170
service_list.append(
156-
{
157-
"service": s["service_name"],
158-
"integration_key": s["integration_key"],
159-
"id": s["id"],
160-
}
171+
PagerDutyServiceConfig(
172+
service=s["service_name"],
173+
integration_key=s["integration_key"],
174+
id=s["id"],
175+
)
161176
)
162177
return {"service_table": service_list}
163178

@@ -220,7 +235,7 @@ def build_integration(self, state: Mapping[str, Any]) -> IntegrationData:
220235

221236

222237
class PagerDutyInstallationRedirect:
223-
def get_app_url(self, account_name=None):
238+
def get_app_url(self, account_name: str | None = None) -> str:
224239
if not account_name:
225240
account_name = "app"
226241

src/sentry/integrations/pagerduty/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def build_incident_attachment(
9595
alert_context: AlertContext,
9696
metric_issue_context: MetricIssueContext,
9797
organization: Organization,
98-
integration_key,
98+
integration_key: str,
9999
notification_uuid: str | None = None,
100100
) -> dict[str, Any]:
101101

0 commit comments

Comments
 (0)