Skip to content

Commit

Permalink
Merge pull request #2004 from openedx/hamza/ENT-8277-record-blackboar…
Browse files Browse the repository at this point in the history
…d-client-calls

[ENT-8277] - feat: record Blackboard client calls
  • Loading branch information
hamzawaleed01 authored Jan 31, 2024
2 parents 5a4d283 + 7446e03 commit 8c10f51
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ Change Log
Unreleased
----------

[4.11.4]
---------
* feat: update blackboard client to store API calls in DB

[4.11.3]
---------
* feat: update cornerstone client to store API calls in DB
Expand Down
2 changes: 1 addition & 1 deletion enterprise/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
Your project description goes here.
"""

__version__ = "4.11.3"
__version__ = "4.11.4"
90 changes: 90 additions & 0 deletions integrated_channels/blackboard/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import copy
import json
import logging
import time
from http import HTTPStatus
from urllib.parse import urljoin

Expand Down Expand Up @@ -594,11 +595,72 @@ def generate_course_content_delete_url(self, course_id, content_id):
path=COURSE_CONTENT_DELETE_PATH.format(course_id=course_id, content_id=content_id)
)

def stringify_and_store_api_record(
self, url, data, time_taken, status_code, response_body
):
"""
Helper method to stringify `data` arg and create new record in
`IntegratedChannelAPIRequestLogs` model
"""
if data is not None:
# Convert data to string if it's not already a string
if not isinstance(data, str):
try:
# Check if data is a dictionary, list, or tuple then convert to JSON string
if isinstance(data, (dict, list, tuple)):
data = json.dumps(data)
else:
# If it's another type, simply convert to string
data = str(data)
except Exception as e: # pylint: disable=broad-except
LOGGER.error(
generate_formatted_log(
self.enterprise_configuration.channel_code(),
self.enterprise_configuration.enterprise_customer.uuid,
None,
None,
f"stringify_and_store_api_record: Unable to stringify data: {e}",
)
)
# Store stringified data in the database
try:
IntegratedChannelAPIRequestLogs = apps.get_model(
"integrated_channel", "IntegratedChannelAPIRequestLogs"
)
IntegratedChannelAPIRequestLogs.store_api_call(
enterprise_customer=self.enterprise_configuration.enterprise_customer,
enterprise_customer_configuration_id=self.enterprise_configuration.id,
endpoint=url,
payload=data,
time_taken=time_taken,
status_code=status_code,
response_body=response_body,
)
except Exception as e: # pylint: disable=broad-except
LOGGER.error(
generate_formatted_log(
self.enterprise_configuration.channel_code(),
self.enterprise_configuration.enterprise_customer.uuid,
None,
None,
f"stringify_and_store_api_record: Failed to store data in the database: {e}",
)
)

def _get(self, url, data=None):
"""
Returns request's get response and raises Client Errors if appropriate.
"""
start_time = time.time()
get_response = self.session.get(url, params=data)
time_taken = time.time() - start_time
self.stringify_and_store_api_record(
url=url,
data=data,
time_taken=time_taken,
status_code=get_response.status_code,
response_body=get_response.text,
)
if get_response.status_code >= 400:
raise ClientError(get_response.text, get_response.status_code)
return get_response
Expand All @@ -607,7 +669,16 @@ def _patch(self, url, data):
"""
Returns request's patch response and raises Client Errors if appropriate.
"""
start_time = time.time()
patch_response = self.session.patch(url, json=data)
time_taken = time.time() - start_time
self.stringify_and_store_api_record(
url=url,
data=data,
time_taken=time_taken,
status_code=patch_response.status_code,
response_body=patch_response.text,
)
if patch_response.status_code >= 400:
raise ClientError(patch_response.text, patch_response.status_code)
return patch_response
Expand All @@ -616,7 +687,17 @@ def _post(self, url, data):
"""
Returns request's post response and raises Client Errors if appropriate.
"""
start_time = time.time()
post_response = self.session.post(url, json=data)
time_taken = time.time() - start_time
self.stringify_and_store_api_record(
url=url,
data=data,
time_taken=time_taken,
status_code=post_response.status_code,
response_body=post_response.text,
)

if post_response.status_code >= 400:
raise ClientError(post_response.text, post_response.status_code)
return post_response
Expand All @@ -625,7 +706,16 @@ def _delete(self, url):
"""
Returns request's delete response and raises Client Errors if appropriate.
"""
start_time = time.time()
response = self.session.delete(url)
time_taken = time.time() - start_time
self.stringify_and_store_api_record(
url=url,
data='',
time_taken=time_taken,
status_code=response.status_code,
response_body=response.text,
)
if response.status_code >= 400:
raise ClientError(response.text, response.status_code)
return response
Expand Down

0 comments on commit 8c10f51

Please sign in to comment.