forked from openedx/edx-platform
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add an API for total watch hours of the user
- Loading branch information
Muhammad Faraz Maqsood
authored and
Muhammad Faraz Maqsood
committed
Jul 5, 2024
1 parent
d7304ad
commit 6432608
Showing
6 changed files
with
102 additions
and
3 deletions.
There are no files selected for viewing
Empty file.
Empty file.
13 changes: 13 additions & 0 deletions
13
openedx/features/sdaia_features/course_progress/api/v1/urls.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
""" | ||
URLs for User Watch Hours - SDAIA Specific. | ||
""" | ||
|
||
from django.urls import path # pylint: disable=unused-import | ||
from .views import UserWatchHoursAPIView | ||
|
||
|
||
app_name = "nafath_api_v1" | ||
|
||
urlpatterns = [ | ||
path(r"user_watch_hours", UserWatchHoursAPIView.as_view()), | ||
] |
63 changes: 63 additions & 0 deletions
63
openedx/features/sdaia_features/course_progress/api/v1/views.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
""" | ||
The User Watch Hours API view - SDAIA Specific. | ||
""" | ||
|
||
import logging | ||
import requests | ||
|
||
from MySQLdb._mysql import escape_string as sql_escape_string | ||
from django.conf import settings | ||
from django.utils.decorators import method_decorator | ||
from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication | ||
from rest_framework import permissions, status | ||
from rest_framework.response import Response | ||
from rest_framework.views import APIView | ||
|
||
from common.djangoapps.util.disable_rate_limit import can_disable_rate_limit | ||
from openedx.core.djangoapps.cors_csrf.decorators import ensure_csrf_cookie_cross_domain | ||
from openedx.core.djangoapps.enrollments.views import EnrollmentCrossDomainSessionAuth | ||
from openedx.core.lib.api.authentication import BearerAuthenticationAllowInactiveUser | ||
from openedx.core.lib.api.permissions import ApiKeyHeaderPermissionIsAuthenticated | ||
|
||
|
||
log = logging.getLogger(__name__) | ||
|
||
|
||
@can_disable_rate_limit | ||
class UserWatchHoursAPIView(APIView): | ||
authentication_classes = ( | ||
JwtAuthentication, | ||
BearerAuthenticationAllowInactiveUser, | ||
EnrollmentCrossDomainSessionAuth, | ||
) | ||
permission_classes = (ApiKeyHeaderPermissionIsAuthenticated,) | ||
|
||
def sql_format(template, *args, **kwargs): | ||
args = [sql_escape_string(arg).decode() for arg in args] | ||
kwargs = { | ||
key: sql_escape_string(value).decode() for key, value in kwargs.items() | ||
} | ||
return template.format(*args, **kwargs) | ||
|
||
@method_decorator(ensure_csrf_cookie_cross_domain) | ||
def get(self, request): | ||
""" | ||
Gets the total watch hours for a user. | ||
""" | ||
user_id = request.user.id | ||
clickhouse_uri = ( | ||
f"{settings.CAIRN_CLICKHOUSE_HTTP_SCHEME}://{settings.CAIRN_CLICKHOUSE_USERNAME}:{settings.CAIRN_CLICKHOUSE_PASSWORD}@" | ||
f"{settings.CAIRN_CLICKHOUSE_HOST}:{settings.CAIRN_CLICKHOUSE_HTTP_PORT}/?database={settings.CAIRN_CLICKHOUSE_DATABASE}" | ||
) | ||
query = self.sql_format( | ||
f"SELECT SUM(duration) as `Watch time` FROM `openedx`.`video_view_segments` WHERE user_id={user_id};" | ||
) | ||
try: | ||
response = requests.get(clickhouse_uri, data=query.encode("utf8")) | ||
watch_time = float(response.content.decode().strip()) / (60 * 60) | ||
return Response(status=status.HTTP_200_OK, data={"watch_time": watch_time}) | ||
except Exception as e: | ||
log.error( | ||
f"Unable to fetch watch for user {user_id} due to this exception: {str(e)}" | ||
) | ||
raise HTTPException(status_code=500, detail=str(e)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
""" | ||
URLs for User Watch Hours - SDAIA Specific. | ||
""" | ||
|
||
from django.urls import path # pylint: disable=unused-import | ||
from django.conf.urls import include | ||
|
||
|
||
urlpatterns = [ | ||
path( | ||
"/api/v1/", | ||
include("openedx.features.sdaia_features.course_progress.api.v1.urls", namespace="course_progress_api_v1"), | ||
), | ||
] |