-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathmain.py
83 lines (66 loc) · 3 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# Standard imports
import json
import urllib.parse
from typing import Any
# Third-party imports
import sentry_sdk
from fastapi import FastAPI, Request
from mangum import Mangum
from sentry_sdk.integrations.aws_lambda import AwsLambdaIntegration
# Local imports
from config import GITHUB_WEBHOOK_SECRET, ENV, PRODUCT_NAME, SENTRY_DSN, UTF8
from scheduler import schedule_handler
from services.gitauto_handler import handle_gitauto
from services.github.github_manager import verify_webhook_signature
from services.webhook_handler import handle_webhook_event
from services.jira.jira_manager import verify_jira_webhook
if ENV != "local":
sentry_sdk.init(
dsn=SENTRY_DSN,
environment=ENV,
integrations=[AwsLambdaIntegration()],
traces_sample_rate=1.0,
)
# Create FastAPI instance and Mangum handler. Mangum is a library that allows you to use FastAPI with AWS Lambda.
app = FastAPI()
mangum_handler = Mangum(app=app, lifespan="off")
# Here is an entry point for the AWS Lambda function. Mangum is a library that allows you to use FastAPI with AWS Lambda.
def handler(event, context):
if "source" in event and event["source"] == "aws.events":
schedule_handler(_event=event, _context=context)
return {"statusCode": 200}
return mangum_handler(event=event, context=context)
@app.post(path="/webhook")
async def handle_webhook(request: Request) -> dict[str, str]:
event_name: str = request.headers.get("X-GitHub-Event", "Event not specified")
# Validate if the webhook signature comes from GitHub
await verify_webhook_signature(request=request, secret=GITHUB_WEBHOOK_SECRET)
# Process the webhook event but never raise an exception as some event_name like "marketplace_purchase" doesn't have a payload
try:
request_body: bytes = await request.body()
except Exception as e: # pylint: disable=broad-except
print(f"Error in reading request body: {e}")
request_body = b""
payload: Any = {}
try:
# First try to parse the body as JSON
payload = json.loads(s=request_body.decode(encoding=UTF8))
except json.JSONDecodeError:
# If JSON parsing fails, treat the body as URL-encoded
decoded_body: dict[str, list[str]] = urllib.parse.parse_qs(
qs=request_body.decode(encoding=UTF8)
)
if "payload" in decoded_body:
payload = json.loads(s=decoded_body["payload"][0])
except Exception as e: # pylint: disable=broad-except
print(f"Error in parsing JSON payload: {e}")
await handle_webhook_event(event_name=event_name, payload=payload)
return {"message": "Webhook processed successfully"}
@app.post(path="/jira-webhook")
async def handle_jira_webhook(request: Request):
payload = await verify_jira_webhook(request)
await handle_gitauto(payload=payload, trigger_type="checkbox", input_from="jira")
return {"message": "Jira webhook processed successfully"}
@app.get(path="/")
async def root() -> dict[str, str]:
return {"message": PRODUCT_NAME}