PT ▾
API de Texto Sem Censura para Pipelines TTShttps://api.ttsapihub.com/v1

Chave de API TTS em Python: configuração, streaming e modo JSON

Este é um guia em Python para a API por trás deste site: armazene a chave, crie um cliente, faça streaming das respostas, force a saída JSON e gerencie os limites de requisições. Uma ressalva antes: ele gera texto, não áudio.

Atualizado

Chave brilhante acima de um terminal com fluxos de dados, ilustrando uma chave de API usada do Python

Pontos principais

  • O endpoint é compatível com OpenAI, então o pacote Python openai funciona com base_url definido para https://api.ttsapihub.com/v1.
  • Mantenha a chave em uma variável de ambiente, nunca no código-fonte.
  • Streaming, modo JSON e chamada de funções são suportados; saída de áudio não é.
  • Trate HTTP 429 com uma breve espera e leia X-Balance-USD para acompanhar os gastos.

Verifique o que a chave abre

Quem procura um exemplo de chave de API TTS em Python geralmente quer converter texto em áudio de voz. A chave deste serviço não faz isso. Ela autentica requisições para um LLM de texto: POST /v1/chat/completions e GET /v1/models, usando o modelo uncensored. Não há síntese de fala, nem upload de áudio nem embeddings.

Se isso se encaixa no seu projeto, por exemplo porque você gera roteiros, diálogos ou narração que você passa para uma ferramenta de fala separada, o restante desta página oferece a você código Python funcional. Se você precisa de saída de áudio da própria API, este é o serviço errado, e é melhor saber isso agora. A documentação lista o conjunto exato de recursos.

Uma maneira prática de usar a geração de texto em um projeto de áudio é tratá-la como a etapa de escrita. O modelo rascunha a narração, reescreve uma linha para se adequar a um limite de tempo ou transforma notas em diálogos com vários falantes. Seu código Python então entrega o texto final à ferramenta de fala que você usar. Manter as etapas separadas também significa que você pode trocar qualquer uma delas sem tocar na outra, e você paga esta API apenas pelas palavras que ela escreve.

Para acompanhar, você precisa do Python 3.9 ou mais recente e de uma chave. Crie uma conta na página de chave de API e resgate o crédito de teste grátis de $0,50 com um clique; ele dura 7 dias e não precisa de cartão.

Armazene a chave e instale o pacote

Nunca escreva a chave em um arquivo que você vai fazer commit. Coloque-a em uma variável de ambiente e leia-a em tempo de execução.

# base URL used below: https://api.ttsapihub.com/v1 , model: uncensored
pip install openai
export API_KEY="paste-your-key-here"

No PowerShell do Windows, o equivalente é $env:API_KEY = "paste-your-key-here". Para um projeto, um arquivo .env carregado com python-dotenv é comum, desde que .env esteja no .gitignore.

Se uma chave vazar para um repositório, trate-a como queimada: remova-a do histórico se puder e solicite uma nova. Lembre-se de que as chaves gastam crédito pré-pago, então uma chave vazada é também um vazamento financeiro.

Crie o cliente e faça uma primeira chamada

O pacote oficial aceita base_url. O resto é o padrão de chamada 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)

O objeto usage mostra quantos tokens a chamada usou, para que você possa calcular o custo: tokens de entrada vezes $0,15 por milhão, mais tokens de saída vezes $0,50 por milhão. Se a chamada acima usou 60 tokens de entrada e 80 tokens de saída, o custo é $0,000009 mais $0,00004, que é $0,000049. Requisições falhas ou recusadas não são cobradas.

max_tokens é opcional. Sem ele, a conclusão pode usar o que restar da janela de 100.000 tokens, então defina-o quando quiser um limite rígido de comprimento e custo.

Faça streaming da resposta

O streaming retorna tokens conforme são gerados usando eventos enviados pelo servidor. Defina stream=True e itere.

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)

A proteção para uma lista choices vazia existe porque o evento final de um fluxo pode conter dados de uso e nenhum texto. Pular esse evento evita um erro de índice. Um detalhe operacional: uma requisição em streaming mantém sua slot de concorrência até o fim do fluxo. Se você iniciar muitos fluxos em threads e nunca terminar de lê-los, atingirá o limite de concorrência mesmo que sua taxa de requisições seja baixa.

Solicite JSON e chame ferramentas

Modo JSON

Defina response_format para um objeto JSON para tornar a resposta analisável. Também diga ao modelo no prompt que você quer JSON; a configuração restringe o formato, e o prompt diz qual formato.

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"]))

