目录
1.什么是API?
什么是API?
API 是一种定义应用程序之间如何相互通信的规则和规范,提供了一种通用的方式来访问数据和功能,简化了应用程序的开发。主要用于获取数据,控制设备,集成应用程序。
Qt调用API的流程是什么?
1.准备工作 :确定要调用的 API 及其功能。阅读 API 文档,了解 API 的使用方法。准备调用 API 所需的参数和数据
2.创建 Qt 对象:使用 Qt 的 API 创建必要的对象,例如网络访问管理器、网络请求等
3. 配置 API 调用:使用 Qt 对象设置 API 调用的参数(鉴权,获取Access_token用户令牌)和数据
4.发起 API 调用:使用QNetworkReply对象发送请求
5.处理 API 响应:处理 API 响应的数据,例如解析 JSON 数据或 XML 数据
6.释放资源:释放调用 API 所使用的 Qt 对象
PS:熟悉一下流程就行,看不懂没关系,下图源自千帆大模型可以看看。后续会按照该图解析文档并且用Qt实现调用文心一言API
Qt调用API需要什么对象?
网络处理类:
1.QNetworkAccessManager:用于管理网络请求和响应(可以理解为管理各种类,这些类可以用于发送请求,可以用于设置请求头等功能)
2.QUrlQuery:解析和操作 URL(不清楚URL没关系,简单理解为唯一标识资源的地址。该地址类似于网页,但是存在很多键值,需要设置这些值来获取对应的Access_token用户令牌等数据)
3.QNetworkReply:表示网络请求响应的类。提供了一系列函数来访问响应数据、处理错误和其他网络相关操作(前面提到的QNetworkAccessManager类,可以用于管理和访问QNetworkReply类)
4.QNetworkRequest:用于封装网络请求信息,设置网络请求的类。其中包含了请求的 URL、头信息和其他相关信息
数据处理类:
1.QByteArray:用于存储和操作二进制数据(可以与QString类型相互转换,使用QByteArray类能更好的接收数据,不用当心数据乱码等)
2.QRegularExpression:用于实现正则表达式功能,匹配、搜索和替换文本(获取到返回的数据时,往往返回的是JSON中数组的形式,对此我们需要使用正则表达式匹配文本,获取对应键值的数据)
3.QRegularExpressionMatch:用于捕获正则表达式匹配结果,匹配的位置,捕获数据(简单理解就是把匹配正则表达式的结果给挑出来)
4.QRegularExpressionMatchIterator:正则表达式匹配结果的迭代器,用于遍历所有匹配结果
5.QJsonObject:用于存储和访问 JSON 对象中的键值对,可以用于各种 JSON 操作
6.QJsonArray:实现JSON 数组。用于存储和访问 JSON 数组中的值
7.QJsonDocument:用于存储和访问 JSON 文档中的内容(代码中主要是用于将QJsonObject对象转换为字符串,后续会讲到转换字符串的原因是用于发送POST请求的函数只接受QByteArray类型)
8.QEventLoop:处理来自操作系统和用户界面的事件
如何查阅提供的文档?
本段以百度千帆大模型讲解,读者可以自行查阅千帆大模型官网。在登录千帆大模型创建应用后,可以在应用列表获取AppID、API Key、Secret Key 等信息
在创建应用后,需要在应用接入中点击价格文档,对需要提供的服务进行付费,一般都是以Token格式的形式进行付费。如果需要文字识别等服务是免费的,但是接入文心一言就需要对其方法使用(听说讯飞星火是免费的,但是本人目前只能使用Python对其调用,Qt提供的编解码函数好像没有)
然后就是查阅文档,主要看错误码。鉴权认证以及需要调用的服务请求说明
调用文档以及千帆大模型官网我放到下面,大家可以自行查阅。后续我将对文档中的错误码,鉴权认证以及我所调用的ERNIE-4.0-8k服务的请求说明进行讲解,并使用QT实现
千帆大模型官网https://cloud.baidu.com/product/wenxinworkshop
千帆大模型文档https://cloud.baidu.com/doc/index.html
查阅错误码文档需要注意什么?
在查阅错误码文档时,需要额外注意数据结构,错误示例以及错误码列表。通过错误示例我们可以找到返回的错误消息会包含什么?形式是什么?通过错误码列表,我们可以快速定位错误信息,排查错误原因
查阅鉴权认证文档需要注意什么?
在查阅鉴权认证文档时,我们需要额外注意如何获取access_toKen,请求说明(包含请求地址,请求方式以及请求参数),请求示例以及响应示例(方便我们对返回的数据进行处理)
阅读过鉴权认证文档后,我们需要根据文档编写代码
QNetworkRequest request; //发送POST请求
QNetworkAccessManager *manager; //网络访问管理器
//初始化鉴权元素,通过应用可查看
APIKey = "";
APISecret = "";
//初始化POST请求的参数
QUrlQuery params;
params.addQueryItem("grant_type", "client_credentials");
params.addQueryItem("client_id", APIKey);
params.addQueryItem("client_secret", APISecret);
QByteArray postData = params.toString(QUrl::FullyEncoded).toUtf8();
// 设置URL和请求头部
request.setUrl(QUrl("https://aip.baidubce.com/oauth/2.0/token"));
request.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
request.setRawHeader("Accept", "application/json");
//将请求数据作为第二个参数传递给post函数,并发送Post请求
reply = manager->post(request, postData);
正确发送POST请求后,需要对返回的数据进行解析,其中返回的数据含有access_token用户令牌,可以通过正则表达式进行解析捕获
//解析返回的数据,获取access_token用户令牌
if (reply->error() == QNetworkReply::NoError) {
QByteArray responseData = reply->readAll();
//修改正则表达式
Regex.setPattern("\"access_token\":\"(.*?)\"");
//在JSON字符串中进行匹配
QRegularExpressionMatch match = Regex.match(responseData);
// 如果找到匹配项,则提取access_token数据
if (match.hasMatch()) {
accessToken = match.captured(1);
return true;
} else {
QMessageBox::information(nullptr,"提示","未获取到Access_token!",QMessageBox::Ok);
return false;
}
}
else {
QMessageBox::warning(nullptr,"错误",reply->errorString(),QMessageBox::Ok);
return false;
}
阅读服务请求说明文档时需要注意什么?
阅读服务请求说明文档时,要注意请求说明(请求地址和请求方式等),以及参照官方请求示例通过调整得出具体的代码
设置请求语句,封装成URL,发送POST请求
//清空请求内容和回复语句
payload = "";
responseData = "";
// 准备请求数据
QJsonObject messageObject;
messageObject["role"] = "user";
messageObject["content"] = Enquiretext;
QJsonArray messagesArray;
messagesArray.append(messageObject);
QJsonObject requestBody;
requestBody["messages"] = messagesArray;
// 将JSON对象转换为字符串
QJsonDocument doc(requestBody);
payload = doc.toJson();
// 设置请求头
QString url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro?access_token=" + accessToken;
request.setUrl(QUrl(url));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
//发送POST请求
reply = manager->post(request, payload);
// 等待响应完成
QEventLoop loop;
QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
loop.exec();
// 读取响应数据
if (reply->error() == QNetworkReply::NoError) {
responseData = reply->readAll();
} else {
QMessageBox::warning(nullptr,"错误",reply->errorString(),QMessageBox::Ok);
}
正确发送POST请求后,等待服务器响应后,我们获取到数据还需要对数据进行解析
QString hex;
//定义正则表达式,用于获取指定result值后的数据
QRegularExpression regular("\"result\":\"(.*?)\"");
QRegularExpressionMatch match = regular.match(text);
QString matchedString = match.captured(); //捕获匹配正则表达式的数据
//设置正则表达式,用于匹配\x后面的数据
regular.setPattern("\\\\x([0-9A-Fa-f]{2})");
//迭代正则表达式匹配的结果
QRegularExpressionMatchIterator iteration = regular.globalMatch(matchedString);
while (iteration.hasNext()) { //循环遍历寻找匹配数据
QRegularExpressionMatch match = iteration.next();
hex = match.captured(1);
bool ok;
int decimal = hex.toInt(&ok, 16);
if (ok) {
matchedString.replace(match.capturedStart(), match.capturedLength(), QString(QChar(decimal)));
}
}
//文本处理
matchedString.replace("result\":\"", "");
matchedString.replace("\\n", "\n");
return matchedString;
解析完返回的数据,便代表调用API的结束(别忘了删除QNetworkReply对象)
reply->deleteLater();
后续
本篇文字就此结束,由于是博客形式,对于代码我就不过多讲解(本人觉得视频会更通透),如果有读者需要完整的调用程序,可在评论区留言。届时本人将通过评论区评论github或者gitte等网站链接提供下载