
7. Assets
While much can be achieved through the features supported by Decision Models, their evaluations, and simulations, just using those features alone would result in a closed and rigid system, which are rarely found in the real world. World Modeler™ offers an Assets based workflow which encapsulates the connections between a decision model and real world data. Each asset represents either a form of data or an operation performed on that data, and are made available to the expressions that compose a decision model.
Assets in World Modeler™ are perfectly analogous to a computer's file system, containing both directories and several different types of files. The types of assets currently supported and their properties can be seen below.
| Asset Type | Purpose | Base Endpoint |
| Decision Models | Decision Models define the basic computational unit in World Modeler™. See more in . | /decisionModel |
| AssetDirectory | AssetDirectories make up the folder structure of the Assets file system. Correspondingly they, and all of the files contained, follow many of the same rules we are accustomed to when using computer file systems. | /assetdirectory |
| DataSource | DataSources make up the actual data that is used in World Modeler™, but don't contain any data themselves. Through encrypted accessor strings, DataSources access data managed on separate servers. DataSources also come in several different types depending on the data they embody. (SQL server, Excel spread sheet, etc...) | /datasource |
| DataReader | DataReaders represent operations performed on DataSources. This can involve querying an SQL server or returning a selection of cells from an Excel worksheet. The operation itself is highly dependant on the DataSource in question. | /datareader |
| Model | Models represent the ability to perform inferences with machine learning models, decision trees, etc..., and contain the information necessary to instantiate and perform inferences. | /model |
| LLM | LLM(Large Language Model) related assets can be learned about in section 8. This includes WMLLMs, WMLLMConnections, and DocumentIndexes | /llm, /llm/connection, /llm/vectorindex |
| Document | Document assets contain the data for any supported file type. Documents can be saved and downloaded elsewhere, queried for text, generated dynamically, or used in LLM retrieval augmented generation. | /document |
| Http | HttpRequests and HttpConnections wrap external APIs to be consumed via the World Modeler™ interface. | /httprequest, /httpconnection |
Asset Common Interfaces, API Endpoints, Qualities
For the sake of being concise, every common quality of assets will be listed here, and shorter sections will be listed afterwards for each individual asset.
As mentioned, assets are analogous to files in a file system, and so exist in a hierarchy. Each asset possesses a parent which dictates where it exists in the hierarchy.
- Being a hierarchical system, every asset, regardless of type, can be uniquely identified with a single "
FullPathName"= "/Path/To/Asset". Two assets cannot have the same FullPathName. See more here. - The parent of an asset must be an AssetDirectory. If an asset does not have a parent, it is automatically parented to the root directory, which exists in code..
- The root directory has "
ID"="c8051982-f490-43b7-92a1-29efe2efd4a6", "Name"="Root", "FullPathName"="Root" - This means that every asset's "
FullPathName" begins with "Root/...", but this is reduced to just "/..." externally.
- The root directory has "
- If a directory is moved to a different location or deleted, all child directories and files will also be moved or deleted.
- Directories and assets have ownership, and are only visible to the user or organization that owns them. See more here.
- Assets are versionable. A single asset can have multiple versions at once, with a Head version that represents the whole. See more here.
When interacting with assets through the REST API. All assets implement the following common interface represented as JSON:
{
"id": string, // The ID of this asset. IDs are unique among asset types.
"name": string, // The name of this asset. names are unique among siblings.
"summary": string, // A description of this asset.
"documentation": string, // Documentation of this asset.
"documentationMIMEType": string, // The MIMEType of this asset's documentation.
"properties": {
// World Modeler standard properties.
"wm": {
"OwnerID": string, // The ID of the entity that owns this asset.
"OwnerType": string, // The type of entity that owns this asset. WMUser or WMOrganization.
"OwnerName": string, // The name of the user, organization, or entity that owns this asset.
"LastUpdated": string, // The date of last update.
"assetType": string // The asset type.
},
"User set property": string,
...
},
"parent": string, // The parent of this asset. This can be provided as an ID or FullPathName. When retrieved this will be resolved to the FullPathName.
"ownerType": string, // An optional field to specify the owner type of this asset.
"ownerID": string, // An optional field to specify the owner ID of this asset.
"versionName": string // An optional name for this version of this asset.
}
When using the REST API, not all of these fields are necessary. Most of these fields have default values that will be set if null in the payload.
{
"id": ... , // Randomly generated GUID.
"summary": "",
"documentation": "",
"documentationMIMEType": "",
"parent": "c8051982-f490-43b7-92a1-29efe2efd4a6", // Root directory.
"ownerType": "WMUser",
"ownerID": ... , // The user's ID.
"versionName": ""
}
When retrieved, assets will gain the additional fields:
{
"fullPathName": "/Path/To/Asset", // The fullPathName of this asset.
"version": int, // The version of this asset.
"status": "Head" | "Working" | "Superseded", // The status of this version.
}
Every asset in World Modeler™ implements a basic set of CRUD endpoints. Note that all {dir} parameters accept both the unique ID of the directory, as well as the URL encoded FullPathName of the directory. Only directories owned by the user or affiliated organizations can be accessed,
| Method | Operation | Description |
| GET | /* | Retrieve all assets of this type the user has access to. |
| GET | /*/{dir} | Retrieve the asset specified by {dir}. |
| POST | /* | Creates a new asset according to the supplied JSON string. The ID of the supplied JSON will be checked for uniqueness, and will fail if not unique. If the ID is not supplied, or left blank, a GUID will be generated. |
| PUT | /*/{dir} | Updates the asset specified with {dir} according to the supplied JSON string. This operation performs a full replacement of the asset. |
| PATCH | /*/{dir} | Allows a partial representation of the asset to be passed in the payload. Only the fields provided will be updated. Not implemented for all asset types. |
| DELETE | /*/{dir} | Deletes the asset specified with {dir}. |
| POST | /*/{dir}/createCopy | Copies the asset specified with {dir} and saves it as an entirely new asset. Allows a partial representation of the asset to be passed in the payload to make modifications while copying, including change in ownership. Not yet implemented. |
| POST | /*/{dir}/createVersion | Copies the asset specified with {dir} and iterates the version. |
| POST | /*/{dir}/commitVersion | Sets the asset specified with {dir} to the head version. |
| POST | /*/{dir}/versions | Retrieves all versions of the asset specified with {dir}. |
- Where * is replaced with the base url string for that asset type.
Asset Versioning
Given that any production system needs a mechanism to test changes before they are pushed to production, Assets in World Modeler™ implement a versioning system that allows assets to be copied, modified, tested, and then committed. Versioning has the following traits:
- An asset can have any number of versions, but only one can be Head.
- An asset that has not been committed to Head is considered "Working", and an asset that was previously Head is considered "Superseded".
- Each version of an asset has the same ID and FullPathName, with the only difference being its version number.
- A Head asset cannot be deleted without first creating a new Head, or specifying that every version should be deleted simultaneously.
Assets have two means of identification, ID or FullPathName. IDs are unique among assets of the same type, FullPathNames are unique among all assets. This means that the two identifiers:
12345-abcde-67890/Path/To/AssetCan identify the same asset.
In addition to the above, an asset's version can be specified by appending it with a semicolon to the identifier, like so:
12345-abcde-67890;1/Path/To/Asset;4These do not specify the same asset, since they target different versions of the same entity.
Asset versions also support the following macros:
- Head, or none, specify that the Head version should be specified.
12345-abcde-67890;Head/Path/To/Asset12345-abcde-67890;3(if 3 is the Head version) all target the same asset and version.
- Latest, targets the highest version of an asset that exists
12345-abcde-67890;Latest/Path/To/Asset;6(if 6 is the highest version)
Organization Ownership
In addition to users, organizations can also own assets. Organization ownership of an asset can be specified by adding the following two optional parameters when creating an asset via its POST HTTP method.
{
"ownerType": "WMOrganization",
"ownerID": "...organization ID"
}
The currently supported owner types are:
| Owner Type | Description |
| * | If the "ownerType" value is not in this table, or if the optional parameters are omitted entirely, the asset will be owned by the user who created it. |
| WMOrganization | This asset belongs to an organization. The organization can be specified by entering its ID in the "ownerID" property. The user creating this asset must have permission from the organization, otherwise this will fail. |
Unlike user owned assets, which are available in their entirety to the user who created them, organizations assign a granular permission structure that dictates which users are allowed to perform which operations on an organization owned asset. See the full details in Section 9. Access Control
Full Path Names
All assets have a unique FullPathName. This path specifies the location of the asset in the file hierarchy, and follow the following rules.
- Every FullPath starts with '/'. If a directory with name
Directory1is placed in the Root directory, its FullPathName will be/Directory1; correspondingly, if we place a data source with nameSource2in that directory, its FullPathName will be/Directory1/Source2 - The exception to this rule is the Root directory, which can be specified in several different ways. If a JSON parameter is requesting a path, entering (
""," ","/","Root",null), or simply leaving out that JSON parameter will specify the Root directory.
AssetDirectories
When returned to the user, this json will have the additional field "members", which will contain a list of child directories and files.
AssetDirectories support the following unique REST API endpoints. Note that all {dir} parameters accept both the unique ID of the directory, as well as the URL encoded FullPathName of the directory.
| Method | Operation | Description |
| GET | /assetDirectory?depth={depth} | Retrieve all directories and their files to the specified {depth}, starting from the root directory. A depth argument of 0 will return only the root directory, a depth argument of -1 will return all directories. Each directory returned will also return populated with all non-directory assets. |
| GET | /assetDirectory/{dir}?depth={depth} | Retrieve all directories and their files to the specified {depth}, starting from the directory specified with {dir}. A depth argument of 0 will return only the specified directory, a depth argument of -1 will return the specified directory and all of its child directories. Each directory returned will also return populated with all non-directory assets. |
Data Sources
- Every DataSource possesses an accessor string. This string is the instruction on how to access the resource held by the DataSource, and is specific to the type of DataSource. An example is the SQLServer DataSource, which uses a connection string as instruction for how to access the SQL server database.
- Every DataSource has a type, referred to as the
registeredType, which specifies how the accessor string should be formatted, and how the resource should be read. - All of the supported
registeredType's are as followsRegistered Type Accessor Description SQLServer connection string This DataSource is an SQL server, it should be accessed with a connection string pointing to the server's location with the necessary login information, and all reader queries should be formatted as SQL queries. - Given the confidential nature of accessor strings, which are a means of directly accessing a client resource, all accessor strings are AES 256 encrypted when stored in the database, and are returned hidden when a data source is retrieved. accessor strings can be retrieved and modified by an individual with the correct credentials via alternate REST API endpoints.
When sent to and from World Modeler™ via the REST API, DataSources have the additional JSON fields:
{
"connectionString": "accessor string",
"registeredType": "SQLServer"
}
DataSources support the following unique REST API endpoints. Note that all {dir} parameters accept both the unique ID of the directory, as well as the URL encoded FullPathName of the directory.
| Method | Operation | Description |
| GET | /dataSource/{dir}/accessorString | Retrieves the accessor string of the data source specified by {dir} as plaintext. |
| PUT | /dataSource/{dir}/accessorString | Updates the accessor string of the data source specified by {dir} according to the supplied JSON string. The supplied json should have a single property "accessorString", whose value is set to the data source's accessor string. |
| POST | /dataSource/evaluate/{dir} | Performs an evaluation according to the supplied JSON string. (see below) |
| POST | /dataSource/{id}/openTransaction | Open a new transaction in the data source with the specified `id` (if supported by the data source type). (see below) |
| POST | /dataSource/commitTransaction{xid} | Commit the transaction with ID = `xid`, as genrated by `openTransaction`. (see below) |
| POST | /dataSource/rollbackTransaction{xid} | Roll back the transaction with ID = `xid` as genrated by `openTransaction`. (see below) |
| POST | /dataSource/{dir}/add | Insert new data into the datasource. (see below) |
| POST | /dataSource/{dir}/update | Update existing data in the datasource. (see below) |
| POST | /dataSource/{dir}/delete | Delete existing data in the datasource datasource. (see below) |
DataSource Evaluations
Evaluations are performed through a set of arguments provided by a JSON string. Each JSON string requires the following parameter:
{
"SourceString": "SELECT * FROM COMPANIES"
}
Where the form of the "SourceString" is dependant on the type of dataSource being evaluated.
DataSource evaluations also have optional parameters, the optional parameters with their default values are listed below:
- Here
"Action"refers to the name of the action specified in the DataReader section table,"Format"refers to the format that the data should be returned in, and can be seen in the following table
{
"queryParameters": {},
"Action": "ReadTable",
"Format": "JSON"
}
| Format | Description |
| JSON | The query result is returned in a JSON, hierarchical format. |
| CSV | The query result is formatted into CSV format, and returned as a string. |
- If the query requires parameters to be specified, those parameters should be specified in the optional
"queryParameters"property to the evaluation JSON string.
"queryParameters": {
"stringParameter": "value",
"intParameter": 2,
}
Insert, Update, Delete Operations in Data Sources
The World Modeler Data Binding interface can perform modifications on data repositories that support it, typically relational databases. Due to the dangerous nature of native support of querying languages, World Modeler requires all database modification to be performed through a secure interface. This serves several purpose, namely
- Allows parameterization of variables, preventing injection attacks.
- Allows tables and other data structures to be validated against schema.
- Ensures that all operations performed are strictly supported.
Each of the
| POST | /dataSource/{dir}/add | Insert new data into the datasource. (see below) |
| POST | /dataSource/{dir}/update | Update existing data in the datasource. (see below) |
| POST | /dataSource/{dir}/delete | Delete existing data in the datasource datasource. (see below) |
operations take an array of InsertUpdateDeleteArg s. Where each individual argument has the following signature:
{
"tableName": "The name of the table to operate on...",
"data": {
"col1": "value1",
"col2": 1,
"col3": true
},
"selector": (See below),
"transactionID": "string"
}
Each property has the following characteristics:
tablename: The name of the table or data structure to operate on
data: a string,object dictionary where each key is a column name and each value is the column value.
selector: See below.
transactionID: An optional transaction ID. if supplied, this operation will be a part of an atomic transaction. If not supplied this operation will be solitary.
Selectors come in a simple and complex mode.
Simple Selectors
Simple selectors can be supplied as a single string to indicate a column to select off of, or omitted entirely to indicate the primary key, respectively. Simple selectors must be paired with data to perform an operation, and can affect one or several rows. For example, the two arguments
/dataSource/{dir}/delete
{
"tableName": "PersonnelAccounts",
"data": {
"ID": "12345",
"Name": "John Smith",
"CreatedDate": "01-12-00",
"Age": 24
},
"selector": "ID"
}
{
"tableName": "PersonnelAccounts",
"data": {
"ID": "12345",
"Name": "John Smith",
"CreatedDate": "01-12-00",
"Age": 24
}
}
Are identical. Given that "ID" is the primary key of "PersonnelAccounts", leaving out "selector" will automatically target "ID" as the selector. Both of these arguments will translate to the follwing SQL:
DELETE FROM PersonnelAccounts
WHERE ID="12345"
Which will delete only a single record.
Whereas the argument
/dataSource/{dir}/delete
{
"tableName": "PersonnelAccounts",
"data": {
"ID": "12345",
"Name": "John Smith",
"Age": 24
},
"selector": "Age"
}
will delete all records with an age of 24.
Complex Selectors
Complex selectors make use of a tree structure to allow arbitrarily complex SQL statements. The most basic unit is the following:
{
"column": ...,
"columnType": "Node",
"value": ...,
"valueType": "Node",
"operation": "Equals",
"where": true,
}
The columnType and valueType fields can be the following values:
| Enum | Description |
| Column | The default value for "columnType". This denotes that "column" or "value" is a string, and is a column name from the query table. |
| Parameter | The default value for "valueType". This denotes that "column" or "value" is a parameter, and will be parameterized in the query to prevent injection attacks. Note that table names or other SQL will be ignored. |
| Node | Denotes that "column" or "value" has the value of another complex selector node. Allows complex selection logic such as WHERE A=@a AND b=@b |
| Table | Denotes that "column" or "value" has the value of a table for operations such as WHERE x in (Select ...). Not implemented. |
As seen in the above table, the values of column and value are expected to be consistent with their associated columnType and valueType .
The operation field can have the following values.
| Enum | Description | Supported Column Types | Supported Value Types |
| Equal | Denotes that "column" and "value" are equal. The default value for "operation" | Column, Parameter | Column, Parameter |
| NotEqual | Denotes that "column" and "value" are not equal. | Column, Parameter | Column, Parameter |
| LessThan | Denotes that "column" is less than "value". | Column, Parameter | Column, Parameter |
| GreaterThan | Denotes that "column" is greater than "value". | Column, Parameter | Column, Parameter |
| LessThanOrEqual | Denotes that "column" is less than or equal to "value". | Column, Parameter | Column, Parameter |
| GreaterThanOrEqual | Denotes that "column" is greater than or equal to "value". | Column, Parameter | Column, Parameter |
| Like | Denotes that "column" is Like "value". SQL equality with wildcards. | Column, Parameter | Column, Parameter |
| Null | Denotes that "column" is null. | Column, Parameter | None |
| NotNull | Denotes that "column" is not null. | Column, Parameter | None |
| And | Denotes that "column" and "value" are true, where both are boolean expressions formed by node branches. | Node | Node |
| Or | Denotes that "column" or "value" are true, where both are boolean expressions formed by node branches. | Node | Node |
| In | Denotes that "column" is in "value", where "value" is a table value. Not implemented. | Column, Parameter | Table |
| NotIn | Denotes that "column" is not in "value", where "value" is a table value. Not implemented. | Column, Parameter | Table |
Because columnType, valueType, and operation all have defaults, the most basic node is:
{
"column": "ColumnName",
"value": Column Value...,
}
Which simply equates to ColumnName=@ColumnName, where @ColumnName = Column Value....
When more complex behavior such as equating columns to columns, parameters to parameters, or AND or OR operations are desired, it is necessary to use the columnType and valueType fields.
When it is desired for the relationship between column and value to be anything other than equality, it is necessary to use the operation field.
When the user wants to operate on the entire table without any WHERE clause at all, the selector should have
{
...
"where": false,
}
Note that where is set to true by default, and it is only necessary to add the where parameter when setting it to false. Extreme caution should be taken when setting the where parameter to false. At best, you will modify every record of a table, at worst you will delete every record of a table. The user should be extremely sure that they know what they are doing when using it.
Insert InsertUpdateDeleteArg Expectations
Insert does not make use of selectors, so the only expectations are a tableName, data, and an optional transactionID
{
"tableName": "The name of the table to operate on...",
"data": {
"col1": "value1",
"col2": 1,
"col3": true
},
"transactionID": "string"
}
Update InsertUpdateDeleteArg Expectations
Besides the required tableName and optional transactionID, Update makes use of data to update with, a simple selector where data contains the selected column name, or a complex selector
{
"tableName": "The name of the table to operate on...",
"data": {
"col1": "value1",
"col2": 1,
"col3": true
},
"selector": ...,
"transactionID": "string"
}
Delete InsertUpdateDeleteArg Expectations
Besides the required tableName and optional transactionID, Delete makes use of a simple selector with data that contains the selected column name, or a complex selector without any data parameter.
{
"tableName": "The name of the table to operate on...",
"data": {
"col1": "value1",
...
},
"selector": "col1",
"transactionID": "string"
}
or
{
"tableName": "The name of the table to operate on...",
"data": {
"primary key name": "value1",
...
},
"transactionID": "string"
}
or
{
"tableName": "The name of the table to operate on...",
"selector": { ... },
"transactionID": "string"
}
Passing Multiple InsertUpdateDeleteArg
While all of the examples have a single InsertUpdateDeleteArg object, the insert, update, and delete endpoints accept an array of objects, like so:
[
{
"tableName": "TableA",
"data": {
"col1": "value1",
"col2": 1,
"col3": true
},
"transactionID": "string"
},
{
"tableName": "TableA",
"data": {
"col1": "value2",
"col2": 2,
"col3": true
},
"transactionID": "string"
},
{
"tableName": "TableA",
"data": {
"col1": "value3",
"col2": 3,
"col3": false
},
"transactionID": "string"
},
{
"tableName": "TableB",
"data": {
"Name": "Adam",
"Age": 24
},
"transactionID": "string"
}
]
Each object in the array is a singular operation and may operate on any table (i.e. you can insert any number of times into TableA and TableB simultaneously), but the whole call will be wrapped in a transaction to ensure atomicity. In the above example, if Adam is already in TableB, all of the insertions to TableA will be reverted when the insertion into TableB fails.
Transaction Control in Data Sources
The World Modeler Data Binding interface can utilize transaction control for those data repositories that support it, typically relational databases.
Overview of Transactions
In a non-transaction-controlled environment, when a data-modifying operation such as an insert, update, or delete, completes, the changes to the database are immediately visible to all clients connected to the database. In addition:
- There is no "undo" possible, and
- A single command is "atomic". That is, in a multi-tasking, multi-user environment, when a database command begins, it will not be interrupted by another command until the operation has completed. Therefore, the command will either complete in its entirety, or fail without making any changes to the data before any other command can make changes to the database.
However, sometimes a single "logical" operation requires the update of several tables requiring several database commands. To ensure data integrity, this requires that:
- The group of operations have to be treated as effectively atomic. No other command can interrupt these commands until the whole sequence has completed.
- The changes cannot become publicly visible until the sequence is complete because until this is so, the database tables may be in an inconsistent state.
- If an error occurs after the group of operations starts, but before it is complete, the tables must be returned to their state before the first operation in the sequence began.
This group of requirements is satisfied by the concept of a Transaction. A transaction includes a sequence of commands treating them as if they were a single command. That is:
- The transaction executes atomically when it is committed
- Changes made within the transaction are only visible in the client session that made the changes, until the transaction is committed
- If a transaction encounters an error, the entire transaction can be "rolled back" eliminating the changes pending in the session.
The sequence of events when using transaction control is:
- Open the transaction
- Perform the sequence of commands within the context of the transaction
- If there is no error, commit the transaction. This pushes the changes pending in the session, to the publicly visible tables.
- If an error occurred, roll back the transaction.
Support for Transactions in World Modeler
The World Modeler Server REST API supports transactions via three API calls:
/dataSource/openTransaction/dataSource/commitTransaction/dataSource/rollbackTransaction
When a set of data source commands is to be executed as a single transaction, the following steps should be used.
1. Open New Transaction
Before making any API calls, a call should be made to /dataSource/openTransaction. This will return a string-valued token (the Transaction ID) that is then passed to the API calls that perform the data update operations. The Transaction ID ensures that each data update occurs within the transaciton associated with the given ID. The signature of the REST call is shown below.
POST /dataSource/{id}/openTransaction
where id is the ID of the Data Source within which the transaction is to be executed.
Upon successfully opening the transaction, the following body will be returned, with the Transaction ID specified by the value key.
{
"status": "Success",
"value": "b7606bca-8735-4fe3-8740-f23129db3538",
"message": null,
"requestTime": "0001-01-01T00:00:00",
"duration": "00:00:00",
"url": "http://hostname/dataSource/ac6b24bc-58e8-4eff-80fc-a46776d44ea6/openTransaction"
}
The Transaction ID should be retained by the client so that it can be passed to subsequent data source calls, as described below.
2. Update Data in the Data Source with /dataSource/add, /dataSource/update, and /dataSource/delete commands
Actual updates to the data in the data source are made by calling /dataSource/add, /dataSource/update, and /dataSource/delete. Ordinarily, these calls will establish a new connection to the data source, execute the operation, and then close the connection. However, each of these API calls accepts an arguemnt:
"TransactionID":"string"
which is either null or a Transaciton ID obtained by calling /dataSource/openTransaction on the same data source. If not null, the operation will be performed within the transaction associated with the Transaction ID. The Transaction ID remains valid until either /dataSource/commitTransaction or /dataSource/rollbackTransaction is called, after which the transaction no longer exists and the Transaction ID can no longer be used.
3. Commit or Rollback the Transaction
When the commands that update the data within the transaction have completed, the transaction must be either committed, if the commands succeeded, or rolled back, if an error occurred during the execution of the data update operations. This is done by calling one of the two APIs, below.
/dataSource/commitTransaction{xid}
/dataSource/rollbackTransaction{xid}
where xid is the Transaction ID obtained from the call to /dataSource/openTransaction
Example
A typical usage pattern in clients using data source transactions is shown below. Assume the functions openTransaction(), commitTransaction(), and rollbackTransaction() are wrappers around the corresponding REST API invocations.
var xid = openTransaction();
try
{
updateData({data}, xid);
addData({data}, xid);
deleteData({data}, xid);
commitTransaction(xid);
}
catch()
{
rollbackTransaction(xid)
}
xid = null;
Data Readers
- Every DataReader possesses a connection to a data source, which is what it queries during evaluations. The connection to a data source is stored as the path to that data source, which means that if the data source is deleted and replaced with another, this reader will still query whichever data source is at the path originally specified.
- Every DataReader possesses a source string. This is the body of the data reader's query, and is dependent on the type of data source being queried.
- Every DataReader possesses an action. The action specifies how the data returned from an evaluation should be returned to the user. Actions have the following properties:
Action int Action name Description 0 ReadTable The entire query is returned to the user. 1 ReadScalar Only the first result is returned to the user. If the result is a table, only the value of the first column of the first row is returned. 2 ReadNone Nothing is returned to the user.
When sent to and from World Modeler™ via the REST API, DataReaders have the additional JSON fields:
{
"dataSource": "/Path/To/DataSource",
"action": 0,
"sourceString": "Select * From Table"
}
DataReaders support the following unique REST API endpoints. Note that all {dir} parameters accept both the unique ID of the directory, as well as the URL encoded FullPathName of the directory.
| Method | Operation | Description |
| POST | /dataReader/evaluate/{dir} | Performs an evaluation according to the supplied JSON string. (see below) |
DataReader Evaluations
Evaluations are performed through a set of arguments provided by a JSON string, however all of the arguments used in DataReader evaluations are optional.
The optional parameters with their default values are listed below:
- Here
"Format"refers to the format that the data should be returned in, and can be seen in the following table
{
"queryParameters": {},
"Format": "JSON"
}
class="wm-api-table">
- If the query requires parameters to be specified, those parameters should be specified in the optional
"queryParameters"property to the evaluation JSON string.
"queryParameters": {
"stringParameter": "value",
"intParameter": 2,
}
Models
- Every Model possesses a source string. This string contains information needed to build the model it represents. Because models may involve sensitive information, the source string is AES 256 encrypted when stored in the database, and are returned hidden when a model is retrieved. Source strings can be retrieved and modified by an individual with the correct credentials via alternate REST API endpoints.
- Every Model possesses a source mode that indicates how the source string contains the information. Currently supported modes are as follows
Source Mode Description PlainText The source string is in a plaintext representation. - Every Model possesses a source format that indicates the type of file to deserialize. Currently supported types are as follows
Source Format Supported Models Description PMML Decision Tree The source string is represented as an XML file using the PMML format. (https://dmg.org/pmml/pmml-v4-3.html) - Every Model has a type, referred to as the
registeredType, which specifies what type of model it is, and how it should perform inferences on input data. - All of the supported
registeredType's are as followsRegistered Type Description DecisionTree This Model is a Decision Tree.
When sent to and from World Modeler™ via the REST API, Models have the additional JSON fields:
{
"sourceString": "<PMML...",
"sourceFormat": "PMML",
"sourceMode": "PlainText",
"registeredType": "DecisionTree"
}
Models support the following unique REST API endpoints. Note that all {dir} parameters accept both the unique ID of the directory, as well as the URL encoded FullPathName of the directory.
| Method | Operation | Description |
| GET | /model/{dir}/sourceString | Retrieves the source string of the model specified by {dir} as plaintext. |
| PUT | /model/{dir}/sourceString | Updates the source string of the model specified by {dir} according to the supplied JSON string. The supplied json should have a single property "sourceString", whose value is set to the model's source string. |
| POST | /model/evaluate | Performs an evaluation according to the supplied JSON string. (see below) |
Model Evaluations
Evaluations are performed through the arguments provided by the following JSON string:
- Where
"model"is the ID or full path name of the model to be evaluated, and parameters has a name-value pair for every parameter in the model's input vector.
{
"model": "/Path/To/Model",
"parameters": {
"stringParameter": "value",
"intParameter": 2
}
}
LLMs
- See Section 8. LLMs
Documents
- A document contains a file as a base 64 encoded string. When a document is created and retrieved, it will always be in a base64 format, therefore it is the responsibility of the end user to perform the conversions.
- For safety reasons, only supported file types are allowed to be documents. The file type is not determined through the extension, but rather the file signature or BOM (byte-order-mark).
The following file formats are supported:
- All text files
- PDFs
- Zip files
- All file formats used by Microsoft Office.
When sent to and from World Modeler™ via the REST API, Documents have the additional JSON fields:
{
"documentData": "string",
"documentName": "string",
"documentMIMEType": "string",
"documentEditedText": "string"
}
Documents support the following unique REST API endpoints. Note that all {dir} parameters accept both the unique ID of the directory, as well as the URL encoded FullPathName of the directory.
| Method | Operation | Description |
| GET | /document/{dir}/data | Retrieves the data of the document specified by {dir} as a base64 string, and the plaintext in the document. Returns as a json object with "documentData" and "documentEditedText" properties. |
| POST | /document/{dir}/generate | Finds the document specified by {dir} and uses it as a template for document generation. See specifics below. |
Document Generation
Documents can be dynamically generated using a paired template document and Decision Model. The template document contains a number of replacement keys (i.e. $ReplacementKey), all of which are dynamically replaced with display elements returned by the decision model whose element name is the same $ReplacementKey. This means that each replacement key must have a corresponding decision model element in the supplied decision model, but not every element must have a replacement key.
Display elements are the return value of decision model elements, and are returned as IADGFormattable type objects, which implement the following properties:
{
"Value": object,
"DataType": string,
"Display": {
"displayKey": object, ...
}
}
The contents of the IADGFormattable object depends on the document being generated:
Plaintext files (.txt, .csv, etc...)
These files only accept the following objects:
{
"Value": "plaintext string",
"DataType": "text",
}
Word Documents
Word documents accept several types of display element:
- Text elements
{
"Value": "string value", // If display is empty or has only false elements, this text as is will replace the replacement key.
"DataType": "text",
"Display": {
"convertHTML": bool, // if true, Value will be interpreted as an html string, and the html will be converted into Word graphic elements
"deleteXML": bool // if true, the replacement key and content will be deleted. This allows the dynamic removal of replacement keys.
}
}
- Image elements
{
"Value": object, // If format = "SVG", this must be an ISVGFormattable
"DataType": "image",
"Display": {
"format": "SVG", // currently, only SVG image elements are accepted. Additionally, SVG cannot contain transforms.
}
}
- Currently, only SVG is accepted.
Valuemust be anISVGImage, which has the following structure:
{
"XML": string, // The XML string, cannot have transforms.
"Width": int,
"Height": int,
"ImageData": { // contains image data. For each image references in the XML, there must be an entry in this dictionary that has the image name and image base64 string representation.
"someImage.png": string
}
}
- Table elements
{
"Value": dataTable, // Value must be a data table object.
"DataType": "table",
"Display": {
}
}
JS representation
Ultimately, decision models are written in JavaScript and can't return .Net objects. These interfaces are exposed through a set of functions available to decision models.
WM.JSADGFormattable(value : string, dataType: string, display : any)- value: a text element
WM.JSADGImage(value : any, imageType: string, display : any)- value: Must be a JSSVGImage if imageType is "SVG"
- imageType: Currently only "SVG" is supported.
WM.JSSVGImage(width : int, height : int)- width and height are the rasterized resolution in pixels of the SVG.
- svgImage.XML must be set before returning.
- svgImage.ImageData should be set according to the
ISVGImagespecifications above.
WM.JSADGTable(data : any[], display : any)- data should be an array of objects whose keys are column names, and values are cells.
Http Requests and Connections
Http requests and connections as assets allow the usage of external APIs internally in the World Modeler™ interface.
HttpRequests contain an HttpConnection reference, an endpoint route, and a method and each serve as an independent operation on a given external API.
When sent to and from World Modeler™ via the REST API, HttpRequests have the additional JSON fields:
{
"httpConnectionID": "string",
"route": "string",
"method": "string",
"headers": {
"Request additional header": "string",
}
}
When sent to and from World Modeler™ via the REST API, HttpConnections have the additional JSON fields:
{
"endpoint": "string",
"headers": {
"Connection base header": "string",
},
"authenticationType": "string",
"authenticationData": {
"authenticationTypeSpecificData": "string",
}
}
HttpConnections contain the base URL, external API details, credentials, and all resources needed to connect to the API. HttpConnections don't do anything other than supply a connection to an HttpRequest, so all in all they can be considered together instead of as independent assets. Both asset types implement the standard CRUD operations for all assets. Additionally, HttpRequest has the following endpoint:
| Method | Operation | Description |
| POST | /httprequest/{id}/evaluate | Evaluates the external API given the supplied JSON and returns the API's response (see below) |
Request Body:
{
"content": string, // The object to send
"mediaType": string, // "application/json", etc...
"queryParameters": {
"@resourceID": "actualResourceID", ... // These replace existing tags in the endpoint
},
"pathParameters": {
"param1": "val1", ... // These are appended to the endpoint as path parameters.
}
}
Response Body:
{
"URL": string, // Value must be a data table object.
"StatusCode": int,
"Headers": {
},
"Content": any
}