From fbe171db337a2d7836aee6fc82782577ea207982 Mon Sep 17 00:00:00 2001
From: Siraj R Aizlewood <siraj@aurelio.ai>
Date: Tue, 30 Apr 2024 03:40:05 +0400
Subject: [PATCH] Pytests for get_schema_openai.

---
 docs/02-dynamic-routes.ipynb       | 87 +++++++++++++-----------------
 tests/unit/llms/test_llm_openai.py | 35 ++++++++++++
 2 files changed, 72 insertions(+), 50 deletions(-)

diff --git a/docs/02-dynamic-routes.ipynb b/docs/02-dynamic-routes.ipynb
index 13174986..5b59ecc9 100644
--- a/docs/02-dynamic-routes.ipynb
+++ b/docs/02-dynamic-routes.ipynb
@@ -79,7 +79,7 @@
           "name": "stdout",
           "output_type": "stream",
           "text": [
-            "Requirement already satisfied: tzdata in c:\\users\\siraj\\documents\\personal\\work\\aurelio\\virtual environments\\semantic_router_3\\lib\\site-packages (2024.1)"
+            "Requirement already satisfied: tzdata in c:\\users\\siraj\\documents\\personal\\work\\aurelio\\virtual environments\\semantic_router_3\\lib\\site-packages (2024.1)\n"
           ]
         },
         {
@@ -88,20 +88,7 @@
           "text": [
             "\n",
             "[notice] A new release of pip is available: 23.1.2 -> 24.0\n",
-            "[notice] To update, run: python.exe -m pip install --upgrade pip\n"
-          ]
-        },
-        {
-          "name": "stdout",
-          "output_type": "stream",
-          "text": [
-            "\n"
-          ]
-        },
-        {
-          "name": "stderr",
-          "output_type": "stream",
-          "text": [
+            "[notice] To update, run: python.exe -m pip install --upgrade pip\n",
             "\n",
             "[notice] A new release of pip is available: 23.1.2 -> 24.0\n",
             "[notice] To update, run: python.exe -m pip install --upgrade pip\n"
@@ -198,27 +185,27 @@
           "name": "stderr",
           "output_type": "stream",
           "text": [
-            "\u001b[32m2024-04-30 01:57:24 INFO semantic_router.utils.logger local\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:24 INFO semantic_router.utils.logger Document 1 length: 34\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:24 INFO semantic_router.utils.logger Document 1 trunc length: 34\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:24 INFO semantic_router.utils.logger Document 2 length: 51\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:24 INFO semantic_router.utils.logger Document 2 trunc length: 51\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:24 INFO semantic_router.utils.logger Document 3 length: 66\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:24 INFO semantic_router.utils.logger Document 3 trunc length: 66\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:24 INFO semantic_router.utils.logger Document 4 length: 38\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:24 INFO semantic_router.utils.logger Document 4 trunc length: 38\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:24 INFO semantic_router.utils.logger Document 5 length: 27\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:24 INFO semantic_router.utils.logger Document 5 trunc length: 27\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:24 INFO semantic_router.utils.logger Document 6 length: 24\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:24 INFO semantic_router.utils.logger Document 6 trunc length: 24\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:24 INFO semantic_router.utils.logger Document 7 length: 21\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:24 INFO semantic_router.utils.logger Document 7 trunc length: 21\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:24 INFO semantic_router.utils.logger Document 8 length: 20\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:24 INFO semantic_router.utils.logger Document 8 trunc length: 20\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:24 INFO semantic_router.utils.logger Document 9 length: 25\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:24 INFO semantic_router.utils.logger Document 9 trunc length: 25\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:24 INFO semantic_router.utils.logger Document 10 length: 22\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:24 INFO semantic_router.utils.logger Document 10 trunc length: 22\u001b[0m\n"
+            "\u001b[32m2024-04-30 02:22:00 INFO semantic_router.utils.logger local\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:00 INFO semantic_router.utils.logger Document 1 length: 34\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:00 INFO semantic_router.utils.logger Document 1 trunc length: 34\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:00 INFO semantic_router.utils.logger Document 2 length: 51\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:00 INFO semantic_router.utils.logger Document 2 trunc length: 51\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:00 INFO semantic_router.utils.logger Document 3 length: 66\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:00 INFO semantic_router.utils.logger Document 3 trunc length: 66\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:00 INFO semantic_router.utils.logger Document 4 length: 38\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:00 INFO semantic_router.utils.logger Document 4 trunc length: 38\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:00 INFO semantic_router.utils.logger Document 5 length: 27\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:00 INFO semantic_router.utils.logger Document 5 trunc length: 27\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:00 INFO semantic_router.utils.logger Document 6 length: 24\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:00 INFO semantic_router.utils.logger Document 6 trunc length: 24\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:00 INFO semantic_router.utils.logger Document 7 length: 21\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:00 INFO semantic_router.utils.logger Document 7 trunc length: 21\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:00 INFO semantic_router.utils.logger Document 8 length: 20\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:00 INFO semantic_router.utils.logger Document 8 trunc length: 20\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:00 INFO semantic_router.utils.logger Document 9 length: 25\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:00 INFO semantic_router.utils.logger Document 9 trunc length: 25\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:00 INFO semantic_router.utils.logger Document 10 length: 22\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:00 INFO semantic_router.utils.logger Document 10 trunc length: 22\u001b[0m\n"
           ]
         }
       ],
