[Python] Huobi API authentication often returning error

Discussão em 'Python' iniciado por Stack, Março 22, 2025.

  1. Stack

    Stack Membro Participativo

    I have the following code working properly, but eventually (in fact quite very often) it returns error {'status': 'error', 'err-code': 'api-signature-not-valid', 'err-msg': 'Signature not valid: Verification failure [校验失败]', 'data': None} during the loop operation. I cannot understand the reason why, because it sometimes works and sometimes doesn't for apparently no reason...

    Have anybody ever faced this kind of issue before? Could somebody please try to help me? I've tried different approaches to solve the problem, but in the end every approach gave me only errors... This is the only solution I have that appears to eventually work. Thank you all in advance for any tip or help!

    from datetime import datetime
    import hmac
    import hashlib
    import base64
    from urllib.parse import urlparse
    import requests
    import time


    def generate_timestamp():
    # Gera o timestamp no formato ISO 8601
    timestamp = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S')
    # Substituir os caracteres para codificação de URL
    timestamp = timestamp.replace(":", "%3A").replace(" ", "%20").upper()
    return timestamp


    def generate_signature(api_secret, method, url, params):
    # Ordenar os parâmetros em ordem alfabética
    sorted_keys = sorted(params.keys())
    query_string = "&".join([f"{key}={params[key]}" for key in sorted_keys])

    # Montar o texto pré-assinado
    url_parts = urlparse(url)
    host = url_parts.netloc
    path = url_parts.path
    pre_signed_text = f"{method.upper()}\n{host}\n{path}\n{query_string}"
    print(f"Pre-signed text:\n{pre_signed_text}")

    # Gerar a assinatura usando HMAC-SHA256
    signature = hmac.new(
    api_secret.encode('utf-8'),
    pre_signed_text.encode('utf-8'),
    hashlib.sha256
    ).digest()

    # Retorna a assinatura em Base64
    return base64.b64encode(signature).decode('utf-8')


    def fetch_balances(api_key, api_secret):
    spot_account_id = "29996280"
    endpoint = f"/v1/account/accounts/{spot_account_id}/balance"
    base_url = "https://api.huobi.pro"
    url = f"{base_url}{endpoint}"

    method = "GET"
    timestamp = generate_timestamp()

    # Parâmetros essenciais
    params = {
    "AccessKeyId": api_key,
    "SignatureMethod": "HmacSHA256",
    "SignatureVersion": "2",
    "Timestamp": timestamp
    }

    # Gerar a assinatura
    signature = generate_signature(api_secret, method, url, params)
    if not signature:
    print("Erro ao gerar a assinatura")
    return []

    # Adicionar a assinatura aos parâmetros
    params["Signature"] = signature
    sorted_keys = sorted(params.keys())
    query_string = "&".join([f"{key}={params[key]}" for key in sorted_keys])

    # Construir a URL final
    final_url = f"{url}?{query_string}"
    print(f"URL Final: {final_url}")

    # Executar a requisição
    headers = {"Content-Type": "application/x-www-form-urlencoded"}
    response = requests.get(final_url, headers=headers)

    if response.status_code == 200:
    print("Requisição bem-sucedida")
    return response.json()
    else:
    print(f"Falha na requisição: {response.status_code}")
    print(f"Resposta JSON: {response.text}")
    return []


    def loop_fetch_balances(api_key, api_secret):
    while True: # Loop infinito
    try:
    # Chama a função fetch_balances
    balances = fetch_balances(api_key, api_secret)

    # Imprime os balances, se disponíveis
    if balances:
    print("Inicio da resposta:", str(balances)[:200]) # Exibe os primeiros 100 caracteres
    else:
    print("Não foi possível obter os balances.")

    # Aguarda 5 segundos antes de repetir
    time.sleep(5)
    except KeyboardInterrupt:
    # Permite sair do loop com Ctrl+C
    print("Encerrando o loop...")
    break


    # Configurações da API
    api_key = "MY_API_KEY"
    api_secret = "MY_API_SECRET"

    # Executa o loop
    loop_fetch_balances(api_key, api_secret)

    Continue reading...

Compartilhe esta Página