Python TTS API 密钥:配置、流式输出与 JSON 模式
这是该网站背后 API 的 Python 指南:存储密钥、创建客户端、流式输出、强制 JSON 输出并处理速率限制。首先注意:它生成文本,而非音频。
更新于

要点
- 该接口兼容 OpenAI,因此 openai Python 包在设置 base_url 为 https://api.ttsapihub.com/v1 时可用
- 将密钥保存在环境变量中,不要保存在源代码中。
- 支持流式输出、JSON 模式和函数调用;不支持音频输出。
- 通过短暂等待处理 HTTP 429,并读取 X-Balance-USD 以跟踪支出。
检查密钥的功能
搜索 tts api key python example 的人通常希望将文本转为语音。此服务的密钥不执行此操作。它用于对文本 LLM 发起请求进行身份验证:POST /v1/chat/completions 和 GET /v1/models,使用模型 uncensored。没有语音合成、没有音频上传,也没有嵌入功能。
如果这符合你的项目需求,例如你生成脚本、对话或旁白并传递给单独的语音工具,本页其余部分提供可用的 Python 代码。如果你需要 API 本身输出音频,则选错了服务,最好尽早知晓。文档列出了确切的功能集。
在音频项目中实用使用文本生成的方法是将其视为写作阶段。模型起草旁白,重写一行以符合时间限制,或将笔记转换为多个说话者的对话。你的 Python 代码随后将最终文本交给你使用的任何语音工具。将阶段分开也意味着你可以交换其中任何一个而不影响另一个,并且你只为它写的单词支付此 API 的费用。
要跟随教程,你需要 Python 3.9 或更高版本以及一个密钥。在 API 密钥页面注册并领取一键式 $0.50 试用额度;有效期 7 天,无需信用卡。
存储密钥并安装包
永远不要将密钥写入你提交的文件中。将其放入环境变量,并在运行时读取。
# base URL used below: https://api.ttsapihub.com/v1 , model: uncensored
pip install openai
export API_KEY="paste-your-key-here"在 Windows PowerShell 中等效的是 $env:API_KEY = "paste-your-key-here"。对于项目,使用 python-dotenv 等包加载的 .env 文件是常见模式,只要 .env 在你的 .gitignore 中即可。
如果密钥泄露到仓库中,将其视为已失效:如果可以,请从历史记录中删除它,并请求一个新的。请记住,密钥会消耗预付额度,因此泄露的密钥也是财务泄露。
创建客户端并进行首次调用
官方包接受 base_url 参数。其余部分均为标准的 OpenAI 调用格式。
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.ttsapihub.com/v1",
api_key=os.environ["API_KEY"],
)
resp = client.chat.completions.create(
model="uncensored",
messages=[
{"role": "system", "content": "You write short narration scripts."},
{"role": "user", "content": "Draft a 40-word intro for a podcast about night trains."},
],
temperature=0.8,
max_tokens=200,
)
print(resp.choices[0].message.content)
print(resp.usage.prompt_tokens, resp.usage.completion_tokens)usage 对象显示调用使用了多少 token,以便你计算成本:输入 token 数量乘以每百万输入 token $0.15,加上输出 token 数量乘以每百万输出 token $0.50。如果上述调用使用了 60 个输入 token 和 80 个输出 token,成本为 $0.000009 加上 $0.00004,即 $0.000049。失败或被拒绝的请求不收费。
max_tokens 是可选的。如果没有它,补全可以使用 100,000-token 窗口中的剩余部分,所以当你要对长度和成本设置硬性限制时,请设置它。
流式输出回复
流式输出使用服务器发送事件返回生成的 token。设置 stream=True 并迭代。
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.ttsapihub.com/v1", api_key=os.environ["API_KEY"])
stream = client.chat.completions.create(
model="uncensored",
messages=[{"role": "user", "content": "Describe a rainy station platform in four sentences."}],
stream=True,
)
parts = []
for chunk in stream:
if not chunk.choices:
continue
delta = chunk.choices[0].delta.content or ""
parts.append(delta)
print(delta, end="", flush=True)
text = "".join(parts)检查空 choices 列表的存在是因为流的最后一个事件可能包含使用数据而没有文本。跳过它可以避免索引错误。一个操作细节:流式请求会占用其并发槽位,直到流结束。如果你在线程中启动许多流且从未读取完毕,即使你的请求速率很低,也会达到并发限制。
请求 JSON 并调用工具
JSON 模式
将 response_format 设置为 JSON 对象以使回复可解析。同时在提示词中告知模型你想要 JSON;该设置约束格式,而提示词告知其结构。
import json, os
from openai import OpenAI
client = OpenAI(base_url="https://api.ttsapihub.com/v1", api_key=os.environ["API_KEY"])
resp = client.chat.completions.create(
model="uncensored",
response_format={"type": "json_object"},
messages=[
{"role": "system", "content": "Reply only with JSON: {\"title\": str, \"beats\": [str]}"},
{"role": "user", "content": "Outline a three-beat radio drama about a lost key."},
],
)
data = json.loads(resp.choices[0].message.content)
print(data["title"], len(data["beats"]))无论如何将 json.loads 包装在 try 块中。达到 max_tokens 的回复可能会在对象中间被截断。
函数调用
传递 tools 和可选的 tool_choice。当模型请求工具时,自己运行它并将结果作为带有 role: "tool" 的消息发回。
import json, os
from openai import OpenAI
client = OpenAI(base_url="https://api.ttsapihub.com/v1", api_key=os.environ["API_KEY"])
tools = [{
"type": "function",
"function": {
"name": "word_count",
"description": "Count the words in a text",
"parameters": {
"type": "object",
"properties": {"text": {"type": "string"}},
"required": ["text"],
},
},
}]
messages = [{"role": "user", "content": "How many words are in: the quick brown fox?"}]
first = client.chat.completions.create(model="uncensored", messages=messages, tools=tools)
msg = first.choices[0].message
if msg.tool_calls:
call = msg.tool_calls[0]
args = json.loads(call.function.arguments)
result = len(args["text"].split())
messages.append(msg)
messages.append({"role": "tool", "tool_call_id": call.id, "content": str(result)})
final = client.chat.completions.create(model="uncensored", messages=messages, tools=tools)
print(final.choices[0].message.content)保持对话并监控 token 预算
API 是无状态的。如果你需要一个能记住对话内容的聊天,需在程序中保留消息列表,并在每次调用时发送全部消息。一个简单的类即可完成此工作,也是限制历史记录以防止成本增加的最佳位置。
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.ttsapihub.com/v1", api_key=os.environ["API_KEY"])
history = [{"role": "system", "content": "You are a dialogue writer. Keep replies under 120 words."}]
def say(user_text, keep_last=12):
history.append({"role": "user", "content": user_text})
# keep the system message plus the most recent turns
trimmed = [history[0]] + history[1:][-keep_last:]
resp = client.chat.completions.create(model="uncensored", messages=trimmed, max_tokens=250)
reply = resp.choices[0].message.content
history.append({"role": "assistant", "content": reply})
return reply, resp.usage.total_tokens
print(say("Open a scene in a ticket office at closing time.")[0])修剪历史记录对省钱比节省上下文窗口更重要。模型总共接受最多 100,000 个 token,但如果每轮都重发 30,000 个历史记录 token,仅输入成本每次调用就为 $0.0045(30,000 乘以每百万个 $0.15)。五十轮这样的调用累计达 $0.225,此时甚至还未计算单个输出 token。保留最近十几轮,或将旧内容总结为简短笔记,通常能保持质量并大幅降低账单。
并发是另一个需要设计考虑的因素。如果你的程序同时服务多个用户,使用限制大小为密钥限制(完整密钥为 8,试用密钥为 2)的信号量,可避免触发 concurrency 错误。超过限制的调用会在你自己的队列中等待,这比在 429 错误时重试更友好。
测试也值得一提。编写一个小型脚本,使用固定的 seed、低 temperature 和短 max_tokens 调用 API,并在更改提示词或设置时运行。种子和低 temperature 使输出更具可重复性,从而让你在不受随机性干扰的情况下比较两个提示词版本。保持这些测试极小化;花费不到一美分的测试可在每次提交时运行,且无人会注意到账单。
最后,记录每个回复的请求 ID。当调用行为异常时,该 ID 是让支持团队定位确切请求的最快方式。
处理限制、错误和余额
完整密钥允许 8 个并发请求和每分钟 300 个请求。试用密钥允许 2 个和 60 个。超过第一个返回 HTTP 429,错误代码为 concurrency,超过第二个返回 429,错误代码为 rate_limited。临时过载也返回带有 Retry-After: 5 头的 429。
OpenAI 包会自动重试一些失败,你可以使用 max_retries 提高该值。对于批处理作业,也添加你自己的并行工作上限,以便保持在并发限制之下,而不是依赖重试。
import os
from openai import OpenAI, RateLimitError
client = OpenAI(base_url="https://api.ttsapihub.com/v1", api_key=os.environ["API_KEY"], max_retries=3)
raw = client.chat.completions.with_raw_response.create(
model="uncensored",
messages=[{"role": "user", "content": "One sentence about trains."}],
max_tokens=60,
)
print("balance:", raw.headers.get("X-Balance-USD"))
print("request id:", raw.headers.get("X-Request-Id"))
print(raw.parse().choices[0].message.content)响应头 X-Request-Id 和 X-Balance-USD 在日志中很有用。联系支持时请引用请求 ID。费用列在 定价页面:每 1M 输入 token $0.15,每 1M 输出 token $0.50,充值金额为 $20 至 $500,并在 $50、$100 和 $200 时分别提供 5%、10% 和 15% 的奖金。接受银行卡(Visa、Mastercard、Apple Pay、Google Pay)和加密货币(TRC20 网络上的 USDT、Base 网络上的 USDC)。提示词不用于训练。该模型适用于合法成人用途,且绝不允许涉及未成年人的色情内容。
更多指南
问答
此 API 密钥可在 Python 中用于文本转语音吗?
不行。该密钥用于验证文本 LLM API,无音频输出。用它生成文本,然后将文本传递给语音工具。
我应该使用哪个 Python 包?
官方 openai 包。将 base_url 设置为 https://api.ttsapihub.com/v1,将模型设置为 uncensored。
如何将密钥排除在代码之外?
从 API_KEY 等环境变量读取,并将任何 .env 文件排除在版本控制之外。
如何查看每次调用的费用?
读取 resp.usage 获取 token 计数,读取 X-Balance-USD 响应头获取剩余余额。
达到速率限制时会发生什么?
API 返回 HTTP 429,错误代码为 rate_limited 或 concurrency。等待几秒后重试;该失败的请求不收费。