diff --git a/common/lib/capa/capa/capa_problem.py b/common/lib/capa/capa/capa_problem.py index 00d3badd5e..e4997db1c6 100644 --- a/common/lib/capa/capa/capa_problem.py +++ b/common/lib/capa/capa/capa_problem.py @@ -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): diff --git a/common/lib/capa/capa/inputtypes.py b/common/lib/capa/capa/inputtypes.py index 13627ae0f6..5b906d71cc 100644 --- a/common/lib/capa/capa/inputtypes.py +++ b/common/lib/capa/capa/inputtypes.py @@ -783,14 +783,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: Initial Text - - %api_key=API_KEY - - + """ template = "matlabinput.html" tags = ['matlabinput'] @@ -807,8 +803,21 @@ class MatlabInput(CodeInput): self.setup_code_response_rendering() xml = self.xml - self.plot_payload = xml.findtext('./plot_payload') + # the new way to define the api key is to set it in the course advanced settings + api_key = getattr(self.capa_system, 'matlab_api_key', None) + if api_key: + plot_payload = '%api_key={}'.format(api_key) + else: + plot_payload = '' + + # the old way to define api_key is to add it to the plot_payload xml. + # are there other things that go in the payload? + xml_payload = xml.findtext('./plot_payload') + if xml_payload: + plot_payload += '\n{}'.format(xml_payload) + + self.plot_payload = plot_payload # Check if problem has been queued self.queuename = 'matlab' self.queue_msg = '' diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index 5b65fb3870..0adbed7eb3 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -1876,10 +1876,14 @@ 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 '' + # matlab api key can be defined in course settings. if so, add it to the grader payload + # only if the problem didn't have an api key already defined. + api_key = getattr(self.capa_system, 'matlab_api_key', None) + if self.xml.find('matlabinput') and api_key and 'api_key' not in grader_payload: + grader_payload += '\n%api_key={}'.format(api_key) + self.payload = {'grader_payload': grader_payload} self.initial_display = find_with_default( diff --git a/common/lib/capa/capa/tests/test_inputtypes.py b/common/lib/capa/capa/tests/test_inputtypes.py index 81acd89afc..ebf8506281 100644 --- a/common/lib/capa/capa/tests/test_inputtypes.py +++ b/common/lib/capa/capa/tests/test_inputtypes.py @@ -628,6 +628,21 @@ class MatlabTest(unittest.TestCase): context = the_input._get_render_context() 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.assertIn('%api_key=test_api_key', payload['grader_payload']) def test_get_html(self): # usual output diff --git a/common/lib/xmodule/xmodule/capa_base.py b/common/lib/xmodule/xmodule/capa_base.py index 45f79df373..a2e73469e6 100644 --- a/common/lib/xmodule/xmodule/capa_base.py +++ b/common/lib/xmodule/xmodule/capa_base.py @@ -189,6 +189,7 @@ class CapaFields(object): default=False, scope=Scope.settings ) + matlab_api_key = String(help="API key for Matlab problems", scope=Scope.settings) class CapaMixin(CapaFields): @@ -292,6 +293,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( diff --git a/common/lib/xmodule/xmodule/modulestore/inheritance.py b/common/lib/xmodule/xmodule/modulestore/inheritance.py index 6555c94d29..0fb8a63915 100644 --- a/common/lib/xmodule/xmodule/modulestore/inheritance.py +++ b/common/lib/xmodule/xmodule/modulestore/inheritance.py @@ -86,7 +86,10 @@ class InheritanceMixin(XBlockMixin): "If the value is not set, infinite attempts are allowed."), values={"min": 0}, scope=Scope.settings ) - + matlab_api_key = String( + help="API key for Matlab problems", + scope=Scope.settings + ) def compute_inherited_metadata(descriptor):