github-events 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,485 @@
1
+ """Event name/type registry. GENERATED by scripts/generate_models.py (octokit/webhooks-schemas 7.6.1)."""
2
+
3
+ from types import UnionType
4
+ from typing import Literal
5
+
6
+ from github_events import _models as m
7
+
8
+ EventName = Literal[
9
+ 'branch_protection_configuration',
10
+ 'branch_protection_rule',
11
+ 'check_run',
12
+ 'check_suite',
13
+ 'code_scanning_alert',
14
+ 'commit_comment',
15
+ 'create',
16
+ 'custom_property',
17
+ 'custom_property_values',
18
+ 'delete',
19
+ 'dependabot_alert',
20
+ 'deploy_key',
21
+ 'deployment',
22
+ 'deployment_protection_rule',
23
+ 'deployment_review',
24
+ 'deployment_status',
25
+ 'discussion',
26
+ 'discussion_comment',
27
+ 'fork',
28
+ 'github_app_authorization',
29
+ 'gollum',
30
+ 'installation',
31
+ 'installation_repositories',
32
+ 'installation_target',
33
+ 'issue_comment',
34
+ 'issues',
35
+ 'label',
36
+ 'marketplace_purchase',
37
+ 'member',
38
+ 'membership',
39
+ 'merge_group',
40
+ 'meta',
41
+ 'milestone',
42
+ 'org_block',
43
+ 'organization',
44
+ 'package',
45
+ 'page_build',
46
+ 'ping',
47
+ 'project',
48
+ 'project_card',
49
+ 'project_column',
50
+ 'projects_v2_item',
51
+ 'public',
52
+ 'pull_request',
53
+ 'pull_request_review',
54
+ 'pull_request_review_comment',
55
+ 'pull_request_review_thread',
56
+ 'push',
57
+ 'registry_package',
58
+ 'release',
59
+ 'repository',
60
+ 'repository_dispatch',
61
+ 'repository_import',
62
+ 'repository_vulnerability_alert',
63
+ 'secret_scanning_alert',
64
+ 'secret_scanning_alert_location',
65
+ 'security_advisory',
66
+ 'sponsorship',
67
+ 'star',
68
+ 'status',
69
+ 'team',
70
+ 'team_add',
71
+ 'watch',
72
+ 'workflow_dispatch',
73
+ 'workflow_job',
74
+ 'workflow_run',
75
+ ]
76
+
77
+ EVENT_NAMES: tuple[str, ...] = ('branch_protection_configuration', 'branch_protection_rule', 'check_run', 'check_suite', 'code_scanning_alert', 'commit_comment', 'create', 'custom_property', 'custom_property_values', 'delete', 'dependabot_alert', 'deploy_key', 'deployment', 'deployment_protection_rule', 'deployment_review', 'deployment_status', 'discussion', 'discussion_comment', 'fork', 'github_app_authorization', 'gollum', 'installation', 'installation_repositories', 'installation_target', 'issue_comment', 'issues', 'label', 'marketplace_purchase', 'member', 'membership', 'merge_group', 'meta', 'milestone', 'org_block', 'organization', 'package', 'page_build', 'ping', 'project', 'project_card', 'project_column', 'projects_v2_item', 'public', 'pull_request', 'pull_request_review', 'pull_request_review_comment', 'pull_request_review_thread', 'push', 'registry_package', 'release', 'repository', 'repository_dispatch', 'repository_import', 'repository_vulnerability_alert', 'secret_scanning_alert', 'secret_scanning_alert_location', 'security_advisory', 'sponsorship', 'star', 'status', 'team', 'team_add', 'watch', 'workflow_dispatch', 'workflow_job', 'workflow_run')
78
+
79
+ EVENT_TYPES: dict[str, object] = {
80
+ 'branch_protection_configuration': m.BranchProtectionConfigurationEvent,
81
+ 'branch_protection_rule': m.BranchProtectionRuleEvent,
82
+ 'check_run': m.CheckRunEvent,
83
+ 'check_suite': m.CheckSuiteEvent,
84
+ 'code_scanning_alert': m.CodeScanningAlertEvent,
85
+ 'commit_comment': m.CommitCommentEvent,
86
+ 'create': m.CreateEvent,
87
+ 'custom_property': m.CustomPropertyEvent,
88
+ 'custom_property_values': m.CustomPropertyValuesEvent,
89
+ 'delete': m.DeleteEvent,
90
+ 'dependabot_alert': m.DependabotAlertEvent,
91
+ 'deploy_key': m.DeployKeyEvent,
92
+ 'deployment': m.DeploymentEvent,
93
+ 'deployment_protection_rule': m.DeploymentProtectionRuleEvent,
94
+ 'deployment_review': m.DeploymentReviewEvent,
95
+ 'deployment_status': m.DeploymentStatusEvent,
96
+ 'discussion': m.DiscussionEvent,
97
+ 'discussion_comment': m.DiscussionCommentEvent,
98
+ 'fork': m.ForkEvent,
99
+ 'github_app_authorization': m.GitHubAppAuthorizationEvent,
100
+ 'gollum': m.GollumEvent,
101
+ 'installation': m.InstallationEvent,
102
+ 'installation_repositories': m.InstallationRepositoriesEvent,
103
+ 'installation_target': m.InstallationTargetEvent,
104
+ 'issue_comment': m.IssueCommentEvent,
105
+ 'issues': m.IssuesEvent,
106
+ 'label': m.LabelEvent,
107
+ 'marketplace_purchase': m.MarketplacePurchaseEvent,
108
+ 'member': m.MemberEvent,
109
+ 'membership': m.MembershipEvent,
110
+ 'merge_group': m.MergeGroupEvent,
111
+ 'meta': m.MetaEvent,
112
+ 'milestone': m.MilestoneEvent,
113
+ 'org_block': m.OrgBlockEvent,
114
+ 'organization': m.OrganizationEvent,
115
+ 'package': m.PackageEvent,
116
+ 'page_build': m.PageBuildEvent,
117
+ 'ping': m.PingEvent,
118
+ 'project': m.ProjectEvent,
119
+ 'project_card': m.ProjectCardEvent,
120
+ 'project_column': m.ProjectColumnEvent,
121
+ 'projects_v2_item': m.ProjectsV2ItemEvent,
122
+ 'public': m.PublicEvent,
123
+ 'pull_request': m.PullRequestEvent,
124
+ 'pull_request_review': m.PullRequestReviewEvent,
125
+ 'pull_request_review_comment': m.PullRequestReviewCommentEvent,
126
+ 'pull_request_review_thread': m.PullRequestReviewThreadEvent,
127
+ 'push': m.PushEvent,
128
+ 'registry_package': m.RegistryPackageEvent,
129
+ 'release': m.ReleaseEvent,
130
+ 'repository': m.RepositoryEvent,
131
+ 'repository_dispatch': m.RepositoryDispatchEvent,
132
+ 'repository_import': m.RepositoryImportEvent,
133
+ 'repository_vulnerability_alert': m.RepositoryVulnerabilityAlertEvent,
134
+ 'secret_scanning_alert': m.SecretScanningAlertEvent,
135
+ 'secret_scanning_alert_location': m.SecretScanningAlertLocationEvent,
136
+ 'security_advisory': m.SecurityAdvisoryEvent,
137
+ 'sponsorship': m.SponsorshipEvent,
138
+ 'star': m.StarEvent,
139
+ 'status': m.StatusEvent,
140
+ 'team': m.TeamEvent,
141
+ 'team_add': m.TeamAddEvent,
142
+ 'watch': m.WatchEvent,
143
+ 'workflow_dispatch': m.WorkflowDispatchEvent,
144
+ 'workflow_job': m.WorkflowJobEvent,
145
+ 'workflow_run': m.WorkflowRunEvent,
146
+ }
147
+
148
+ ACTION_EVENTS: frozenset[str] = frozenset({
149
+ 'branch_protection_configuration',
150
+ 'branch_protection_rule',
151
+ 'check_run',
152
+ 'check_suite',
153
+ 'code_scanning_alert',
154
+ 'commit_comment',
155
+ 'custom_property',
156
+ 'custom_property_values',
157
+ 'dependabot_alert',
158
+ 'deploy_key',
159
+ 'deployment',
160
+ 'deployment_protection_rule',
161
+ 'deployment_review',
162
+ 'deployment_status',
163
+ 'discussion',
164
+ 'discussion_comment',
165
+ 'github_app_authorization',
166
+ 'installation',
167
+ 'installation_repositories',
168
+ 'installation_target',
169
+ 'issue_comment',
170
+ 'issues',
171
+ 'label',
172
+ 'marketplace_purchase',
173
+ 'member',
174
+ 'membership',
175
+ 'merge_group',
176
+ 'meta',
177
+ 'milestone',
178
+ 'org_block',
179
+ 'organization',
180
+ 'package',
181
+ 'project',
182
+ 'project_card',
183
+ 'project_column',
184
+ 'projects_v2_item',
185
+ 'pull_request',
186
+ 'pull_request_review',
187
+ 'pull_request_review_comment',
188
+ 'pull_request_review_thread',
189
+ 'registry_package',
190
+ 'release',
191
+ 'repository',
192
+ 'repository_vulnerability_alert',
193
+ 'secret_scanning_alert',
194
+ 'secret_scanning_alert_location',
195
+ 'security_advisory',
196
+ 'sponsorship',
197
+ 'star',
198
+ 'team',
199
+ 'watch',
200
+ 'workflow_job',
201
+ 'workflow_run',
202
+ })
203
+
204
+ ACTION_TYPES: dict[tuple[str, str], type | UnionType] = {
205
+ ('branch_protection_configuration', 'disabled'): m.BranchProtectionConfigurationDisabledEvent,
206
+ ('branch_protection_configuration', 'enabled'): m.BranchProtectionConfigurationEnabledEvent,
207
+ ('branch_protection_rule', 'created'): m.BranchProtectionRuleCreatedEvent,
208
+ ('branch_protection_rule', 'deleted'): m.BranchProtectionRuleDeletedEvent,
209
+ ('branch_protection_rule', 'edited'): m.BranchProtectionRuleEditedEvent,
210
+ ('check_run', 'completed'): m.CheckRunCompletedEvent,
211
+ ('check_run', 'created'): m.CheckRunCreatedEvent,
212
+ ('check_run', 'requested_action'): m.CheckRunRequestedActionEvent,
213
+ ('check_run', 'rerequested'): m.CheckRunRerequestedEvent,
214
+ ('check_suite', 'completed'): m.CheckSuiteCompletedEvent,
215
+ ('check_suite', 'requested'): m.CheckSuiteRequestedEvent,
216
+ ('check_suite', 'rerequested'): m.CheckSuiteRerequestedEvent,
217
+ ('code_scanning_alert', 'appeared_in_branch'): m.CodeScanningAlertAppearedInBranchEvent,
218
+ ('code_scanning_alert', 'closed_by_user'): m.CodeScanningAlertClosedByUserEvent,
219
+ ('code_scanning_alert', 'created'): m.CodeScanningAlertCreatedEvent,
220
+ ('code_scanning_alert', 'fixed'): m.CodeScanningAlertFixedEvent,
221
+ ('code_scanning_alert', 'reopened'): m.CodeScanningAlertReopenedEvent,
222
+ ('code_scanning_alert', 'reopened_by_user'): m.CodeScanningAlertReopenedByUserEvent,
223
+ ('commit_comment', 'created'): m.CommitCommentCreatedEvent,
224
+ ('custom_property', 'created'): m.CustomPropertyCreatedEvent,
225
+ ('custom_property', 'deleted'): m.CustomPropertyDeletedEvent,
226
+ ('custom_property_values', 'updated'): m.CustomPropertyValuesUpdatedEvent,
227
+ ('dependabot_alert', 'created'): m.DependabotAlertCreatedEvent,
228
+ ('dependabot_alert', 'dismissed'): m.DependabotAlertDismissedEvent,
229
+ ('dependabot_alert', 'fixed'): m.DependabotAlertFixedEvent,
230
+ ('dependabot_alert', 'reintroduced'): m.DependabotAlertReintroducedEvent,
231
+ ('dependabot_alert', 'reopened'): m.DependabotAlertReopenedEvent,
232
+ ('deploy_key', 'created'): m.DeployKeyCreatedEvent,
233
+ ('deploy_key', 'deleted'): m.DeployKeyDeletedEvent,
234
+ ('deployment', 'created'): m.DeploymentCreatedEvent,
235
+ ('deployment_protection_rule', 'requested'): m.DeploymentProtectionRuleRequestedEvent,
236
+ ('deployment_review', 'approved'): m.DeploymentReviewApprovedEvent,
237
+ ('deployment_review', 'rejected'): m.DeploymentReviewRejectedEvent,
238
+ ('deployment_review', 'requested'): m.DeploymentReviewRequestedEvent,
239
+ ('deployment_status', 'created'): m.DeploymentStatusCreatedEvent,
240
+ ('discussion', 'answered'): m.DiscussionAnsweredEvent,
241
+ ('discussion', 'category_changed'): m.DiscussionCategoryChangedEvent,
242
+ ('discussion', 'created'): m.DiscussionCreatedEvent,
243
+ ('discussion', 'deleted'): m.DiscussionDeletedEvent,
244
+ ('discussion', 'edited'): m.DiscussionEditedEvent,
245
+ ('discussion', 'labeled'): m.DiscussionLabeledEvent,
246
+ ('discussion', 'locked'): m.DiscussionLockedEvent,
247
+ ('discussion', 'pinned'): m.DiscussionPinnedEvent,
248
+ ('discussion', 'transferred'): m.DiscussionTransferredEvent,
249
+ ('discussion', 'unanswered'): m.DiscussionUnansweredEvent,
250
+ ('discussion', 'unlabeled'): m.DiscussionUnlabeledEvent,
251
+ ('discussion', 'unlocked'): m.DiscussionUnlockedEvent,
252
+ ('discussion', 'unpinned'): m.DiscussionUnpinnedEvent,
253
+ ('discussion_comment', 'created'): m.DiscussionCommentCreatedEvent,
254
+ ('discussion_comment', 'deleted'): m.DiscussionCommentDeletedEvent,
255
+ ('discussion_comment', 'edited'): m.DiscussionCommentEditedEvent,
256
+ ('github_app_authorization', 'revoked'): m.GitHubAppAuthorizationRevokedEvent,
257
+ ('installation', 'created'): m.InstallationCreatedEvent,
258
+ ('installation', 'deleted'): m.InstallationDeletedEvent,
259
+ ('installation', 'new_permissions_accepted'): m.InstallationNewPermissionsAcceptedEvent,
260
+ ('installation', 'suspend'): m.InstallationSuspendEvent,
261
+ ('installation', 'unsuspend'): m.InstallationUnsuspendEvent,
262
+ ('installation_repositories', 'added'): m.InstallationRepositoriesAddedEvent,
263
+ ('installation_repositories', 'removed'): m.InstallationRepositoriesRemovedEvent,
264
+ ('installation_target', 'renamed'): m.InstallationTargetRenamedEvent,
265
+ ('issue_comment', 'created'): m.IssueCommentCreatedEvent,
266
+ ('issue_comment', 'deleted'): m.IssueCommentDeletedEvent,
267
+ ('issue_comment', 'edited'): m.IssueCommentEditedEvent,
268
+ ('issues', 'assigned'): m.IssuesAssignedEvent,
269
+ ('issues', 'closed'): m.IssuesClosedEvent,
270
+ ('issues', 'deleted'): m.IssuesDeletedEvent,
271
+ ('issues', 'demilestoned'): m.IssuesDemilestonedEvent,
272
+ ('issues', 'edited'): m.IssuesEditedEvent,
273
+ ('issues', 'labeled'): m.IssuesLabeledEvent,
274
+ ('issues', 'locked'): m.IssuesLockedEvent,
275
+ ('issues', 'milestoned'): m.IssuesMilestonedEvent,
276
+ ('issues', 'opened'): m.IssuesOpenedEvent,
277
+ ('issues', 'pinned'): m.IssuesPinnedEvent,
278
+ ('issues', 'reopened'): m.IssuesReopenedEvent,
279
+ ('issues', 'transferred'): m.IssuesTransferredEvent,
280
+ ('issues', 'unassigned'): m.IssuesUnassignedEvent,
281
+ ('issues', 'unlabeled'): m.IssuesUnlabeledEvent,
282
+ ('issues', 'unlocked'): m.IssuesUnlockedEvent,
283
+ ('issues', 'unpinned'): m.IssuesUnpinnedEvent,
284
+ ('label', 'created'): m.LabelCreatedEvent,
285
+ ('label', 'deleted'): m.LabelDeletedEvent,
286
+ ('label', 'edited'): m.LabelEditedEvent,
287
+ ('marketplace_purchase', 'cancelled'): m.MarketplacePurchaseCancelledEvent,
288
+ ('marketplace_purchase', 'changed'): m.MarketplacePurchaseChangedEvent,
289
+ ('marketplace_purchase', 'pending_change'): m.MarketplacePurchasePendingChangeEvent,
290
+ ('marketplace_purchase', 'pending_change_cancelled'): m.MarketplacePurchasePendingChangeCancelledEvent,
291
+ ('marketplace_purchase', 'purchased'): m.MarketplacePurchasePurchasedEvent,
292
+ ('member', 'added'): m.MemberAddedEvent,
293
+ ('member', 'edited'): m.MemberEditedEvent,
294
+ ('member', 'removed'): m.MemberRemovedEvent,
295
+ ('membership', 'added'): m.MembershipAddedEvent,
296
+ ('membership', 'removed'): m.MembershipRemovedEvent,
297
+ ('merge_group', 'checks_requested'): m.MergeGroupChecksRequestedEvent,
298
+ ('merge_group', 'destroyed'): m.MergeGroupDestroyedEvent,
299
+ ('meta', 'deleted'): m.MetaDeletedEvent,
300
+ ('milestone', 'closed'): m.MilestoneClosedEvent,
301
+ ('milestone', 'created'): m.MilestoneCreatedEvent,
302
+ ('milestone', 'deleted'): m.MilestoneDeletedEvent,
303
+ ('milestone', 'edited'): m.MilestoneEditedEvent,
304
+ ('milestone', 'opened'): m.MilestoneOpenedEvent,
305
+ ('org_block', 'blocked'): m.OrgBlockBlockedEvent,
306
+ ('org_block', 'unblocked'): m.OrgBlockUnblockedEvent,
307
+ ('organization', 'deleted'): m.OrganizationDeletedEvent,
308
+ ('organization', 'member_added'): m.OrganizationMemberAddedEvent,
309
+ ('organization', 'member_invited'): m.OrganizationMemberInvitedEvent,
310
+ ('organization', 'member_removed'): m.OrganizationMemberRemovedEvent,
311
+ ('organization', 'renamed'): m.OrganizationRenamedEvent,
312
+ ('package', 'published'): m.PackagePublishedEvent,
313
+ ('package', 'updated'): m.PackageUpdatedEvent,
314
+ ('project', 'closed'): m.ProjectClosedEvent,
315
+ ('project', 'created'): m.ProjectCreatedEvent,
316
+ ('project', 'deleted'): m.ProjectDeletedEvent,
317
+ ('project', 'edited'): m.ProjectEditedEvent,
318
+ ('project', 'reopened'): m.ProjectReopenedEvent,
319
+ ('project_card', 'converted'): m.ProjectCardConvertedEvent,
320
+ ('project_card', 'created'): m.ProjectCardCreatedEvent,
321
+ ('project_card', 'deleted'): m.ProjectCardDeletedEvent,
322
+ ('project_card', 'edited'): m.ProjectCardEditedEvent,
323
+ ('project_card', 'moved'): m.ProjectCardMovedEvent,
324
+ ('project_column', 'created'): m.ProjectColumnCreatedEvent,
325
+ ('project_column', 'deleted'): m.ProjectColumnDeletedEvent,
326
+ ('project_column', 'edited'): m.ProjectColumnEditedEvent,
327
+ ('project_column', 'moved'): m.ProjectColumnMovedEvent,
328
+ ('projects_v2_item', 'archived'): m.ProjectsV2ItemArchivedEvent,
329
+ ('projects_v2_item', 'converted'): m.ProjectsV2ItemConvertedEvent,
330
+ ('projects_v2_item', 'created'): m.ProjectsV2ItemCreatedEvent,
331
+ ('projects_v2_item', 'deleted'): m.ProjectsV2ItemDeletedEvent,
332
+ ('projects_v2_item', 'edited'): m.ProjectsV2ItemEditedEvent,
333
+ ('projects_v2_item', 'reordered'): m.ProjectsV2ItemReorderedEvent,
334
+ ('projects_v2_item', 'restored'): m.ProjectsV2ItemRestoredEvent,
335
+ ('pull_request', 'assigned'): m.PullRequestAssignedEvent,
336
+ ('pull_request', 'auto_merge_disabled'): m.PullRequestAutoMergeDisabledEvent,
337
+ ('pull_request', 'auto_merge_enabled'): m.PullRequestAutoMergeEnabledEvent,
338
+ ('pull_request', 'closed'): m.PullRequestClosedEvent,
339
+ ('pull_request', 'converted_to_draft'): m.PullRequestConvertedToDraftEvent,
340
+ ('pull_request', 'demilestoned'): m.PullRequestDemilestonedEvent,
341
+ ('pull_request', 'dequeued'): m.PullRequestDequeuedEvent,
342
+ ('pull_request', 'edited'): m.PullRequestEditedEvent,
343
+ ('pull_request', 'enqueued'): m.PullRequestEnqueuedEvent,
344
+ ('pull_request', 'labeled'): m.PullRequestLabeledEvent,
345
+ ('pull_request', 'locked'): m.PullRequestLockedEvent,
346
+ ('pull_request', 'milestoned'): m.PullRequestMilestonedEvent,
347
+ ('pull_request', 'opened'): m.PullRequestOpenedEvent,
348
+ ('pull_request', 'ready_for_review'): m.PullRequestReadyForReviewEvent,
349
+ ('pull_request', 'reopened'): m.PullRequestReopenedEvent,
350
+ ('pull_request', 'review_request_removed'): m.PullRequestReviewRequestRemovedEvent,
351
+ ('pull_request', 'review_requested'): m.PullRequestReviewRequestedEvent,
352
+ ('pull_request', 'synchronize'): m.PullRequestSynchronizeEvent,
353
+ ('pull_request', 'unassigned'): m.PullRequestUnassignedEvent,
354
+ ('pull_request', 'unlabeled'): m.PullRequestUnlabeledEvent,
355
+ ('pull_request', 'unlocked'): m.PullRequestUnlockedEvent,
356
+ ('pull_request_review', 'dismissed'): m.PullRequestReviewDismissedEvent,
357
+ ('pull_request_review', 'edited'): m.PullRequestReviewEditedEvent,
358
+ ('pull_request_review', 'submitted'): m.PullRequestReviewSubmittedEvent,
359
+ ('pull_request_review_comment', 'created'): m.PullRequestReviewCommentCreatedEvent,
360
+ ('pull_request_review_comment', 'deleted'): m.PullRequestReviewCommentDeletedEvent,
361
+ ('pull_request_review_comment', 'edited'): m.PullRequestReviewCommentEditedEvent,
362
+ ('pull_request_review_thread', 'resolved'): m.PullRequestReviewThreadResolvedEvent,
363
+ ('pull_request_review_thread', 'unresolved'): m.PullRequestReviewThreadUnresolvedEvent,
364
+ ('registry_package', 'published'): m.RegistryPackagePublishedEvent,
365
+ ('registry_package', 'updated'): m.RegistryPackageUpdatedEvent,
366
+ ('release', 'created'): m.ReleaseCreatedEvent,
367
+ ('release', 'deleted'): m.ReleaseDeletedEvent,
368
+ ('release', 'edited'): m.ReleaseEditedEvent,
369
+ ('release', 'prereleased'): m.ReleasePrereleasedEvent,
370
+ ('release', 'published'): m.ReleasePublishedEvent,
371
+ ('release', 'released'): m.ReleaseReleasedEvent,
372
+ ('release', 'unpublished'): m.ReleaseUnpublishedEvent,
373
+ ('repository', 'archived'): m.RepositoryArchivedEvent,
374
+ ('repository', 'created'): m.RepositoryCreatedEvent,
375
+ ('repository', 'deleted'): m.RepositoryDeletedEvent,
376
+ ('repository', 'edited'): m.RepositoryEditedEvent,
377
+ ('repository', 'privatized'): m.RepositoryPrivatizedEvent,
378
+ ('repository', 'publicized'): m.RepositoryPublicizedEvent,
379
+ ('repository', 'renamed'): m.RepositoryRenamedEvent,
380
+ ('repository', 'transferred'): m.RepositoryTransferredEvent,
381
+ ('repository', 'unarchived'): m.RepositoryUnarchivedEvent,
382
+ ('repository_vulnerability_alert', 'create'): m.RepositoryVulnerabilityAlertCreateEvent,
383
+ ('repository_vulnerability_alert', 'dismiss'): m.RepositoryVulnerabilityAlertDismissEvent,
384
+ ('repository_vulnerability_alert', 'reopen'): m.RepositoryVulnerabilityAlertReopenEvent,
385
+ ('repository_vulnerability_alert', 'resolve'): m.RepositoryVulnerabilityAlertResolveEvent,
386
+ ('secret_scanning_alert', 'created'): m.SecretScanningAlertCreatedEvent,
387
+ ('secret_scanning_alert', 'reopened'): m.SecretScanningAlertReopenedEvent,
388
+ ('secret_scanning_alert', 'resolved'): m.SecretScanningAlertResolvedEvent,
389
+ ('secret_scanning_alert', 'revoked'): m.SecretScanningAlertRevokedEvent,
390
+ ('secret_scanning_alert_location', 'created'): m.SecretScanningAlertLocationCreatedEvent,
391
+ ('security_advisory', 'performed'): m.SecurityAdvisoryPerformedEvent,
392
+ ('security_advisory', 'published'): m.SecurityAdvisoryPublishedEvent,
393
+ ('security_advisory', 'updated'): m.SecurityAdvisoryUpdatedEvent,
394
+ ('security_advisory', 'withdrawn'): m.SecurityAdvisoryWithdrawnEvent,
395
+ ('sponsorship', 'cancelled'): m.SponsorshipCancelledEvent,
396
+ ('sponsorship', 'created'): m.SponsorshipCreatedEvent,
397
+ ('sponsorship', 'edited'): m.SponsorshipEditedEvent,
398
+ ('sponsorship', 'pending_cancellation'): m.SponsorshipPendingCancellationEvent,
399
+ ('sponsorship', 'pending_tier_change'): m.SponsorshipPendingTierChangeEvent,
400
+ ('sponsorship', 'tier_changed'): m.SponsorshipTierChangedEvent,
401
+ ('star', 'created'): m.StarCreatedEvent,
402
+ ('star', 'deleted'): m.StarDeletedEvent,
403
+ ('team', 'added_to_repository'): m.TeamAddedToRepositoryEvent,
404
+ ('team', 'created'): m.TeamCreatedEvent,
405
+ ('team', 'deleted'): m.TeamDeletedEvent,
406
+ ('team', 'edited'): m.TeamEditedEvent,
407
+ ('team', 'removed_from_repository'): m.TeamRemovedFromRepositoryEvent,
408
+ ('watch', 'started'): m.WatchStartedEvent,
409
+ ('workflow_job', 'completed'): m.WorkflowJobCompletedEvent,
410
+ ('workflow_job', 'in_progress'): m.WorkflowJobInProgressEvent,
411
+ ('workflow_job', 'queued'): m.WorkflowJobQueuedEvent,
412
+ ('workflow_job', 'waiting'): m.WorkflowJobWaitingEvent,
413
+ ('workflow_run', 'completed'): m.WorkflowRunCompletedEvent,
414
+ ('workflow_run', 'in_progress'): m.WorkflowRunInProgressEvent,
415
+ ('workflow_run', 'requested'): m.WorkflowRunRequestedEvent,
416
+ }
417
+
418
+ WebhookEvent = (
419
+ m.BranchProtectionConfigurationEvent
420
+ | m.BranchProtectionRuleEvent
421
+ | m.CheckRunEvent
422
+ | m.CheckSuiteEvent
423
+ | m.CodeScanningAlertEvent
424
+ | m.CommitCommentEvent
425
+ | m.CreateEvent
426
+ | m.CustomPropertyEvent
427
+ | m.CustomPropertyValuesEvent
428
+ | m.DeleteEvent
429
+ | m.DependabotAlertEvent
430
+ | m.DeployKeyEvent
431
+ | m.DeploymentEvent
432
+ | m.DeploymentProtectionRuleEvent
433
+ | m.DeploymentReviewEvent
434
+ | m.DeploymentStatusEvent
435
+ | m.DiscussionEvent
436
+ | m.DiscussionCommentEvent
437
+ | m.ForkEvent
438
+ | m.GitHubAppAuthorizationEvent
439
+ | m.GollumEvent
440
+ | m.InstallationEvent
441
+ | m.InstallationRepositoriesEvent
442
+ | m.InstallationTargetEvent
443
+ | m.IssueCommentEvent
444
+ | m.IssuesEvent
445
+ | m.LabelEvent
446
+ | m.MarketplacePurchaseEvent
447
+ | m.MemberEvent
448
+ | m.MembershipEvent
449
+ | m.MergeGroupEvent
450
+ | m.MetaEvent
451
+ | m.MilestoneEvent
452
+ | m.OrgBlockEvent
453
+ | m.OrganizationEvent
454
+ | m.PackageEvent
455
+ | m.PageBuildEvent
456
+ | m.PingEvent
457
+ | m.ProjectEvent
458
+ | m.ProjectCardEvent
459
+ | m.ProjectColumnEvent
460
+ | m.ProjectsV2ItemEvent
461
+ | m.PublicEvent
462
+ | m.PullRequestEvent
463
+ | m.PullRequestReviewEvent
464
+ | m.PullRequestReviewCommentEvent
465
+ | m.PullRequestReviewThreadEvent
466
+ | m.PushEvent
467
+ | m.RegistryPackageEvent
468
+ | m.ReleaseEvent
469
+ | m.RepositoryEvent
470
+ | m.RepositoryDispatchEvent
471
+ | m.RepositoryImportEvent
472
+ | m.RepositoryVulnerabilityAlertEvent
473
+ | m.SecretScanningAlertEvent
474
+ | m.SecretScanningAlertLocationEvent
475
+ | m.SecurityAdvisoryEvent
476
+ | m.SponsorshipEvent
477
+ | m.StarEvent
478
+ | m.StatusEvent
479
+ | m.TeamEvent
480
+ | m.TeamAddEvent
481
+ | m.WatchEvent
482
+ | m.WorkflowDispatchEvent
483
+ | m.WorkflowJobEvent
484
+ | m.WorkflowRunEvent
485
+ )
@@ -0,0 +1,138 @@
1
+ """Framework-free GitHub webhook dispatch: verify, parse, validate, route.
2
+
3
+ Works with any HTTP framework (or none) — you bring the raw request body and
4
+ headers, WebhookDispatcher does the rest. github_events.fastapi wraps this for
5
+ FastAPI apps.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import hashlib
11
+ import hmac
12
+ import inspect
13
+ import json
14
+ from collections.abc import Callable
15
+ from typing import Any, TypeVar
16
+
17
+ __all__ = ["SignatureVerificationError", "WebhookDispatcher", "WebhookError"]
18
+
19
+ Handler = TypeVar("Handler", bound=Callable[..., Any])
20
+
21
+
22
+ class WebhookError(Exception):
23
+ """Base class for dispatch failures."""
24
+
25
+
26
+ class SignatureVerificationError(WebhookError):
27
+ """X-Hub-Signature-256 was missing or didn't match the body."""
28
+
29
+
30
+ class WebhookDispatcher:
31
+ """Handler registry keyed by (event, action), with signature verification.
32
+
33
+ @hook.on("issues", action="opened") -> called with an IssuesOpenedEvent payload
34
+ @hook.on("issues") -> called with every issues action
35
+ @hook.on_any -> called with (event_name, payload) for all deliveries
36
+
37
+ Handlers may be sync or async. With validate=True (the default, requires
38
+ pydantic) payloads are checked against the generated TypedDicts before
39
+ dispatch; events GitHub adds after generation pass through unvalidated.
40
+ """
41
+
42
+ def __init__(self, secret: str | bytes | None = None, *, validate: bool = True) -> None:
43
+ if isinstance(secret, str):
44
+ secret = secret.encode()
45
+ self._secret = secret
46
+ self._handlers: dict[tuple[str, str | None], list[Callable[..., Any]]] = {}
47
+ self._any_handlers: list[Callable[..., Any]] = []
48
+ self._validate: Callable[[str, str | None, Any], Any]
49
+ if validate:
50
+ from github_events.validation import validate_payload
51
+
52
+ self._validate = validate_payload
53
+ else:
54
+ self._validate = lambda _event, _action, data: data
55
+
56
+ def on(
57
+ self, event: str, action: str | list[str] | None = None
58
+ ) -> Callable[[Handler], Handler]:
59
+ """Register a handler for one event, optionally narrowed to one action
60
+ or a list of actions (the handler fires for any of them)."""
61
+ actions: list[str | None]
62
+ if action is None:
63
+ actions = [None]
64
+ elif isinstance(action, str):
65
+ actions = [action]
66
+ else:
67
+ actions = list(dict.fromkeys(action)) # dedupe, keep order
68
+ if not actions:
69
+ raise ValueError("action list must not be empty")
70
+
71
+ def register(fn: Handler) -> Handler:
72
+ for a in actions:
73
+ self._handlers.setdefault((event, a), []).append(fn)
74
+ return fn
75
+
76
+ return register
77
+
78
+ def on_any(self, fn: Handler) -> Handler:
79
+ """Register a handler called with (event_name, payload) for every delivery."""
80
+ self._any_handlers.append(fn)
81
+ return fn
82
+
83
+ def verify_signature(self, body: bytes, signature_256: str | None) -> None:
84
+ """Constant-time HMAC-SHA256 check. No-op unless a secret is configured."""
85
+ if self._secret is None:
86
+ return
87
+ if not signature_256:
88
+ raise SignatureVerificationError("missing X-Hub-Signature-256 header")
89
+ expected = "sha256=" + hmac.new(self._secret, body, hashlib.sha256).hexdigest()
90
+ if not hmac.compare_digest(expected, signature_256):
91
+ raise SignatureVerificationError("X-Hub-Signature-256 mismatch")
92
+
93
+ async def dispatch(
94
+ self,
95
+ event: str,
96
+ body: bytes | str | dict[str, Any],
97
+ *,
98
+ signature_256: str | None = None,
99
+ ) -> Any:
100
+ """Verify, parse, validate and route one delivery; returns the payload.
101
+
102
+ Raises SignatureVerificationError (a secret is configured and the
103
+ signature is missing/wrong), json.JSONDecodeError (malformed body), and
104
+ — with validation enabled — pydantic.ValidationError when a field that
105
+ is present has the wrong type.
106
+ """
107
+ if isinstance(body, dict):
108
+ if self._secret is not None:
109
+ raise ValueError(
110
+ "cannot verify a signature against a pre-parsed body; pass raw bytes"
111
+ )
112
+ data = body
113
+ else:
114
+ raw = body.encode() if isinstance(body, str) else body
115
+ self.verify_signature(raw, signature_256)
116
+ data = json.loads(raw)
117
+ action = data.get("action") if isinstance(data, dict) else None
118
+ payload = self._validate(event, action if isinstance(action, str) else None, data)
119
+ # dict.fromkeys dedupes (action-less events would otherwise route twice)
120
+ for key in dict.fromkeys(((event, action), (event, None))):
121
+ for fn in self._handlers.get(key, []):
122
+ if inspect.isawaitable(result := fn(payload)):
123
+ await result
124
+ for fn in self._any_handlers:
125
+ if inspect.isawaitable(result := fn(event, payload)):
126
+ await result
127
+ return payload
128
+
129
+ def as_fastapi_router(self, *, path: str = "/") -> Any:
130
+ """Build a FastAPI APIRouter with a POST endpoint wired to this dispatcher.
131
+
132
+ Requires fastapi (github-events[fastapi]). Returns fastapi.APIRouter.
133
+ """
134
+ from github_events.fastapi import create_router
135
+
136
+ # Suppression needed because the .pyi stub shadows this module, so
137
+ # `self`'s impl type doesn't unify with the stub's WebhookDispatcher.
138
+ return create_router(self, path=path) # ty: ignore[invalid-argument-type]