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<string, object> options = null);
小牛試刀
今天我們拋開官方SDK,使用WebApiClientCore請求我們感興趣的人臉檢測介面,雖然只有一個介面,但我會盡量按高規格的設計質量來呼叫這個介面,讓朋友們瞭解WebApiClientCore的魅力之處。首先,我們先閱讀官方文件:Api文件.人臉檢測,根據文件內容,大概有以下知識塊:
- access_token獲取與使用
- access_token的過期與重新整理
- 請求引數模型
- 正確的響應結果模型
- 人臉識別錯誤碼
模型設計
請求引數模型
為了使用方便,我們將圖片型別、人臉型別設計為列舉型別,注意實際請求時,傳輸的是列舉的鍵名,而不是值。
/// <summary>
/// 表示待人臉檢測的圖片
/// </summary>
public class DetectImage
{
/// <summary>
/// 圖片資訊
/// </summary>
public string Image { get; set; }
/// <summary>
/// 圖片資訊
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public ImageType Image_type { get; set; }
/// <summary>
/// 最多處理人臉的數目
/// </summary>
[Range(1, 10)]
public int? Max_face_num { get; set; } = 1;
/// <summary>
/// 人臉的型別
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public FaceType Face_type { get; set; }
/// <summary>
/// 影像型別
/// </summary>
public enum ImageType
{
/// <summary>
/// 圖片的base64值
/// </summary>
BASE64,
/// <summary>
/// 圖片的 URL地址
/// </summary>
URL,
/// <summary>
/// 人臉圖片的唯一標識
/// </summary>
FACE_TOKEN
}
/// <summary>
/// 人臉的型別
/// </summary>
public enum FaceType
{
/// <summary>
/// 生活照
/// </summary>
LIVE,
/// <summary>
/// 身份證晶片照
/// </summary>
IDCARD,
/// <summary>
/// 帶水印證件照
/// </summary>
WATERMARK,
/// <summary>
/// 證件照片
/// </summary>
CERT
}
}
響應模型
通過PostMan預請求,我們發現官方文件裡提到的響應內容,實際上只是完整響應內容的裡面的Result值而已(官方文件有點不靠譜) 。
/// <summary>
/// 響應內容
/// </summary>
/// <typeparam name="T"></typeparam>
public class Response<T>
{
/// <summary>
/// 錯誤碼
/// </summary>
public int Error_code { get; set; }
/// <summary>
/// 錯誤資訊
/// </summary>
public string Error_msg { get; set; }
/// <summary>
/// 結果值
/// </summary>
public T Result { get; set; }
}
/// <summary>
/// 表示檢測結果
/// </summary>
public class DetectResult
{
/// <summary>
/// 人臉數量
/// </summary>
public int Face_num { get; set; }
/// <summary>
/// 人臉列表
/// </summary>
public FaceItem[] Face_list { get; set; }
/// <summary>
/// 人臉
/// </summary>
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; }
/// <summary>
/// 位置
/// </summary>
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; }
}
/// <summary>
/// 角度
/// </summary>
public class FaceAngle
{
public double Yaw { get; set; }
public double Pitch { get; set; }
public double Roll { get; set; }
}
}
}
介面宣告
應用請求與響應模型
/// <summary>
/// 百度人臉相關介面
/// </summary>
public interface IBaiduFaceApi
{
/// <summary>
/// 影像的人臉檢測
/// </summary>
/// <param name="detectImage">待檢測影像</param>
/// <returns></returns>
[HttpPost("rest/2.0/face/v3/detect")]
ITask<Response<DetectResult>> DetectAsync([JsonContent] DetectImage detectImage);
}
應用請求日誌
為了方便除錯,我們需要將實際請求內容輸出到日誌元件,這裡為介面應用[LoggingFilter]。
/// <summary>
/// 百度人臉相關介面
/// </summary>
[LoggingFilter]
public interface IBaiduFaceApi
{
/// <summary>
/// 影像的人臉檢測
/// </summary>
/// <param name="detectImage">待檢測影像</param>
/// <returns></returns>
[HttpPost("rest/2.0/face/v3/detect")]
ITask<Response<DetectResult>> DetectAsync([JsonContent] DetectImage detectImage);
}
應用access_token
access_token我們可以做為一個切面處理,WebApiClientCore.Extensions.OAuths擴充套件包專門處理這個切面,由於百度的access_token不是標準的放到Authorization請求頭,而是放到access_token的query引數,所以我們需要繼承ClientCredentialsTokenAttribute來實現自定義token應用特性。
/// <summary>
/// token應用特性
/// </summary>
class AccessTokenAttribute : ClientCredentialsTokenAttribute
{
protected override void UseTokenResult(ApiRequestContext context, TokenResult tokenResult)
{
context.HttpContext.RequestMessage.AddUrlQuery("access_token", tokenResult.Access_token);
}
}
/// <summary>
/// 百度人臉相關介面
/// </summary>
[AccessToken]
[LoggingFilter]
public interface IBaiduFaceApi
{
/// <summary>
/// 影像的人臉檢測
/// </summary>
/// <param name="detectImage">待檢測影像</param>
/// <returns></returns>
[HttpPost("rest/2.0/face/v3/detect")]
ITask<Response<DetectResult>> DetectAsync([JsonContent] DetectImage detectImage);
}
介面註冊與配置
介面註冊
services.AddHttpApi<IBaiduFaceApi>(c =>
{
c.HttpHost = new Uri("https://aip.baidubce.com/");
});
token提供者配置
百度返回的token有refreshToken值,但文件裡沒有提到怎麼重新整理token,嘗試使用token請求地址去重新整理token會失敗,所以這裡直接配置禁用使用refreshToken的功能,強迫時間到期之後,重新去申請一次token。
services.AddClientCredentialsTokenProvider<IBaiduFaceApi>(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,只求提供良好建議。