@@ -267,8 +254,8 @@
           "name": "stderr",
           "output_type": "stream",
           "text": [
-            "\u001b[32m2024-04-30 01:57:25 INFO semantic_router.utils.logger Document 1 length: 24\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:25 INFO semantic_router.utils.logger Document 1 trunc length: 24\u001b[0m\n"
+            "\u001b[32m2024-04-30 02:22:01 INFO semantic_router.utils.logger Document 1 length: 24\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:01 INFO semantic_router.utils.logger Document 1 trunc length: 24\u001b[0m\n"
           ]
         },
         {
@@ -345,7 +332,7 @@
         {
           "data": {
             "text/plain": [
-              "'17:57'"
+              "'18:22'"
             ]
           },
           "execution_count": 6,
@@ -462,13 +449,13 @@
           "name": "stderr",
           "output_type": "stream",
           "text": [
-            "\u001b[32m2024-04-30 01:57:25 INFO semantic_router.utils.logger Adding `get_time` route\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:25 INFO semantic_router.utils.logger Document 1 length: 34\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:25 INFO semantic_router.utils.logger Document 1 trunc length: 34\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:25 INFO semantic_router.utils.logger Document 2 length: 27\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:25 INFO semantic_router.utils.logger Document 2 trunc length: 27\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:25 INFO semantic_router.utils.logger Document 3 length: 32\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:25 INFO semantic_router.utils.logger Document 3 trunc length: 32\u001b[0m\n"
+            "\u001b[32m2024-04-30 02:22:01 INFO semantic_router.utils.logger Adding `get_time` route\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:01 INFO semantic_router.utils.logger Document 1 length: 34\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:01 INFO semantic_router.utils.logger Document 1 trunc length: 34\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:01 INFO semantic_router.utils.logger Document 2 length: 27\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:01 INFO semantic_router.utils.logger Document 2 trunc length: 27\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:01 INFO semantic_router.utils.logger Document 3 length: 32\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:01 INFO semantic_router.utils.logger Document 3 trunc length: 32\u001b[0m\n"
           ]
         }
       ],
@@ -510,9 +497,9 @@
           "name": "stderr",
           "output_type": "stream",
           "text": [
-            "\u001b[32m2024-04-30 01:57:26 INFO semantic_router.utils.logger Document 1 length: 34\u001b[0m\n",
-            "\u001b[32m2024-04-30 01:57:26 INFO semantic_router.utils.logger Document 1 trunc length: 34\u001b[0m\n",
-            "\u001b[33m2024-04-30 01:57:26 WARNING semantic_router.utils.logger No LLM provided for dynamic route, will use OpenAI LLM default. Ensure API key is set in OPENAI_API_KEY environment variable.\u001b[0m\n"
+            "\u001b[32m2024-04-30 02:22:02 INFO semantic_router.utils.logger Document 1 length: 34\u001b[0m\n",
+            "\u001b[32m2024-04-30 02:22:02 INFO semantic_router.utils.logger Document 1 trunc length: 34\u001b[0m\n",
+            "\u001b[33m2024-04-30 02:22:02 WARNING semantic_router.utils.logger No LLM provided for dynamic route, will use OpenAI LLM default. Ensure API key is set in OPENAI_API_KEY environment variable.\u001b[0m\n"
           ]
         },
         {
@@ -539,7 +526,7 @@
         {
           "data": {
             "text/plain": [
-              "'17:57'"
+              "'18:22'"
             ]
           },
           "execution_count": 13,
diff --git a/tests/unit/llms/test_llm_openai.py b/tests/unit/llms/test_llm_openai.py
index 2f1171db..a53b5910 100644
--- a/tests/unit/llms/test_llm_openai.py
+++ b/tests/unit/llms/test_llm_openai.py
@@ -2,6 +2,7 @@ import pytest
 
 from semantic_router.llms import OpenAILLM
 from semantic_router.schema import Message
+from semantic_router.utils.function_call import get_schema_openai
 
 
 @pytest.fixture
@@ -54,3 +55,37 @@ class TestOpenAILLM:
         llm_input = [Message(role="user", content="test")]
         output = openai_llm(llm_input)
         assert output == "test"
+
+    def test_get_schema_openai_with_valid_callable(self):
+        def sample_function(param1: int, param2: str = "default") -> str:
+            """Sample function for testing."""
+            return f"param1: {param1}, param2: {param2}"
+
+        expected_schema = {
+            "type": "function",
+            "function": {
+                "name": "sample_function",
+                "description": "Sample function for testing.",
+                "parameters": {
+                    "type": "object",
+                    "properties": {
+                        "param1": {
+                            "type": "number",
+                            "description": "No description available.",
+                        },
+                        "param2": {
+                            "type": "string",
+                            "description": "No description available.",
+                        },
+                    },
+                    "required": ["param1"],
+                },
+            },
+        }
+        schema = get_schema_openai(sample_function)
+        assert schema == expected_schema, "Schema did not match expected output."
+
+    def test_get_schema_openai_with_non_callable(self):
+        non_callable = "I am not a function"
+        with pytest.raises(ValueError):
+            get_schema_openai(non_callable)
-- 
GitLab