# 通过Token认证的方式访问在线服务
Token在计算机系统中代表令牌（临时）的意思。拥有Token就代表拥有某种权限。Token认证就是在调用API的时候将Token加到请求消息头，从而通过身份认证，获得操作API的权限。
如果在线服务的状态处于"运行中"，则表示在线服务已部署成功，部署成功的在线服务，将为用户提供一个可调用的API，此API为标准RESTful API。通过Token认证，用户可以在调用在线服务时验证其身份，从而获得操作在线服务API的权限。
Token认证是一种用于访问ModelArts平台在线服务的认证方式。Token的有效期通常为24小时，到期后需要重新获取。Token认证适用于快速开发和测试场景，简单易用，但有效期较短。
在将在线服务RESTful API集成至生产环境之前，需要对此API进行调测，您可以使用以下方式通过Token认证向在线服务发起预测请求：
- [方式一：使用图形界面的软件进行预测（以Postman为例）]。Windows系统建议使用Postman。
- [方式二：使用curl命令发送预测请求]。Linux系统建议使用curl命令。
- [方式三：使用Python语言发送预测请求]。
- [方式四：使用Java语言发送预测请求]。
#### 约束限制
调用API访问在线服务时，对预测请求体大小和预测时间有限制：
- 请求体的大小不超过12MB，超过后请求会被拦截。
- 因APIG（API网关）限制，平台每次请求预测的时间不超过40秒。
 
 #### 前提条件
已经获取**用户Token** 、**预测文件的本地路径** 、**在线服务的调用地址** 和**在线服务的输入参数**信息。
- 用户Token的获取请参见[获取Token认证](https://support.huaweicloud.com/api-modelarts/modelarts_03_0004.html#section0)。获取Token认证时，由于ModelArts生成的在线服务API不支持domain范围的token，因此需获取使用范围为project的Token信息，即scope参数的取值为project。
- 预测文件的本地路径既可使用绝对路径（如Windows格式"D:/test.png"，Linux格式"/opt/data/test.png"），也可以使用相对路径（如"./test.png"）。
- 在线服务的调用地址和输入参数信息，可以在控制台的"在线服务详情 \> 调用指南"页面获取。 "API接口公网地址"即在线服务的调用地址。当模型配置文件中apis定义了路径，调用地址后需拼接自定义路径。如："{在线服务的调用地址}/predictions/poetry"。
  图1获取在线服务API接口地址和文件预测输入参数信息   
  ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002041770276.png "点击放大") 
 
 #### 方式一：使用图形界面的软件进行预测（以Postman为例）
1. 下载Postman软件并安装，您也可以直接在Chrome浏览器添加Postman扩展程序（也可使用其他支持发送post请求的软件）。Postman推荐使用7.24.0版本。
2. 打开Postman，如[图2]所示。
   图2Postman界面   
   ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000001986182913.png "点击放大") 
3. 在Postman界面填写参数，以图像分类举例说明。
   - 选择POST任务，将在线服务的调用地址复制到POST后面的方框。Headers页签的Key值填写为"X-Auth-Token"，Value值为用户Token。
     
     ![](https://support.huaweicloud.com/usermanual-standard-modelarts/public_sys-resources/note_3.0-zh-cn.png)
     您也可以通过AK（Access Key ID）/SK（Secret Access Key）加密调用请求，具体可参见[用户AK-SK认证模式](https://support.huaweicloud.com/sdkreference-modelarts/modelarts_04_0123.html#section2)。
     图3参数填写   
     ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002717575980.png "点击放大") 
   
   - 在Body页签，根据模型的输入参数不同，可分为2种类型：文件输入、文本输入。
     - **文件输入**
       选择"form-data"。在"KEY"值填写模型的入参，和在线服务的输入参数对应，比如本例中预测图片的参数为"images"。然后在"VALUE"值，选择文件，上传一张待预测图片（当前仅支持单张图片预测），如[图4]所示。
       图4填写Body   
       ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002747255917.png "点击放大")
       
       
     
     - **文本输入**
       选择"raw"，选择JSON(application/json)类型，在下方文本框中填写请求体，请求体样例如下：
       ```
       {
         "meta": {
           "uuid": "10eb0091-887f-4839-9929-cbc884f1e20e"
         },
         "data": {
           "req_data": [
             {
               "sepal_length": 3,
               "sepal_width": 1,
               "petal_length": 2.2,
               "petal_width": 4
             }
           ]
         }
       }
       ```
       其中，"meta"中可携带"uuid"，调用时传入一个"uuid"，返回预测结果时回传此"uuid"用于跟踪请求，如无此需要可不填写meta**。**"data"包含了一个"req_data"的数组，可传入单条或多条请求数据，其中每个数据的参数由模型决定，比如本例中的"sepal_length"、"sepal_width"等。
       
      
    
