From 8f9b4ec044e7dd8c00211b3534e7cc56db699a97 Mon Sep 17 00:00:00 2001 From: F-G Fernandez <26927750+frgfm@users.noreply.github.com> Date: Mon, 30 Oct 2023 12:38:36 +0100 Subject: [PATCH] refactor: Refactors analytics into telemetry module (#20) * refactor: Refactored telemetry * docs: Fixes codecov badge in README * refactor: Renamed constructor arg --- README.md | 2 +- src/app/api/api_v1/endpoints/guidelines.py | 10 +++++----- src/app/api/api_v1/endpoints/login.py | 10 +++++----- src/app/api/api_v1/endpoints/repos.py | 16 ++++++++-------- src/app/api/api_v1/endpoints/users.py | 6 +++--- .../{core/analytics.py => services/telemetry.py} | 14 +++++++------- 6 files changed, 29 insertions(+), 29 deletions(-) rename src/app/{core/analytics.py => services/telemetry.py} (62%) diff --git a/README.md b/README.md index 40171fd..77cb2e0 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ - +
diff --git a/src/app/api/api_v1/endpoints/guidelines.py b/src/app/api/api_v1/endpoints/guidelines.py index 399930f..1db7277 100644 --- a/src/app/api/api_v1/endpoints/guidelines.py +++ b/src/app/api/api_v1/endpoints/guidelines.py @@ -9,10 +9,10 @@ from fastapi import APIRouter, Depends, Path, Security, status from app.api.dependencies import get_current_user, get_guideline_crud -from app.core.analytics import analytics_client from app.crud import GuidelineCRUD from app.models import Guideline, UserScope from app.schemas.guidelines import ContentUpdate, GuidelineCreate, GuidelineEdit, OrderUpdate +from app.services.telemetry import telemetry_client router = APIRouter() @@ -24,7 +24,7 @@ async def create_guideline( user=Security(get_current_user, scopes=[UserScope.USER, UserScope.ADMIN]), ) -> Guideline: guideline = await guidelines.create(payload) - analytics_client.capture(user.id, event="guideline-creation", properties={"repo_id": payload.repo_id}) + telemetry_client.capture(user.id, event="guideline-creation", properties={"repo_id": payload.repo_id}) return guideline @@ -53,7 +53,7 @@ async def update_guideline_content( user=Security(get_current_user, scopes=[UserScope.USER, UserScope.ADMIN]), ) -> Guideline: guideline = await guidelines.update(guideline_id, ContentUpdate(**payload.dict(), updated_at=datetime.utcnow())) - analytics_client.capture(user.id, event="guideline-content", properties={"repo_id": guideline.repo_id}) + telemetry_client.capture(user.id, event="guideline-content", properties={"repo_id": guideline.repo_id}) return guideline @@ -65,7 +65,7 @@ async def update_guideline_order( user=Security(get_current_user, scopes=[UserScope.USER, UserScope.ADMIN]), ) -> Guideline: guideline = await guidelines.update(guideline_id, OrderUpdate(order=order_idx, updated_at=datetime.utcnow())) - analytics_client.capture(user.id, event="guideline-order", properties={"repo_id": guideline.repo_id}) + telemetry_client.capture(user.id, event="guideline-order", properties={"repo_id": guideline.repo_id}) return guideline @@ -77,4 +77,4 @@ async def delete_guideline( ) -> None: guideline = cast(Guideline, await guidelines.get(guideline_id, strict=True)) await guidelines.delete(guideline_id) - analytics_client.capture(user.id, event="guideline-deletion", properties={"repo_id": guideline.repo_id}) + telemetry_client.capture(user.id, event="guideline-deletion", properties={"repo_id": guideline.repo_id}) diff --git a/src/app/api/api_v1/endpoints/login.py b/src/app/api/api_v1/endpoints/login.py index 6385032..3f40085 100644 --- a/src/app/api/api_v1/endpoints/login.py +++ b/src/app/api/api_v1/endpoints/login.py @@ -12,13 +12,13 @@ from pydantic import HttpUrl from app.api.dependencies import get_user_crud -from app.core.analytics import analytics_client from app.core.config import settings from app.core.security import create_access_token, hash_password, verify_password from app.crud import UserCRUD from app.models import UserScope from app.schemas.login import GHAccessToken, GHToken, GHTokenRequest, Token, TokenRequest from app.schemas.users import UserCreation +from app.services.telemetry import telemetry_client router = APIRouter() @@ -72,7 +72,7 @@ async def login_with_creds( # create access token using user user_id/user_scopes token_data = {"sub": str(user.id), "scopes": user.scope.split()} token = await create_access_token(token_data, settings.ACCESS_TOKEN_UNLIMITED_MINUTES) - analytics_client.capture(user.id, event="user-login", properties={"login": user.login}) + telemetry_client.capture(user.id, event="user-login", properties={"login": user.login}) return Token(access_token=token, token_type="bearer") # nosec B106 # noqa S106 @@ -101,7 +101,7 @@ async def login_with_github_token( user = await users.get(gh_user["id"], strict=False) # Register if non existing if user is None: - analytics_client.identify( + telemetry_client.identify( gh_user["id"], properties={ "login": gh_user["login"], @@ -118,11 +118,11 @@ async def login_with_github_token( scope=UserScope.USER, ) ) - analytics_client.capture(user.id, event="user-creation", properties={"login": gh_user["login"]}) + telemetry_client.capture(user.id, event="user-creation", properties={"login": gh_user["login"]}) # create access token using user user_id/user_scopes token_data = {"sub": str(user.id), "scopes": user.scope.split()} token = await create_access_token(token_data, settings.ACCESS_TOKEN_UNLIMITED_MINUTES) - analytics_client.capture(user.id, event="user-login", properties={"login": user.login}) + telemetry_client.capture(user.id, event="user-login", properties={"login": user.login}) return Token(access_token=token, token_type="bearer") # nosec B106 # noqa S106 diff --git a/src/app/api/api_v1/endpoints/repos.py b/src/app/api/api_v1/endpoints/repos.py index 883bf3c..52cce47 100644 --- a/src/app/api/api_v1/endpoints/repos.py +++ b/src/app/api/api_v1/endpoints/repos.py @@ -9,11 +9,11 @@ from fastapi import APIRouter, Depends, HTTPException, Path, Security, status from app.api.dependencies import get_current_user, get_guideline_crud, get_repo_crud -from app.core.analytics import analytics_client from app.crud import GuidelineCRUD, RepositoryCRUD from app.models import Guideline, Repository, User, UserScope from app.schemas.guidelines import OrderUpdate from app.schemas.repos import GuidelineOrder, RepoCreate, RepoCreation, RepoUpdate +from app.services.telemetry import telemetry_client router = APIRouter() @@ -29,13 +29,13 @@ async def create_repo( if entry is not None: await repos.update(payload.id, RepoUpdate(removed_at=None)) entry.removed_at = None - analytics_client.capture( + telemetry_client.capture( user.id, event="repo-enable", properties={"repo_id": payload.id, "full_name": payload.full_name} ) return entry repo = await repos.create(RepoCreation(**payload.dict(), installed_by=user.id)) - analytics_client.capture( + telemetry_client.capture( user.id, event="repo-creation", properties={"repo_id": payload.id, "full_name": payload.full_name} ) return repo @@ -56,7 +56,7 @@ async def fetch_repos( user=Security(get_current_user, scopes=[UserScope.USER, UserScope.ADMIN]), ) -> List[Repository]: entries = await repos.fetch_all() if user.scope == UserScope.ADMIN else await repos.fetch_all(("owner_id", user.id)) - analytics_client.capture(user.id, event="repo-fetch") + telemetry_client.capture(user.id, event="repo-fetch") return [elt for elt in entries] @@ -81,7 +81,7 @@ async def reorder_guidelines( await guidelines.update(guideline_id, OrderUpdate(order=order_idx, updated_at=datetime.utcnow())) for order_idx, guideline_id in enumerate(payload.guideline_ids) ] - analytics_client.capture(user.id, event="guideline-order", properties={"repo_id": repo_id}) + telemetry_client.capture(user.id, event="guideline-order", properties={"repo_id": repo_id}) return guideline_list @@ -92,7 +92,7 @@ async def disable_repo( user=Security(get_current_user, scopes=[UserScope.USER, UserScope.ADMIN]), ) -> Repository: repo = await repos.update(repo_id, RepoUpdate(removed_at=datetime.utcnow())) - analytics_client.capture(user.id, event="repo-disable", properties={"repo_id": repo_id}) + telemetry_client.capture(user.id, event="repo-disable", properties={"repo_id": repo_id}) return repo @@ -103,7 +103,7 @@ async def enable_repo( user=Security(get_current_user, scopes=[UserScope.USER, UserScope.ADMIN]), ) -> Repository: repo = await repos.update(repo_id, RepoUpdate(removed_at=None)) - analytics_client.capture(user.id, event="repo-enable", properties={"repo_id": repo_id}) + telemetry_client.capture(user.id, event="repo-enable", properties={"repo_id": repo_id}) return repo @@ -114,7 +114,7 @@ async def delete_repo( user=Security(get_current_user, scopes=[UserScope.ADMIN]), ) -> None: await repos.delete(repo_id) - analytics_client.capture(user.id, event="repo-delete", properties={"repo_id": repo_id}) + telemetry_client.capture(user.id, event="repo-delete", properties={"repo_id": repo_id}) @router.get("/{repo_id}/guidelines", status_code=status.HTTP_200_OK) diff --git a/src/app/api/api_v1/endpoints/users.py b/src/app/api/api_v1/endpoints/users.py index 2335ae1..ddc5ae0 100644 --- a/src/app/api/api_v1/endpoints/users.py +++ b/src/app/api/api_v1/endpoints/users.py @@ -8,11 +8,11 @@ from fastapi import APIRouter, Depends, Path, Security, status from app.api.dependencies import get_current_user, get_user_crud -from app.core.analytics import analytics_client from app.core.security import hash_password from app.crud import UserCRUD from app.models import User, UserScope from app.schemas.users import Cred, CredHash, UserCreate, UserCreation +from app.services.telemetry import telemetry_client router = APIRouter() @@ -29,7 +29,7 @@ async def create_user( user = await users.create( UserCreation(id=payload.id, login=payload.login, hashed_password=pwd, scope=payload.scope) ) - analytics_client.capture(payload.id, event="user-creation", properties={"login": payload.login}) + telemetry_client.capture(payload.id, event="user-creation", properties={"login": payload.login}) return user @@ -68,4 +68,4 @@ async def delete_user( user=Security(get_current_user, scopes=[UserScope.ADMIN]), ) -> None: await users.delete(user_id) - analytics_client.capture(user_id, event="user-deletion", properties={"login": user.login}) + telemetry_client.capture(user_id, event="user-deletion", properties={"login": user.login}) diff --git a/src/app/core/analytics.py b/src/app/services/telemetry.py similarity index 62% rename from src/app/core/analytics.py rename to src/app/services/telemetry.py index eae1d92..8e33aa6 100644 --- a/src/app/core/analytics.py +++ b/src/app/services/telemetry.py @@ -12,14 +12,14 @@ logger = logging.getLogger("uvicorn.error") -__all__ = ["analytics_client"] +__all__ = ["telemetry_client"] -class AnalyticsClient: - def __init__(self, ph_api_key: Union[str, None] = None) -> None: - self.is_enabled = isinstance(ph_api_key, str) - if isinstance(ph_api_key, str): - self.ph_client = Posthog(project_api_key=ph_api_key, host="https://eu.posthog.com") +class TelemetryClient: + def __init__(self, api_key: Union[str, None] = None) -> None: + self.is_enabled = isinstance(api_key, str) + if isinstance(api_key, str): + self.ph_client = Posthog(project_api_key=api_key, host="https://eu.posthog.com") logger.info("PostHog enabled") def capture(self, *args, **kwargs) -> None: @@ -31,4 +31,4 @@ def identify(self, *args, **kwargs) -> None: self.ph_client.identify(*args, **kwargs) -analytics_client = AnalyticsClient(ph_api_key=settings.POSTHOG_KEY) +telemetry_client = TelemetryClient(api_key=settings.POSTHOG_KEY)