access_token.py 3.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import os
  2. import sys
  3. sys.path.append(os.path.dirname(os.path.dirname(__file__)))
  4. import httpx
  5. from typing import Optional
  6. from pydantic import BaseModel
  7. from db.user import UserOAuthToken,UserOAuthRepository
  8. from config import *
  9. class DouyinAccessTokenResponse(BaseModel):
  10. error_code: int
  11. data: dict
  12. message: str
  13. async def check_access_token_response(response_json: dict):
  14. model_data = DouyinAccessTokenResponse(**response_json)
  15. if model_data.error_code != 0:
  16. raise Exception(f"获取 access token 失败,错误码:{model_data.error_code}")
  17. return model_data.data
  18. '''
  19. response success:
  20. {
  21. "data": {
  22. "access_token": "act.f7094fbffab2ecbfc45e9af9c32bc241oYdckvBKe82BPx8T******",
  23. "captcha": "",
  24. "desc_url": "",
  25. "description": "",
  26. "error_code": 0,
  27. "expires_in": 1296000,
  28. "log_id": "20230525105733ED3ED7AC56A******",
  29. "open_id": "b9b71865-7fea-44cc-******",
  30. "refresh_expires_in": 2592000,
  31. "refresh_token": "rft.713900b74edde9f30ec4e246b706da30t******",
  32. "scope": "user_info"
  33. },
  34. "message": "success"
  35. }
  36. response error:
  37. {
  38. "data": {
  39. "description": "Parameter error",
  40. "error_code": 2100005
  41. },
  42. "extra": {
  43. "logid": "2020070614111601022506808001045D59",
  44. "now": 1594015876138
  45. }
  46. }
  47. '''
  48. async def get_access_token(code):
  49. # if not PRODUCE_ENV:
  50. # # 测试环境使用。因为每次 get_access_token 的 code 只能使用一次就过期了,为了避免频繁扫码,直接模拟返回请求结果
  51. # return {'access_token': 'act.3.UCzqnMwbL7uUTH0PkWbvDvIHcpy417HnfMqymbvBSpo9b1MJ3jOdwCxw-UPstOOjsGDWIdNwTGev4oEp8eUR-vHbU24XU5K4BkhPeOKJW1CLrEUS3XFxpG6SHqoQtvL6qhEgINcvt4V3KQX6C2qTeTkgQ-KwPO6jWi5uoin3YXo5DqwuGk3bbQ9dZoY=', 'captcha': '', 'desc_url': '', 'description': '', 'error_code': 0, 'expires_in': 1296000, 'log_id': '2024012915260549B5ED1A675515CD573C', 'open_id': '_000QadFMhmU1jNCI3JdPnyVDL6XavC70dFy', 'refresh_expires_in': 2592000, 'refresh_token': 'rft.c29d64456ea3d5e4c932247ee93dd735aq5OhtcYNXNFAD70XHKrdntpE6U0', 'scope': 'user_info,trial.whitelist'}
  52. client_key = os.environ.get("CLIENT_KEY") # 从环境变量中获取 client_key
  53. client_secret = os.environ.get("CLIENT_SECRET") # 从环境变量中获取 client_secret
  54. async with httpx.AsyncClient() as client:
  55. response = await client.post(
  56. "https://open.douyin.com/oauth/access_token/",
  57. headers={"Content-Type": "application/json"},
  58. json={
  59. "grant_type": "authorization_code",
  60. "client_key": client_key,
  61. "client_secret": client_secret,
  62. "code": code,
  63. },
  64. )
  65. res_json = response.json()
  66. logger.debug(res_json.get("data"))
  67. return res_json.get("data")
  68. # 单元测试
  69. def main():
  70. # 访问: https://swl-8l9.pages.dev/ 点击立即体验
  71. # 浏览器打开调试模式F12,扫码登录
  72. # 在浏览器调试窗口 - 网络 - 名称 - 第一条 /verify?code=936c3671e073703c25Ze7zlgwxcOjvsYJ6Iz&state=&scope - 获得 code
  73. import asyncio
  74. res = asyncio.run(get_access_token("936c3671e073703c25Ze7zlgwxcOjvsYJ6Iz"))
  75. print("res:",res)
  76. '''
  77. {'access_token': 'act.3.wl8L3DFQ3sj3uKYzQShOSs8HbOgKh0FVvjxKeaTum0ZOEXoyBI8D1N7gTBqGbrY32KP-Pm41EAvcobSheOBi8tvRdhj7m5-5ZVoprZZu_GN5J2KnH2fZ_X9_l7Q6iFyvpPoMkX3Zyom3PCkeRZp4Jg9sE2ZiwuvZVdnvft0A25uBWXvj2IEbWW_0Bf8=', 'captcha': '', 'desc_url': '', 'description': '', 'error_code': 0, 'expires_in': 1296000, 'log_id': '20240129123749239735B0529965BC6D93', 'open_id': '_000QadFMhmU1jNCI3JdPnyVDL6XavC70dFy', 'refresh_expires_in': 2592000, 'refresh_token': 'rft.c29d64456ea3d5e4c932247ee93dd735aq5OhtcYNXNFAD70XHKrdntpE6U0', 'scope': 'user_info,trial.whitelist'}
  78. '''
  79. if __name__ == "__main__":
  80. main()