Updated on 2024-10-29 GMT+08:00

Accessing a Real-Time Service Through App Authentication

You can enable application authentication when deploying a real-time service. ModelArts registers an API that supports application authentication for the service. After this API is authorized to an application, you can call this API using the AppKey/AppSecret or AppCode of the application.

The process of application authentication for a real-time service is as follows:

  1. Enabling Application Authentication: Enable application authentication. You can select or create an application.
  2. Managing Authorization for Real-Time Services: Manage your applications, including viewing, resetting, or deleting them, as well as binding or unbinding real-time services and obtaining your AppKey and AppSecret, or AppCode.
  3. Application Authentication: To call an API that supports app authentication, you will need to authenticate first. There are two authentication methods: AppKey and AppSecret, or AppCode. You can choose the one that suits you best.
  4. Send an inference request.

Constraints

When you call an API to access a real-time service, the size of the prediction request body and the prediction time are subject to the following limitations:
  • The size of a request body cannot exceed 12 MB. Otherwise, the request will fail.
  • Due to the limitation of API Gateway, the prediction duration of each request does not exceed 40 seconds.

Prerequisites

  • An AI application in the Normal state is available in ModelArts.
  • The account is not in arrears to ensure available resources for service running.
  • The local path to the inference file has been obtained. The path can be an absolute path (for example, D:/test.png for Windows and /opt/data/test.png for Linux) or a relative path (for example, ./test.png).

Enabling Application Authentication

When deploying a real-time service, you can enable application authentication. You can also modify a deployed real-time service to support application authentication.

  1. Log in to the ModelArts console and choose Model Deployment > Real-Time Services.
  2. Enable application authentication.
    • When deploying a real-time service, enable application authentication on the Deploy page.
    • For a deployed real-time service, go to the Real-Time Services page, and click Modify in the Operation column of the service. On the service modification page, enable application authentication.
      Figure 1 Enabling application authentication

  3. Select an application for authorization from the drop-down list. If no application is available, follow these steps to create one:
    • Click Create Application, enter the application name and description, and click OK. By default, the application name is prefixed with app_. You can change this name if needed.
    • On the Model Deployment > Real-Time Services page, click Authorize. On the Manage Authorization of Real-Time Services page, click Create Application. For details, see Managing Authorization for Real-Time Services.
  4. After enabling application authentication, authorize a service that supports application authentication to the application. Then, you can use the created AppKey/AppSecret or AppCode to call the service's API that supports application authentication.

Managing Authorization for Real-Time Services

If you want to use application authentication, it is good practice to create an application on the authorization management page before deploying a real-time service. In the navigation pane, choose Model Deployment > Real-Time Services. On the Real-Time Services page, click Authorize. From there, you can create, reset, or delete applications, query plaintext, unbind real-time services from applications, and obtain the AppKey/AppSecret or AppCode.

Figure 2 Managing authorization for real-time services

  • Creating an application

    Click Create Application, enter the application name and description, and click OK. By default, the application name is prefixed with app_. You can change this name if needed.

  • Viewing, resetting, or deleting an application

    Query plaintext, reset, or delete an application by clicking the corresponding icon in the Operation column of the application. After an application is created, the AppKey and AppSecret are automatically generated for application authentication.

    Figure 3 Query Plaintext, Reset, or Delete

  • Unbinding a service

    Click next to the target application name to view the real-time services bound to the application. Click Unbind in the Operation column to cancel the binding. Then, this API cannot be called.

  • Obtaining the AppKey/AppSecret or AppCode

    Application authentication is required for API calling. The AppKey and AppSecret are automatically generated during application creation. Click in the Operation column of the application in the Manage Authorization of Real-Time Services dialog box to view the complete AppSecret. Click next to the application name to show the drop-down list. Click Add AppCode to automatically generate an AppCode. Then, click in the Operation column to view the complete AppCode.

    Figure 4 Adding the AppCode

Application Authentication

When a real-time service that supports application authentication is in the Running state, the service' API can be called. Before calling the API, perform application authentication.

