From e8281a77e354dd8392945cd9235d3dacb2d28b6e Mon Sep 17 00:00:00 2001
From: William Coolidge <wac@mmmi.sdu.dk>
Date: Fri, 14 Mar 2025 15:12:21 +0100
Subject: [PATCH] minimal doc for use as pip3 package

---
 README.md                           | 61 +++++++++++++++++++++++++++--
 pyproject.toml                      |  4 +-
 src/semantic/api/semantic_client.py |  9 +----
 src/semantic/py_mqtt/py_mqtt.py     |  8 ++--
 tests/steps/api_insert.py           |  7 ++--
 5 files changed, 68 insertions(+), 21 deletions(-)

diff --git a/README.md b/README.md
index c6512e9..e38269f 100644
--- a/README.md
+++ b/README.md
@@ -3,19 +3,72 @@
 
 #### Versions
 
-```0.0.18``` : Intial version with only the API for insertion and query.
+```0.0.19``` : Intial version with only the API for insertion and query.
 
 | Element | Status | Comment |
 |:--- |:--- |:--- |
-| insert  | ✅ | complete |
-| query  | ✅ | complete |
+| semantic data insertion capability | ✅ | complete |
+| semantic data query capability | ✅ | complete |
+| documentation of semantic and semantic.client methods and functions |   ❌  | in-process |
 | typelib |   ❌  | in-process |
 | type tools | ❌ | in-process |
 | database tools | ❌ | in-process |
 | chain tools  | ❌ | in-process | 
 
 
-#### 1 [Python API](src/doc/python-api.md)
+### Install
+
+```pip3 install semantic-api```
+
+### Use
+
+#### Import
+```
+from semantic.api.semantic_api import semantic
+from semantic.common.utils import defineSchemaId
+from semantic.api.config import brokerIP, dbUri, batch_size, topics
+```
+
+
+#### Schema context configuration
+
+An ontology is assumed to built from a set of ontology clusters and identified by a ```schemaName```, and a ```schemaVersion```.
+
+This ```schemaName-schemaVersion``` pair defines a schema instance in the database which is further identified by ```instanceName``` since it is common  practice to have multiple logical instances in the database for the same ontology.
+
+The function ```defineSchemaId(schemaName, schemaVersion, instanceName, dbUri)``` from ```semantic.common.utils```defines and instance of the type ```SchemaID``` that is used to bind with the semantic context in the database. 
+
+The extra ```dbUri``` parameter provides the domain information of the schema and data and the ```JSON-LD``` ```@context``` that is returned in queries.
+
+The Semantic API shall be instantiated before using api.narration or api.chain methods as these require a connection to the MQTT broker. Note that a database with the ```schemaName-schemaVersion-instanceName``` is assumed to be running along with a semantic service (out of scope of this project).
+
+```
+api = semantic( brokerIp, defineSchemaId(schemaName, schemaVersion, instanceName, dbUri), batch_size, topics)
+```
+
+| Parameter | Use | Suggestion |
+|:--- |:--- |:--- |
+| brokerIP | MQTT Broker IP | use remote broker for project, default from config is 'localhost' |
+| schemaName | identifying name for schema | according to defined schemas |
+| schemaVersion | schema version | according to defined schemas|
+| instanceName | database instance for schemaName-schemaVersion | suggest user defined instance assuming this has been created and instantiated with schema |
+| dbUri | db IP:port URI | use default from config defined as 'http://127.0.0.1:6363/'|
+                                      
+
+#### Database client
+
+The API supports a lower level database client ```semantic.client```that is useful for database configuration tasks. Currently, only two methods are exposed on ```client``` but will be filled out and adequately documented to match the current service API. A commnand line version of this client libary will also be provided as the command line is more useful for maintenance than programtic use, as per the current node.js based semantic-client.
+
+
+| semantic.client methods | return |
+|:--- |:--- |
+| ```getSchemaId()``` |  ```SchemaID``` instance in service |
+| ```setSchemaId(schemaName, schemaVersion, instanceName)``` | sets ```SchemaId``` instance (assumning current ```dBUri```)|
+
+
+The following section describes the usage of the API.
+
+#### 1 [Semantic API](src/doc/python-api.md)
 
 #### 2 [Background](src/doc/background.md)
 
diff --git a/pyproject.toml b/pyproject.toml
index c354ecf..c42c39b 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
 [project]
 name = "semantic-api"
