---
# System prepended metadata

title: WISE-iFactory Development Kit for Python
tags: [WISE-iFactory Development Kit for Python, Python, SDK]

---

# Quickstart
This guide details the steps needed to install or update the WISE-iFactory SDK for Python.

> **Note:**
> Documentation and developers tend to refer to the WISE-iFactory SDK for Python as “ifactorysdk,” and this documentation often does so as well.

## Installation
To use ifactorysdk, you first need to install it and its dependencies.

### Install or update Python

Before installing the ifactorysdk, make sure you have Python 3.7 or later installed on your system. Python 3.6 and earlier versions are deprecated and not supported. You can visit the official Python documentation to download and install the latest version of Python.

For information about how to get the latest version of Python, see the official [Python documentation](https://www.python.org/downloads/).

### Install ifactorysdk

Install the latest ifactorysdk release via pip:
```python
pip install ifactorysdk-1.0.0.tar.gz
```
    
If your project requires a specific version of ifactorysdk, or has compatibility concerns with certain versions, you may provide constraints when installing:
```python
# Install ifactorysdk version 1.0 specifically
pip install ifactorysdk==1.0.0

# Make sure Boto3 is no older than version 1.0.3
pip install ifactorysdk>=1.0.3

# Avoid versions of ifactorysdk newer than version 1.0.1
pip install ifactorysdk<=1.0.1
```
    
3. Wait for the installation to complete. Once the installation is finished, you can proceed to use the ifactorysdk in your Python projects.

# Configuration 

Before using ifactorysdk on development or testing, you need to apply for a client key. Follow these steps to apply for a client key:

1. Visit the iFactory website or contact the iFactory support team to apply for a client key. Provide them with the necessary information about your project and intended use of the SDK.
2. Wait for the approval and receive your client key. The client key is a unique identifier that authorizes your access to the iFactory API.

![](https://hackmd.io/_uploads/H19v8gBFh.png)


# Using ifactorysdk

To use ifactorysdk, you must first import it and indicate which service or services you’re going to use:
```python=
from ifactorysdk import WISEiFactoryClient
``` 

## Client Connection
Create an instance of the SDK client by providing the required parameters, such as the host URL and client key:
```python=
sdk = WISEiFactoryClient(host="https://pivot-api-hub-iaio-eks001.sg.wise-ifactory.com", key="YOUR_CLIENT_KEY")
```
> **Note:**
> Replace "YOUR_CLIENT_KEY" with the client key you received after applying.

You can now interact with the iFactory API using the SDK client. The following is an example of getting a Group List:
```python!
res, frame = sdk.get_group_lst()
print(res, frame)
``` 
```
id            name
0  R3JvdXA.ZEuXXjdkBQAHEQOw          SMT-L1
1  R3JvdXA.ZFsQZLIH_wAHKPks  iAIO_Reporters
2  R3JvdXA.ZHBlDkhTnwAHhfp4              SC
3  R3JvdXA.ZHVxrkhTnwAHhfqC       barryTest
4  R3JvdXA.ZHWzFUhTnwAHhfqc             SAE
```
Save the Python file and run it. You should see the output based on the API responses.

## Environment Parser
This module can help users parse the connection location when getting the ENSAAS_SERVICES variable in cloud k8s, or parse the password file in the edge server (AIO).

```env!
#.env --> k8s
ENSAAS_SERVICES = {...}
# .env --> edge
MONGODB_PASSWORD_FILE = ""
```

Parsing variables in ENSAAS_SERVICES in k8s, parsing PASSWORD_FILE in AIO becomes PASSWORD. 

```python!
from ifactorysdk import EnvUtils as env

print(env.MONGODB_URL)      # mongodb1-eks001.sg.wise-ifactory.com:27017
print(env.MONGODB_DATABASE) # 43f56782-f453-4930-9bc3-05ba44219558
print(env.MONGODB_PASSWORD)
```


Congratulations! You have successfully installed and integrated the iFactory SDK into your Python project. Remember to use the client key provided during the application process for authentication and access to the iFactory API.

Resources and Collections are covered in more detail in the following sections.

# WISEiFactoryClient Code Example
This section describes code examples that demonstrate how to use the WISE-iFactory SDK for Python to call various WISE-iFactory services. The source files for the examples, plus additional example programs, are available in the WISE-iFactory Code Catalog.

## WISEiFactoryClient Connection Examples
There are two ways to create a WISEiFactoryClient connection, which are respectively applied in the development and the production. The following demonstrates them respectively:

```python!
from ifactorysdk import WISEiFactoryClient
```

### **Development & Testing**
When developing, you need to use the applied "YOUR_CLIENT_KEY" to connect to the terminal service on the local machine for call development.
```python!
# Create SDK Client for development or testing
sdk = WISEiFactoryClient(host="https://pivot-api-hub-iaio-eks001.sg.wise-ifactory.com", name="“YOUR_APP_NAME”", version="“YOUR_VERSION", key="“YOUR_CLIENT_KEY”")
```

### **Production**
When it is commercialized, you can set etcd_enable to true and deploy it in the same environment, **such as the same local machine or the same namespace on k8s,** it will send a request to etcd where the service is located to obtain the key.
```python!
# Create SDK Client for production
sdk = WISEiFactoryClient(host="https://pivot-api-hub-iaio-eks001.sg.wise-ifactory.com", name="YOUR_APP_NAME", version="YOUR_VERSION", etcd_enable=True)
```
When the key is successfully obtained, all services of the sdk can be successfully called.

## WISEiFactoryClient Metadata Registration Examples

### Registration GQL federation
Integrate GQL API URL registration back into GQL federation.
```python!
sdk = WISEiFactoryClient(host=IFACTORY_URL, name=YOUR_APP_NAME, version=YOUR_VERSION, etcd_enable=True)
if sdk.etcd_enable:
    sdk.client3.put_federation_metadata(url=YOUR_GRAPHQL_URL)
```

### Registration Link Metadata
By calling different put_xxx_link_metadata, you can register the developer’s APP name and URL to the AIO machine. The APP name will be displayed on the screen of the AIO machine. After clicking, it will jump to the entered URL screen.

```python!
# Create SDK Client for production
sdk = WISEiFactoryClient(host="https://pivot-api-hub-iaio-eks001.sg.wise-ifactory.com", name="YOUR_APP_NAME", version="YOUR_VERSION", etcd_enable=True)
if sdk.etcd_enable:
    sdk.client3.put_reporting_link_metadata(name="YOUR_APP_NAME", url="YOUR_APP_URL")
    sdk.client3.put_analysis_link_metadata(name="YOUR_APP_NAME", url="YOUR_APP_URL")
    sdk.client3.put_algorithm_link_metadata(name="YOUR_APP_NAME", url="YOUR_APP_URL")
    sdk.client3.put_iaio_link_metadata(name="YOUR_APP_NAME", url="YOUR_APP_URL", kind="YOUR_KIND")
```
![](https://hackmd.io/_uploads/rkUkgzlY2.png)


## WISEiFactoryClient Base Data Examples

All method interfaces for obtaining service data, if you use "YOUR_CLIENT_KEY" as the development method to call, you don't need to put tenantId.

### Token Validation
Token validation and get login user data.
```python!
# Example: Token Validation
res = sdk.token_validation(cookie="YOUR_COOKIE")
print(res)
```

### Get Group List
Get the groups under choose tenant.
```python!
res, frame = sdk.get_group_lst(, tenantId=YOUR_CHOOSE_TENANTID)
print(res, frame)
```
```
0  R3JvdXA.ZEuXXjdkBQAHEQOw          SMT-L1
1  R3JvdXA.ZFsQZLIH_wAHKPks  iAIO_Reporters
2  R3JvdXA.ZHBlDkhTnwAHhfp4              SC
3  R3JvdXA.ZHVxrkhTnwAHhfqC       barryTest
4  R3JvdXA.ZHWzFUhTnwAHhfqc             SAE
```

### Get Machine List
Get the machines under all tenants
```python!
res, frame = sdk.get_machine_lst(, tenantId=YOUR_CHOOSE_TENANTID)
print(res, frame)
```
```
0  TWFjaGluZQ.ZEuXezdkBQAHEQOz       Machine1          SMT-L1
1  TWFjaGluZQ.ZEuYgTdkBQAHEQO1       Machine2          SMT-L1
2  TWFjaGluZQ.ZEuYiDdkBQAHEQO3       Machine3          SMT-L1
3  TWFjaGluZQ.ZEuYkDdkBQAHEQO5       Machine4          SMT-L1
4  TWFjaGluZQ.ZEyFcTdkBQAHEQPT       Machine5          SMT-L1
```

### Get Parameters List
Obtain the historical data of the parameter name "qty" under all tenant machines, and limit its time interval.
```python!
res, frame = sdk.get_params_by_name_range(name="qty", fromTime="2023-06-01T02:00:00.000Z", toTime="2023-06-26T02:00:00.000Z", tenantId=YOUR_CHOOSE_TENANTID)
print(res, frame)
```
```
Name                      time  num
0   UGFyYW1ldGVy.ZJEnUl22CgAIYEbH  qty    Machine1  2023-06-20T04:13:17.000Z  100
1   UGFyYW1ldGVy.ZJEnUl22CgAIYEbH  qty    Machine1  2023-06-20T07:24:07.000Z   50
2   UGFyYW1ldGVy.ZJFpc122CgAIYEb6  qty      Mount2  2023-06-20T08:58:41.000Z   50
3   UGFyYW1ldGVy.ZJFpc122CgAIYEb6  qty      Mount2  2023-06-20T08:59:00.000Z   50
4   UGFyYW1ldGVy.ZJFpc122CgAIYEb6  qty      Mount2  2023-06-21T03:04:51.000Z   88
5   UGFyYW1ldGVy.ZJFpc122CgAIYEb6  qty      Mount2  2023-06-21T03:05:18.000Z   88
```

### Get Machine Parameters List
Obtain the historical data of all the parameter names filled in the names of the machines with the same id under the tenant, and limit the time interval.
```python!
# Example: Get select machine parameters values by name list and time range
res = sdk.get_machine_params_by_name_range(machineId="TWFjaGluZQ.ZEuXezdkBQAHEQOz", names=["Test1"], fromTime="2023-06-01T02:00:00.000Z", toTime="2023-06-26T02:00:00.000Z", tenantId=YOUR_CHOOSE_TENANTID)
print(res)
```
```
{'id': 'TWFjaGluZQ.ZEuXezdkBQAHEQOz', 'name': 'Machine1', 'parametersByNames': [{'id': 'UGFyYW1ldGVy.ZJ6J5F22CgAIYEpn', 'name': 'Test1', 'valuesInRange': [{'time': '2023-06-06T01:56:58.845Z', 'num': 80, 'str': None, 'savedAt': '2023-06-30T07:54:01.944Z'}, {'time': '2023-06-07T01:56:58.845Z', 'num': 80, 'str': None, 'savedAt': '2023-06-30T07:54:01.944Z'}, {'time': '2023-06-25T01:56:58.000Z', 'num': 80, 'str': None, 'savedAt': '2023-06-30T08:34:27.739Z'}, {'time': '2023-06-25T01:56:58.845Z', 'num': 80, 'str': None, 'savedAt': '2023-06-30T07:54:18.636Z'}]}]}
```

### Add Parameter
Add parameter under select machine
```python!
# Example: Add parameter under select machine
res = sdk.add_parameter(machineId="TWFjaGluZQ.ZEuXezdkBQAHEQOz", name="Test1", tenantId=YOUR_CHOOSE_TENANTID)
print(res)
```

### Remove Parameter
Remove select parameter
```python!
res = sdk.remove_parameter(parameterId="UGFyYW1ldGVy.ZJ6I7l22CgAIYEpk", tenantId=YOUR_CHOOSE_TENANTID)
print(res)
```

### Set Constant Parameter Values
Set select parameter point values.
```python!
# Example: Set select parameter point values list
res = sdk.set_constant_parameter_values(
    parameterId="UGFyYW1ldGVy.ZJ6J5F22CgAIYEpn", 
    pointValues=[
        {
            "time": "2023-06-30T01:56:58",
            "num": 80
        },
        {
            "time": "2023-06-30T01:56:58",
            "num": 80
        }
    ], tenantId=YOUR_CHOOSE_TENANTID)

print(res)
```

> **Note:**
> How to get tenantId from browser cookie.
![](https://hackmd.io/_uploads/rk3euMeK2.png)

### Get All User
Retrieve all users' data.
```python!
res = sdk.get_users(tenantId=YOUR_CHOOSE_TENANTID)
print(res)
```

### Get User by Id List
Query the permissions of a specific user.
```python!
res = sdk.get_user_by_id(userIdlst=["UGFy.ZJ6gAIYk"], tenantId=YOUR_CHOOSE_TENANTID)
print(res)
```

### Get Avalible Quota Kinds
Retrieve the quota kinds available for the app.
```python!
res = sdk.get_avalible_quota_kinds(appName=SPC, tenantId=YOUR_CHOOSE_TENANTID)
print(res)
```

### Get Avalible Quota Count
Retrieve the quota count available for the app.
```python!
res = sdk.get_avalible_quota_kinds(appName=SPC, tenantId=YOUR_CHOOSE_TENANTID)
print(res)
```

### Get Quota Object
Retrieve the quota object available for the app.
```python!
res = sdk.get_quota_object(appName=SPC, tenantId=YOUR_CHOOSE_TENANTID)
print(res)
```

### Add Quota Object
add the quota object available for the app.
```python!
res = sdk.add_quota_object(appName=SPC, kind="object", tenantId=YOUR_CHOOSE_TENANTID)
print(res)
```
### Remove Quota Object
remove the quota object available for the app.
```python!
res = sdk.remove_quota_object(appName=SPC, kind="object", tenantId=YOUR_CHOOSE_TENANTID)
print(res)
```

# WISEiFactoryModelIntegrationClient Code Example

This is an internal model integration module that exposes a Graphql interface on an internal port (5000). It provides implementations for the following interfaces: Query InAppEdgeModel/InAppEdgeModels and Mutation dryRunInAppEdgeModelInference/addInAppEdgeModelInference.

### **Development & Testing** & **Production**

When enabling the interface, please directly import the WISEiFactoryModelIntegrationClient.

```python!
from ifactorysdk import WISEiFactoryModelIntegrationClient

data = [{'name': '{ModelName}'}, {'name': '{ModelName}'}]

server = WISEiFactoryModelIntegrationClient(data, thread_enable=True)
server.on_connect()
```

## Multi-threading Route example

If thread_enable is set to True, developers can define their own API routes using port numbers other than 5000. For example, the following code will create a GQL route on port 5000 and an API route on port 8080:

```python!
from ifactorysdk import WISEiFactoryModelIntegrationClient
from fastapi import FastAPI, Request
import uvicorn, time

app = FastAPI()

@app.get("/", tags=['Root'])
def read_root(*, request: Request):
    return f"This api is already working."

if __name__ == '__main__':
    server = WISEiFactoryModelIntegrationClient(data, thread_enable=True)
    server.on_connect()
    uvicorn.run( app=app, host='0.0.0.0', port=8080, workers=1, loop="asyncio", reload=False)
```
### GraphQL Interface Sample
There will be a total of four GraphQL (GQL) interfaces generated.
```graphql!
query MyQuery {
  inAppEdgeModels {
    id
    name
  }
}
```

```graphql!
query MyQuery {
  inAppEdgeModel(id: "TW9kZWw=.84163328") {
    id
    name
  }
}
```

```graphql!
mutation MyMutation {
  addInAppEdgeModelInference(
    input: {targetParameterId: "UGFyYW1ldGVy.ZLohYfwb4wAHWVZB", modelId: "TW9kZWw=.84163328", sourceParameterIds: "UGFyYW1ldGVy.ZLohYPwb4wAHWVZA"}
  ) {
    inference {
      modelId
      result
      sourceParameterIds
      targetParameterId
      ts
    }
  }
}
```

```graphql!
mutation MyMutation {
  dryRunInAppEdgeModelInference(
    input: {targetParameterId: "UGFyYW1ldGVy.ZLohYfwb4wAHWVZB", modelId: "TW9kZWw=.84163328", sourceParameterIds: "UGFyYW1ldGVy.ZLohYPwb4wAHWVZA"}
  ) {
    inference {
      modelId
      result
      sourceParameterIds
      targetParameterId
      ts
    }
  }
}
```

### Registration Interface
The registration interface request for federation is being replaced with the internal API mechanism, allowing for simultaneous calls to multiple vendors' inference engine integrations.

```python!
if sdk.etcd_enable:
    #sdk.client3.put_federation_metadata(url=YOUR_GRAPHQL_URL)
    sdk.client3.put_internal_api_metadata(url=YOUR_GRAPHQL_URL)
```

## Real-Time Messaging (RTM) Integration for Custom Algorithms and Model Applications

The module imported in server.on_message will listen and receive requests when the RTM (Real-Time Messaging) calls the GraphQL dryRunInAppEdgeModelInference/addInAppEdgeModelInference interface. Afterward, the module can incorporate its own algorithms and model applications, and finally write back the parameters to the AIO RTM. This process enables the integration of custom algorithms and models with the RTM for further data processing and updates.

```json!
taskobj = {
    "targetId": input.targetParameterId, #要回寫的參數
    "sourceId": input.sourceParameterIds, #要獲取的參數
    "modelId": input.modelId, #使用個模型id
    "createdAt": datetime.utcnow(),
    "updatedAt": datetime.utcnow()
}
```

```python!
def test_func(route:str, taskobj:dict):
    print("Route::: ", route, "Task:::", taskobj)
```
```python!
server = WISEiFactoryModelIntegrationClient(data, thread_enable=True)
server.on_message = test_func
server.on_connect()
```

### Target id rechange
Target ID Rechange: Convert targetId received in taskobj to pointId for updating transformation parameter values.

```python!
pointId = sdk.targetId_tochange_pointId(taskobj.get('targetId'))
```

### Set Transformation Parameter Value
Writing Parameter Values into pointId.
```python!
server.set_transformation_parameter_values(pointId, 100, "2023-05-23T08:46:16.564Z")
```

### Influx Get Parameters Data
The task is to retrieve parameter data from InfluxDB using either InfluxQL or Flux query language, depending on the version of InfluxDB being used. The query should specify the measurement name and the desired time range to fetch the data. Access privileges and connection settings to the InfluxDB instance should be verified before executing the query.
```python!
sourceidlst= ["UGFyYW1ldGVy.ZLohYfwb4wAHWVZA", "UGFyYW1ldGVy.ZLohYfwb4wAHWVZB"]
sourceData = sdk.get_params_by_id(sourceidlst)
server.influx_get_params_data(sourceData)
```


© 1983-2023 Advantech Co., Ltd. | [Privacy Policy](https://www.advantech.com/zh-tw/legal/privacy) || [Console](https://reurl.cc/LAnmd4) | [Technical Documentation](https://docs.wise-paas.advantech.com/en/wise-ifactory)


