Bläddra i källkod

add overrriding parameters when using run a synapse by name in API

nico 7 år sedan
förälder
incheckning
82e4b2d54a

+ 9 - 0
Tests/brains/brain_test_api.yml

@@ -17,3 +17,12 @@
   
   - includes:
     - included_brain_test.yml
+
+  - name: "test4"
+    signals:
+      - order: "test_order_with_parameter"
+    neurons:
+      - say:
+          message:
+            - "test message {{ parameter1 }}"
+

+ 91 - 69
Tests/test_rest_api.py

@@ -1,17 +1,16 @@
 import json
 import os
-import tempfile
 import unittest
 
 from flask import Flask
 from flask_testing import LiveServerTestCase
 from mock import mock
 
-from kalliope.core import LIFOBuffer
-from kalliope.core.Models import Singleton
 from kalliope._version import version_str
+from kalliope.core import LIFOBuffer
 from kalliope.core.ConfigurationManager import BrainLoader
 from kalliope.core.ConfigurationManager import SettingLoader
+from kalliope.core.Models import Singleton
 from kalliope.core.RestAPI.FlaskAPI import FlaskAPI
 
 
@@ -66,74 +65,65 @@ class TestRestAPI(LiveServerTestCase):
         expected_content = {
             "Kalliope version": "%s" % version_str
         }
-        self.assertEqual(json.dumps(expected_content, sort_keys=True), json.dumps(json.loads(response.get_data().decode('utf-8')), sort_keys=True))
+        self.assertEqual(json.dumps(expected_content, sort_keys=True),
+                         json.dumps(json.loads(response.get_data().decode('utf-8')), sort_keys=True))
 
     def test_get_all_synapses(self):
         url = self.get_server_url()+"/synapses"
 
         response = self.client.get(url)
         expected_content = {
-            "synapses": [
-                {
-                    "name": "test",
-                    "neurons": [
-                        {
-                            "name": "say",
-                            "parameters": {
-                                "message": [
-                                    "test message"
-                                ]
-                            }
-                        }
-                    ],
-                    "signals": [
-                        {
-                            "order": "test_order"
-                        }
-                    ]
-                },
-                {
-                    "name": "test2",
-                    "neurons": [
-                        {
-                            "name": "say",
-                            "parameters": {
-                                "message": [
-                                    "test message"
-                                ]
-                            }
-                        }
-                    ],
-                    "signals": [
-                        {
-                            "order": "bonjour"
-                        }
-                    ]
-                },
-                {
-                    "name": "test3",
-                    "neurons": [
-                        {
-                            "name": "say",
-                            "parameters": {
-                                "message": [
-                                    "test message"
-                                ]
-                            }
-                        }
-                    ],
-                    "signals": [
-                        {
-                            "order": "test_order_3"
-                        }
-                    ]
-                }
-            ]
+            "synapses": [{
+                "name": "test",
+                "neurons": [{
+                    "name": "say",
+                    "parameters": {
+                        "message": ["test message"]
+                    }
+                }],
+                "signals": [{
+                    "order": "test_order"
+                }]
+            }, {
+                "name": "test2",
+                "neurons": [{
+                    "name": "say",
+                    "parameters": {
+                        "message": ["test message"]
+                    }
+                }],
+                "signals": [{
+                    "order": "bonjour"
+                }]
+            }, {
+                "name": "test4",
+                "neurons": [{
+                    "name": "say",
+                    "parameters": {
+                        "message": ["test message {{parameter1}}"]
+                    }
+                }],
+                "signals": [{
+                    "order": "test_order_with_parameter"
+                }]
+            }, {
+                "name": "test3",
+                "neurons": [{
+                    "name": "say",
+                    "parameters": {
+                        "message": ["test message"]
+                    }
+                }],
+                "signals": [{
+                    "order": "test_order_3"
+                }]
+            }]
         }
         # a lot of char ti process
         self.maxDiff = None
         self.assertEqual(response.status_code, 200)
-        self.assertEqual(json.dumps(expected_content, sort_keys=True), json.dumps(json.loads(response.get_data().decode('utf-8')), sort_keys=True))
+        self.assertEqual(json.dumps(expected_content, sort_keys=True),
+                         json.dumps(json.loads(response.get_data().decode('utf-8')), sort_keys=True))
 
     def test_get_one_synapse(self):
         url = self.get_server_url() + "/synapses/test"
