redfox-python-sdk 0.5.1__tar.gz → 0.6.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/PKG-INFO +62 -5
  2. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/README.md +61 -4
  3. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/__init__.py +1 -1
  4. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/client.py +41 -11
  5. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/endpoints/ai_search.py +24 -24
  6. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/endpoints/autohome.py +8 -4
  7. redfox_python_sdk-0.6.0/redfox/endpoints/baijiahao.py +89 -0
  8. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/endpoints/bilibili.py +16 -12
  9. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/endpoints/dongchedi.py +8 -4
  10. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/endpoints/doubao_image.py +8 -6
  11. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/endpoints/doubao_video.py +4 -2
  12. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/endpoints/douyin.py +32 -15
  13. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/endpoints/gpt_image.py +4 -3
  14. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/endpoints/hotspot.py +6 -2
  15. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/endpoints/instagram.py +8 -5
  16. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/endpoints/kuaishou.py +12 -7
  17. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/endpoints/tiktok.py +8 -4
  18. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/endpoints/tools.py +24 -22
  19. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/endpoints/toutiao.py +10 -7
  20. redfox_python_sdk-0.6.0/redfox/endpoints/twitter.py +155 -0
  21. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/endpoints/wechat.py +32 -17
  22. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/endpoints/wechat_channels.py +14 -11
  23. redfox_python_sdk-0.6.0/redfox/endpoints/weibo.py +54 -0
  24. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/endpoints/xiaohongshu.py +31 -20
  25. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/endpoints/yiche.py +21 -8
  26. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/endpoints/youtube.py +20 -6
  27. redfox_python_sdk-0.6.0/redfox/endpoints/zhihu.py +45 -0
  28. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox_python_sdk.egg-info/PKG-INFO +62 -5
  29. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox_python_sdk.egg-info/SOURCES.txt +3 -0
  30. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/setup.py +1 -1
  31. redfox_python_sdk-0.5.1/redfox/endpoints/twitter.py +0 -84
  32. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/endpoints/__init__.py +0 -0
  33. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox/exceptions.py +0 -0
  34. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox_python_sdk.egg-info/dependency_links.txt +0 -0
  35. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox_python_sdk.egg-info/requires.txt +0 -0
  36. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/redfox_python_sdk.egg-info/top_level.txt +0 -0
  37. {redfox_python_sdk-0.5.1 → redfox_python_sdk-0.6.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: redfox-python-sdk
3
- Version: 0.5.1
3
+ Version: 0.6.0
4
4
  Summary: RedFox 红狐数据平台 Python SDK — 同步+异步双客户端,自动重试,零配置
5
5
  Home-page: https://redfox.hk
6
6
  Author: RedFox
@@ -36,7 +36,7 @@ Dynamic: summary
36
36
  </a>
37
37
  </p>
38
38
 
39
- [RedFoxHub](https://redfox.hk/?source=github) Python SDK,提供 [抖音](https://redfox.hk/apis/douyin/0OT1E306)、[小红书](https://redfox.hk/apis/xiaohongshu/4IVIDHEN)、[公众号](https://redfox.hk/apis/gongzhonghao/6C4A77XR)、[B站](https://redfox.hk/apis/bilibili/TIN1NMTZ)、[今日头条](https://redfox.hk/apis/jinritoutiao/28CFGF5I)、[TikTok](https://redfox.hk/apis/tool-tiktok/20070019)、快手、视频号、YouTube、X (Twitter)、Instagram、懂车帝、易车、汽车之家 14 大内容平台的数据采集接口,多平台热点榜单聚合接口,短视频去水印下载与素材上传工具,以及 GPT 图片生成、豆包图片/视频生成、AI 搜索(Kimi/豆包/Deepseek/元宝/千问/百度)AI 能力接口。
39
+ [RedFoxHub](https://redfox.hk/?source=github) Python SDK,提供 [抖音](https://redfox.hk/apis/douyin/0OT1E306)、[小红书](https://redfox.hk/apis/xiaohongshu/4IVIDHEN)、[公众号](https://redfox.hk/apis/gongzhonghao/6C4A77XR)、[B站](https://redfox.hk/apis/bilibili/TIN1NMTZ)、[今日头条](https://redfox.hk/apis/jinritoutiao/28CFGF5I)、[TikTok](https://redfox.hk/apis/tool-tiktok/20070019)、快手、视频号、YouTube、X (Twitter)、Instagram、微博、百家号、知乎、懂车帝、易车、汽车之家 17 大内容平台的数据采集接口,多平台热点榜单聚合接口,短视频去水印下载与素材上传工具,以及 GPT 图片生成、豆包图片/视频生成、AI 搜索(Kimi/豆包/Deepseek/元宝/千问/百度)AI 能力接口。
40
40
 
41
41
  ## 为什么选择 RedFoxHub
42
42
 
@@ -155,11 +155,14 @@ result = client.ai_search.kimi_result(task_id=task["taskId"])
155
155
  | 🎵 TikTok | `client.tiktok` | 4 | 用户搜索、视频搜索、作品详情、用户作品列表 |
156
156
  | 🎬 快手 | `client.kuaishou` | 6 | 作品搜索、作品详情、账号作品、账号搜索、视频提文案 |
157
157
  | 💚 视频号 | `client.wechat_channels` | 7 | 作品搜索、作品详情、账号作品、链接实时详情、账号搜索、链接提文案 |
158
- | ▶️ YouTube | `client.youtube` | 4 | 视频搜索、视频详情、视频评论、视频提文案(字幕提取) |
159
- | 🐦 X (Twitter) | `client.twitter` | 4 | 推文搜索、推文详情、用户信息、推文评论 |
158
+ | ▶️ YouTube | `client.youtube` | 5 | 视频搜索、视频详情、视频评论、视频提文案(字幕提取)、字幕详情 |
159
+ | 🐦 X (Twitter) | `client.twitter` | 7 | 推文搜索、推文详情、用户信息、推文评论、关注列表、用户发帖、热门账号榜 |
160
160
  | 📸 Instagram | `client.instagram` | 4 | 综合搜索、帖子详情、帖子评论、用户信息 |
161
+ | 🔵 微博 | `client.weibo` | 3 | 账号搜索、内容详情、用户详情 |
162
+ | 📰 百家号 | `client.baijiahao` | 5 | 账号搜索、作品搜索、视频详情、作品内容 html、账号信息 |
163
+ | 💡 知乎 | `client.zhihu` | 1 | 关键词搜索作品 |
161
164
  | 🚗 懂车帝 | `client.dongchedi` | 4 | 作品搜索、作品详情、用户作品、用户搜索 |
162
- | 🚙 易车 | `client.yiche` | 5 | 作品搜索、文章详情、视频详情、账号作品、账号搜索 |
165
+ | 🚙 易车 | `client.yiche` | 6 | 作品搜索、文章详情、文章详情V2、视频详情、账号作品、账号搜索 |
163
166
  | 🚘 汽车之家 | `client.autohome` | 4 | 作品搜索、文章详情、视频详情、账号作品 |
164
167
  | 🔥 热点榜单 | `client.hotspot` | 3 | 各平台热点榜、全网热搜查询、全网聚合热点 TOP10 |
165
168
  | 🖼️ GPT 图片 | `client.gpt_image` | 2 | 图片生成、结果查询 |
@@ -406,6 +409,9 @@ client.youtube.get_comments(video_id="sa8AzBK4dao", sort_by="top")
406
409
 
407
410
  # 视频提文案(提取字幕/口播文案)
408
411
  client.youtube.get_transcript(video_url="https://www.youtube.com/watch?v=sa8AzBK4dao")
412
+
413
+ # 获取视频字幕详情(视频信息 + 可用字幕语言列表)
414
+ client.youtube.get_info(video_url="https://www.youtube.com/watch?v=sa8AzBK4dao")
409
415
  ```
410
416
 
411
417
  ### X (Twitter)
@@ -422,6 +428,15 @@ client.twitter.get_user(screen_name="elonmusk")
422
428
 
423
429
  # 获取推文评论
424
430
  client.twitter.get_comments(tweet_id="1957000000000000000")
431
+
432
+ # 获取用户关注列表
433
+ client.twitter.get_following(screen_name="elonmusk")
434
+
435
+ # 获取用户发帖(screen_name / rest_id 至少传一个)
436
+ client.twitter.get_user_works(screen_name="elonmusk")
437
+
438
+ # X 热门账号榜(rank_date 必填,支持性别/行业筛选)
439
+ client.twitter.get_hot_account_rank(rank_date="2026-09-23", page_num=1, gender="all")
425
440
  ```
426
441
 
427
442
  ### Instagram
@@ -440,6 +455,45 @@ client.instagram.get_comments(code_or_url="DRhvwVLAHAG", sort_by="recent")
440
455
  client.instagram.get_user(username="natgeo")
441
456
  ```
442
457
 
458
+ ### 微博
459
+
460
+ ```python
461
+ # 搜索账号
462
+ client.weibo.search_users(keyword="汽水音乐", page=1)
463
+
464
+ # 获取微博内容详情
465
+ client.weibo.get_work(opus_id="5200000000000000")
466
+
467
+ # 获取用户详情
468
+ client.weibo.get_user(user_id="7799374443")
469
+ ```
470
+
471
+ ### 百家号
472
+
473
+ ```python
474
+ # 账号关键词搜索(第一页 page="0",下一页传返回数据中的 page 值)
475
+ client.baijiahao.search_users(keyword="头条", page="0")
476
+
477
+ # 关键词搜索作品(pn 翻页 +10,sort="1" 焦点排序 / "2" 时间排序)
478
+ client.baijiahao.search_works(keyword="新能源汽车", pn="0", sort="2")
479
+
480
+ # 获取视频详情
481
+ client.baijiahao.get_video(sv_id="1000000000000000000")
482
+
483
+ # 获取作品内容 html
484
+ client.baijiahao.get_article_html(article_id="1000000000000000000")
485
+
486
+ # 获取账号信息
487
+ client.baijiahao.get_user(uk="d0000000000000000")
488
+ ```
489
+
490
+ ### 知乎
491
+
492
+ ```python
493
+ # 关键词搜索作品(offset +20 翻页,支持排序/时间范围/类型筛选)
494
+ client.zhihu.search_works(keyword="人工智能", offset="0", sort="upvoted_count", vertical="answer")
495
+ ```
496
+
443
497
  ### 懂车帝
444
498
 
445
499
  ```python
@@ -465,6 +519,9 @@ client.yiche.search_works(keyword="小米SU7", page=1, source_type="xinwen")
465
519
  # 获取文章详情
466
520
  client.yiche.get_article(url="https://news.yiche.com/hao/wenzhang/xxx.html")
467
521
 
522
+ # 获取文章详情 V2
523
+ client.yiche.get_article_v2(url="https://news.yiche.com/hao/wenzhang/xxx.html")
524
+
468
525
  # 获取视频详情
469
526
  client.yiche.get_video(work_id="50000000")
470
527
 
@@ -12,7 +12,7 @@
12
12
  </a>
13
13
  </p>
14
14
 
15
- [RedFoxHub](https://redfox.hk/?source=github) Python SDK,提供 [抖音](https://redfox.hk/apis/douyin/0OT1E306)、[小红书](https://redfox.hk/apis/xiaohongshu/4IVIDHEN)、[公众号](https://redfox.hk/apis/gongzhonghao/6C4A77XR)、[B站](https://redfox.hk/apis/bilibili/TIN1NMTZ)、[今日头条](https://redfox.hk/apis/jinritoutiao/28CFGF5I)、[TikTok](https://redfox.hk/apis/tool-tiktok/20070019)、快手、视频号、YouTube、X (Twitter)、Instagram、懂车帝、易车、汽车之家 14 大内容平台的数据采集接口,多平台热点榜单聚合接口,短视频去水印下载与素材上传工具,以及 GPT 图片生成、豆包图片/视频生成、AI 搜索(Kimi/豆包/Deepseek/元宝/千问/百度)AI 能力接口。
15
+ [RedFoxHub](https://redfox.hk/?source=github) Python SDK,提供 [抖音](https://redfox.hk/apis/douyin/0OT1E306)、[小红书](https://redfox.hk/apis/xiaohongshu/4IVIDHEN)、[公众号](https://redfox.hk/apis/gongzhonghao/6C4A77XR)、[B站](https://redfox.hk/apis/bilibili/TIN1NMTZ)、[今日头条](https://redfox.hk/apis/jinritoutiao/28CFGF5I)、[TikTok](https://redfox.hk/apis/tool-tiktok/20070019)、快手、视频号、YouTube、X (Twitter)、Instagram、微博、百家号、知乎、懂车帝、易车、汽车之家 17 大内容平台的数据采集接口,多平台热点榜单聚合接口,短视频去水印下载与素材上传工具,以及 GPT 图片生成、豆包图片/视频生成、AI 搜索(Kimi/豆包/Deepseek/元宝/千问/百度)AI 能力接口。
16
16
 
17
17
  ## 为什么选择 RedFoxHub
18
18
 
@@ -131,11 +131,14 @@ result = client.ai_search.kimi_result(task_id=task["taskId"])
131
131
  | 🎵 TikTok | `client.tiktok` | 4 | 用户搜索、视频搜索、作品详情、用户作品列表 |
132
132
  | 🎬 快手 | `client.kuaishou` | 6 | 作品搜索、作品详情、账号作品、账号搜索、视频提文案 |
133
133
  | 💚 视频号 | `client.wechat_channels` | 7 | 作品搜索、作品详情、账号作品、链接实时详情、账号搜索、链接提文案 |
134
- | ▶️ YouTube | `client.youtube` | 4 | 视频搜索、视频详情、视频评论、视频提文案(字幕提取) |
135
- | 🐦 X (Twitter) | `client.twitter` | 4 | 推文搜索、推文详情、用户信息、推文评论 |
134
+ | ▶️ YouTube | `client.youtube` | 5 | 视频搜索、视频详情、视频评论、视频提文案(字幕提取)、字幕详情 |
135
+ | 🐦 X (Twitter) | `client.twitter` | 7 | 推文搜索、推文详情、用户信息、推文评论、关注列表、用户发帖、热门账号榜 |
136
136
  | 📸 Instagram | `client.instagram` | 4 | 综合搜索、帖子详情、帖子评论、用户信息 |
137
+ | 🔵 微博 | `client.weibo` | 3 | 账号搜索、内容详情、用户详情 |
138
+ | 📰 百家号 | `client.baijiahao` | 5 | 账号搜索、作品搜索、视频详情、作品内容 html、账号信息 |
139
+ | 💡 知乎 | `client.zhihu` | 1 | 关键词搜索作品 |
137
140
  | 🚗 懂车帝 | `client.dongchedi` | 4 | 作品搜索、作品详情、用户作品、用户搜索 |
138
- | 🚙 易车 | `client.yiche` | 5 | 作品搜索、文章详情、视频详情、账号作品、账号搜索 |
141
+ | 🚙 易车 | `client.yiche` | 6 | 作品搜索、文章详情、文章详情V2、视频详情、账号作品、账号搜索 |
139
142
  | 🚘 汽车之家 | `client.autohome` | 4 | 作品搜索、文章详情、视频详情、账号作品 |
140
143
  | 🔥 热点榜单 | `client.hotspot` | 3 | 各平台热点榜、全网热搜查询、全网聚合热点 TOP10 |
141
144
  | 🖼️ GPT 图片 | `client.gpt_image` | 2 | 图片生成、结果查询 |
@@ -382,6 +385,9 @@ client.youtube.get_comments(video_id="sa8AzBK4dao", sort_by="top")
382
385
 
383
386
  # 视频提文案(提取字幕/口播文案)
384
387
  client.youtube.get_transcript(video_url="https://www.youtube.com/watch?v=sa8AzBK4dao")
388
+
389
+ # 获取视频字幕详情(视频信息 + 可用字幕语言列表)
390
+ client.youtube.get_info(video_url="https://www.youtube.com/watch?v=sa8AzBK4dao")
385
391
  ```
386
392
 
387
393
  ### X (Twitter)
@@ -398,6 +404,15 @@ client.twitter.get_user(screen_name="elonmusk")
398
404
 
399
405
  # 获取推文评论
400
406
  client.twitter.get_comments(tweet_id="1957000000000000000")
407
+
408
+ # 获取用户关注列表
409
+ client.twitter.get_following(screen_name="elonmusk")
410
+
411
+ # 获取用户发帖(screen_name / rest_id 至少传一个)
412
+ client.twitter.get_user_works(screen_name="elonmusk")
413
+
414
+ # X 热门账号榜(rank_date 必填,支持性别/行业筛选)
415
+ client.twitter.get_hot_account_rank(rank_date="2026-09-23", page_num=1, gender="all")
401
416
  ```
402
417
 
403
418
  ### Instagram
@@ -416,6 +431,45 @@ client.instagram.get_comments(code_or_url="DRhvwVLAHAG", sort_by="recent")
416
431
  client.instagram.get_user(username="natgeo")
417
432
  ```
418
433
 
434
+ ### 微博
435
+
436
+ ```python
437
+ # 搜索账号
438
+ client.weibo.search_users(keyword="汽水音乐", page=1)
439
+
440
+ # 获取微博内容详情
441
+ client.weibo.get_work(opus_id="5200000000000000")
442
+
443
+ # 获取用户详情
444
+ client.weibo.get_user(user_id="7799374443")
445
+ ```
446
+
447
+ ### 百家号
448
+
449
+ ```python
450
+ # 账号关键词搜索(第一页 page="0",下一页传返回数据中的 page 值)
451
+ client.baijiahao.search_users(keyword="头条", page="0")
452
+
453
+ # 关键词搜索作品(pn 翻页 +10,sort="1" 焦点排序 / "2" 时间排序)
454
+ client.baijiahao.search_works(keyword="新能源汽车", pn="0", sort="2")
455
+
456
+ # 获取视频详情
457
+ client.baijiahao.get_video(sv_id="1000000000000000000")
458
+
459
+ # 获取作品内容 html
460
+ client.baijiahao.get_article_html(article_id="1000000000000000000")
461
+
462
+ # 获取账号信息
463
+ client.baijiahao.get_user(uk="d0000000000000000")
464
+ ```
465
+
466
+ ### 知乎
467
+
468
+ ```python
469
+ # 关键词搜索作品(offset +20 翻页,支持排序/时间范围/类型筛选)
470
+ client.zhihu.search_works(keyword="人工智能", offset="0", sort="upvoted_count", vertical="answer")
471
+ ```
472
+
419
473
  ### 懂车帝
420
474
 
421
475
  ```python
@@ -441,6 +495,9 @@ client.yiche.search_works(keyword="小米SU7", page=1, source_type="xinwen")
441
495
  # 获取文章详情
442
496
  client.yiche.get_article(url="https://news.yiche.com/hao/wenzhang/xxx.html")
443
497
 
498
+ # 获取文章详情 V2
499
+ client.yiche.get_article_v2(url="https://news.yiche.com/hao/wenzhang/xxx.html")
500
+
444
501
  # 获取视频详情
445
502
  client.yiche.get_video(work_id="50000000")
446
503
 
@@ -3,7 +3,7 @@
3
3
  from .client import RedFoxClient, AsyncRedFoxClient
4
4
  from .exceptions import RedFoxAPIError, RedFoxAuthError, RedFoxRateLimitError
5
5
 
6
- __version__ = "0.5.1"
6
+ __version__ = "0.6.0"
7
7
  __all__ = [
8
8
  "RedFoxClient",
9
9
  "AsyncRedFoxClient",
@@ -31,6 +31,9 @@ from .endpoints.doubao_image import DoubaoImageAPI
31
31
  from .endpoints.doubao_video import DoubaoVideoAPI
32
32
  from .endpoints.ai_search import AISearchAPI
33
33
  from .endpoints.tools import ToolsAPI
34
+ from .endpoints.weibo import WeiboAPI
35
+ from .endpoints.baijiahao import BaijiahaoAPI
36
+ from .endpoints.zhihu import ZhihuAPI
34
37
 
35
38
  logger = logging.getLogger("redfox")
36
39
 
@@ -67,13 +70,22 @@ class _RequestMixin:
67
70
  self, method: str, path: str,
68
71
  params: Optional[Dict[str, Any]] = None,
69
72
  data: Optional[Dict[str, Any]] = None,
73
+ source: Optional[str] = None,
70
74
  ) -> tuple:
71
- """准备请求 URL 和清洗后的参数"""
75
+ """准备请求 URL 和清洗后的参数
76
+
77
+ source 为调用来源标识:GET 请求放入 query,其余放入请求体 body。
78
+ """
72
79
  url = f"{self.base_url}{path}"
73
80
  if data:
74
81
  data = {k: v for k, v in data.items() if v is not None}
75
82
  if params:
76
83
  params = {k: v for k, v in params.items() if v is not None}
84
+ if source is not None:
85
+ if method.upper() == "GET":
86
+ params = {**(params or {}), "source": source}
87
+ else:
88
+ data = {**(data or {}), "source": source}
77
89
  return url, params, data
78
90
 
79
91
  def _handle_response(self, response) -> dict:
@@ -224,6 +236,9 @@ class RedFoxClient(_RequestMixin):
224
236
  self.doubao_video = DoubaoVideoAPI(self)
225
237
  self.ai_search = AISearchAPI(self)
226
238
  self.tools = ToolsAPI(self)
239
+ self.weibo = WeiboAPI(self)
240
+ self.baijiahao = BaijiahaoAPI(self)
241
+ self.zhihu = ZhihuAPI(self)
227
242
 
228
243
  def request(
229
244
  self,
@@ -231,6 +246,7 @@ class RedFoxClient(_RequestMixin):
231
246
  path: str,
232
247
  params: Optional[Dict[str, Any]] = None,
233
248
  data: Optional[Dict[str, Any]] = None,
249
+ source: Optional[str] = None,
234
250
  ) -> dict:
235
251
  """
236
252
  发送 API 请求(含自动重试 + 指数退避)
@@ -242,7 +258,7 @@ class RedFoxClient(_RequestMixin):
242
258
  :return: API 响应 data 字段内容
243
259
  :raises RedFoxAPIError: 重试耗尽后仍失败时抛出
244
260
  """
245
- url, params, data = self._prepare_request(method, path, params, data)
261
+ url, params, data = self._prepare_request(method, path, params, data, source)
246
262
  last_exception = None
247
263
 
248
264
  for attempt in range(self.max_retries + 1):
@@ -285,13 +301,15 @@ class RedFoxClient(_RequestMixin):
285
301
  # 重试耗尽
286
302
  raise self._map_exception(last_exception) if last_exception else RedFoxAPIError("请求失败")
287
303
 
288
- def post(self, path: str, data: Optional[Dict[str, Any]] = None) -> dict:
304
+ def post(self, path: str, data: Optional[Dict[str, Any]] = None,
305
+ source: Optional[str] = None) -> dict:
289
306
  """发送 POST 请求"""
290
- return self.request("POST", path, data=data)
307
+ return self.request("POST", path, data=data, source=source)
291
308
 
292
- def get(self, path: str, params: Optional[Dict[str, Any]] = None) -> dict:
309
+ def get(self, path: str, params: Optional[Dict[str, Any]] = None,
310
+ source: Optional[str] = None) -> dict:
293
311
  """发送 GET 请求"""
294
- return self.request("GET", path, params=params)
312
+ return self.request("GET", path, params=params, source=source)
295
313
 
296
314
  def upload(
297
315
  self,
@@ -299,6 +317,7 @@ class RedFoxClient(_RequestMixin):
299
317
  file,
300
318
  data: Optional[Dict[str, Any]] = None,
301
319
  field_name: str = "file",
320
+ source: Optional[str] = None,
302
321
  ) -> dict:
303
322
  """
304
323
  上传文件(multipart/form-data,含自动重试)
@@ -313,6 +332,8 @@ class RedFoxClient(_RequestMixin):
313
332
  filename, content = self._read_file(file, field_name)
314
333
  if data:
315
334
  data = {k: v for k, v in data.items() if v is not None}
335
+ if source is not None:
336
+ data = {**(data or {}), "source": source}
316
337
  last_exception = None
317
338
 
318
339
  for attempt in range(self.max_retries + 1):
@@ -438,6 +459,9 @@ class AsyncRedFoxClient(_RequestMixin):
438
459
  self.doubao_video = DoubaoVideoAPI(self)
439
460
  self.ai_search = AISearchAPI(self)
440
461
  self.tools = ToolsAPI(self)
462
+ self.weibo = WeiboAPI(self)
463
+ self.baijiahao = BaijiahaoAPI(self)
464
+ self.zhihu = ZhihuAPI(self)
441
465
 
442
466
  async def request(
443
467
  self,
@@ -445,6 +469,7 @@ class AsyncRedFoxClient(_RequestMixin):
445
469
  path: str,
446
470
  params: Optional[Dict[str, Any]] = None,
447
471
  data: Optional[Dict[str, Any]] = None,
472
+ source: Optional[str] = None,
448
473
  ) -> dict:
449
474
  """
450
475
  异步发送 API 请求(含自动重试 + 指数退避)
@@ -455,7 +480,7 @@ class AsyncRedFoxClient(_RequestMixin):
455
480
  :param data: 请求体 JSON 数据
456
481
  :return: API 响应 data 字段内容
457
482
  """
458
- url, params, data = self._prepare_request(method, path, params, data)
483
+ url, params, data = self._prepare_request(method, path, params, data, source)
459
484
  last_exception = None
460
485
 
461
486
  for attempt in range(self.max_retries + 1):
@@ -495,13 +520,15 @@ class AsyncRedFoxClient(_RequestMixin):
495
520
 
496
521
  raise self._map_exception(last_exception) if last_exception else RedFoxAPIError("请求失败")
497
522
 
498
- async def post(self, path: str, data: Optional[Dict[str, Any]] = None) -> dict:
523
+ async def post(self, path: str, data: Optional[Dict[str, Any]] = None,
524
+ source: Optional[str] = None) -> dict:
499
525
  """异步发送 POST 请求"""
500
- return await self.request("POST", path, data=data)
526
+ return await self.request("POST", path, data=data, source=source)
501
527
 
502
- async def get(self, path: str, params: Optional[Dict[str, Any]] = None) -> dict:
528
+ async def get(self, path: str, params: Optional[Dict[str, Any]] = None,
529
+ source: Optional[str] = None) -> dict:
503
530
  """异步发送 GET 请求"""
504
- return await self.request("GET", path, params=params)
531
+ return await self.request("GET", path, params=params, source=source)
505
532
 
506
533
  async def upload(
507
534
  self,
@@ -509,6 +536,7 @@ class AsyncRedFoxClient(_RequestMixin):
509
536
  file,
510
537
  data: Optional[Dict[str, Any]] = None,
511
538
  field_name: str = "file",
539
+ source: Optional[str] = None,
512
540
  ) -> dict:
513
541
  """
514
542
  异步上传文件(multipart/form-data,含自动重试)
@@ -523,6 +551,8 @@ class AsyncRedFoxClient(_RequestMixin):
523
551
  filename, content = self._read_file(file, field_name)
524
552
  if data:
525
553
  data = {k: v for k, v in data.items() if v is not None}
554
+ if source is not None:
555
+ data = {**(data or {}), "source": source}
526
556
  last_exception = None
527
557
 
528
558
  for attempt in range(self.max_retries + 1):
@@ -16,7 +16,7 @@ class AISearchAPI:
16
16
 
17
17
  # ─── Kimi ───────────────────────────────────────────────
18
18
 
19
- def kimi_submit(self, inquiry_text: str) -> dict:
19
+ def kimi_submit(self, inquiry_text: str, source: str = "Kimi 联网 AI 搜索-SDK") -> dict:
20
20
  """
21
21
  Kimi 纯文字搜索 - 提交任务
22
22
 
@@ -24,10 +24,10 @@ class AISearchAPI:
24
24
  :return: 包含 taskId 的字典
25
25
  """
26
26
  return self._client.post(
27
- "/story/api/kimi/submit", data={"inquiryText": inquiry_text}
27
+ "/story/api/kimi/submit", data={"inquiryText": inquiry_text}, source=source
28
28
  )
29
29
 
30
- def kimi_result(self, task_id: str) -> dict:
30
+ def kimi_result(self, task_id: str, source: str = "查询 Kimi 搜索任务结果-SDK") -> dict:
31
31
  """
32
32
  Kimi 纯文字搜索 - 查询任务结果
33
33
 
@@ -35,12 +35,12 @@ class AISearchAPI:
35
35
  :return: 任务结果字典,包含 completed/content/webPages
36
36
  """
37
37
  return self._client.post(
38
- "/story/api/kimi/result", data={"taskId": task_id}
38
+ "/story/api/kimi/result", data={"taskId": task_id}, source=source
39
39
  )
40
40
 
41
41
  # ─── 豆包 ───────────────────────────────────────────────
42
42
 
43
- def doubao_submit(self, inquiry_text: str) -> dict:
43
+ def doubao_submit(self, inquiry_text: str, source: str = "豆包联网 AI 搜索-SDK") -> dict:
44
44
  """
45
45
  豆包纯文字搜索 - 提交任务
46
46
 
@@ -48,10 +48,10 @@ class AISearchAPI:
48
48
  :return: 包含 taskId 的字典
49
49
  """
50
50
  return self._client.post(
51
- "/story/api/deepSearch/dbSubmit", data={"inquiryText": inquiry_text}
51
+ "/story/api/deepSearch/dbSubmit", data={"inquiryText": inquiry_text}, source=source
52
52
  )
53
53
 
54
- def doubao_result(self, task_id: str) -> dict:
54
+ def doubao_result(self, task_id: str, source: str = "查询豆包搜索任务结果-SDK") -> dict:
55
55
  """
56
56
  豆包纯文字搜索 - 查询任务结果
57
57
 
@@ -59,12 +59,12 @@ class AISearchAPI:
59
59
  :return: 任务结果字典
60
60
  """
61
61
  return self._client.post(
62
- "/story/api/deepSearch/dbResult", data={"taskId": task_id}
62
+ "/story/api/deepSearch/dbResult", data={"taskId": task_id}, source=source
63
63
  )
64
64
 
65
65
  # ─── Deepseek ───────────────────────────────────────────
66
66
 
67
- def deepseek_submit(self, inquiry_text: str) -> dict:
67
+ def deepseek_submit(self, inquiry_text: str, source: str = "Deepseek 联网 AI 搜索-SDK") -> dict:
68
68
  """
69
69
  Deepseek 纯文字搜索 - 提交任务
70
70
 
@@ -72,10 +72,10 @@ class AISearchAPI:
72
72
  :return: 包含 taskId 的字典
73
73
  """
74
74
  return self._client.post(
75
- "/story/api/deepSearch/dsSubmit", data={"inquiryText": inquiry_text}
75
+ "/story/api/deepSearch/dsSubmit", data={"inquiryText": inquiry_text}, source=source
76
76
  )
77
77
 
78
- def deepseek_result(self, task_id: str) -> dict:
78
+ def deepseek_result(self, task_id: str, source: str = "查询 Deepseek 搜索任务结果-SDK") -> dict:
79
79
  """
80
80
  Deepseek 纯文字搜索 - 查询任务结果
81
81
 
@@ -83,12 +83,12 @@ class AISearchAPI:
83
83
  :return: 任务结果字典
84
84
  """
85
85
  return self._client.post(
86
- "/story/api/deepSearch/dsResult", data={"taskId": task_id}
86
+ "/story/api/deepSearch/dsResult", data={"taskId": task_id}, source=source
87
87
  )
88
88
 
89
89
  # ─── 元宝 ───────────────────────────────────────────────
90
90
 
91
- def yuanbao_submit(self, inquiry_text: str) -> dict:
91
+ def yuanbao_submit(self, inquiry_text: str, source: str = "元宝联网 AI 搜索-SDK") -> dict:
92
92
  """
93
93
  元宝纯文字搜索 - 提交任务
94
94
 
@@ -96,10 +96,10 @@ class AISearchAPI:
96
96
  :return: 包含 taskId 的字典
97
97
  """
98
98
  return self._client.post(
99
- "/story/api/deepSearch/ybSubmit", data={"inquiryText": inquiry_text}
99
+ "/story/api/deepSearch/ybSubmit", data={"inquiryText": inquiry_text}, source=source
100
100
  )
101
101
 
102
- def yuanbao_result(self, task_id: str) -> dict:
102
+ def yuanbao_result(self, task_id: str, source: str = "查询元宝搜索任务结果-SDK") -> dict:
103
103
  """
104
104
  元宝纯文字搜索 - 查询任务结果
105
105
 
@@ -107,12 +107,12 @@ class AISearchAPI:
107
107
  :return: 任务结果字典
108
108
  """
109
109
  return self._client.post(
110
- "/story/api/deepSearch/ybResult", data={"taskId": task_id}
110
+ "/story/api/deepSearch/ybResult", data={"taskId": task_id}, source=source
111
111
  )
112
112
 
113
113
  # ─── 千问 ───────────────────────────────────────────────
114
114
 
115
- def qianwen_submit(self, inquiry_text: str) -> dict:
115
+ def qianwen_submit(self, inquiry_text: str, source: str = "千问联网 AI 搜索-SDK") -> dict:
116
116
  """
117
117
  千问纯文字搜索 - 提交任务
118
118
 
@@ -120,10 +120,10 @@ class AISearchAPI:
120
120
  :return: 包含 taskId 的字典
121
121
  """
122
122
  return self._client.post(
123
- "/story/api/deepSearch/qwSubmit", data={"inquiryText": inquiry_text}
123
+ "/story/api/deepSearch/qwSubmit", data={"inquiryText": inquiry_text}, source=source
124
124
  )
125
125
 
126
- def qianwen_result(self, task_id: str) -> dict:
126
+ def qianwen_result(self, task_id: str, source: str = "查询千问搜索任务结果-SDK") -> dict:
127
127
  """
128
128
  千问纯文字搜索 - 查询任务结果
129
129
 
@@ -131,12 +131,12 @@ class AISearchAPI:
131
131
  :return: 任务结果字典
132
132
  """
133
133
  return self._client.post(
134
- "/story/api/deepSearch/qwResult", data={"taskId": task_id}
134
+ "/story/api/deepSearch/qwResult", data={"taskId": task_id}, source=source
135
135
  )
136
136
 
137
137
  # ─── 百度 ───────────────────────────────────────────────
138
138
 
139
- def baidu_submit(self, inquiry_text: str) -> dict:
139
+ def baidu_submit(self, inquiry_text: str, source: str = "百度联网 AI 搜索-SDK") -> dict:
140
140
  """
141
141
  百度纯文字搜索 - 提交任务
142
142
 
@@ -144,10 +144,10 @@ class AISearchAPI:
144
144
  :return: 包含 taskId 的字典
145
145
  """
146
146
  return self._client.post(
147
- "/story/api/deepSearch/bdSubmit", data={"inquiryText": inquiry_text}
147
+ "/story/api/deepSearch/bdSubmit", data={"inquiryText": inquiry_text}, source=source
148
148
  )
149
149
 
150
- def baidu_result(self, task_id: str) -> dict:
150
+ def baidu_result(self, task_id: str, source: str = "查询百度搜索任务结果-SDK") -> dict:
151
151
  """
152
152
  百度纯文字搜索 - 查询任务结果
153
153
 
@@ -155,5 +155,5 @@ class AISearchAPI:
155
155
  :return: 任务结果字典
156
156
  """
157
157
  return self._client.post(
158
- "/story/api/deepSearch/bdResult", data={"taskId": task_id}
158
+ "/story/api/deepSearch/bdResult", data={"taskId": task_id}, source=source
159
159
  )
@@ -19,6 +19,7 @@ class AutohomeAPI:
19
19
  offset: str = "0",
20
20
  page: str = "1",
21
21
  source_type: str = "video",
22
+ source: str = "汽车之家关键词搜索作品-SDK",
22
23
  ) -> dict:
23
24
  """
24
25
  汽车之家关键词搜索作品
@@ -35,9 +36,9 @@ class AutohomeAPI:
35
36
  "page": str(page),
36
37
  "sourceType": source_type,
37
38
  }
38
- return self._client.post("/story/api/autohome/searchWork", data=data)
39
+ return self._client.post("/story/api/autohome/searchWork", data=data, source=source)
39
40
 
40
- def get_article(self, work_id: str, page: int = 0) -> dict:
41
+ def get_article(self, work_id: str, page: int = 0, source: str = "获取汽车之家文章详情-SDK") -> dict:
41
42
  """
42
43
  汽车之家文章详情(车家号)
43
44
 
@@ -48,9 +49,10 @@ class AutohomeAPI:
48
49
  return self._client.post(
49
50
  "/story/api/autohome/articleDetail",
50
51
  data={"workId": work_id, "page": page},
52
+ source=source,
51
53
  )
52
54
 
53
- def get_video(self, video_id: str, video_type: int) -> dict:
55
+ def get_video(self, video_id: str, video_type: int, source: str = "获取汽车之家视频详情-SDK") -> dict:
54
56
  """
55
57
  汽车之家视频详情(原创账号+车家号)
56
58
 
@@ -61,9 +63,10 @@ class AutohomeAPI:
61
63
  return self._client.post(
62
64
  "/story/api/autohome/videoDetail",
63
65
  data={"videoId": video_id, "videoType": video_type},
66
+ source=source,
64
67
  )
65
68
 
66
- def get_user_works(self, author_id: str, page: int = 0) -> dict:
69
+ def get_user_works(self, author_id: str, page: int = 0, source: str = "获取汽车之家作者作品列表-SDK") -> dict:
67
70
  """
68
71
  汽车之家作品列表(原创账号)
69
72
 
@@ -74,4 +77,5 @@ class AutohomeAPI:
74
77
  return self._client.post(
75
78
  "/story/api/autohome/workList",
76
79
  data={"authorId": author_id, "page": page},
80
+ source=source,
77
81
  )