When you use application authentication and enable simplified authentication, you can use your AppKey/AppSecret for signing and verification, or AppCode for simplified authentication. ModelArts uses simplified authentication by default. AppKey/AppSecret-based authentication is recommended because it is more secure than AppCode-based authentication.

  • AppKey/AppSecret-based authentication: The AppKey and AppSecret are used to encrypt a request, identify the sender, and prevent the request from being modified. When using AppKey/AppSecret-based authentication, use a dedicated signing SDK to sign requests.
    • AppKey: access key ID of the application, which is a unique identifier used together with a secret access key to sign requests cryptographically.
    • AppSecret: application secret access key, used together with the access key ID to encrypt the request, identify the sender, and prevent the request from being tempered.

    AppKeys can be used for simplified authentication. When an API is called, the apikey parameter (value: AppKey) is added to the HTTP request header to accelerate authentication.

  • AppCode-based authentication: Requests are authenticated using AppCodes.

    In AppCode-based authentication, the X-Apig-AppCode parameter (value: AppCode) is added to the HTTP request header when an API is called. The request content does not need to be signed. The API gateway only verifies the AppCode, achieving quick response.

You can obtain the API URL (url of the real-time service), AppKey/AppSecret (app_key and app_secret), and AppCode (app_code) from the Usage Guides tab on the service details page (see Figure 5). Use the API URL for application authentication in the second line of the figure.

Modify the API URL in the following scenarios:

  • If apis defines a path in the model configuration file, append the user-defined path to the URL, for example, {URL of the real-time service}/predictions/poetry.
  • If an SD WebUI inference service is deployed, add a slash (/) to the end of the calling address, for example, https://8e******5fe.apig.******.huaweicloudapis.com/v1/infers/f2682******f42/.
Figure 5 Obtaining application authentication information

Method 1: Use Python to Send an Inference request Through AppKey/AppSecret-based Authentication

  1. Download the Python SDK and configure it in the development tool.
  2. Create a request body for inference.
    • File input
      # coding=utf-8
      
      import requests
      import os
      from apig_sdk import signer
      
      if __name__ == '__main__':
          # Config url, ak, sk and file path.
          # API URL, for example, "https://8e******5fe.apig.******.huaweicloudapis.com/v1/infers/f2682******f42"
          url = "URL of the real-time service"
          # Hardcoded or plaintext app_key and app_secret are risky. For security, encrypt and store them in the configuration file or environment variables.
          # In this example, the app_key and app_secret are stored in environment variables for identity authentication. Before running this example, set environment variables HUAWEICLOUD_APP_KEY and HUAWEICLOUD_APP_SECRET.
          app_key = os.environ["HUAWEICLOUD_APP_KEY"]
          app_secret= os.environ["HUAWEICLOUD_APP_SECRET"]
          file_path = "Local path to the inference file"
      
          # Create request, set method, url, headers and body.
          method = 'POST'
          headers = {"x-sdk-content-sha256": "UNSIGNED-PAYLOAD"}
          request = signer.HttpRequest(method, url, headers)
      
          # Create sign, set the AK/SK to sign and authenticate the request.
          sig = signer.Signer()
          sig.Key = app_key
          sig.Secret = app_secret
          sig.Sign(request)
      
          # Send request
          files = {'images': open(file_path, 'rb')}
          resp = requests.request(request.method, request.scheme + "://" + request.host + request.uri, headers=request.headers, files=files)
      
          # Print result
          print(resp.status_code)
          print(resp.text)
      Request body format of files: files = {"Request parameter": ("Load path", File content, "File type")}. For details about parameters of files, see Table 1.
      Table 1 Parameters of files

      Parameter

      Mandatory

      Description

      Request parameter

      Yes

      Parameter name of the real-time service.

      File path

      No

      Path for storing the file.

      File content

      Yes

      Content of the file to be uploaded.

      File type

      No

      Type of the file to be uploaded, which can be one of the following options:

      • txt: text/plain
      • jpg/jpeg: image/jpeg
      • png: image/png
    • Text input (JSON)

      The following is an example request body for reading the local inference file and performing Base64 encoding:

      # coding=utf-8
      
      import base64
      import json
      import os
      import requests
      from apig_sdk import signer
      
      if __name__ == '__main__':
          # Config url, ak, sk and file path.
          # API URL, for example, "https://8e******5fe.apig.******.huaweicloudapis.com/v1/infers/f2682******f42"
          url = "URL of the real-time service"
          # Hardcoded or plaintext app_key and app_secret are risky. For security, encrypt and store them in the configuration file or environment variables.
          # In this example, the app_key and app_secret are stored in environment variables for identity authentication. Before running this example, set environment variables HUAWEICLOUD_APP_KEY and HUAWEICLOUD_APP_SECRET.
          app_key = os.environ["HUAWEICLOUD_APP_KEY"]
          app_secret= os.environ["HUAWEICLOUD_APP_SECRET"]
          file_path = "Local path to the inference file"
          with open(file_path, "rb") as file:
              base64_data = base64.b64encode(file.read()).decode("utf-8")
      
          # Create request, set method, url, headers and body.
          method = 'POST'
          headers = {
              'Content-Type': 'application/json'
          }
          body = {
              'image': base64_data
          }
          request = signer.HttpRequest(method, url, headers, json.dumps(body))
      
          # Create sign, set the AppKey&AppSecret to sign and authenticate the request.
          sig = signer.Signer()
          sig.Key = app_key
          sig.Secret = app_secret
          sig.Sign(request)
      
          # Send request
          resp = requests.request(request.method, request.scheme + "://" + request.host + request.uri, headers=request.headers, data=request.body)
      
          # Print result
          print(resp.status_code)
          print(resp.text)

      The body name is determined by the input parameter of the real-time service. The parameter name must be the same as that of the input parameter of the string type. image is used as an example. The value of base64_data in body is of the string type.