-version = "0.0.18"
+version = "0.0.19"
 dependencies = [
     "behave == 1.2.6",
     "paho-mqtt == 2.1.0",
@@ -44,10 +44,10 @@ license = {text="Apache Licenses 2.0"}
 license-files = ["LICEN[CS]E*"]
 
 
-
 [tool.hatch.build.targets.wheel]
 only-include = ["src"]
 
+# src/ is only stripped off of semantic
 [tool.hatch.build.targets.wheel.sources]
 "src/semantic" = "semantic"
 
diff --git a/src/semantic/api/semantic_client.py b/src/semantic/api/semantic_client.py
index 96c550d..0de43e9 100644
--- a/src/semantic/api/semantic_client.py
+++ b/src/semantic/api/semantic_client.py
@@ -84,7 +84,6 @@ class semanticClient:
           txt = f'semantic_client: insert_primitive : Exception: {e}'
           redMsg(txt)
     
-
       #greenMsg('insert_primitive result: '+str(query_result))
      
       return query_result
@@ -95,9 +94,7 @@ class semanticClient:
       
       query_result = {}
       try:
-          redMsg('awaiting call ---------------------------------------------------------------------')
           query_result = await asyncio.wrap_future(asyncio.run_coroutine_threadsafe(self.mqtt.publish_with_response(args.get('topic'), stringified), self.loop))
-           #query_result = await self.mqtt.publish_with_response(args.get('topic'), stringified)
       except Exception as e:
           txt = f'semantic_client: query_primitive : Exception: {e}'
           redMsg(txt)
@@ -122,20 +119,16 @@ class semanticClient:
           "doc": body,
           "frame": None 
         }
-      redMsg('semantic_config pipe_args: '+json.dumps(pipe_args, indent=6))
+      #greenMsg('semantic_config pipe_args: '+json.dumps(pipe_args, indent=6))
       return await self.query_primitive(pipe_args)
 
   
   async def getSchemaId(self):
-    #msg('getSchemaId()')
-    #result = self.loop.run_until_complete(self.semantic_config('getSchemaId', None))
     result = await self.semantic_config('getSchemaIdInUse', None)
     greenMsg('getSchemaId: '+json.dumps(result, indent=6))
     return result.get('doc')
   
   async def setSchemaId(self, args: SchemaId):
-    #msg('setSchemaId()')
-    #result = self.loop.run_until_complete(self.semantic_config('setSchemaId', args))
     result = await self.semantic_config('setCurrentSchemaId', args)
     greenMsg('setSchemaId: '+json.dumps(result, indent=6))
     return result.get('doc')
diff --git a/src/semantic/py_mqtt/py_mqtt.py b/src/semantic/py_mqtt/py_mqtt.py
index 1915bf6..2e8d822 100644
--- a/src/semantic/py_mqtt/py_mqtt.py
+++ b/src/semantic/py_mqtt/py_mqtt.py
@@ -157,7 +157,7 @@ class MQTTClient:
         Will send a message to the broker, on the specified topic and wait for a response
         ¨ to return.'
         """
-        redMsg('>----------------------- pub w r')
+       
         try: 
             if self.loop is None or self.loop.is_running() == False:
                 self.loop = asyncio.get_running_loop()
@@ -175,12 +175,12 @@ class MQTTClient:
             self.got_message = future
             self.pending_queries[dict_key] = future
             '''
-            msg('pub w r'+message)
+            
             msg_info = self.client.publish(topic, message, self.qos)
             msg_info.wait_for_publish()
-            msg('pub awaiting')
+          
             future_result = await self.got_message
-            msg('pub got it')
+           
             self.got_message = None
 
         except Exception as e:
diff --git a/tests/steps/api_insert.py b/tests/steps/api_insert.py
index 0c1707b..372cffb 100644
--- a/tests/steps/api_insert.py
+++ b/tests/steps/api_insert.py
@@ -9,11 +9,9 @@ from pymonad.tools import curry
 import json, re
 
 from semantic.common.utils import msg, redMsg, greenMsg, sort_by_instance, refForPath, defineSchemaId, out_either, resolve_promised, chain_out, resolve_either, reject_either
-#from semantic_api.api_python.src.semantic_api import flatPMap
-from semantic.fera.fera_types.type_constructors import joint_state, tool_center_point_state
-#from semantic_api.api_python.src.test_data import  type1, name1, name2, shoulder_pan_name, joint_state_test1, joint_state_test2, parent, shoulder_pan_path, float6
 from semantic.api.semantic_api import frame_constructor, flatten, function_constructor
 
+from semantic.fera.fera_types.type_constructors import joint_state, tool_center_point_state
 from test_data import  type1, name1, name2, shoulder_pan_name, joint_state_test1, joint_state_test2, parent, shoulder_pan_path, float6
 
 
@@ -234,6 +232,8 @@ def step_impl(context):
 @given('we use the ToolCenterPointState type constructor and narrate')
 @async_run_until_complete
 async def step_impl(context):
+#from semantic_api.api_python.src.test_data import  type1, name1, name2, shoulder_pan_name, joint_state_test1, joint_state_test2, parent, shoulder_pan_path, float6
+
    
    path_either : Either = await context.pathMap.pathForSegment( 'base_link')
    path = path_either.either(lambda e: f'Error: base_link: {e}', lambda x: x)
@@ -422,6 +422,7 @@ async def step_impl(context):
       async for index in async_iter:
          await context.semantic.narrate( tool_center_point_state('base_link_test_df_'+str(index), 'now', 'now', 1, parent, float6, float6, float6))
 
+      await context.semantic.insert()
    else:
       redMsg('narration failure as path is left or None')
 
-- 
GitLab