11from __future__ import annotations
22
3+ from typing import Annotated
4+
35from fastapi import FastAPI , Header
46from loguru import logger
57from pydantic import BaseModel
810logger .disable (__name__ )
911
1012
11- class GitHubWebhook (BaseModel ):
12- gh_hook_id : str = Header (alias = "X-GitHub-Hook-ID" )
13- action : str
14- issue : dict
13+ class GitHubWebhookHeaders (BaseModel ):
14+ # X-GitHub-Delivery: A globally unique identifier (GUID) to identify the event.
15+ gh_delivery : str = Header (alias = "x-github-delivery" )
16+ # X-GitHub-Event: The name of the event that triggered the delivery.
17+ gh_event : str = Header (alias = "x-github-event" )
18+ # X-GitHub-Hook-ID: The unique identifier of the webhook.
19+ gh_hook_id : str = Header (alias = "x-github-hook-id" )
20+ # X-GitHub-Hook-Installation-Target-ID: The unique identifier of the resource where the webhook was created.
21+ gh_hook_installation_target_id : str = Header (alias = "x-github-hook-installation-target-id" )
22+ # X-GitHub-Hook-Installation-Target-Type: The type of resource where the webhook was created.
23+ gh_hook_installation_target_type : str = Header (alias = "x-github-hook-installation-target-type" )
24+ # X-Hub-Signature-256: This header is sent if the webhook is configured with a secret. This is the HMAC hex digest of
25+ # the request body, and is generated using the SHA-256 hash function and the secret as the HMAC key. For more
26+ # information, see Validating webhook deliveries.
27+ hub_signature_256 : str | None = Header (alias = "x-hub-signature-256" , default = None )
28+ # User-Agent: This header will always have the prefix GitHub-Hookshot/.
29+ user_agent : str = Header (alias = "user-agent" )
30+
31+
32+ class PushGitHubWebhook (BaseModel ):
33+ after : str
34+ base_ref : str | None = None
35+ before : str
36+ commits : list [dict ]
37+ compare : str
38+ created : bool
39+ deleted : bool
40+ enterprise : dict | None = None
41+ forced : bool
42+ head_commit : dict | None = None
43+ installation : dict | None = None
44+ organization : dict | None = None
45+ pusher : dict
46+ ref : str
1547 repository : dict
16- sender : dict
48+ sender : dict | None = None
1749
1850
1951class GitHubWebhooksApp (FastAPI ):
@@ -25,8 +57,15 @@ async def get_github_webhook():
2557 return PlainTextResponse (content = "OK" )
2658
2759 @self .post ("/" )
28- async def post_github_webhook ():
29- return PlainTextResponse (content = "OK, noted" )
60+ async def post_github_webhook (
61+ headers : Annotated [GitHubWebhookHeaders , Header ()],
62+ hook : PushGitHubWebhook | dict | None = None ,
63+ ) -> dict :
64+ return {
65+ "headers" : headers ,
66+ "hook_type" : type (hook ).__name__ ,
67+ "hook" : hook ,
68+ }
3069
3170 async def __call__ (self , scope , receive , send ):
3271 logger .info (f"{ scope = } { receive = } { send = } " )
0 commit comments