1. 程式人生 > >WebApiClientCore簡約呼叫百度AI介面

WebApiClientCore簡約呼叫百度AI介面

### WebApiClientCore WebApiClient.JIT/AOT的netcore版本,集高效能高可擴充套件性於一體的宣告式http客戶端庫,特別適用於微服務的restful資源請求,也適用於各種畸形http介面請求。 ### 百度AI 百度AI目前相當開放(至少在使用上),如果不是高併發請求場景,一般免費使用即可。鑑於其提供的`.net sdk`比較先進(laji),使用Dictionary型別替代模型引數,以及使用萬能的JObject型別做為返回值型別的設計,正常人都無法體會其中精髓。試看以下的api原型,想必大家都想找找沒有文件說明吧?我覺得這sdk更像是一個httpUtil,只提供了一個 object Send( object )方法。 ``` public JObject Detect(string image, string imageType, Dictionary options = null); ``` ### 小牛試刀 今天我們拋開官方SDK,使用WebApiClientCore請求我們感興趣的人臉檢測介面,雖然只有一個介面,但我會盡量按高規格的設計質量來呼叫這個介面,讓朋友們瞭解WebApiClientCore的魅力之處。首先,我們先閱讀官方文件:[Api文件.人臉檢測](https://cloud.baidu.com/doc/FACE/s/yk37c1u4t),根據文件內容,大概有以下知識塊: * access_token獲取與使用 * access_token的過期與重新整理 * 請求引數模型 * 正確的響應結果模型 * 人臉識別錯誤碼 ### 模型設計 #### 請求引數模型 為了使用方便,我們將圖片型別、人臉型別設計為列舉型別,注意實際請求時,傳輸的是列舉的鍵名,而不是值。 ``` /// /// 表示待人臉檢測的圖片 ///
public class DetectImage { /// /// 圖片資訊 /// public string Image { get; set; } /// /// 圖片資訊 /// [JsonConverter(typeof(JsonStringEnumConverter))] public ImageType Image_type { get; set; } /// /// 最多處理人臉的數目 /// [Range(1, 10)] public int? Max_face_num { get; set; } = 1; /// /// 人臉的型別 ///
[JsonConverter(typeof(JsonStringEnumConverter))] public FaceType Face_type { get; set; } /// /// 影象型別 /// public enum ImageType { /// /// 圖片的base64值 /// BASE64, /// /// 圖片的 URL地址 /// URL, /// /// 人臉圖片的唯一標識 ///
FACE_TOKEN } /// /// 人臉的型別 /// public enum FaceType { /// /// 生活照 /// LIVE, /// /// 身份證晶片照 /// IDCARD, /// /// 帶水印證件照 /// WATERMARK, /// /// 證件照片 /// CERT } } ``` #### 響應模型 通過PostMan預請求,我們發現官方文件裡提到的響應內容,實際上只是完整響應內容的裡面的Result值而已(官方文件有點不靠譜) 。 ``` /// /// 響應內容 /// /// public class Response { /// /// 錯誤碼 /// public int Error_code { get; set; } /// /// 錯誤資訊 /// public string Error_msg { get; set; } /// /// 結果值 /// public T Result { get; set; } } /// /// 表示檢測結果 /// public class DetectResult { /// /// 人臉數量 /// public int Face_num { get; set; } /// /// 人臉列表 /// public FaceItem[] Face_list { get; set; } /// /// 人臉 /// public class FaceItem { public string Face_token { get; set; } public FaceLocation Location { get; set; } public int Face_probability { get; set; } public FaceAngle Angle { get; set; } /// /// 位置 /// public class FaceLocation { public double Left { get; set; } public double Top { get; set; } public int Width { get; set; } public int Height { get; set; } public int Rotation { get; set; } } /// /// 角度 /// public class FaceAngle { public double Yaw { get; set; } public double Pitch { get; set; } public double Roll { get; set; } } } } ``` ### 介面宣告 #### 應用請求與響應模型 ``` /// /// 百度人臉相關介面 /// public interface IBaiduFaceApi { /// /// 影象的人臉檢測 /// /// 待檢測影象 /// [HttpPost("rest/2.0/face/v3/detect")] ITask> DetectAsync([JsonContent] DetectImage detectImage); } ``` #### 應用請求日誌 為了方便除錯,我們需要將實際請求內容輸出到日誌元件,這裡為介面應用[LoggingFilter]。 ``` /// /// 百度人臉相關介面 /// [LoggingFilter] public interface IBaiduFaceApi { /// /// 影象的人臉檢測 /// /// 待檢測影象 /// [HttpPost("rest/2.0/face/v3/detect")] ITask> DetectAsync([JsonContent] DetectImage detectImage); } ``` #### 應用access_token access_token我們可以做為一個切面處理,WebApiClientCore.Extensions.OAuths擴充套件包專門處理這個切面,由於百度的access_token不是標準的放到Authorization請求頭,而是放到access_token的query引數,所以我們需要繼承ClientCredentialsTokenAttribute來實現自定義token應用特性。 ``` /// /// token應用特性 /// class AccessTokenAttribute : ClientCredentialsTokenAttribute { protected override void UseTokenResult(ApiRequestContext context, TokenResult tokenResult) { context.HttpContext.RequestMessage.AddUrlQuery("access_token", tokenResult.Access_token); } } /// /// 百度人臉相關介面 /// [AccessToken] [LoggingFilter] public interface IBaiduFaceApi { /// /// 影象的人臉檢測 /// /// 待檢測影象 /// [HttpPost("rest/2.0/face/v3/detect")] ITask> DetectAsync([JsonContent] DetectImage detectImage); } ``` ### 介面註冊與配置 #### 介面註冊 ``` services.AddHttpApi(c => { c.HttpHost = new Uri("https://aip.baidubce.com/"); }); ``` #### token提供者配置 百度返回的token有refreshToken值,但文件裡沒有提到怎麼重新整理token,嘗試使用token請求地址去重新整理token會失敗,所以這裡直接配置禁用使用refreshToken的功能,強迫時間到期之後,重新去申請一次token。 ``` services.AddClientCredentialsTokenProvider(c => { c.Endpoint = new Uri("https://aip.baidubce.com/oauth/2.0/token"); c.UseRefreshToken = false; c.Credentials.Client_id = "API Key"; c.Credentials.Client_secret = "Secret Key"; }); ``` ### 介面呼叫 將IBaiduFaceApi注入到我們的服務,即可呼叫 ``` public class FaceService { private readonly IBaiduFaceApi baiduFaceApi; public FaceService(IBaiduFaceApi baiduFaceApi) { this.baiduFaceApi = baiduFaceApi; } public async Task DetectAsync() { var img = new DetectImage { Face_type = DetectImage.FaceType.IDCARD, Image = "http://xxx.jpg", Image_type = DetectImage.ImageType.URL }; var result = await baiduFaceApi.DetectAsync(img); } } ``` 現在,我們已經拿到正常的結果,順便檢視請求日誌確認請求是否正確。 ``` POST /rest/2.0/face/v3/detect?access_token=省略值 HTTP/1.1 Host: aip.baidubce.com User-Agent: WebApiClientCore/1.0.6.0 Accept: application/json; q=0.01, application/xml; q=0.01 Content-Type: application/json; charset=utf-8 {"image":"http://xxx.jpg","image_type":"URL","max_face_num":1,"face_type":"IDCARD"} ``` ``` HTTP/1.1 200 OK Connection: keep-alive Date: Thu, 23 Jul 2020 02:05:58 GMT Content-Type: application/json Content-Length: 328 {"error_code":0,"error_msg":"SUCCESS","log_id":2599254579794,"timestamp":1595469958,"cached":0,"result":{"face_num":1,"face_list":[{"face_token":"97071a7f306483fea94d0766cfeb120c","location":{"left":34.54,"top":74.23,"width":101,"height":101,"rotation":0},"face_probability":1,"angle":{"yaw":-0.92,"pitch":6.68,"roll":-3.72}}]}} ``` ### 結束語 以上為WebApiClientCore在百度Ai請求的一個小例子,當然WebApiClientCore還有好多功能,點選專案連結,帶你GET到N種使用技能,不求star,只求提供良好建議。 > [https://github.com/dotnetcore/WebApiClient](https://github.com/dotnetcore/WebApi