Skip to content

Commit

Permalink
Merge pull request #565 from openedx/eahmadjaved/ENT-10020
Browse files Browse the repository at this point in the history
feat: get groups data from membership endpoint using enterprise client
  • Loading branch information
jajjibhai008 authored Feb 25, 2025
2 parents ecb8af8 + 7db0106 commit ee84fa9
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 7 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ Unreleased

=========================

[10.9.0] - 2025-02-24
---------------------
* feat: get groups data from membership endpoint using enterprise client.

[10.8.1] - 2025-02-20
---------------------
* feat: Added 2 new columns in module performance report model and exposed them via associated REST API.
Expand Down
2 changes: 1 addition & 1 deletion enterprise_data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
Enterprise data api application. This Django app exposes API endpoints used by enterprises.
"""

__version__ = "10.8.1"
__version__ = "10.9.0"
53 changes: 47 additions & 6 deletions enterprise_data/api/v1/views/enterprise_learner.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from rest_framework import filters, viewsets
from rest_framework.decorators import action
from rest_framework.exceptions import NotFound
from rest_framework.response import Response

from django.conf import settings
Expand All @@ -20,6 +21,7 @@

from enterprise_data.admin_analytics.database.utils import LOGGER
from enterprise_data.api.v1 import serializers
from enterprise_data.clients import EnterpriseApiClient
from enterprise_data.models import EnterpriseGroupMembership, EnterpriseLearner, EnterpriseLearnerEnrollment
from enterprise_data.paginators import EnterpriseEnrollmentsPagination
from enterprise_data.renderers import EnrollmentsCSVRenderer
Expand Down Expand Up @@ -176,12 +178,51 @@ def apply_filters(self, queryset):

group_uuid = query_filters.get('group_uuid')
if group_uuid:
flex_group_exists = EnterpriseGroupMembership.objects.filter(
enterprise_customer_user_id=OuterRef('enterprise_user_id'),
enterprise_group_uuid=group_uuid,
group_type='flex'
)
queryset = queryset.filter(Exists(flex_group_exists))
queryset = self.filter_by_group_uuid(queryset, group_uuid)

return queryset

def filter_by_group_uuid(self, queryset, group_uuid):
"""
Filters the queryset based on the provided group_uuid. If no records are found,
it attempts to fetch group learners from the API and filter the queryset again.
Args:
queryset (QuerySet): The initial queryset to filter.
group_uuid (str): The UUID of the group to filter by.
Returns:
QuerySet: The filtered queryset.
"""
flex_group_exists = EnterpriseGroupMembership.objects.filter(
enterprise_customer_user_id=OuterRef('enterprise_user_id'),
enterprise_group_uuid=group_uuid,
group_type='flex'
)

# First, filter the queryset using flex_group_exists
filtered_queryset = queryset.filter(Exists(flex_group_exists))

# If no records are found, attempt to fetch group_learners from the API
if not filtered_queryset.exists():
try:
enterprise_api_client = EnterpriseApiClient(
settings.BACKEND_SERVICE_EDX_OAUTH2_PROVIDER_URL,
settings.BACKEND_SERVICE_EDX_OAUTH2_KEY,
settings.BACKEND_SERVICE_EDX_OAUTH2_SECRET,
)
group_learners = enterprise_api_client.get_enterprise_group_learners(group_uuid)
if group_learners:
group_learners_ids = [learner['enterprise_customer_user_id'] for learner in group_learners]
queryset = queryset.filter(enterprise_user_id__in=group_learners_ids)
else:
LOGGER.warning(f"No group learners found for group: {group_uuid}")
raise NotFound(f"No learners found for group: {group_uuid}")
except (Exception) as e: # pylint: disable=broad-exception-caught
LOGGER.error("Failed to fetch group learners from API: %s", e)
queryset = queryset.none() # API call failed or unexpected error, return an empty queryset
else:
queryset = filtered_queryset

return queryset

Expand Down
27 changes: 27 additions & 0 deletions enterprise_data/clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,30 @@ def get_enterprise_customer(self, enterprise_uuid):
TieredCache.set_all_tiers(cache_key, data, DEFAULT_REPORTING_CACHE_TIMEOUT)

return data

def get_enterprise_group_learners(self, group_uuid):
"""
Get the learners associated with a given enterprise group.
Returns: list of learners or None if unable to retrieve or no learners exist
"""
LOGGER.info(f'[EnterpriseApiClient] getting learners for enterprise group:{group_uuid}')
url = urljoin(self.API_BASE_URL, f'enterprise-group/{group_uuid}/learners/')
all_learners = []

try:
while url:
response = self.get(url)
response.raise_for_status()
data = response.json()
all_learners.extend(data.get('results', []))
url = data.get('next') # Get the URL for the next page, if any

except (HTTPError, RequestException) as exc:
LOGGER.warning(
"[Data Overview Failure] Unable to retrieve Enterprise Group Learners details. "
f"Group: {group_uuid}, Exception: {exc}"
)
return None

return all_learners

0 comments on commit ee84fa9

Please sign in to comment.