创建应用
这一步的目的是为了拿到AppID、API Key、Secret Key这三个值,将来调接口需要鉴权,鉴权时就用到了这三个值。
打开这个链接:https://console.bce.baidu.com/ai/#/ai/intelligentwriting/overview/index,点击创建应用。
如果你找不到上面的入口了,你就打开这个链接:https://console.bce.baidu.com/ai,然后在产品服务中,找到智能创作平台。
进入到概览页面之后,点击创建应用。
创建成功之后,就可以点击应用列表了。
你应该在应用列表中,找到刚才创建的应用,留个链接吧:https://console.bce.baidu.com/ai/#/ai/intelligentwriting/app/list
复制以下信息:
AppID: 45901666
API Key: sTBSZqSfB3spuC0otTCkn1zc
Secret Key: jGjOe13CgkCTyPTRngb3y0yIkEObXFN2
获取access_token
想要调用百度ai的某个具体的接口,需要OAuth2.0授权通过才能成功,所以,OAuth2.0授权通过会返回一个Access_token值,我们自己调用具体接口时需要带着这个Access_token值,所以,这一步就是演示如何拿到Access_token值。
1. 从创建好的应用中,拿到AppID、API Key、Secret Key这三个值,这里就用上了
访问这个链接:https://console.bce.baidu.com/ai/#/ai/intelligentwriting/app/list
2. 通过requests发送请求获取access_token
代码:
# -*- coding = utf-8 -*-
import requests
class MyBaiduAI(object):
def __init__(self, AppID, APIKey, SecretKey, access_token_url):
self.AppID = AppID
self.APIKey = APIKey
self.SecretKey = SecretKey
self.access_token_url = access_token_url
def get_access_token(self):
# payload和headers参考的官网,我这里照抄
payload = ""
headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
response = requests.post(
url=self.access_token_url,
params={ # 拼接请求参数
"grant_type": "client_credentials", # 必须参数,固定为client_credentials
"client_id": self.APIKey, # 必须参数,应用的API Key;
"client_secret": self.SecretKey, # 必须参数,应用的Secret Key
},
headers=headers, data=payload
)
# 返回的是json数据
# print(response.headers['Content-Type']) # 'application/json'
res = response.json()
"""
{
'refresh_token': '25.27092d5ca3cd03788aeb93089a1cfb2b.315360000.2019094914.282335-45901666',
'expires_in': 2592000,
'session_key': '9mzdWWhVe/g3yQxgfk5kp1Cfif8eGrrsrKBn3b3zrzCnaax33jpqQWbNSwpTdINycLvR2KP+T5HcoVe6K27ZjyJX0bVNSw==',
'access_token': '24.b29406247dba0514849b4a4cd6a9457d.2592000.1706326914.282335-45901666',
'scope': 'public brain_all_scope brain_ernievilg_txt2img brain_rpc_ernievilg_v2 brain_ttv_material wise_adapt lebo_resource_base lightservice_public hetu_basic lightcms_map_poi kaidian_kaidian ApsMisTest_Test权限 vis-classify_flower lpq_开放 cop_helloScope ApsMis_fangdi_permission smartapp_snsapi_base smartapp_mapp_dev_manage iop_autocar oauth_tp_app smartapp_smart_game_openapi oauth_sessionkey smartapp_swanid_verify smartapp_opensource_openapi smartapp_opensource_recapi fake_face_detect_开放Scope vis-ocr_虚拟人物助理 idl-video_虚拟人物助理 smartapp_component smartapp_search_plugin avatar_video_test b2b_tp_openapi b2b_tp_openapi_online smartapp_gov_aladin_to_xcx',
'session_secret': 'ff8abf643f6f3345e1c36d4172ed8877'
}
"""
# 根据官档,access_token的有效期是30天
access_token = res['access_token']
# print(access_token)
return access_token
if __name__ == '__main__':
obj = MyBaiduAI(
AppID=45901666,
APIKey="sTBSZqSfB3spuC0otTCkn1zc",
SecretKey="jGjOe13CgkCTyPTRngb3y0yIkEObXFN2",
access_token_url="https://aip.baidubce.com/oauth/2.0/token",
)
obj.get_access_token()
升级版本,结合redis版本
上面的代码示例,当你需要access_token时,都需要从新发送一次请求获取一个新的access_token,这样有损性能,且按照官档来说,access_token的有效期是30天,我们完全可以获取一次access_token,保存起来,30天内不需要再重获取了。
所以,这我结合redis,优化下代码逻辑。
当拿到新的access_token时,保存到redis中,并且设置30天超时,然后后续需要access_token时,先去检查redis中是否存在access_token,存在直接返回;不存在的话,表示这个access_token已经失效了,redis中也自动删除了,那么我们代码再重新获取一份access_token,并且把它再保存到redis中。
# -*- coding = utf-8 -*-
import requests
import redis
# 创建连接对象,后续操作都是通过连接对象来操作,方式1
conn = redis.Redis(host='127.0.0.1', port=6379, password='1234', encoding='utf-8', decode_responses=True, db=0)
class MyBaiduAI(object):
def __init__(self, AppID, APIKey, SecretKey, access_token_url):
self.AppID = AppID
self.APIKey = APIKey
self.SecretKey = SecretKey
self.access_token_url = access_token_url
def get_access_token(self):
payload = ""
headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
response = requests.post(
url=self.access_token_url,
params={ # 拼接请求参数
"grant_type": "client_credentials", # 必须参数,固定为client_credentials
"client_id": self.APIKey, # 必须参数,应用的API Key;
"client_secret": self.SecretKey, # 必须参数,应用的Secret Key
},
headers=headers, data=payload
)
res = response.json()
access_token = res['access_token']
# print(access_token)
return access_token
def get_access_token_redis(self):
key = "baiduai_access_token"
access_token = conn.get(key)
if access_token:
return access_token
else:
payload = ""
headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
response = requests.post(
url=self.access_token_url,
params={ # 拼接请求参数
"grant_type": "client_credentials", # 必须参数,固定为client_credentials
"client_id": self.APIKey, # 必须参数,应用的API Key;
"client_secret": self.SecretKey, # 必须参数,应用的Secret Key
},
headers=headers, data=payload
)
res = response.json()
# 根据官档,access_token的有效期是30天
access_token = res['access_token']
conn.setex(key, 3600 * 24 * 29, access_token) # 3600 * 24 * 29, 提前设置29天过期,不要真等access_token超时了再处理
return access_token
if __name__ == '__main__':
obj = MyBaiduAI(
AppID=45901666,
APIKey="sTBSZqSfB3spuC0otTCkn1zc",
SecretKey="jGjOe13CgkCTyPTRngb3y0yIkEObXFN2",
access_token_url="https://aip.baidubce.com/oauth/2.0/token",
)
access_token = obj.get_access_token_redis()
print(access_token)
AI成片示例
# -*- coding = utf-8 -*-
import requests
import redis
# 创建连接对象,后续操作都是通过连接对象来操作,方式1
# conn = redis.Redis(host='127.0.0.1', port=6379, password='1234', encoding='utf-8', decode_responses=True, db=0)
class MyBaiduAI(object):
def __init__(self, AppID, APIKey, SecretKey, access_token_url):
self.AppID = AppID
self.APIKey = APIKey
self.SecretKey = SecretKey
self.access_token_url = access_token_url
def get_access_token(self):
payload = ""
headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
response = requests.post(
url=self.access_token_url,
params={ # 拼接请求参数
"grant_type": "client_credentials", # 必须参数,固定为client_credentials
"client_id": self.APIKey, # 必须参数,应用的API Key;
"client_secret": self.SecretKey, # 必须参数,应用的Secret Key
},
headers=headers, data=payload
)
res = response.json()
access_token = res['access_token']
# print(access_token)
return access_token
def get_access_token_redis(self):
key = "baiduai_access_token"
access_token = "24.2910ccccc7dd8af38113cd6b24b65a30.2592000.1706451650.282335-45774366"
if access_token:
return access_token
else:
payload = ""
headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
response = requests.post(
url=self.access_token_url,
params={ # 拼接请求参数
"grant_type": "client_credentials", # 必须参数,固定为client_credentials
"client_id": self.APIKey, # 必须参数,应用的API Key;
"client_secret": self.SecretKey, # 必须参数,应用的Secret Key
},
headers=headers, data=payload
)
res = response.json()
# 根据官档,access_token的有效期是30天
access_token = res['access_token']
# conn.setex(key, 3600 * 24 * 29, access_token) # 3600 * 24 * 29, 提前设置29天过期,不要真等access_token超时了再处理
return access_token
# AI成片,接口文档:https://ai.baidu.com/ai-doc/NLP/Zk7ylspjv
class MyBaiduAIAPITTV(object):
headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
def __init__(self, utils: MyBaiduAI):
self.utils = utils
def img_to_video(self):
url = "https://aip.baidubce.com/rpc/2.0/brain/creative/ttv/material"
data = {
"source": {
"structs": [
{
"type": "text",
"text": "人物跳舞,缓歌缦舞、鸾回凤翥、翩跹而舞,轻歌曼舞、舞态生风、翾风回雪,妖歌曼舞、羽衣蹁跹、翥凤翔鸾"
},
{
"type": "image",
"mediaSource": {
"type": 3,
"url": "https://creative-static.cdn.bcebos.com/public/F01DAF27445D4DAD82BF8DE8A57CF440.png"
}
}
]
},
"config": {
"productType": "video",
"duration": -1,
"resolution": [
1280,
720
]
}
}
params = {"access_token": self.utils.get_access_token_redis()}
print(111, params)
res = requests.post(url=url, params=params, json=data, headers=self.headers)
print(222, res.headers)
print(333, res.text)
if __name__ == '__main__':
obj = MyBaiduAI(
AppID=45774366,
APIKey="Zb91lvzHzhiP5m2OORcjyaQc",
SecretKey="Yak66gkAiDGQGWdROezB3fVYI5UguB3g",
access_token_url="https://aip.baidubce.com/oauth/2.0/token",
)
# access_token = obj.get_access_token_redis()
# print(access_token)
ttv = MyBaiduAIAPITTV(utils=obj)
ttv.img_to_video()
"""
# 成片结果展示:videoAddr
{
"error_code": 0,
"error_msg": "ok",
"data": {
"statusCode": "1",
"videoAddr": "http://su.bcebos.com/v1/creative-brain-hd/multimedia/37A3D2BB2F14414D94EA5DE917F0026E/creation_1703859707818_538.mp4?authorization=bce-auth-v1%2F4c51a3f4165641c593d19229a23cbd61%2F2023-12-29T14%3A21%3A48Z%2F604800%2F%2F3fb553604c4c45931b08650299f6ce6c59ba9b0a13301268e5a05c4f5d7f844c",
"mediaLibs": [
"original"
],
"chargeInfo": {
"points": "2.43",
"basicDuration": 12130
}
},
"log_id": "1740741528228386025"
}
"""
常见报错
struct中字符应处于20到2000之间
这个报错是因为示例中的文本的值的长度可能不够20个字符, 或者超过2000个字符了:
["log_id":1740295745687669399,"error-msg":"struct中字符应处于20到2000之间""error-code":30901}
解决办法也就简单了,那就是增加描述字符。
��加描述字符。