@@ -159,7 +149,8 @@ class TestRestAPI(LiveServerTestCase):
                 ]
             }
         }
-        self.assertEqual(json.dumps(expected_content, sort_keys=True), json.dumps(json.loads(response.get_data().decode('utf-8')), sort_keys=True))
+        self.assertEqual(json.dumps(expected_content, sort_keys=True),
+                         json.dumps(json.loads(response.get_data().decode('utf-8')), sort_keys=True))
 
     def test_get_synapse_not_found(self):
         url = self.get_server_url() + "/synapses/test-none"
@@ -186,7 +177,35 @@ class TestRestAPI(LiveServerTestCase):
                                   'synapse_name': 'test'}],
                             'user_order': None
                             }
-        self.assertEqual(json.dumps(expected_content, sort_keys=True), json.dumps(json.loads(result.get_data().decode('utf-8')), sort_keys=True))
+        self.assertEqual(json.dumps(expected_content, sort_keys=True),
+                         json.dumps(json.loads(result.get_data().decode('utf-8')), sort_keys=True))
+        self.assertEqual(result.status_code, 201)
+
+        # run a synapse by its name with parameter
+        url = self.get_server_url() + "/synapses/start/id/test4"
+        headers = {"Content-Type": "application/json"}
+        data = {"parameters": {"parameter1": "replaced_value"}}
+        result = self.client.post(url, headers=headers, data=json.dumps(data))
+
+        expected_content = {
+          "matched_synapses": [
+            {
+              "matched_order": None,
+              "neuron_module_list": [
+                {
+                  "generated_message": "test message replaced_value",
+                  "neuron_name": "Say"
+                }
+              ],
+              "synapse_name": "test4"
+            }
+          ],
+          "status": "complete",
+          "user_order": None
+        }
+
+        self.assertEqual(json.dumps(expected_content, sort_keys=True),
+                         json.dumps(json.loads(result.get_data().decode('utf-8')), sort_keys=True))
         self.assertEqual(result.status_code, 201)
 
     def test_post_synapse_not_found(self):
@@ -199,7 +218,8 @@ class TestRestAPI(LiveServerTestCase):
             }
         }
 
-        self.assertEqual(json.dumps(expected_content, sort_keys=True), json.dumps(json.loads(result.get_data().decode('utf-8')), sort_keys=True))
+        self.assertEqual(json.dumps(expected_content, sort_keys=True),
+                         json.dumps(json.loads(result.get_data().decode('utf-8')), sort_keys=True))
         self.assertEqual(result.status_code, 404)
 
     def test_run_synapse_with_order(self):
@@ -219,12 +239,13 @@ class TestRestAPI(LiveServerTestCase):
                                                     'generated_message': 'test message', 'neuron_name': 'Say'
                                                 }
                                             ],
-                                  'synapse_name': 'test'
+                                        'synapse_name': 'test'
                                     }
                                 ],
                             'user_order': "test_order"
                             }
-        self.assertEqual(json.dumps(expected_content, sort_keys=True), json.dumps(json.loads(result.get_data().decode('utf-8')), sort_keys=True))
+        self.assertEqual(json.dumps(expected_content, sort_keys=True),
+                         json.dumps(json.loads(result.get_data().decode('utf-8')), sort_keys=True))
         self.assertEqual(result.status_code, 201)
 
     def test_post_synapse_by_order_not_found(self):
@@ -237,7 +258,8 @@ class TestRestAPI(LiveServerTestCase):
 
         expected_content = {'status': None, 'matched_synapses': [], 'user_order': u'non existing order'}
 
-        self.assertEqual(json.dumps(expected_content, sort_keys=True), json.dumps(json.loads(result.get_data().decode('utf-8')), sort_keys=True))
+        self.assertEqual(json.dumps(expected_content, sort_keys=True),
+                         json.dumps(json.loads(result.get_data().decode('utf-8')), sort_keys=True))
         self.assertEqual(result.status_code, 201)
 
         # TODO this doesn't work on travis but works locally with python -m unittest discover
@@ -283,7 +305,7 @@ class TestRestAPI(LiveServerTestCase):
 
         with mock.patch("os.system") as mock_os_system:
             # Scenario 1 : input wav file
-            temp_file = "/tmp/kalliope/tempfile.wav" # tempfile.NamedTemporaryFile(suffix=".wav")
+            temp_file = "/tmp/kalliope/tempfile.wav"  # tempfile.NamedTemporaryFile(suffix=".wav")
             result_file = FlaskAPI._convert_to_wav(temp_file)
             self.assertEqual(temp_file, result_file)
             mock_os_system.assert_not_called()
