This commit is contained in:
root 2025-07-12 19:51:13 +08:00
parent b5a5944b64
commit c1a33333d1
2 changed files with 286 additions and 44 deletions

View File

@ -36,7 +36,7 @@ class Settings(BaseSettings):
default_video_codec: str = "libx264"
default_audio_codec: str = "aac"
# cloud flare
cloudflare_api_key: str = "dlGquMNiAX-S7SV9pXne7YGfdH_fEgq3TfIGgNcQ"
cloudflare_api_key: str = "hAiXy3jB-Lt5q-XiIV588lyvyH1c8FJaG3oieqeT"
cloudflare_url: str = "https://api.cloudflare.com/client/v4/"
cloudflare_account_id: str = "67720b647ff2b55cf37ba3ef9e677083"
cloudflare_kv_id: str = "995d7eff088547d7a7d8fea53e56115b"

View File

@ -12,73 +12,315 @@ class Kv:
self.cf_account_id = settings.cloudflare_account_id
self.cf_kv_api_token = settings.cloudflare_api_key
self.cf_kv_id = settings.cloudflare_kv_id
def gets(self, keys: list[str]):
self.base_url = f"https://api.cloudflare.com/client/v4/accounts/{self.cf_account_id}/storage/kv/namespaces/{self.cf_kv_id}"
self.headers = {"Authorization": f"Bearer {self.cf_kv_api_token}"}
def get(self, key: str, default=None):
"""
获取单个键的值
Args:
key: 要获取的键
default: 如果键不存在时返回的默认值
Returns:
键对应的值如果不存在则返回default
"""
try:
with httpx.Client() as client:
response = client.post(
f"https://api.cloudflare.com/client/v4/accounts/{self.cf_account_id}/storage/kv/namespaces/{self.cf_kv_id}/bulk/get",
headers={"Authorization": f"Bearer {self.cf_kv_api_token}"},
json={
"keys": keys,
"type": "json"
}
response = client.get(
f"{self.base_url}/values/{key}",
headers=self.headers
)
if response.status_code == 404:
return default
response.raise_for_status()
return response.text
except httpx.RequestError as e:
logger.error(f"An error occurred while put kv to cloudflare")
logger.error(f"An error occurred while getting key '{key}' from cloudflare: {e}")
raise e
except httpx.HTTPStatusError as e:
logger.error(f"HTTP error occurred while get kv from cloudflare {str(e)}")
if e.response.status_code == 404:
return default
logger.error(f"HTTP error occurred while getting key '{key}' from cloudflare: {e}")
raise e
except Exception as e:
logger.error(f"An unexpected error occurred: {str(e)}")
logger.error(f"An unexpected error occurred while getting key '{key}': {e}")
raise e
def sets(self, caches: Dict[str, str]):
def set(self, key: str, value: str):
"""
设置单个键值对
Args:
key: 键名
value:
expiration_ttl: TTL过期时间
expiration: 绝对过期时间Unix时间戳
Returns:
操作结果
"""
try:
with httpx.Client() as client:
params = {}
response = client.put(
f"https://api.cloudflare.com/client/v4/accounts/{self.cf_account_id}/storage/kv/namespaces/{self.cf_kv_id}/bulk",
headers={"Authorization": f"Bearer {self.cf_kv_api_token}"},
json=[
{
"based64": False,
"key": key,
"value": value,
}
for (key, value) in caches.items()
]
f"{self.base_url}/values/{key}",
headers=self.headers,
params=params,
content=value
)
response.raise_for_status()
return response.json() if response.text else {"success": True}
except httpx.RequestError as e:
logger.error(f"An error occurred while put kv to cloudflare")
logger.error(f"An error occurred while setting key '{key}' to cloudflare: {e}")
raise e
except httpx.HTTPStatusError as e:
logger.error(f"HTTP error occurred while get kv from cloudflare {str(e)}")
logger.error(f"HTTP error occurred while setting key '{key}' to cloudflare: {e}")
raise e
except Exception as e:
logger.error(f"An unexpected error occurred: {str(e)}")
logger.error(f"An unexpected error occurred while setting key '{key}': {e}")
raise e
def remove(self, key: str):
"""
删除单个键
Args:
key: 要删除的键名
Returns:
操作结果
"""
try:
with httpx.Client() as client:
response = client.delete(
f"{self.base_url}/values/{key}",
headers=self.headers
)
if response.status_code == 404:
return {"success": True, "message": "Key not found"}
response.raise_for_status()
return response.json() if response.text else {"success": True}
except httpx.RequestError as e:
logger.error(f"An error occurred while removing key '{key}' from cloudflare: {e}")
raise e
except httpx.HTTPStatusError as e:
if e.response.status_code == 404:
return {"success": True, "message": "Key not found"}
logger.error(f"HTTP error occurred while removing key '{key}' from cloudflare: {e}")
raise e
except Exception as e:
logger.error(f"An unexpected error occurred while removing key '{key}': {e}")
raise e
def sets(self, caches: Dict[str, str]):
"""
批量设置多个键值对
Args:
caches: 包含键值对的字典
expiration_ttl: TTL过期时间
expiration: 绝对过期时间Unix时间戳
Returns:
操作结果
"""
try:
with httpx.Client() as client:
bulk_data = []
for key, value in caches.items():
item = {
"base64": False,
"key": key,
"value": value,
}
bulk_data.append(item)
response = client.put(
f"{self.base_url}/bulk",
headers=self.headers,
json=bulk_data
)
response.raise_for_status()
return response.json()
except httpx.RequestError as e:
logger.error(f"An error occurred while bulk setting keys to cloudflare: {e}")
raise e
except httpx.HTTPStatusError as e:
logger.error(f"HTTP error occurred while bulk setting keys to cloudflare: {e}")
raise e
except Exception as e:
logger.error(f"An unexpected error occurred while bulk setting keys: {e}")
raise e
def remove(self, keys: list[str]):
with httpx.Client() as client:
try:
def removes(self, keys: list[str]):
"""
批量删除多个键
Args:
keys: 要删除的键列表
Returns:
操作结果
"""
try:
with httpx.Client() as client:
response = client.post(
f"https://api.cloudflare.com/client/v4/accounts/{self.cf_account_id}/storage/kv/namespaces/{self.cf_kv_id}/bulk/delete",
headers={"Authorization": f"Bearer {self.cf_kv_api_token}"},
f"{self.base_url}/bulk/delete",
headers=self.headers,
json=keys
)
response.raise_for_status()
except httpx.RequestError as e:
logger.error(f"An error occurred while put kv to cloudflare")
raise e
except httpx.HTTPStatusError as e:
logger.error(f"HTTP error occurred while get kv from cloudflare {str(e)}")
raise e
except Exception as e:
logger.error(f"An unexpected error occurred: {str(e)}")
raise e
return response.json()
except httpx.RequestError as e:
logger.error(f"An error occurred while bulk removing keys from cloudflare: {e}")
raise e
except httpx.HTTPStatusError as e:
logger.error(f"HTTP error occurred while bulk removing keys from cloudflare: {e}")
raise e
except Exception as e:
logger.error(f"An unexpected error occurred while bulk removing keys: {e}")
raise e
def exists(self, key: str) -> bool:
"""
检查键是否存在
Args:
key: 要检查的键名
Returns:
如果键存在返回True否则返回False
"""
try:
with httpx.Client() as client:
response = client.get(
f"{self.base_url}/values/{key}",
headers=self.headers
)
return response.status_code == 200
except httpx.HTTPStatusError as e:
if e.response.status_code == 404:
return False
raise e
except Exception:
return False
def list_keys(self, prefix: str = None, limit: int = 1000, cursor: str = None):
"""
列出KV存储中的键
Args:
prefix: 键名前缀过滤
limit: 返回的最大键数量默认1000
cursor: 分页游标
Returns:
包含键列表和分页信息的字典
"""
try:
with httpx.Client() as client:
params = {"limit": limit}
if prefix:
params["prefix"] = prefix
if cursor:
params["cursor"] = cursor
response = client.get(
f"{self.base_url}/keys",
headers=self.headers,
params=params
)
response.raise_for_status()
return response.json()
except httpx.RequestError as e:
logger.error(f"An error occurred while listing keys from cloudflare: {e}")
raise e
except httpx.HTTPStatusError as e:
logger.error(f"HTTP error occurred while listing keys from cloudflare: {e}")
raise e
except Exception as e:
logger.error(f"An unexpected error occurred while listing keys: {e}")
raise e
def get_metadata(self, key: str):
"""
获取键的元数据
Args:
key: 键名
Returns:
键的元数据信息
"""
try:
with httpx.Client() as client:
response = client.get(
f"{self.base_url}/metadata/{key}",
headers=self.headers
)
if response.status_code == 404:
return None
response.raise_for_status()
return response.json()
except httpx.RequestError as e:
logger.error(f"An error occurred while getting metadata for key '{key}' from cloudflare: {e}")
raise e
except httpx.HTTPStatusError as e:
if e.response.status_code == 404:
return None
logger.error(f"HTTP error occurred while getting metadata for key '{key}' from cloudflare: {e}")
raise e
except Exception as e:
logger.error(f"An unexpected error occurred while getting metadata for key '{key}': {e}")
raise e
def clear_all(self, prefix: str = None):
"""
清空所有键危险操作
Args:
prefix: 如果提供只删除指定前缀的键
Returns:
操作结果
"""
try:
# 首先获取所有键
all_keys = []
cursor = None
while True:
result = self.list_keys(prefix=prefix, limit=1000, cursor=cursor)
keys_data = result.get("result", [])
if not keys_data:
break
# 提取键名
for key_info in keys_data:
if isinstance(key_info, dict):
all_keys.append(key_info.get("name"))
else:
all_keys.append(str(key_info))
# 检查是否有更多数据
result_info = result.get("result_info", {})
cursor = result_info.get("cursor")
if not cursor:
break
# 批量删除
if all_keys:
return self.removes(all_keys)
else:
return {"success": True, "message": "No keys to delete"}
except Exception as e:
logger.error(f"An error occurred while clearing keys: {e}")
raise e
kv = Kv()