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

news2024/10/1 5:38:17

百度智能云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.html

class 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;

	// method
	req->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;
	}

	// url
	canonicalReq += QString("%1\n").arg(UrlEncode(QString::fromStdString(req->url)));

	// query string
	hv::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';
	}

	// header
	canonicalReq += 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]));
			}
		}
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1979713.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java常用类和数据结构与算法

1. 其他常用类 1.1. Math类 java.lang.Math提供了一系列静态方法用于科学计算&#xff1b;其方法的参数和返回值一般为double型。如果需要更加强大的数学运算能力&#xff0c;可以使用apache commons下面的Math类库 public class TestMath {public static void main(String[…

python 图片爬虫记录

看了2-3个小时的奥运会&#xff0c; 感觉内心空虚。 写点代码。 不知道做什么&#xff0c;随便搞一下爬虫&#xff0c;积累一点经验&#xff0c; 写篇博客&#xff0c;记录一下。 1. 注意检查响应头 情况描述: 对于这样一个 图片的 url https://blogger.googleusercontent.…

基于FPGA的数字信号处理(20)--半减器和全减器

目录 1、前言 2、半减器 3、全减器 4、减法器 文章总目录点这里&#xff1a;《基于FPGA的数字信号处理》专栏的导航与说明 1、前言 既然有半加器和全加器&#xff0c;那自然也有半减器和全减器了。尽管在电路中减法的实现基本都是 补码 加法 的形式&#xff0c;但是正所谓…

Hadoop搭建集群

Hadoop搭建集群 前言一、环境配置1.配置JDK2.配置Hadoop环境 二、Hadoop本地运行三、Hadoop集群部署1.准备三台服务器2.节点规划3.环境配置4.无秘登录5.配置核心文件1&#xff09;修改core-site.xml2&#xff09;修改hdfs-site.xml3&#xff09;修改yarn-site.xml4&#xff09;…

【linux】【操作系统】内核之sched.c源码阅读

sched.c提供的代码片段包含了与操作系统内核中的进程调度和管理相关的多个函数。schedule函数首先对所有任务&#xff08;进程&#xff09;进行检测&#xff0c;唤醒任何一个已经得到信号的任务。具体方法是针对任务数组中的每个任务&#xff0c;检查其报警定时值alam。如果任务…

Midjourney咒语之手机壁纸国画艺术

手机壁纸 Mountains, surfaces, mysterious landscapes --ar 9:16 Abstract shapes of billowing flowing colorful gauze fabric, --ar 9:16 国画艺术 Peony is

如何快速看完一个网页上的视频

如何快速看完一个视频 懂的都懂。 Edge浏览器 添加下面两个书签&#xff1a; javascript:document.querySelector("video").dispatchEvent(new Event("ended"))javascript:var vdocument.querySelector("video");if(v){v.mutedtrue;v.playba…

从艺术创作到作物生长,农业AI迎来“GPT“时刻

&#xff08;于景鑫 国家农业信息化工程技术研究中心&#xff09;"GPT"一词早已不再神秘,其在文本、图像生成领域掀起的风暴正以摧枯拉朽之势席卷全球。人们惊叹于ChatGPT对话之智能、思维之敏捷,更对Stable Diffusion、Midjourney创作的艺术画作赞叹不已。而大语言模…

无代码开发AI服务 - 利用向量库Kendra和Llama大模型在亚马逊云科技AWS上创建RAG知识库

简介&#xff1a; 小李哥将继续每天介绍一个基于亚马逊云科技AWS云计算平台的全球前沿AI技术解决方案&#xff0c;帮助大家快速了解国际上最热门的云计算平台亚马逊云科技AWS AI最佳实践&#xff0c;并应用到自己的日常工作里。 上次我们介绍了我们利用ElasticSearch作为向量…

网鼎杯comment二次注入

靶机网址&#xff1a;BUUCTF在线评测 进来就是这个界面&#xff0c;点击发帖后需要进行登录。 从界面可以看出用户是zhangwei&#xff0c;密码是zhangwei***&#xff0c;密码的最后三位需要进行暴力破解。 这里需要用到工具Burp Suite进行抓包。 这就是抓到的包&#xff0c;我…

【大模型从入门到精通8】openAI API 提升机器推理:高级策略2

这里写目录标题 示例定义处理输入的函数链式思考提示示例&#xff1a;结构化系统和用户提示获取并展示模型的回答实现内心独白结论与最佳实践 示例 设置环境 在深入实施之前&#xff0c;设置必要的环境至关重要。这包括加载 OpenAI API 密钥并导入相关的 Python 库。以下代码块…

Chapter 25 面向对象

欢迎大家订阅【Python从入门到精通】专栏&#xff0c;一起探索Python的无限可能&#xff01; 文章目录 前言一、初识对象二、成员方法三、类和对象 前言 面向对象编程&#xff08;OOP&#xff09;是Python编程中的一个核心概念&#xff0c;它能帮助程序员更好地组织和管理代码…

01 计算机系统基础-2

操作系统 进程管理 进程管理是操作系统的核心&#xff0c;但如果设计不当&#xff0c;就会出现死锁的问题。如果一个进程在等待一件不可能发生的事&#xff0c;则进程就死锁了。而如果一个或多个进程产生死锁&#xff0c;就会造成系统死锁。基于死锁产生机制及解决方案&#…

LeetCode Hard|【460. LFU 缓存】

力扣题目链接 LFU全称是最不经常使用算法&#xff08;Least Frequently Used&#xff09;&#xff0c;LFU算法的基本思想和所有的缓存算法一样&#xff0c;一定时期内被访问次数最少的页&#xff0c;在将来被访问到的几率也是最小的。 相较于 LRU 算法&#xff0c;LFU 更加注重…

MATLAB霍夫曼表盘识别系统

MATLAB霍夫曼表盘识别系统 一、介绍 本设计为基于MATLAB的表盘指针识别&#xff0c;算法原理是基于hough变换。可检测压力表&#xff0c;石英手表&#xff0c;电表刻度&#xff0c;气压表等带指针刻度的表盘。通过hough检测直线和圆的关系&#xff0c;得出指针夹角&#xff0…

保形分位数回归(CQR)

目录 简介1 介绍提纲式总结 分位数回归从数据中估计分位数 3 共性预测4 保形分位数回归(CQR)两个定理 6 实验7 结论 简介 保形预测是一种构造在有限样本中获得有效覆盖的预测区间的技术&#xff0c;无需进行分布假设。尽管有这种吸引力&#xff0c;但现有的保形方法可能是不必…

(C题老外游中国)2024年华数杯大学生数学建模竞赛解题思路完整代码论文集合

我是Tina表姐&#xff0c;毕业于中国人民大学&#xff0c;对数学建模的热爱让我在这一领域深耕多年。我的建模思路已经帮助了百余位学习者和参赛者在数学建模的道路上取得了显著的进步和成就。现在&#xff0c;我将这份宝贵的经验和知识凝练成一份全面的解题思路与代码论文集合…

Open3D 三维重建-Delaunay Triangulation (德劳内三角剖分)

目录 一、概述 1.1原理 1.2实现步骤 1.3应用 二、代码实现 2.1关键函数 2.2完整代码 三、实现效果 3.1原始点云 3.2重建后点云 Open3D点云算法汇总及实战案例汇总的目录地址&#xff1a; Open3D点云算法与点云深度学习案例汇总&#xff08;长期更新&#xff09;-CSD…

MySQL--日志管理

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 一、日志简介 MySQL日志主要分为4类&#xff0c;使用这些日志文件&#xff0c;可以查看MySQL内部发生的事情。这4类日志分别是: 错误日志&#xff1…

程序编译及链接

你好&#xff01;感谢支持孔乙己的新作&#xff0c;本文就程序的编译及链接与大家分析我的思路。 希望能大佬们多多纠正及支持 &#xff01;&#xff01;&#xff01; 个人主页&#xff1a;爱摸鱼的孔乙己-CSDN博客 ​ ​ 1.翻译译环境与运行环境 当我们进行程序设计时&…