Skip to content
This repository was archived by the owner on Mar 13, 2026. It is now read-only.

Commit 90f269d

Browse files
arponpesduhow
authored andcommitted
Small improvements in app
1 parent 7093a8c commit 90f269d

2 files changed

Lines changed: 57 additions & 27 deletions

File tree

app.py

Lines changed: 56 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,110 @@
1-
from flask import Flask, request, abort
1+
from datetime import datetime, timedelta
2+
from logging.config import dictConfig
3+
4+
from flask import Flask, abort, request
25

3-
import logging
46
from const import GithubHeaders
5-
from datetime import datetime, timedelta
67

7-
_LOGGER = logging.getLogger(__name__)
8+
dictConfig(
9+
{
10+
"version": 1,
11+
"formatters": {
12+
"default": {
13+
"format": "[%(asctime)s]: %(levelname)s| %(message)s",
14+
}
15+
},
16+
"handlers": {
17+
"wsgi": {
18+
"class": "logging.StreamHandler",
19+
"stream": "ext://flask.logging.wsgi_errors_stream",
20+
"formatter": "default",
21+
}
22+
},
23+
"root": {"level": "INFO", "handlers": ["wsgi"]},
24+
}
25+
)
826

927
app = Flask(__name__)
1028

1129
jobs = dict()
1230

31+
1332
def parse_datetime(date: str) -> datetime:
1433
exp = "%Y-%m-%dT%H:%M:%SZ"
1534
return datetime.strptime(date, exp)
1635

36+
37+
def prune_jobs():
38+
# if the first job is older than 2 days, prune all jobs older than 2 days
39+
# this might happen due to not completed jobs
40+
if datetime.fromtimestamp(list(jobs.values())[0]) > datetime.now() - timedelta(
41+
days=2
42+
):
43+
app.logger.info("Pruning jobs")
44+
for job_id, timestamp in jobs.items():
45+
if (datetime.now() - datetime.fromtimestamp(timestamp)).days >= 2:
46+
del jobs[job_id]
47+
48+
1749
def validate_origin_github() -> bool:
1850
userAgent = request.headers.get("User-Agent")
1951
if not userAgent.startswith("GitHub-Hookshot"):
20-
_LOGGER.warning("User-Agent is {userAgent}")
52+
app.logger.warning("User-Agent is {userAgent}")
2153
return False
2254

2355
if request.headers.get("Content-Type") != "application/json":
24-
_LOGGER.warning("Content is not JSON")
56+
app.logger.warning("Content is not JSON")
2557
return False
2658

2759
if not request.headers.get(GithubHeaders.EVENT.value):
28-
_LOGGER.warning("No GitHub Event received!")
60+
app.logger.warning("No GitHub Event received!")
2961
return False
3062

3163
return True
3264

65+
3366
def process_workflow_job():
3467
job = request.get_json()
3568

3669
job_id = job["workflow_job"]["run_id"]
37-
name = job["workflow_job"]["workflow_name"]
70+
workflow = job["workflow_job"]["workflow_name"]
3871
time_start = parse_datetime(job["workflow_job"]["started_at"])
3972
repository = job["repository"]["full_name"]
4073
action = job["action"]
41-
NOW = datetime.now()
4274

4375
if action == "queued":
4476
# add to memory as timestamp
4577
jobs[job_id] = int(time_start.timestamp())
46-
msg = f"{NOW} {action=} {repository=} workflow={name} {job_id=} {time_start=}"
78+
msg = f"{action=} {repository=} {workflow=} {job_id=}"
79+
prune_jobs()
4780

4881
elif action == "in_progress":
49-
job_requested = jobs.get(job_id, None)
82+
job_requested = jobs.get(job_id)
5083
if not job_requested:
51-
_LOGGER.warning(f"Job {job_id} is {action} but not stored!")
84+
app.logger.warning(f"Job {job_id} is {action} but not stored!")
5285
time_to_start = 0
5386
else:
54-
time_to_start = (
55-
time_start - datetime.fromtimestamp(job_requested)
56-
).seconds
57-
msg = f"{NOW} {action=} {repository=} workflow={name} {job_id=} {time_to_start=}"
87+
time_to_start = (time_start - datetime.fromtimestamp(job_requested)).seconds
88+
msg = f"{action=} {repository=} {workflow=} {job_id=} {time_to_start=}"
5889

5990
elif action == "completed":
60-
job_requested = jobs.get(job_id, None)
91+
job_requested = jobs.get(job_id)
6192
if not job_requested:
62-
_LOGGER.warning(f"Job {job_id} is {action} but not stored!")
93+
app.logger.warning(f"Job {job_id} is {action} but not stored!")
6394
time_to_finish = 0
6495
else:
6596
time_to_finish = (
66-
time_start - datetime.fromtimestamp(job_requested)
97+
parse_datetime(job["workflow_job"]["completed_at"]) - time_start
6798
).seconds
6899
# delete from memory
69100
del jobs[job_id]
70-
71-
msg = f"{NOW} {action=} {repository=} workflow={name} {job_id=} {time_to_finish=}"
72101

73-
print(msg)
102+
msg = f"{action=} {repository=} {workflow=} {job_id=} {time_to_finish=}"
74103

104+
app.logger.info(msg)
75105
return True
76106

107+
77108
@app.route("/github-webhook", methods=["POST"])
78109
def github_webhook_process():
79110
if not validate_origin_github():
@@ -82,16 +113,14 @@ def github_webhook_process():
82113
event = request.headers.get(GithubHeaders.EVENT.value)
83114
command = f"process_{event}"
84115

85-
#if hasattr(command) and callable(getattr(command)):
86116
if command == "process_workflow_job":
87-
_LOGGER.debug(f"Calling function {command}")
88-
#response = getattr(command)()
117+
app.logger.debug(f"Calling function {command}")
89118
response = process_workflow_job()
90119

91120
if not response:
92-
_LOGGER.error(f"Error calling {event} function")
121+
app.logger.error(f"Error calling {event} function")
93122
return abort(500)
94123
return "OK"
95124

96-
_LOGGER.error(f"Unknown event type {event}, can't handle")
125+
app.logger.error(f"Unknown event type {event}, can't handle")
97126
return abort(405)

const.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# StrEnum only in Python 3.11
22
from enum import Enum
33

4+
45
class GithubHeaders(str, Enum):
56
# NOTE: Flask manipulates as Capital-Word-Per-Section
67
EVENT = "X-Github-Event"

0 commit comments

Comments
 (0)