Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
celine-m-s committed Dec 30, 2024
1 parent a8e3f2c commit 77f100e
Show file tree
Hide file tree
Showing 9 changed files with 734 additions and 2 deletions.
3 changes: 3 additions & 0 deletions config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -738,3 +738,6 @@
# Brevo
# ------------------------------------------------------------------------------
BREVO_API_KEY = os.getenv("BREVO_API_KEY")

# Github
API_GITHUB_BASE_URL = "https://api.github.com"
1 change: 1 addition & 0 deletions itou/analytics/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class Migration(migrations.Migration):
("SENTRY-002", "Taux de requêtes en échec"),
("UPDOWN-001", "Taux de disponibilité"),
("UPDOWN-002", "Apdex"),
("GITHUB-001", "Total des PR de correctifs fusionnées aujourd'hui"),
]
),
),
Expand Down
1 change: 1 addition & 0 deletions itou/analytics/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class DatumCode(models.TextChoices):
TECH_SENTRY_FAILURE_RATE = "SENTRY-002", "Taux de requêtes en échec"
TECH_UPDOWN_UPTIME = "UPDOWN-001", "Taux de disponibilité"
TECH_UPDOWN_APDEX = "UPDOWN-002", "Apdex"
TECH_GH_TOTAL_BUGS = "GITHUB-001", "Total des PR de correctifs fusionnées aujourd'hui"


PERCENTAGE_DATUM = [
Expand Down
3 changes: 3 additions & 0 deletions itou/analytics/tech.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from dateutil.relativedelta import relativedelta

from itou.utils.apis.github import GithubApiClient
from itou.utils.apis.sentry import SentryApiClient
from itou.utils.apis.updown import UpdownApiClient

Expand All @@ -12,10 +13,12 @@ def collect_analytics_data(before):
sentry_metrics = SentryApiClient().get_metrics(start=start, end=end)
# uptime is already multiplied by 100 by Updown.
updown_metrics = UpdownApiClient().get_metrics(start=start, end=end)
github_metrics = GithubApiClient().get_metrics(date=start)
data = {
models.DatumCode.TECH_SENTRY_APDEX: round(sentry_metrics["apdex"] * 10000),
models.DatumCode.TECH_SENTRY_FAILURE_RATE: round(sentry_metrics["failure_rate"] * 10000),
models.DatumCode.TECH_UPDOWN_UPTIME: round(updown_metrics["uptime"]),
models.DatumCode.TECH_GH_TOTAL_BUGS: github_metrics["total_pr_bugs"],
}
if updown_metrics.get("apdex"):
data[models.DatumCode.TECH_UPDOWN_APDEX] = round(updown_metrics["apdex"] * 10000)
Expand Down
50 changes: 50 additions & 0 deletions itou/utils/apis/github.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import datetime
import logging

import httpx
import tenacity
from django.conf import settings
from django.utils import timezone


logger = logging.getLogger(__name__)


class GithubApiClient:
def __init__(self):
self.client = httpx.Client(
base_url=f"{settings.API_GITHUB_BASE_URL}/repos/gip-inclusion/",
# Authentication is not required as our repo is public.
headers={
"Accept": "application/vnd.github+json",
"Content-Type": "application/json",
"X-GitHub-Api-Version": "2022-11-28",
},
)

@tenacity.retry(wait=tenacity.wait_fixed(2), stop=tenacity.stop_after_attempt(8))
def _request(self, endpoint, start):
params = {
"labels": ["bug"],
"state": "closed",
"pulls": True,
"since": start.isoformat(), # The GH API does not allow an end date.
}

response = self.client.get(endpoint, params=params)
response.raise_for_status()
return response

def get_metrics(self, date):
response = self._request(endpoint="les-emplois/issues/", start=date)
data_received = response.json()

today_data = []
for data in data_received:
data_date = datetime.datetime.fromisoformat(data["updated_at"])
# TODO; make sure we pass the correct timezone in call.
# https://docs.github.com/en/rest/using-the-rest-api/timezones-and-the-rest-api?apiVersion=2022-11-28#explicitly-providing-an-iso-8601-timestamp-with-timezone-information
if timezone.localdate(data_date) == date.date():
today_data.append(data)

return {"total_pr_bugs": len(today_data)}
6 changes: 4 additions & 2 deletions tests/analytics/test_tech_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,24 @@


@freeze_time("2024-12-03")
def test_collect_tech_metrics_return_all_codes(sentry_respx_mock, updown_respx_mock):
def test_collect_tech_metrics_return_all_codes(sentry_respx_mock, updown_respx_mock, github_respx_mock):
now = timezone.now()
assert tech.collect_analytics_data(before=now).keys() == {
models.DatumCode.TECH_SENTRY_APDEX,
models.DatumCode.TECH_SENTRY_FAILURE_RATE,
models.DatumCode.TECH_UPDOWN_UPTIME,
models.DatumCode.TECH_UPDOWN_APDEX,
models.DatumCode.TECH_GH_TOTAL_BUGS,
}


@freeze_time("2024-12-03")
def test_collect_tech_metrics_with_data(sentry_respx_mock, updown_respx_mock):
def test_collect_tech_metrics_with_data(sentry_respx_mock, updown_respx_mock, github_respx_mock):
now = timezone.now()
assert tech.collect_analytics_data(before=now) == {
models.DatumCode.TECH_SENTRY_APDEX: 9556,
models.DatumCode.TECH_SENTRY_FAILURE_RATE: 812,
models.DatumCode.TECH_UPDOWN_UPTIME: 100,
models.DatumCode.TECH_UPDOWN_APDEX: 9860,
models.DatumCode.TECH_GH_TOTAL_BUGS: 1,
}
26 changes: 26 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import copy
import datetime
import io
import json
import os
import socket
import threading
Expand Down Expand Up @@ -689,3 +690,28 @@ def updown_respx_mock_fixture(respx_mock):

url = f"{settings.API_UPDOWN_BASE_URL}/checks/{settings.API_UPDOWN_CHECK_ID}/metrics/"
return respx_mock.route(headers=headers, method="GET", params=params, url=url).respond(json=json)


@pytest.fixture(name="github_respx_mock")
def github_respx_mock_fixture(respx_mock):
# 4 results between 2024-12-12 and 2024-12-20.
# 3 results updated before 2024-12-17 (the last one being the 16th).
with open(os.path.join(settings.ROOT_DIR, "tests", "data", "github.json")) as file:
resp_json = json.load(file)

# 1 result
start = datetime.datetime(2024, 12, 2, 0, 0, 0, tzinfo=datetime.UTC)
params = {
"labels": ["bug"],
"state": "closed",
"pulls": True,
"since": start.isoformat(), # The GH API does not allow an end date.
}
headers = {
"Accept": "application/vnd.github+json",
"Content-Type": "application/json",
"X-GitHub-Api-Version": "2022-11-28",
}

url = f"{settings.API_GITHUB_BASE_URL}/repos/gip-inclusion/les-emplois/issues/"
return respx_mock.route(headers=headers, method="GET", params=params, url=url).respond(json=resp_json)
Loading

0 comments on commit 77f100e

Please sign in to comment.