Commit ed9ab3ad by Dave St.Germain

Merge pull request #3501 from edx/dcs/matlab-api-key

Allow courses to set Matlab API key globally, in advanced settings.
parents 2fd2eda6 0173eaf9
......@@ -14,6 +14,7 @@ PROBLEM_WEIGHT = "Problem Weight"
RANDOMIZATION = 'Randomization'
SHOW_ANSWER = "Show Answer"
TIMER_BETWEEN_ATTEMPTS = "Timer Between Attempts"
MATLAB_API_KEY = "Matlab API key"
@step('I have created a Blank Common Problem$')
def i_created_blank_common_problem(step):
......@@ -40,11 +41,12 @@ def i_see_advanced_settings_with_values(step):
world.verify_all_setting_entries(
[
[DISPLAY_NAME, "Blank Common Problem", True],
[MATLAB_API_KEY, "", False],
[MAXIMUM_ATTEMPTS, "", False],
[PROBLEM_WEIGHT, "", False],
[RANDOMIZATION, "Never", False],
[SHOW_ANSWER, "Finished", False],
[TIMER_BETWEEN_ATTEMPTS, "0", False]
[TIMER_BETWEEN_ATTEMPTS, "0", False],
])
......
......@@ -92,6 +92,7 @@ class LoncapaSystem(object):
seed, # Why do we do this if we have self.seed?
STATIC_URL, # pylint: disable=invalid-name
xqueue,
matlab_api_key=None
):
self.ajax_url = ajax_url
self.anonymous_student_id = anonymous_student_id
......@@ -105,6 +106,7 @@ class LoncapaSystem(object):
self.seed = seed # Why do we do this if we have self.seed?
self.STATIC_URL = STATIC_URL # pylint: disable=invalid-name
self.xqueue = xqueue
self.matlab_api_key = matlab_api_key
class LoncapaProblem(object):
......
......@@ -793,14 +793,10 @@ class MatlabInput(CodeInput):
"""
InputType for handling Matlab code input
TODO: API_KEY will go away once we have a way to specify it per-course
Example:
<matlabinput rows="10" cols="80" tabsize="4">
Initial Text
<plot_payload>
%api_key=API_KEY
</plot_payload>
</matlabinput>
</matlabinput>
"""
template = "matlabinput.html"
tags = ['matlabinput']
......@@ -817,8 +813,8 @@ class MatlabInput(CodeInput):
self.setup_code_response_rendering()
xml = self.xml
self.plot_payload = xml.findtext('./plot_payload')
self.plot_payload = xml.findtext('./plot_payload')
# Check if problem has been queued
self.queuename = 'matlab'
self.queue_msg = ''
......@@ -967,7 +963,10 @@ class MatlabInput(CodeInput):
contents = {
'grader_payload': self.plot_payload,
'student_info': json.dumps(student_info),
'student_response': response
'student_response': response,
'token': getattr(self.capa_system, 'matlab_api_key', None),
'endpoint_version': "2",
'requestor_id': anonymous_student_id,
}
(error, msg) = qinterface.send_to_queue(header=xheader,
......
......@@ -1878,11 +1878,18 @@ class CodeResponse(LoncapaResponse):
self.answer (an answer to display to the student in the LMS)
self.payload
"""
# Note that CodeResponse is agnostic to the specific contents of
# grader_payload
grader_payload = codeparam.find('grader_payload')
grader_payload = grader_payload.text if grader_payload is not None else ''
self.payload = {'grader_payload': grader_payload}
self.payload = {
'grader_payload': grader_payload,
}
# matlab api key can be defined in course settings. if so, add it to the grader payload
api_key = getattr(self.capa_system, 'matlab_api_key', None)
if self.xml.find('matlabinput') and api_key:
self.payload['token'] = api_key
self.payload['endpoint_version'] = "2"
self.payload['requestor_id'] = self.capa_system.anonymous_student_id
self.initial_display = find_with_default(
codeparam, 'initial_display', '')
......
......@@ -625,6 +625,22 @@ class MatlabTest(unittest.TestCase):
the_input = self.input_class(test_capa_system(), elt, state)
self.assertEqual(the_input.status, 'unsubmitted')
def test_matlab_api_key(self):
"""
Test that api_key ends up in the xqueue payload
"""
elt = etree.fromstring(self.xml)
system = test_capa_system()
system.matlab_api_key = 'test_api_key'
the_input = lookup_tag('matlabinput')(system, elt, {})
data = {'submission': 'x = 1234;'}
response = the_input.handle_ajax("plot", data)
body = system.xqueue['interface'].send_to_queue.call_args[1]['body']
payload = json.loads(body)
self.assertEqual('test_api_key', payload['token'])
self.assertEqual('2', payload['endpoint_version'])
def test_get_html(self):
# usual output
......
......@@ -189,6 +189,15 @@ class CapaFields(object):
default=False,
scope=Scope.settings
)
matlab_api_key = String(
display_name="Matlab API key",
help="Enter the API key provided by MathWorks for accessing the MATLAB Hosted Service. "
"This key is granted for exclusive use by this course for the specified duration. "
"Please do not share the API key with other courses and notify MathWorks immediately "
"if you believe the key is exposed or compromised. To obtain a key for your course, "
"or to report and issue, please contact moocsupport@mathworks.com",
scope=Scope.settings
)
class CapaMixin(CapaFields):
......@@ -292,6 +301,7 @@ class CapaMixin(CapaFields):
seed=self.runtime.seed, # Why do we do this if we have self.seed?
STATIC_URL=self.runtime.STATIC_URL,
xqueue=self.runtime.xqueue,
matlab_api_key=self.matlab_api_key
)
return LoncapaProblem(
......
......@@ -86,7 +86,15 @@ class InheritanceMixin(XBlockMixin):
"If the value is not set, infinite attempts are allowed."),
values={"min": 0}, scope=Scope.settings
)
matlab_api_key = String(
display_name="Matlab API key",
help="Enter the API key provided by MathWorks for accessing the MATLAB Hosted Service. "
"This key is granted for exclusive use by this course for the specified duration. "
"Please do not share the API key with other courses and notify MathWorks immediately "
"if you believe the key is exposed or compromised. To obtain a key for your course, "
"or to report and issue, please contact moocsupport@mathworks.com",
scope=Scope.settings
)
def compute_inherited_metadata(descriptor):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment