当前位置: 首页 > news >正文

QT百度智能云API鉴权,查询 文心一言 服务调用情况

百度智能云API鉴权

做了一个利用Qt实现调用文字大模型的API 小软件 AI.xyz。

想通过api直接访问国产语言大模型的调用情况,翻了半天 豆包、通义、文心 的官方文档。最后只找到百度提供通过api读取访问的功能。

一开始只看到 python 的sdk,试了试还可以,用 Qt 实现了下并集成进了AI.xyz。
在这里插入图片描述

resp = resources.Service.V2.describe_preset_services(service_ids=['svcp-7d6044e91474', 'svcp-7940ab471306']
)
print(json.dumps(resp.body, indent=4))resp = resources.Service.V2.service_metric("2024-07-04T15:51:00Z", "2024-08-04T15:51:00Z",service_id=[],app_id= ["94470723"] )
print(json.dumps(resp.body, indent=4))
print(json.dumps(resp.headers, indent=4))

软件内简单做了个页面显示。

在这里插入图片描述

希望豆包、通义赶紧增加对应接口,要不然只能统计本地调用的tokens。

最后写完发现官方也提供了SDK,没去编译,照着官方的又改了下自己写的。


百度智能云API鉴权

鉴权的主要目的是用于校验调用者的身份信息。调用千帆平台功能OpenAPI需使用基于安全认证AK/SK进行签名计算鉴权。

百度智能云鉴权简介

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

百度智能云提供的在线生成签名工具。

在这里插入图片描述

1 使用 QT 计算鉴权Authorization

#ifndef ModelApiMetrics_H
#define ModelApiMetrics_H#include <QJsonObject>
#include <QCryptographicHash>
#include <QMessageAuthenticationCode>
#include <QString>
#include <QByteArray>#include "hv/HttpClient.h"// 大模型服务度量指标// 百度鉴权 https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Sly8bm96d
// 百度签名计算工具 https://cloud.baidu.com/signature/index.htmlclass ModelApiMetrics {
public:// 生成百度服务度量指标static QMap<QString, QList<int> >GenerateBaiDuServiceMetric(const QString& ak, const QString& sk, const QString& appId);private:// 生成百度服务的认证签名static QString GenerateBaiDuAuth(HttpRequestPtr& req, QString ak, QString sk, int expireSeconds = 300);// 使用 HMAC-SHA256 算法生成十六进制签名。static QString HmacSha256Hex(const QString& key, const QString& message);// 对字符串进行 URL 编码。static QString UrlEncode(const QString& src, bool encodeSlash = false);// 去掉字符串首尾指定的字符。static QString Trim(const QString& s, const QString& chars = QStringLiteral(" \t\n\r\f\v"));
};#endif // ifndef ModelApiMetrics_H

QString ModelApiMetrics::GenerateBaiDuAuth(HttpRequestPtr& req, QString ak, QString sk, int expireSeconds)
{QString authStr;QString signTime = QDateTime::currentDateTimeUtc().toString(Qt::ISODate);authStr = QString("bce-auth-v1/%1/%2/%3").arg(ak).arg(signTime).arg(expireSeconds);QString canonicalReq;// methodreq->method = HTTP_POST;switch (req->method) {case HTTP_GET:canonicalReq += QString("GET\n");break;case HTTP_POST:canonicalReq += QString("POST\n");break;case HTTP_PUT:canonicalReq += QString("PUT\n");break;default:break;}// urlcanonicalReq += QString("%1\n").arg(UrlEncode(QString::fromStdString(req->url)));// query stringhv::QueryParams params = req->query_params;if (0 != params.size()) {QStringList paramList;for (auto& pair : params) {QString encodedKey = UrlEncode(Trim(QString::fromStdString(pair.first)));QString encodedValue = UrlEncode(Trim(QString::fromStdString(pair.second)));paramList.append(QString("%1=%2").arg(encodedKey, encodedValue));}std::sort(paramList.begin(), paramList.end());canonicalReq += QString("%1\n").arg(paramList.join("&"));} else {canonicalReq += '\n';}// headercanonicalReq += QString("host:%1").arg(UrlEncode(QString::fromStdString(req->headers["Host"])));QString signKey = HmacSha256Hex(sk, authStr);QString signature = HmacSha256Hex(signKey, canonicalReq);authStr += QString("/host/%1").arg(signature);return authStr;
}QString ModelApiMetrics::HmacSha256Hex(const QString& key, const QString& message)
{QByteArray keyBytes = key.toUtf8();QByteArray messageBytes = message.toUtf8();QByteArray hmac = QMessageAuthenticationCode::hash(messageBytes, keyBytes, QCryptographicHash::Sha256);return QString(hmac.toHex());
}QString ModelApiMetrics::UrlEncode(const QString& src, bool encodeSlash)
{QByteArray encodedBytes;for (QChar c : src) {if ((c.isLetterOrNumber() || (c == '_') || (c == '-') || (c == '~') || (c == '.')) ||((c == '/') && !encodeSlash)) {encodedBytes.append(c.toLatin1());} else {encodedBytes.append('%');QByteArray hex = QByteArray::number(c.unicode(), 16).toUpper();if (hex.size() == 1) {encodedBytes.append('0');}encodedBytes.append(hex);}}return QString::fromUtf8(encodedBytes);
}QString ModelApiMetrics::Trim(const QString& s, const QString& chars)
{int start = 0;int end = s.size() - 1;while (start <= end && chars.contains(s[start])) {++start;}while (end >= start && chars.contains(s[end])) {--end;}return s.mid(start, end - start + 1);
}

2 通过 Libhv 查询 文心一言 服务调用情况

查询服务调用情况

QMap<QString, QList<int> >ModelApiMetrics::GenerateBaiDuServiceMetric(const QString& ak, const QString& sk, const QString& appId)
{QMap<QString, QList<int> > resultMap;HttpRequestPtr req(new HttpRequest);req->url = "/v2/service";req->method = HTTP_POST;req->headers["Host"] = "qianfan.baidubce.com";req->headers["Content-Type"] = "application/json";req->query_params["Action"] = "DescribeServiceMetric";req->headers["Authorization"] = GenerateBaiDuAuth(req, ak, sk).toLocal8Bit();req->url = "https://qianfan.baidubce.com/v2/service";QDateTime   currentDateTimeUtc = QDateTime::currentDateTimeUtc();QDateTime   dateTime20DaysAgo = currentDateTimeUtc.addDays(-20);QJsonObject jsonObject;jsonObject["startTime"] = dateTime20DaysAgo.toString(Qt::ISODate);jsonObject["endTime"] = currentDateTimeUtc.toString(Qt::ISODate);jsonObject["appId"] = QJsonArray{ appId };QJsonDocument jsonDocument(jsonObject);QByteArray    jsonData = jsonDocument.toJson(QJsonDocument::Compact);req->body = jsonData;hv::HttpClient client;HttpResponse   resp;int ret = client.send(req.get(), &resp);if (ret != 0) {return resultMap;}QJsonParseError jsonError;QJsonDocument   jsonDoc = QJsonDocument::fromJson(resp.body.c_str(), &jsonError);if (jsonDoc.isNull() || (jsonError.error != QJsonParseError::NoError)) {return resultMap;}QJsonObject resultObject = jsonDoc.object();QJsonObject result = resultObject["result"].toObject();QJsonArray  serviceList = result["serviceList"].toArray();for (const QJsonValue& serviceVal : serviceList) {QJsonObject serviceObj = serviceVal.toObject();QString     serviceName = serviceObj["serviceName"].toString();QJsonArray  appList = serviceObj["appList"].toArray();for (const QJsonValue& appVal : appList) {QJsonObject appObj = appVal.toObject();QJsonObject metric = appObj["metric"].toObject();QList<int> metricsList;metricsList.append(metric["inputTokensTotal"].toInt());metricsList.append(metric["outputTokensTotal"].toInt());metricsList.append(metric["tokensTotal"].toInt());metricsList.append(metric["succeedCallTotal"].toInt());metricsList.append(metric["failureCallTotal"].toInt());metricsList.append(metric["callTotal"].toInt());resultMap[serviceName] = metricsList;}}return resultMap;
}

3 使用返回结果

在这里插入图片描述

void SettingsPanelWid::ServiceMetric()
{ConfigManager::GetInstance().WriteValue("ernie_ak", ui->ernie_ak->text());ConfigManager::GetInstance().WriteValue("ernie_sk", ui->ernie_sk->text());ConfigManager::GetInstance().WriteValue("ernie_appId", ui->ernie_appId->text());QMap<QString, QList<int> > resMap = ModelApiMetrics::GenerateBaiDuServiceMetric(ui->ernie_ak->text(), ui->ernie_sk->text(), ui->ernie_appId->text());QString labName = QString("lab_transfer_%1_%2");foreach(auto& name, resMap.keys()){int model = static_cast<int>(ModelInfoManager::GetModel(name));for (int i = 0; i < resMap[name].size(); i++) {QString labObjName = labName.arg(model).arg(i + 1);QLabel* lab = ui->tab_4->findChild<QLabel *>(labObjName);if (lab) {lab->setText(QString::number(resMap[name][i]));}}}
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • PXE服务器自助部署
  • Adobe ColdFusion反序列化漏洞(cve-2017-3066)
  • 【Day04】0基础微信小程序入门-学习笔记
  • SQL报错注入之updatexml
  • 数据仓库怎么建设?一文详解数仓的建设过程!
  • Haproxy搭建Web群集(群集)
  • c++----初识模板
  • 案例分享-国外UI设计界面赏析
  • 盘点5个PDF 怎么转换成 Word 的实用技巧
  • Elasticsearch 概述
  • SQLiteStudio 连接sqlite3数据库(真机数据库可视化调试)
  • 使用 VueDraggable 创建可拖拽列表的全面指南
  • Web开发-CSS篇-上
  • Python代码之特征工程基础
  • 互联网重构“规则制定权”,周期性谋咒开始轮转!
  • #Java异常处理
  • android高仿小视频、应用锁、3种存储库、QQ小红点动画、仿支付宝图表等源码...
  • Git的一些常用操作
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • JAVA_NIO系列——Channel和Buffer详解
  • Java-详解HashMap
  • oldjun 检测网站的经验
  • Python socket服务器端、客户端传送信息
  • SpiderData 2019年2月23日 DApp数据排行榜
  • 包装类对象
  • 大数据与云计算学习:数据分析(二)
  • 回顾2016
  • 机器人定位导航技术 激光SLAM与视觉SLAM谁更胜一筹?
  • 力扣(LeetCode)56
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 前端知识点整理(待续)
  • 驱动程序原理
  • 如何借助 NoSQL 提高 JPA 应用性能
  • 如何正确配置 Ubuntu 14.04 服务器?
  • 使用Swoole加速Laravel(正式环境中)
  • 跳前端坑前,先看看这个!!
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • 用jQuery怎么做到前后端分离
  • 《天龙八部3D》Unity技术方案揭秘
  • 专访Pony.ai 楼天城:自动驾驶已经走过了“从0到1”,“规模”是行业的分水岭| 自动驾驶这十年 ...
  • 组复制官方翻译九、Group Replication Technical Details
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • ###C语言程序设计-----C语言学习(3)#
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • (Java)【深基9.例1】选举学生会
  • (附源码)计算机毕业设计大学生兼职系统
  • (附源码)计算机毕业设计高校学生选课系统
  • (利用IDEA+Maven)定制属于自己的jar包
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (一)SpringBoot3---尚硅谷总结
  • .gitattributes 文件
  • .NET Core MongoDB数据仓储和工作单元模式封装
  • .NET 给NuGet包添加Readme
  • .Net 基于MiniExcel的导入功能接口示例
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)