4. 参数填写完成，单击"send"发送请求，结果会在"Response"下的对话框里显示。
   - 文件输入形式的预测结果样例如[图5]所示，返回结果的字段值根据不同模型可能有所不同。
   
   - 文本输入形式的预测结果样例如[图6]所示，请求体包含"meta"及"data"。如输入请求中包含"uuid"，则输出结果中回传此"uuid"。如未输入，则为空。"data"包含了一个"resp_data"的数组，返回单条或多条输入数据的预测结果，其中每个结果的参数由模型决定，比如本例中的"sepal_length"、"predictresult"等。
     图5文件输入预测结果   
     ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002747175835.png "点击放大")
     
     图6文本输入预测结果   
     ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002717735904.png "点击放大") 
    
 
 #### 方式二：使用curl命令发送预测请求
使用curl命令发送预测请求的命令格式也分为文件输入、文本输入两类。
- 文件输入
  ```
  curl -kv -F 'images=@图片路径' -H 'X-Auth-Token:Token值' -X POST 在线服务地址
  ```
  - "-k"是指允许不使用证书访问SSL站点。
  
  - "-F"是指上传数据的是文件，本例中参数名为"images"，这个名字可以根据具体情况变化，@后面是图片的存储路径。
  
  - "-H"是post命令的headers，Headers的Key值为"X-Auth-Token"，这个名字为固定的， Token值是获取的用户Token。
  
  - "POST"后面跟随的是在线服务的调用地址。
  
  
  curl命令文件输入样例：
  ```
  curl -kv -F 'images=@/home/data/test.png' -H 'X-Auth-Token:Token值' -X POST https://modelarts-infers-1.xxx/v1/infers/eb3e0c54-3dfa-4750-****-95c45e5d3e83
  ```
  
- 文本输入
  ```
  curl -kv -d '{"data":{"req_data":[{"sepal_length":3,"sepal_width":1,"petal_length":2.2,"petal_width":4}]}}' -H 'X-Auth-Token:Token值' -H 'Content-type: application/json' -X POST https://modelarts-infers-1.xxx/v1/infers/eb3e0c54-3dfa-4750-****-95c45e5d3e83
  ```
  "-d"是Body体的文本内容。
  
 #### 方式三：使用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
     if __name__ == '__main__':
         # Config url, token and file path.
         url = "在线服务的调用地址"
         token = "用户Token"
         file_path = "预测文件的本地路径"
         # Send request.
         headers = {
             'X-Auth-Token': token
         }
         files = {
             'images': open(file_path, 'rb')
         }
         resp = requests.post(url, headers=headers, files=files)
         # Print result.
         print(resp.status_code)
         print(resp.text)
     ```
     "files"中的参数名由在线服务的输入参数决定，需要和"类型"为"file"的输入参数"名称"保持一致。以[前提条件]里获取的文件预测输入参数"images"为例。
     
   
   - **输入为文本格式（json类型）**
     读取本地预测文件并进行base64编码的请求体示例如下：
     ```
     # coding=utf-8
     import base64
     import requests
     if __name__ == '__main__':
         # Config url, token and file path
         url = "在线服务的调用地址"
         token = "用户Token"
         file_path = "预测文件的本地路径"
         with open(file_path, "rb") as file:
             base64_data = base64.b64encode(file.read()).decode("utf-8")
         # Set body,then send request
         headers = {
             'Content-Type': 'application/json',
             'X-Auth-Token': token
         }
         body = {
             'image': base64_data
         }
         resp = requests.post(url, headers=headers, json=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工程依赖httpmime模块。
   1. 在工程"libs"中增加httpmime-x.x.x.jar。完整的Java依赖库如[图7]所示。
      httpmime-x.x.x.jar建议使用4.5及以上版本，下载地址：<https://mvnrepository.com/artifact/org.apache.httpcomponents/httpmime>。
      图7Java依赖库   
      ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002717735902.png) 
   
   2. httpmime-x.x.x.jar添加完成后，在Java工程的.classpath文件中，补充httpmime信息，如下所示：
      ```
      <?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. 创建Java类，进行预测请求。
   - **输入为文件格式**
     Java的请求体示例如下：
     ```
     // 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 MyTokenFile {
         public static void main(String[] args) {
             // Config url, token and filePath
             String url = "在线服务的调用地址";
             String token = "用户Token";
             String filePath = "预测文件的本地路径";
             try {
                 // Create post
                 HttpPost httpPost = new HttpPost(url);
                 // Add header parameters
                 httpPost.setHeader("X-Auth-Token", token);
                 // Add a body if you have specified the PUT or POST method. 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();
             }
         }
     }
     ```
     "addBinaryBody"中的参数名由在线服务的输入参数决定，需要和"类型"为"file"的输入参数"名称"保持一致。此处以[前提条件]里获取的"images"为例。
     
   
   - **输入为文本格式（json类型）**
     读取本地预测文件并进行base64编码的请求体示例如下：
     ```
     // 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 MyTokenTest {
         public static void main(String[] args) {
             // Config url, token and body
             String url = "在线服务的调用地址";
             String token = "用户Token";
             String body = "{}";
             try {
                 // Create post
                 HttpPost httpPost = new HttpPost(url);
                 // Add header parameters
                 httpPost.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
                 httpPost.setHeader("X-Auth-Token", token);
                 // 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"由具体文本格式决定，此处以json为例。
     
    
 