@@ -299,6 +321,6 @@ if __name__ == '__main__':
     unittest.main()
 
     # suite = unittest.TestSuite()
-    # suite.addTest(TestRestAPI("test_post_synapse_by_order_not_found"))
+    # suite.addTest(TestRestAPI("test_run_synapse_by_name"))
     # runner = unittest.TextTestRunner()
     # runner.run(suite)

+ 6 - 1
kalliope/core/Models/MatchedSynapse.py

@@ -8,11 +8,12 @@ class MatchedSynapse(object):
     This class represent a synapse that has matched an order send by an User.
     """
 
-    def __init__(self, matched_synapse=None, matched_order=None, user_order=None):
+    def __init__(self, matched_synapse=None, matched_order=None, user_order=None, overriding_parameter=None):
         """
         :param matched_synapse: The synapse that has matched in the brain.
         :param matched_order: The order from the synapse that have matched.
         :param user_order: The order said by the user.
+        :param overriding_parameter: If set, those parameters will over
         """
 
         # create a copy of the synapse. the received synapse come from the brain.
@@ -26,6 +27,10 @@ class MatchedSynapse(object):
         if matched_order is not None:
             self.parameters = NeuronParameterLoader.get_parameters(synapse_order=self.matched_order,
                                                                    user_order=user_order)
+        if overriding_parameter is not None:
+            # we suppose that we don't have any parameters.
+            # We replace the current parameter object with the received one
+            self.parameters = overriding_parameter
 
         # list of Neuron Module
         self.neuron_module_list = list()

+ 30 - 3
kalliope/core/RestAPI/FlaskAPI.py

@@ -142,7 +142,13 @@ class FlaskAPI(threading.Thread):
 
         run a synapse without making kalliope speaking
         curl -i -H "Content-Type: application/json" --user admin:secret -X POST  \
-        -d '{"no_voice":"true"} http://127.0.0.1:5000/synapses/start/id/say-hello-fr
+        -d '{"no_voice":"true"}' http://127.0.0.1:5000/synapses/start/id/say-hello-fr
+
+        Run a synapse by its name and pass order's parameters
+        curl -i -H "Content-Type: application/json" --user admin:secret -X POST  \
+        -d '{"no_voice":"true", "parameters": {"parameter1": "value1" }}' \
+        http://127.0.0.1:5000/synapses/start/id/say-hello-fr
+
         :param synapse_name: name(id) of the synapse to execute
         :return:
         """
@@ -153,6 +159,9 @@ class FlaskAPI(threading.Thread):
         # get no_voice_flag if present
         no_voice = self.get_no_voice_flag_from_request(request)
 
+        # get parameters
+        parameters = self.get_parameters_from_request(request)
+
         if synapse_target is None:
             data = {
                 "synapse name not found": "%s" % synapse_name
@@ -160,7 +169,7 @@ class FlaskAPI(threading.Thread):
             return jsonify(error=data), 404
         else:
             # generate a MatchedSynapse from the synapse
-            matched_synapse = MatchedSynapse(matched_synapse=synapse_target)
+            matched_synapse = MatchedSynapse(matched_synapse=synapse_target, overriding_parameter=parameters)
             # get the current LIFO buffer
             lifo_buffer = LIFOBuffer()
             # this is a new call we clean up the LIFO
@@ -329,7 +338,7 @@ class FlaskAPI(threading.Thread):
 
         no_voice = False
         try:
-            received_json = http_request.get_json()
+            received_json = http_request.get_json(force=True, silent=True, cache=True)
             if 'no_voice' in received_json:
                 no_voice = self.str_to_bool(received_json['no_voice'])
         except TypeError:
@@ -349,3 +358,21 @@ class FlaskAPI(threading.Thread):
                 return False
             else:
                 return False
+
+    @staticmethod
+    def get_parameters_from_request(http_request):
+        """
+        Get "parameters" object from the
+        :param http_request:
+        :return:
+        """
+        parameters = None
+        try:
+            received_json = http_request.get_json(silent=False, force=True)
+            if 'parameters' in received_json:
+                parameters = received_json['parameters']
+        except TypeError:
+            pass
+        logger.debug("[FlaskAPI] Overridden parameters: %s" % parameters)
+
+        return parameters