Method 2: Use Java to Send an Inference request Through AppKey/AppSecret-based Authentication

  1. Download the Java SDK and configure it in the development tool.
  2. Create a Java request body for inference.

    In the APIG Java SDK, request.setBody() can only be a string. Therefore, only text inference requests are supported.

    The following is an example of the request body (JSON) for reading the local inference file and performing Base64 encoding:

    // Package name of the demo.
    package com.apig.sdk.demo;
    
    import com.cloud.apigateway.sdk.utils.Client;
    import com.cloud.apigateway.sdk.utils.Request;
    import org.apache.http.HttpHeaders;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.client.methods.HttpRequestBase;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.util.EntityUtils;
    
    public class MyAkSkTest {
    
        public static void main(String[] args) {
           # API URL, for example, "https://8e******5fe.apig.******.huaweicloudapis.com/v1/infers/f2682******f42"
            String url = "URL of the real-time service";
           // Hard-coded or plaintext app_key and app_secret are risky. For security, encrypt and store them in the configuration file or environment variables.
           // In this example, the app_key and app_secret are stored in environment variables for identity authentication. Before running this example, set environment variables HUAWEICLOUD_APP_KEY and HUAWEICLOUD_APP_SECRET.
            String appKey = System.getenv("HUAWEICLOUD_APP_KEY");
           String appSecret = System.getenv("HUAWEICLOUD_APP_SECRET");
            String body = "{}";
    
            try {
                // Create request
                Request request = new Request();
    
                // Set the AK/AppSecret to sign and authenticate the request.
                request.setKey(appKey);
                request.setSecret(appSecret);
    
                // Specify a request method, such as GET, PUT, POST, DELETE, HEAD, and PATCH.
                request.setMethod(HttpPost.METHOD_NAME);
    
                // Add header parameters
                request.addHeader(HttpHeaders.CONTENT_TYPE, "application/json");
    
                // Set a request URL in the format of https://{Endpoint}/{URI}.
                request.setUrl(url);
    
                // Special characters, such as the double quotation mark ("), contained in the body must be escaped.
                request.setBody(body);
    
                // Sign the request.
                HttpRequestBase signedRequest = Client.sign(request);
    
                // Send request.
                CloseableHttpResponse response = HttpClients.createDefault().execute(signedRequest);
    
                // Print result
                System.out.println(response.getStatusLine().getStatusCode());
                System.out.println(EntityUtils.toString(response.getEntity()));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    body is determined by the text format. JSON is used as an example.

Method 3: Use Python to Send an Inference request Through AppCode-based Authentication

  1. Download the Python SDK and configure it in the development tool.
  2. Create a request body for inference.
    • File input
      # coding=utf-8
      
      import requests
      import os
      
      if __name__ == '__main__':
          # Config url, app code and file path.
         # API URL, for example, "https://8e******5fe.apig.******.huaweicloudapis.com/v1/infers/f2682******f42"
          url = "URL of the real-time service"
          # Hardcoded or plaintext app_code is risky. For security, encrypt and store it in the configuration file or environment variables.
          # In this example, the app_code is stored in environment variables for identity authentication. Before running this example, set environment variable HUAWEICLOUD_APP_CODE.
          app_code = os.environ["HUAWEICLOUD_APP_CODE"]
          file_path = "Local path to the inference file"
      
          # Send request.
          headers = {
              'X-Apig-AppCode': app_code
          }
          files = {
              'images': open(file_path, 'rb')
          }
          resp = requests.post(url, headers=headers, files=files)
      
          # Print result
          print(resp.status_code)
          print(resp.text)

      The files name is determined by the input parameter of the real-time service. The parameter name must be the same as that of the input parameter of the file type. In this example, images is used.

    • Text input (JSON)

      The following is an example request body for reading the local inference file and performing Base64 encoding:

      # coding=utf-8
      
      import base64
      import requests
      import os
      
      if __name__ == '__main__':
          # Config url, app code and request body.
         # API URL, for example, "https://8e******5fe.apig.******.huaweicloudapis.com/v1/infers/f2682******f42"
          url = "URL of the real-time service"
          # Hardcoded or plaintext app_code is risky. For security, encrypt and store it in the configuration file or environment variables.
          # In this example, the app_code is stored in environment variables for identity authentication. Before running this example, set environment variable HUAWEICLOUD_APP_CODE.
          app_code = os.environ["HUAWEICLOUD_APP_CODE"]
          file_path = "Local path to the inference file"
          with open(file_path, "rb") as file:
              base64_data = base64.b64encode(file.read()).decode("utf-8")
      
          # Send request
          headers = {
              'Content-Type': 'application/json',
              'X-Apig-AppCode': app_code
          }
          body = {
              'image': base64_data
          }
          resp = requests.post(url, headers=headers, json=body)
      
          # Print result
          print(resp.status_code)
          print(resp.text)

      The body name is determined by the input parameter of the real-time service. The parameter name must be the same as that of the input parameter of the string type. image is used as an example. The value of base64_data in body is of the string type.

Method 4: Use Java to Send an Inference request Through AppCode-based Authentication

  1. Download the Java SDK and configure it in the development tool.
  2. (Optional) If the inference request input is in a file format, follow these steps to ensure the Java project includes the httpmime module as a dependency.
    1. Add httpmime-x.x.x.jar to the libs folder. Figure 6 shows a complete Java dependency library.

      You are advised to use httpmime-x.x.x.jar 4.5 or later. Download httpmime-x.x.x.jar from https://mvnrepository.com/artifact/org.apache.httpcomponents/httpmime.

      Figure 6 Java dependency library
    2. After httpmime-x.x.x.jar is added, add httpmime information to the .classpath file of the Java project as follows:
      <?xml version="1.0" encoding="UTF-8"?>
      <classpath>
      <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
      <classpathentry kind="src" path="src"/>
      <classpathentry kind="lib" path="libs/commons-codec-1.11.jar"/>
      <classpathentry kind="lib" path="libs/commons-logging-1.2.jar"/>
      <classpathentry kind="lib" path="libs/httpclient-4.5.13.jar"/>
      <classpathentry kind="lib" path="libs/httpcore-4.4.13.jar"/>
      <classpathentry kind="lib" path="libs/httpmime-x.x.x.jar"/>
      <classpathentry kind="lib" path="libs/java-sdk-core-3.1.2.jar"/>
      <classpathentry kind="lib" path="libs/okhttp-3.14.9.jar"/>
      <classpathentry kind="lib" path="libs/okio-1.17.2.jar"/>
      <classpathentry kind="output" path="bin"/>
      </classpath>
  3. Create a Java request body for inference.
    • File input
      A sample Java request body is as follows:
      // Package name of the demo.
      package com.apig.sdk.demo;
      
      import org.apache.http.Consts;
      import org.apache.http.HttpEntity;
      import org.apache.http.client.methods.CloseableHttpResponse;
      import org.apache.http.client.methods.HttpPost;
      import org.apache.http.entity.ContentType;
      import org.apache.http.entity.mime.MultipartEntityBuilder;
      import org.apache.http.impl.client.HttpClients;
      import org.apache.http.util.EntityUtils;
      
      import java.io.File;
      
      public class MyAppCodeFile {
      
          public static void main(String[] args) {
             # API URL, for example, "https://8e******5fe.apig.******.huaweicloudapis.com/v1/infers/f2682******f42"
              String url = "URL of the real-time service";
             // Hard-coded or plaintext appCode is risky. For security, encrypt and store it in the configuration file or environment variables.
             // In this example, the appCode is stored in environment variables for identity authentication. Before running this example, set environment variable HUAWEICLOUD_APP_CODE.
              String appCode = System.getenv("HUAWEICLOUD_APP_CODE");
              String filePath = "Local path to the inference file";
      
              try {
                  // Create post
                  HttpPost httpPost = new HttpPost(url);
      
                  // Add header parameters
                  httpPost.setHeader("X-Apig-AppCode", appCode);
      
                  // Special characters, such as the double quotation mark ("), contained in the body must be escaped.
                  File file = new File(filePath);
                  HttpEntity entity = MultipartEntityBuilder.create().addBinaryBody("images", file).setContentType(ContentType.MULTIPART_FORM_DATA).setCharset(Consts.UTF_8).build();
                  httpPost.setEntity(entity);
      
                  // Send post
                  CloseableHttpResponse response = HttpClients.createDefault().execute(httpPost);
      
                  // Print result
                  System.out.println(response.getStatusLine().getStatusCode());
                  System.out.println(EntityUtils.toString(response.getEntity()));
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      }

      The addBinaryBody name is determined by the input parameter of the real-time service. The parameter name must be the same as that of the input parameter of the file type. In this example, images is used.

    • Text input (JSON)

      The following is an example request body for reading the local inference file and performing Base64 encoding:

      // Package name of the demo.
      package com.apig.sdk.demo;
      
      import org.apache.http.HttpHeaders;
      import org.apache.http.client.methods.CloseableHttpResponse;
      import org.apache.http.client.methods.HttpPost;
      import org.apache.http.entity.StringEntity;
      import org.apache.http.impl.client.HttpClients;
      import org.apache.http.util.EntityUtils;
      
      public class MyAppCodeTest {
      
          public static void main(String[] args) {
             # API URL, for example, "https://8e******5fe.apig.******.huaweicloudapis.com/v1/infers/f2682******f42"
              String url = "URL of the real-time service";
             // Hard-coded or plaintext appCode is risky. For security, encrypt and store it in the configuration file or environment variables.
             // In this example, the appCode is stored in environment variables for identity authentication. Before running this example, set environment variable HUAWEICLOUD_APP_CODE.
              String appCode = System.getenv("HUAWEICLOUD_APP_CODE");
              String body = "{}";
      
              try {
                  // Create post
                  HttpPost httpPost = new HttpPost(url);
      
                  // Add header parameters
                  httpPost.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
                  httpPost.setHeader("X-Apig-AppCode", appCode);
      
                  // Special characters, such as the double quotation mark ("), contained in the body must be escaped.
                  httpPost.setEntity(new StringEntity(body));
      
                  // Send post
                  CloseableHttpResponse response = HttpClients.createDefault().execute(httpPost);
      
                  // Print result
                  System.out.println(response.getStatusLine().getStatusCode());
                  System.out.println(EntityUtils.toString(response.getEntity()));
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      }

      body is determined by the text format. JSON is used as an example.