Не могу получить данные по API

Ключи не рабочие. Просто ради примера привел.

import hmac
import base64
import requests
import json
import datetime

api_key = 'd024f2f3-2707-4504-8968-c25ddc7dd0dc',
secret_key = '6C2B92730CF43903CDC8C3986553FBC3',
passphras = 'Warlock2014'
timestamp = datetime.datetime.utcnow().strftime("%Y%m%dT%H%M%S.%fZ")

CONTENT_TYPE = 'Content-Type'
OK_ACCESS_KEY = 'OK-ACCESS-KEY'
OK_ACCESS_SIGN = 'OK-ACCESS-SIGN'
OK_ACCESS_TIMESTAMP = 'OK-ACCESS-TIMESTAMP'
OK_ACCESS_PASSPHRASE = 'OK-ACCESS-PASSPHRASE'
APPLICATION_JSON = 'application/json'



def signature(timestamp, method, request_path, body, secret_key):
    if str(body) == '{}' or str(body) == 'None':
        body = ''
    message = str(timestamp) + str.upper(method) + request_path + str(body)
    mac = hmac.new(bytes(secret_key, encoding='utf8'), bytes(message, encoding='utf-8'), digestmod='sha256')
    d = mac.digest()
    return base64.b64encode(d)

# set request header
def get_header(api_key, sign, timestamp, passphrase):
    header = dict()
    header[CONTENT_TYPE] = APPLICATION_JSON
    header[OK_ACCESS_KEY] = api_key
    header[OK_ACCESS_SIGN] = sign
    header[OK_ACCESS_TIMESTAMP] = str(timestamp)
    header[OK_ACCESS_PASSPHRASE] = passphrase
    return header


def parse_params_to_str(params):
    url = '?'
    for key, value in params.items():
        url = url + str(key) + '=' + str(value) + '&'

    return url[0:-1]



base_url = 'https://www.okex.com'
request_path = '/api/account/v3/currencies'
# set request header
header = get_header('d024f2f3-2707-4504-8968-c25ddc7dd0dc', signature(timestamp, 'GET', request_path, body = '', secret_key= '6C2B92730CF43903CDC8C3986553FBC3'), timestamp, 'Warlock2014')
# do request
response = requests.get(base_url + request_path, headers=header)
# json
print(response.json())

Output:

{'error_message': 'Invalid OK-ACCESS-TIMESTAMP', 'code': 30005, 'error_code': '30005', 'message': 'Invalid OK-ACCESS-TIMESTAMP'}

Пишет неверный timestamp. Сделал вроде как по их же требованиям. Что не так делаю?

Unless otherwise specified, all timestamps from the API are returned in ISO 8601 with milliseconds resolution. Make sure you can parse the ISO 8601 format with the example below. Most modern languages and libraries can handle this without issues.

Example
2014-11-06T10:34:47.123Z

Библиотека на всякий случай. https://www.okex.com/docs/en/#summary-rules


Ответы (2 шт):

Автор решения: CrazyElf

Не нужно форматировать строку "вручную", есть же готовая функция isoformat, попробуйте её:

timestamp = datetime.datetime.utcnow().isoformat()
# 2021-10-12T11:00:51.614611
→ Ссылка
Автор решения: gil9red

Руками сделал дату в нужном формате:

dt_now = datetime.datetime.utcnow()
ms = str(dt_now.microsecond).zfill(6)[:3]
timestamp = f'{dt_now:%Y-%m-%dT%H:%M:%S}.{ms}Z'
print(timestamp)

Пример:

2021-10-12T11:22:19.865Z

После этого уже другая ошибка:

{'error_message': 'Invalid Authority', 'code': 30012, 'error_code': '30012', 'message': 'Invalid Authority'}

Скорее всего, неправильное значение в secret_key или passphras


Весь код (немного его отрефакторил):

import base64
import datetime
import hmac

import requests


def signature(timestamp: str, method: str, request_path: str, secret_key: str, body: str = '') -> str:
    if not body:
        body = ''

    message = timestamp + method.upper() + request_path + body
    mac = hmac.new(
        bytes(secret_key, encoding='utf-8'),
        bytes(message, encoding='utf-8'),
        digestmod='sha256'
    )
    d = mac.digest()
    return base64.b64encode(d).decode('utf-8')


api_key = 'd024f2f3-2707-4504-8968-c25ddc7dd0dc'
secret_key = '6C2B92730CF43903CDC8C3986553FBC3'
passphras = 'Warlock2014'

dt_now = datetime.datetime.utcnow()
ms = str(dt_now.microsecond).zfill(6)[:3]
timestamp = f'{dt_now:%Y-%m-%dT%H:%M:%S}.{ms}Z'


base_url = 'https://www.okex.com'
request_path = '/api/v5/market/ticker'
headers = {
    'Content-Type': 'application/json',
    'OK-ACCESS-KEY': api_key,
    'OK-ACCESS-SIGN': signature(timestamp, 'GET', request_path, secret_key),
    'OK-ACCESS-TIMESTAMP': timestamp,
    'OK-ACCESS-PASSPHRASE': passphras,
}
params = {
    'instId': 'BTC-USD-SWAP'
}
# do request
response = requests.get(base_url + request_path, params=params, headers=headers)
# json
print(response.json())

Результат после изменения request_path и указания instId:

{'code': '0', 'msg': '', 'data': [{'instType': 'SWAP', 'instId': 'BTC-USD-SWAP', 'last': '56840', 'lastSz': '1', 'askPx': '56829', 'askSz': '347', 'bidPx': '56828.9', 'bidSz': '363', 'open24h': '56577', 'high24h': '57853.5', 'low24h': '56434.6', 'volCcy24h': '15309.4666', 'vol24h': '8759159', 'ts': '1634043284042', 'sodUtc0': '57491', 'sodUtc8': '57494.8'}]}
→ Ссылка