
# 通过AK/SK认证的方式访问在线服务
AK/SK认证是华为云ModelArts平台用于身份验证的一种方式，其中AK（Access Key）和SK（Secret Key）是用于访问华为云服务的密钥。
如果在线服务的状态处于"运行中"，则表示在线服务已部署成功。部署成功的在线服务，将为用户提供一个可调用的API，此API为标准RESTful API。用户可以通过AK/SK签名认证方式调用API。
AK/SK签名认证方式，仅支持Body体12M以内，12M以上的请求，需使用Token认证，详情请见[通过Token认证的方式访问在线服务](https://support.huaweicloud.com/inference-modelarts/inference-modelarts-0023.html)。
使用AK/SK认证时，您可以通过APIG SDK访问，也可以通过ModelArts SDK访问。使用ModelArts SDK访问参见[用户AK-SK认证模式](https://support.huaweicloud.com/sdkreference-modelarts/modelarts_04_0123.html#section2)。本文档详细介绍如何通过APIG SDK访问在线服务，具体操作流程如下：
1. [获取AK/SK]
2. [获取在线服务信息]
3. 发送预测请求
   - [方式一：使用Python语言发送预测请求]
   
   - [方式二：使用Java语言发送预测请求]
    
#### 约束限制
- 调用API访问在线服务时，对预测请求体大小和预测时间有限制：
  - 请求体的大小不超过12MB，超过后请求会被拦截。
  
  - 因APIG（API网关）限制，平台每次请求预测的时间不超过40秒。
   
- 客户端须注意本地时间与时钟服务器的同步，避免请求消息头X-Sdk-Date的值出现较大误差。因为API网关除了校验时间格式外，还会校验该时间值与网关收到请求的时间差，如果时间差超过15分钟，API网关将拒绝请求。
 
 #### 获取AK/SK
如果已生成过AK/SK，则可跳过此步骤，找到原来已下载的AK/SK文件，文件名一般为：credentials.csv。
如下图所示，文件包含了租户名（User Name），AK（Access Key Id），SK（Secret Access Key）。
图1credential.csv文件内容   
![](https://support.huaweicloud.com/inference-modelarts/figure/zh-cn_image_0000001986182701.png)
AK/SK生成步骤：
1. 注册并登录[管理控制台](https://console.huaweicloud.com/)。
2. 单击右上角的用户名，在下拉列表中单击"我的凭证"。
3. 单击"访问密钥"。
4. 单击"新增访问密钥"，进入"身份验证"页面。
5. 根据提示完成身份验证，下载密钥，并妥善保管。
 
 #### 获取在线服务信息
在调用接口时，需获取在线服务的调用地址，以及在线服务的输入参数信息。步骤如下：
1. 登录[ModelArts管理控制台](https://console.huaweicloud.com/modelarts/)，在左侧导航栏中选择"模型部署 \> 在线服务"，默认进入"在线服务"列表。
2. 单击目标服务名称，进入服务详情页面。
3. 在"在线服务"的详情页面，可以获取该服务的调用地址和输入参数信息。
   "API接口公网地址"即在线服务的调用地址。当模型配置文件中apis定义了路径，调用地址后需拼接自定义路径。如："{在线服务的调用地址}/predictions/poetry"。
   图2获取在线服务API接口地址和文件预测输入参数信息   
   ![](https://support.huaweicloud.com/inference-modelarts/figure/zh-cn_image_0000002397156778.png) 
 
 #### 方式一：使用Python语言发送预测请求
1. 下载Python SDK并在开发工具中完成SDK配置。具体操作请参见[在Python环境中集成API请求签名的SDK](https://support.huaweicloud.com/devg-apisign/api-sign-sdk-python.html)。
2. 创建请求体，进行预测请求。
   - **输入为文件格式**
     ```
     # coding=utf-8
     import requests
     import os
     from apig_sdk import signer
     if __name__ == '__main__':
         # Config url, ak, sk and file path.
         url = "在线服务的调用地址"
         # 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全;
         # 本示例以ak和sk保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK。
         ak = os.environ["HUAWEICLOUD_SDK_AK"]
         sk = os.environ["HUAWEICLOUD_SDK_SK"]
         file_path = "预测文件的本地路径"
         # 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 = ak
         sig.Secret = sk
         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)
     ```
     "file_path"为预测文件的本地路径，既可使用绝对路径（如Windows格式"D:/test.png"，Linux格式"/opt/data/test.png"），也可以使用相对路径（如"./test.png"）。
     "files"参数的请求体样式为"files={"请求参数":("文件路径"，文件内容，"文件类型")}"，参数填写可以参考[表1]。
      表1files参数说明 
     | 参数   | 是否必填 | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
     |:---|:---|:---|
     | 请求参数 | 是    | 在线服务输入参数名称。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
     | 文件路径 | 否    | 上传文件的路径。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
     | 文件内容 | 是    | 上传文件的内容。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
     | 文件类型 | 否    | 上传文件类型。当前支持以下类型： - txt类型：text/plain  - jpg/jpeg类型：image/jpeg  - png类型：image/png   |
        
     
   
   - **输入为文本格式（json类型）**
     读取本地预测文件并进行base64编码的请求体示例如下：
     ```
     # 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.
         url = "在线服务的调用地址"
         # 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全;
         # 本示例以ak和sk保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK。
         ak = os.environ["HUAWEICLOUD_SDK_AK"]
         sk = os.environ["HUAWEICLOUD_SDK_SK"]
         file_path = "预测文件的本地路径"
         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 AK/SK to sign and authenticate the request.
         sig = signer.Signer()
         sig.Key = ak
         sig.Secret = sk
         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)
     ```
     "body"中的参数名由在线服务的输入参数决定，需要和"类型"为"string"的输入参数"名称"保持一致。此处以"image"为例。"body"中的base64_data值为string类型。
     
    
 
 #### 方式二：使用Java语言发送预测请求
1. 下载Java SDK并在开发工具中完成SDK配置。具体操作请参见[在Java环境中集成API请求签名的SDK](https://support.huaweicloud.com/devg-apisign/api-sign-sdk-java.html)
2. 创建Java类，进行预测请求。 由于在APIG的Java SDK中，"request.setBody()"只支持String类型，所以只支持输入为文本格式的预测请求。如果输入的是文件格式，需要先进行base64编码转换成文本。
   - **输入为文件格式**
     此处以json格式为例介绍读取本地预测文件并进行base64编码的请求体，请求体示例如下：
     ```
     package com.apig.sdk.demo;
     import com.cloud.apigateway.sdk.utils.Client;
     import com.cloud.apigateway.sdk.utils.Request;
     import org.apache.commons.codec.binary.Base64;
     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;
     import java.io.FileInputStream;
     import java.io.IOException;
     import java.io.InputStream;
     public class MyAkSkTest2 {
         public static void main(String[] args) {
             String url = "在线服务的调用地址";
            // 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险，建议在配置文件或者环境变量中密文存放，使用时解密，确保安全；
            // 本示例以ak和sk保存在环境变量中来实现身份验证为例，运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK。 
             String ak = System.getenv("HUAWEICLOUD_SDK_AK");
            String sk = System.getenv("HUAWEICLOUD_SDK_SK");
             String filePath = "预测文件的本地路径";
             try {
                 // Create request
                 Request request = new Request();
                 // Set the AK/SK to sign and authenticate the request.
                 request.setKey(ak);
                 request.setSecret(sk);
                 // 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);
                 // build your json body
                 String body = "{\"image\":\"" + getBase64FromFile(filePath) + "\"}";
                 // 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();
             }
         }
         /**
          * Convert the file into a byte array and Base64 encode it
          * @return
          */
         private static String getBase64FromFile(String filePath) {
             // Convert the file into a byte array
             InputStream in = null;
             byte[] data = null;
             try {
                 in = new FileInputStream(filePath);
                 data = new byte[in.available()];
                 in.read(data);
                 in.close();
             } catch (IOException e) {
                 e.printStackTrace();
             }
             // Base64 encode
             return new String(Base64.encodeBase64(data));
         }
     }
     ```
     ![](https://support.huaweicloud.com/inference-modelarts/public_sys-resources/caution_3.0-zh-cn.png)
     使用base64编码方式，需要在模型推理代码中增加对请求体解码的代码。
     
   
   
   
   - **输入为文本格式（json类型）**
     ```
     // 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) {
             String url = "在线服务的调用地址";
            // 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险，建议在配置文件或者环境变量中密文存放，使用时解密，确保安全；
            // 本示例以ak和sk保存在环境变量中来实现身份验证为例，运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK。 
             String ak = System.getenv("HUAWEICLOUD_SDK_AK");
            String sk = System.getenv("HUAWEICLOUD_SDK_SK");
             try {
                 // Create request
                 Request request = new Request();
                 // Set the AK/SK to sign and authenticate the request.
                 request.setKey(ak);
                 request.setSecret(sk);
                 // 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.
                 String body = "{}";
                 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"由具体文本格式决定，此处以json为例。
     
    
 
