wrappers.rst 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. Wrappers
  2. ========
  3. Several wrappers can be defined for the Modelverse, as the Modelverse is merely a service running externally.
  4. To communicate effectively, and automatically, a programming language wrapper is recommended.
  5. Nonetheless, it is possible to communicatie manually as well.
  6. These are some of the implemented wrappers.
  7. Prompt
  8. ------
  9. The simplest wrapper is the prompt wrapper, which merely sends the input and output directly to the user.
  10. This wrapper has almost no code, but requires users to manually decide which content to send next.
  11. It has no built-in integration with any model or action language compilers.
  12. Nonetheless, it is an easy way to test out the raw communication protocol manually.
  13. Python
  14. ------
  15. The first real wrapper is the Python-based wrapper.
  16. It provides a set of functions for use by Python code.
  17. These functions wrap not only the interface, but also provides simple error handling through the use of Python exceptions and contains the model and action language compilers.
  18. An overview of all functions and associatied exceptions is provided below.
  19. All operations happen *synchronously*, meaning that they block until the Modelverse has performed the requested operation.
  20. Note that some functions are only applicable in a certain *context*.
  21. In practice, this means that you should first issue the *init* and *login* operations, as otherwise your connection with the Modelverse will not have started up yet.
  22. Functions
  23. ^^^^^^^^^
  24. .. function:: init(address_param="http://127.0.0.1:8001", timeout=20.0)
  25. Start up the connection to the Modelverse, residing at *address_param*.
  26. This connection is an XML/HTTPRequest and will start up a new task at the Modelverse.
  27. Retries for *timeout* seconds until giving up.
  28. The timeout includes all HTTP errors, and will therefore keep retrying even on failed attempts.
  29. As this request is synchronous, like all others, it will block until a connection has been established.
  30. .. function:: login(username, password)
  31. Explanation
  32. Logs in the currently active Modelverse connection to the specified *username* and *password*.
  33. If the user does not exist, it will create a new user with the specified password.
  34. If the user already exists, it will try to log in with the provided password.
  35. .. function:: model_add(model_name, metamodel_name, model_code=None)
  36. Explanation
  37. Upload a new model that can later be referred to as *model_name*, conforming to *metamodel_name*.
  38. The model itself is stored in the string *model_code*.
  39. This string is parsed using the HUTN compiler and subsequently sent to the Modelverse.
  40. When *model_code* is empty, an empty model is created.
  41. .. function:: upload_code(code)
  42. Upload a string of *code* in the Action Language formalism.
  43. This piece of code is compiled with the HUTN compiler and sent to the Modelverse directly.
  44. Makes the assumption that the **construct_function()** operation is currently running on the Modelverse, as otherwise the data will be misinterpreted.
  45. This is normally only useful in model transformations, where you want to upload a piece of code on-the-fly (e.g., adding a breakpoint in Action Language).
  46. .. function:: model_delete(model_name)
  47. Delete the model referred to by name *model_name*.
  48. This is a non-cascading delete, with almost no checks: model transformations depending on this model will likely become corrupted.
  49. .. function:: model_list()
  50. Returns a list of all models existing in the Modelverse, together with their type.
  51. .. function:: model_list_full()
  52. Returns a detailed list of all models existing in the Modelverse.
  53. This list includes information on permissions, owner, and group.
  54. .. function:: verify(model_name)
  55. Verify whether *model_name* conforms to its specified metamodel, as stored in the Modelverse.
  56. Returns either "OK" if the model conforms, or a string specifying the reason for non-conformance.
  57. .. function:: model_overwrite(model_name, new_model_code=None)
  58. Overwrites the model previously known under the name *model_name* with the model code in *new_model_code*.
  59. This operation differs from first deleting the model and then recreating it, as all metadata of the model is kept, such as access permissions.
  60. The new model can be kept empty, in which case the model will be cleared.
  61. .. function:: user_logout()
  62. Logs out the current user, thereby closing the task.
  63. Subsequent operations will no longer have any effect, as the task was terminated.
  64. To log in as a different user, the *init* operation has to be executed again.
  65. .. function:: user_delete()
  66. Delete the current user and thereafter log out.
  67. This removes the current user, making it impossible to log in as this user again.
  68. Existing models tied to this user, such as those the user is an owner of, remain bound to the (removed) user.
  69. While it is possible to recreate a new user with the same name, model permissions will not be inherited to this new user with the same name.
  70. .. function:: model_render(model_name, mapper_name)
  71. Render the model by name of *model_name* using the mapper by name of *mapper_name*.
  72. Both parameters have to be known models in the Modelverse.
  73. Outputs a JSON representation of the rendered model.
  74. .. function:: transformation_between(source, target)
  75. List all transformations that originate at *source* and end at *target*.
  76. Transformations can still be selected, even if they take more source models than those specified in the parameters.
  77. .. function:: transformation_add_MT(source_metamodels, target_metamodels, operation_name, code, callback=lambda: None)
  78. Create a new model transformation operation.
  79. The new transformation takes *source_metamodels* as input, and generates *target_metamodels* as output.
  80. Both parameters are dictionaries of the form {name: metamodel_name}.
  81. The name is used later on in the model transformation as a prefix to the type.
  82. A single metamodel_name can be used for multiple names.
  83. Note that the target metamodel names may overlap with the source metamodel names, but the metamodel type should be identical.
  84. The operation is henceforth known by *operation_name* and is provided as a model in the string *code*.
  85. Optionally, a callback is defined which performs some operations on the merged metamodel, for example to define tracability links between (previously unrelated) metamodels.
  86. In the background, this operation does all necessary RAMification and model merging.
  87. .. function:: transformation_add_AL(source_metamodels, target_metamodels, operation_name, code, callback=lambda: None)
  88. Creates a new action language operation.
  89. Similar to *transformation_add_MT*, but now does not require RAMification.
  90. The *code* parameter also is not specified as a Modelverse model (.mvc), but as action language (.alc).
  91. .. function:: transformation_add_MANUAL(source_metamodels, target_metamodels, operation_name, callback=lambda: None)
  92. Creates a new manual operation.
  93. Identical to *transformation_add_AL*, but does not take any code as content.
  94. .. function:: transformation_execute_AL(operation_name, input_models_dict, output_models_dict, callback=lambda i: None)
  95. Executes the Action Language model *operation_name* with *input_models_dict* as inputs and *output_models_dict* as outputs.
  96. For both dicts, the contents describe the mapping between the parameter names of the operation to the names in the Modelverse.
  97. Values in *input_models_dict* must be existing models, whereas values in *output_models_dict* can be non-existing upon invocation.
  98. A *callback* function can be defined when the action language model requires user input or output.
  99. This callback function can be used to communicate with the executing action language directly.
  100. .. function:: transformation_execute_MANUAL(operation_name, input_models_dict, output_models_dict, callback=lambda i: None)
  101. Executes the manual model operation *operation_name*.
  102. Furthermore, this is identical to *transformation_execute_AL*, with the exception of the *callback* function.
  103. In this case, the callback function can be just another series of Modelverse operations, though pertaining to a single model.
  104. As such, the *model_name* parameter of these operations **MUST** be set to *None*.
  105. .. function:: transformation_execute_MT(operation_name, input_models_dict, output_models_dict, callback=lambda i: None)
  106. Executes the model transformation operation *operation_name*.
  107. Identical to *transformation_execute_AL*.
  108. .. function:: transformation_list()
  109. Returns a list of all operations specified in the Modelverse, together with their type.
  110. .. function:: process_execute(process_name, prefix, callbacks)
  111. Execute the process model stored as *process_name*.
  112. All models are stored with their names prefixed with *prefix* to allow for multiple executions of the same model.
  113. Note that this applies to the resolution of input models as well.
  114. Optionally, a dictionary of *callbacks* can be defined with as key the operation that is being executed, and value the actual callback.
  115. The callbacks must be similarly defined just like how they were defined in the individual *transformation_execute* operations.
  116. .. function:: permission_modify(model_name, permissions)
  117. Change the permissions of *model_name* to *permissions*.
  118. The permissions is a string of three characters, each between 0 and 2.
  119. The format is similar to the UNIX permission system: the leftmost character is the permission for the owning user, the middle character for members of the ownin group, and the rightmost character for all other users.
  120. Character 0 signifies no access, 1 read-only access, and 2 full read/write access.
  121. .. function:: permission_owner(model_name, owner)
  122. Change the owner of the model *model_name* to *owner*.
  123. .. function:: permission_group(model_name, group)
  124. Change the owning group of the model *model_name* to *group*.
  125. .. function:: group_create(group_name)
  126. Create a new group named *group_name*.
  127. .. function:: group_delete(group_name)
  128. Delete the group named *group_name*.
  129. .. function:: group_owner_add(group_name, user_name)
  130. Add user *user_name* as an owner of group *group_name*.
  131. This automatically makes the user join the specified group if this was not yet the case.
  132. .. function:: group_owner_delete(group_name, user_name)
  133. Remove user *user_name* as an owner of group *group_name*.
  134. .. function:: group_join(group_name, user_name)
  135. Have user *user_name* join the group *group_name* as an ordinary user.
  136. .. function:: group_kick(group_name, user_name)
  137. Remove user *user_name* from the group *group_name*.
  138. If the user was an owner of the group, these permissions are also revoked.
  139. .. function:: admin_promote(user_name)
  140. Promote user *user_name* to admin status.
  141. Admin status grants users access to all operations.
  142. .. function:: admin_demote(user_name)
  143. Demote user *user_name* to ordinary user.
  144. .. function:: element_list(model_name)
  145. Returns a list of all elements and their type specified in the model named *model_name*.
  146. .. function:: types(model_name)
  147. Returns a list of all types usable in the model named *model_name*.
  148. This is similar to executing *element_list* on the metamodel of this model.
  149. .. function:: types_full(model_name)
  150. Returns a list of all types usable in the model named *model_name*.
  151. In contrast to *types*, this includes hidden elements as well (i.e., those starting with __)
  152. .. function:: read(model_name, ID)
  153. Read the content of model element *ID* in model *model_name*.
  154. This returns the type of the element, and the set of source and destination if the element is an edge (*None* otherwise).
  155. .. function:: read_attrs(model_name, ID)
  156. Return a dictionary of all attributes of model element *ID* in model *model_name*, containing their values.
  157. All values in the Modelverse are primitive types, and as such, this is also the case in this operation.
  158. .. function:: instantiate(model_name, typename, edge=None, ID="")
  159. Instantiate a new instance of *typename* in the model *model_name*.
  160. If the instance is an edge, provide a tuple containing the source and target as *edge*.
  161. A preferred *ID* can be specified, though there is no guarantee that this name is actually taken (e.g., if it is already taken by another element).
  162. This operation returns the actually assigned ID.
  163. .. function:: delete_element(model_name, ID)
  164. Delete the element *ID* in the model *model_name*.
  165. This is a recursive delete, and all incoming and outgoing edges will be removed (recursively) as well.
  166. .. function:: attr_assign(model_name, ID, attr, value)
  167. Assign the value *value* to the attribute named *attr* of the element *ID* in the model named *model_name*.
  168. If the attribute already has an assigned value, the previous value is removed first.
  169. .. function:: attr_assign_code(model_name, ID, attr, code)
  170. Assign the code block *code* to the attribute named *attr* of the element *ID* in the model named *model_name*.
  171. If the attribute already has an assigned value, the previous value is removed first.
  172. The assigned code is compiled to Action Language by the HUTN compiler.
  173. .. function:: attr_delete(model_name, ID, attr)
  174. Unset the attribute *attr* of model element *ID* in the model *model_name*.
  175. .. function:: read_outgoing(model_name, ID, typename)
  176. Returns a list of all outgoing associations of *ID*, typed by *typename*, in model *model_name*.
  177. Typename can be set to the empty string to indicate that all types must match.
  178. Note that this returns the association itself, **NOT** the destination.
  179. .. function:: read_incoming(model_name, ID, typename)
  180. Returns a list of all incoming associations of *ID*, typed by *typename*, in model *model_name*.
  181. Typename can be set to the empty string to indicate that all types must match.
  182. Note that this returns the association itself, **NOT** the source.
  183. .. function:: read_association_source(model_name, ID)
  184. Returns the identifier of the source of association *ID* in model *model_name*.
  185. .. function:: read_association_destination(model_name, ID)
  186. Returns the identifier of the target of association *ID* in model *model_name*.
  187. Exceptions
  188. ^^^^^^^^^^
  189. Below is a list of all exceptions that the wrappers can raise, together with a summary of the kind of error that occured.
  190. .. exception:: ModelverseException
  191. Generic Modelverse Exception, of which all others inherit.
  192. This should be the only type of exception that the wrapper can raise.
  193. .. exception:: UnknownError
  194. Unknown exception has occured.
  195. This is likely something wrong with the connection, such as the Modelverse that suddenly disconnected.
  196. .. exception:: UnknownIdentifier
  197. The specified identifier could not be resolved in the Modelverse.
  198. .. exception:: UnknownType
  199. The specified identifier could not be resolved as a type in the Modelverse.
  200. .. exception:: NotAnAssociation
  201. The specified identifier does not resolve to an association (or edge), even though this was intended.
  202. .. exception:: UnsupportedValue
  203. The specified value is not a primitive that can be serialized.
  204. Supported types are: string, boolean, integer, float, and action.
  205. .. exception:: CompilationError
  206. Error in the HUTN compiler during compilation.
  207. .. exception:: NoSuchAttribute
  208. The specified attribute does not exist for this element.
  209. .. exception:: UnknownModel
  210. The specified model can not be resolved in the Modelverse.
  211. .. exception:: ConnectionError
  212. Error with the connection to the Modelverse.
  213. .. exception:: ModelExists
  214. The identifier to give to the newly created model already exists.
  215. .. exception:: PermissionDenied
  216. Permission denied to either write or read the specified resource.
  217. .. exception:: InvalidMode
  218. An operation was executed in the wrong context.
  219. For example, all operations are only valid after a successful *init* and *login* call.
  220. .. exception:: InterfaceMismatch
  221. The Modelverse responded with an unexpected response.
  222. As a response came, the Modelverse is likely still running, though we have no idea how to interpret the result.
  223. Likely, the wrapper is not up to date with the latest Modelverse operations.
  224. Custom
  225. ------
  226. Other wrappers can be made as desired, in whatever language required.
  227. This is due to the fact that the Modelverse communicates only through XML/HTTPRequests.
  228. As such, all languages that support this, can simply mimic the interface used by any of the implemented wrappers.