如何理解API额度、速率限制与分页

区块链文库报道:

引言

你的CoinMarketCap计划能走多远,取决于三个因素:信用额度如何计算、调用的频率如何控制,以及如何对大量结果集进行分页。如果这些方面处理不当,就会最快地消耗掉月度配额,或在生产环境中触发速率限制。

本指南将介绍信用额度模型、速率限制结构以及分页参数,并附上信用额度的具体计算方式,帮助你在开发前合理规划用量。

信用额度的工作原理

信用额度是CoinMarketCap用于计量API使用量的单位。你的套餐包含每月信用额度,每次调用会根据返回的数据量消耗相应积分。

核心规则:每返回200个数据点消耗1个信用额度,向上取整。

请求 -limit=1
数据点 -1
信用额度 -1

请求 -limit=100
数据点 -100
信用额度 -1

请求 -limit=200
数据点 -200
信用额度 -1

请求 -limit=201
数据点 -201
信用额度 -2

请求 -limit=500
数据点 -500
信用额度 -3

部分端点免费。例如 /v1/cryptocurrency/map 和 /v1/key/info 这类实用接口消耗0信用额度,因此你可以免费刷新ID映射或查看用量。

除第一个币种外,每次额外转换币种会增加1个信用额度。例如,对一个资产请求 convert=USD,EUR,GBP,基础消耗1信用额度,再加上2个额外转换额度。

你可以随时通过响应状态对象中的 credit_count 字段确认每次调用的精确成本。

查看你的用量

/v1/key/info 端点会返回你当前的信用额度和套餐限制,并且调用该接口完全免费。

import os
import requests

response = requests.get(“https://pro-api.coinmarketcap.com/v1/key/info”,
headers={“Accept”: “application/json”,
“X-CMC_PRO_API_KEY”: os.getenv(“CMC_API_KEY”)})

info = response.json()[“data”]
usage = info[“usage”]
print(f”本月已用信用额度: {usage[‘current_month’][‘credits_used’]}”)
print(f”本月剩余信用额度: {usage[‘current_month’][‘credits_left’]}”)
print(f”本分钟请求数: {usage[‘current_minute’][‘requests_made’]}”)

定期轮询该接口,以跟踪消耗速率,并在达到月度上限前及时预警。

速率限制

速率限制控制的是调用频率,与月度信用额度上限相互独立。该限制按分钟执行,并根据你的套餐等级动态调整。

当超出每分钟速率限制时,API会返回HTTP 429状态码,并附带 error_code 1007。当月度信用额度耗尽时,同样返回HTTP 429,但 error_code 为1008。两者均返回429,因此需通过 error_code 加以区分。

def classify_429(response):
error_code = response.json().get(“status”, {}).get(“error_code”)
if error_code == 1007:
return “rate_limit” # 降低速度,稍等片刻后重试
if error_code == 1008:
return “monthly_cap” # 升级套餐或等待重置
return “unknown”

每分钟速率限制每60秒重置一次。月度信用额度上限在每个计费周期开始时重置。

分页

列表类端点每次调用只返回有限数量的结果。要获取更多数据,请使用 start 和 limit 参数逐页遍历。

参数 – start
默认值 – 1
说明 – 基于1的结果起始索引

参数 – limit
默认值 – 100
说明 – 每页结果数量

要获取排名第1到第100的数据,使用 start=1&limit=100。要获取排名第101到第200的数据,使用 start=101&limit=100。

import time
import requests

HEADERS = {
“Accept”: “application/json”,
“X-CMC_PRO_API_KEY”: os.getenv(“CMC_API_KEY”)
}

def fetch_all(page_size=200, max_pages=50):
all_assets = []
start = 1
for _ in range(max_pages):
response = requests.get(“https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest”,
headers=HEADERS,
params={“start”: str(start), “limit”: str(page_size), “convert”: “USD”})
response.raise_for_status()
batch = response.json()[“data”]
if not batch:
break
all_assets.extend(batch)
if len(batch) < page_size:
break
start += page_size
time.sleep(0.5) # 保持在每分钟速率限制以内
return all_assets

分页的信用额度计算

使用更大的页面大小进行分页,调用次数更少,但消耗的信用额度相同,因为信用额度基于数据点而非调用次数。

页面大小 – 100
获取10,000个资产所需页数 – 100
调用次数 – 100
信用额度 – 约50

页面大小 – 200
获取10,000个资产所需页数 – 50
调用次数 – 50
信用额度 – 约50

页面大小 – 500
获取10,000个资产所需页数 – 20
调用次数 – 20
信用额度 – 约30

更大的页面消耗的信用额度相同或更少,且调用次数大幅减少,这有助于你保持在速率限制以内。使用 limit=500 是遍历大型数据集最高效的方式。

常见错误

误区一:认为每次调用消耗1个信用额度。信用额度根据返回的数据点数量计算,而不是调用次数。一次 limit=500 的调用消耗3个信用额度。

误区二:混淆速率限制与信用额度上限。两者相互独立。你可能还有剩余信用额度,却已触发每分钟速率限制,反之亦然。遇到429错误时,务必检查 error_code 字段。

误区三:不做缓存。大多数数据最长每60秒更新一次。在更新间隔内缓存响应并进行刷新,是节省信用额度最有效的方法。

© 版权声明
THE END
喜欢就支持一下吧
分享