Envolva json.loads em um bloco try mesmo assim. Uma resposta que atinge max_tokens pode ser cortada no meio de um objeto.

Chamada de funções

Passe tools e opcionalmente tool_choice. Quando o modelo solicitar uma ferramenta, execute-a você mesmo e envie o resultado de volta como uma mensagem com 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)

Mantenha uma conversa e monitore o orçamento de tokens

A API é sem estado. Se você quer um chat que lembre o que foi dito, você mantém a lista de mensagens no seu programa e envia tudo isso com cada chamada. Uma pequena classe faz o trabalho, e é também o lugar certo para limitar o histórico para que o custo não aumente.

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])

O corte importa mais para o dinheiro do que para a janela. O modelo aceita até 100.000 tokens no total, mas se cada turno reenviar 30.000 tokens de histórico, cada chamada custa $0,0045 apenas de entrada (30.000 vezes $0,15 por milhão). Cinquenta desses turnos somam $0,225 antes que um único token de saída seja contado. Manter as últimas dúzias de turnos, ou resumir os mais antigos em uma nota curta, geralmente mantém a qualidade e corta a conta drasticamente.

A concurrency é a outra coisa para projetar. Se o seu programa serve vários usuários ao mesmo tempo, um semáforo dimensionado para o limite da sua chave (8 para uma chave completa, 2 para uma chave de teste) evita que você acione o erro concurrency. Chamadas acima do limite aguardam na sua própria fila em vez de falhar, o que é mais amigável do que tentar novamente em um 429.

Os testes também valem uma palavra. Escreva um pequeno script que chama a API com um seed fixo, uma temperatura baixa e um max_tokens curto, e execute-o sempre que alterar prompts ou configurações. Uma semente e temperatura baixa tornam a saída mais repetível, o que permite comparar duas versões de prompt sem ruído. Mantenha esses testes pequenos; um teste que custa uma fração de um centavo pode ser executado em cada commit sem que ninguém note a conta.

Finalmente, registre o ID da solicitação de cada resposta. Quando uma chamada se comporta estranhamente, esse ID é a maneira mais rápida de apontar o suporte para a solicitação exata.

Gerencie limites, erros e saldo

Uma chave completa permite 8 requisições simultâneas e 300 requisições por minuto. A chave de teste permite 2 e 60. Exceder o primeiro retorna HTTP 429 com o código de erro concurrency, e exceder o segundo retorna 429 com rate_limited. Sobrecarga temporária também retorna 429 com um cabeçalho Retry-After: 5.

O pacote OpenAI tenta novamente algumas falhas por conta própria, e você pode aumentar isso com max_retries. Para um trabalho em lote, adicione também seu próprio limite de trabalho paralelo, para que você fique abaixo do limite de concorrência em vez de depender de tentativas novamente.

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)

Os cabeçalhos de resposta X-Request-Id e X-Balance-USD são úteis em logs. Cite o ID da requisição quando entrar em contato com o suporte. Os custos estão listados na página de preços: $0,15 por 1M de tokens de entrada e $0,50 por 1M de tokens de saída, com recargas de $20 a $500 e bônus de 5%, 10% e 15% em $50, $100 e $200. Cartão (Visa, Mastercard, Apple Pay, Google Pay) e cripto (USDT em TRC20, USDC em Base) são aceitos. Os prompts não são usados para treinamento. O modelo é destinado ao uso adulto lícito, e conteúdo sexual envolvendo menores de idade nunca é permitido.

Perguntas e respostas

Esta chave de API funciona para texto para fala em Python?

Não. A chave autentica uma API LLM de texto sem saída de áudio. Use-a para gerar texto e, em seguida, passe esse texto para uma ferramenta de fala.

Qual pacote Python devo usar?

O pacote openai oficial. Defina base_url para https://api.ttsapihub.com/v1 e model para uncensored.

Como manter a chave fora do meu código?

Leia-a de uma variável de ambiente como API_KEY e mantenha qualquer arquivo .env fora do controle de versão.

Como posso ver quanto uma chamada custou?

Leia resp.usage para contagens de tokens e o cabeçalho de resposta X-Balance-USD para o saldo restante.

O que acontece ao atingir o limite de requisições?

A API retorna HTTP 429 com o código rate_limited ou concurrency. Aguarde alguns segundos e tente novamente; a requisição que falhou não é cobrada.

Sua chave está a um formulário de distância

Crie uma conta, copie a chave e altere a URL base. Essa é toda a configuração.

Obter chave de API