justoneapi 3.0.81__tar.gz → 3.0.83__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 (69) hide show
  1. {justoneapi-3.0.81/justoneapi.egg-info → justoneapi-3.0.83}/PKG-INFO +2 -1
  2. {justoneapi-3.0.81 → justoneapi-3.0.83}/README.md +1 -0
  3. justoneapi-3.0.83/justoneapi/_version.py +1 -0
  4. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/__init__.py +0 -6
  5. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/xiaohongshu.py +23 -0
  6. {justoneapi-3.0.81 → justoneapi-3.0.83/justoneapi.egg-info}/PKG-INFO +2 -1
  7. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi.egg-info/SOURCES.txt +0 -2
  8. {justoneapi-3.0.81 → justoneapi-3.0.83}/tests/test_codegen.py +111 -0
  9. justoneapi-3.0.81/justoneapi/_version.py +0 -1
  10. justoneapi-3.0.81/justoneapi/generated/resources/pixabay.py +0 -39
  11. justoneapi-3.0.81/justoneapi/generated/resources/vcg.py +0 -48
  12. {justoneapi-3.0.81 → justoneapi-3.0.83}/LICENSE +0 -0
  13. {justoneapi-3.0.81 → justoneapi-3.0.83}/MANIFEST.in +0 -0
  14. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/__init__.py +0 -0
  15. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/_exceptions.py +0 -0
  16. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/_resource.py +0 -0
  17. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/_response.py +0 -0
  18. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/_transport.py +0 -0
  19. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/client.py +0 -0
  20. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/config.py +0 -0
  21. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/__init__.py +0 -0
  22. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/models.py +0 -0
  23. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/aliexpress.py +0 -0
  24. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/amazon.py +0 -0
  25. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/beike.py +0 -0
  26. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/bilibili.py +0 -0
  27. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/dewu.py +0 -0
  28. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/douban.py +0 -0
  29. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/douyin.py +0 -0
  30. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/douyin_ec.py +0 -0
  31. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/douyin_xingtu.py +0 -0
  32. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/facebook.py +0 -0
  33. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/field_1688.py +0 -0
  34. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/imdb.py +0 -0
  35. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/instagram.py +0 -0
  36. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/jd.py +0 -0
  37. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/kuaishou.py +0 -0
  38. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/linkedin.py +0 -0
  39. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/llm.py +0 -0
  40. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/qq_huxuan.py +0 -0
  41. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/reddit.py +0 -0
  42. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/search.py +0 -0
  43. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/shopee.py +0 -0
  44. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/taobao.py +0 -0
  45. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/temu.py +0 -0
  46. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/tiktok.py +0 -0
  47. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/tiktok_shop.py +0 -0
  48. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/toutiao.py +0 -0
  49. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/twitter.py +0 -0
  50. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/weibo.py +0 -0
  51. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/weixin.py +0 -0
  52. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/weixin_channels.py +0 -0
  53. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/xianyu.py +0 -0
  54. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/xiaohongshu_ec.py +0 -0
  55. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/xiaohongshu_pgy.py +0 -0
  56. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/youku.py +0 -0
  57. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/youtube.py +0 -0
  58. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/zcool.py +0 -0
  59. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/generated/resources/zhihu.py +0 -0
  60. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi/log.py +0 -0
  61. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi.egg-info/dependency_links.txt +0 -0
  62. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi.egg-info/requires.txt +0 -0
  63. {justoneapi-3.0.81 → justoneapi-3.0.83}/justoneapi.egg-info/top_level.txt +0 -0
  64. {justoneapi-3.0.81 → justoneapi-3.0.83}/pyproject.toml +0 -0
  65. {justoneapi-3.0.81 → justoneapi-3.0.83}/setup.cfg +0 -0
  66. {justoneapi-3.0.81 → justoneapi-3.0.83}/tests/test_bump_version.py +0 -0
  67. {justoneapi-3.0.81 → justoneapi-3.0.83}/tests/test_generated_surface.py +0 -0
  68. {justoneapi-3.0.81 → justoneapi-3.0.83}/tests/test_integration_smoke.py +0 -0
  69. {justoneapi-3.0.81 → justoneapi-3.0.83}/tests/test_runtime.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: justoneapi
3
- Version: 3.0.81
3
+ Version: 3.0.83
4
4
  Summary: OpenAPI-driven Python SDK for Just One API
5
5
  Author-email: Just One API <support@justoneapi.com>
6
6
  Requires-Python: >=3.10
@@ -175,6 +175,7 @@ except BusinessError as exc:
175
175
  - [用户发布笔记 (V2)](https://docs.justoneapi.com/zh/api/xiaohongshu-rednote/user-published-notes-v2?utm_source=github.com&utm_medium=referral&utm_campaign=justoneapi_justoneapi_python&utm_content=repo_readme_api_list) <!-- api-operation:GET /api/xiaohongshu/get-user-note-list/v2 -->
176
176
  - [用户发布笔记 (V3)](https://docs.justoneapi.com/zh/api/xiaohongshu-rednote/user-published-notes-v3?utm_source=github.com&utm_medium=referral&utm_campaign=justoneapi_justoneapi_python&utm_content=repo_readme_api_list) <!-- api-operation:GET /api/xiaohongshu/get-user-note-list/v3 -->
177
177
  - [用户笔记 (V4)](https://docs.justoneapi.com/zh/api/xiaohongshu-rednote/user-notes-v4?utm_source=github.com&utm_medium=referral&utm_campaign=justoneapi_justoneapi_python&utm_content=repo_readme_api_list) <!-- api-operation:GET /api/xiaohongshu/get-user-note-list/v4 --> <sub>[JSON](https://github.com/justoneapi-official/justoneapi-python/blob/main/docs/api-examples/getApiXiaohongshuGetUserNoteListV4.json)</sub>
178
+ - [用户收藏的笔记 (V1)](https://docs.justoneapi.com/zh/api/xiaohongshu-rednote/user-favorited-notes-v1?utm_source=github.com&utm_medium=referral&utm_campaign=justoneapi_justoneapi_python&utm_content=repo_readme_api_list) <!-- api-operation:GET /api/xiaohongshu/get-user-faved-note-list/v1 -->
178
179
  - [笔记详情 (V1)](https://docs.justoneapi.com/zh/api/xiaohongshu-rednote/note-details-v1?utm_source=github.com&utm_medium=referral&utm_campaign=justoneapi_justoneapi_python&utm_content=repo_readme_api_list) <!-- api-operation:GET /api/xiaohongshu/get-note-detail/v1 --> <sub>[JSON](https://github.com/justoneapi-official/justoneapi-python/blob/main/docs/api-examples/getApiXiaohongshuGetNoteDetailV1.json)</sub>
179
180
  - [笔记详情 (V2)](https://docs.justoneapi.com/zh/api/xiaohongshu-rednote/note-details-v2?utm_source=github.com&utm_medium=referral&utm_campaign=justoneapi_justoneapi_python&utm_content=repo_readme_api_list) <!-- api-operation:GET /api/xiaohongshu/get-note-detail/v2 -->
180
181
  - [笔记详情 (V3)](https://docs.justoneapi.com/zh/api/xiaohongshu-rednote/note-details-v3?utm_source=github.com&utm_medium=referral&utm_campaign=justoneapi_justoneapi_python&utm_content=repo_readme_api_list) <!-- api-operation:GET /api/xiaohongshu/get-note-detail/v3 -->
@@ -159,6 +159,7 @@ except BusinessError as exc:
159
159
  - [用户发布笔记 (V2)](https://docs.justoneapi.com/zh/api/xiaohongshu-rednote/user-published-notes-v2?utm_source=github.com&utm_medium=referral&utm_campaign=justoneapi_justoneapi_python&utm_content=repo_readme_api_list) <!-- api-operation:GET /api/xiaohongshu/get-user-note-list/v2 -->
160
160
  - [用户发布笔记 (V3)](https://docs.justoneapi.com/zh/api/xiaohongshu-rednote/user-published-notes-v3?utm_source=github.com&utm_medium=referral&utm_campaign=justoneapi_justoneapi_python&utm_content=repo_readme_api_list) <!-- api-operation:GET /api/xiaohongshu/get-user-note-list/v3 -->
161
161
  - [用户笔记 (V4)](https://docs.justoneapi.com/zh/api/xiaohongshu-rednote/user-notes-v4?utm_source=github.com&utm_medium=referral&utm_campaign=justoneapi_justoneapi_python&utm_content=repo_readme_api_list) <!-- api-operation:GET /api/xiaohongshu/get-user-note-list/v4 --> <sub>[JSON](https://github.com/justoneapi-official/justoneapi-python/blob/main/docs/api-examples/getApiXiaohongshuGetUserNoteListV4.json)</sub>
162
+ - [用户收藏的笔记 (V1)](https://docs.justoneapi.com/zh/api/xiaohongshu-rednote/user-favorited-notes-v1?utm_source=github.com&utm_medium=referral&utm_campaign=justoneapi_justoneapi_python&utm_content=repo_readme_api_list) <!-- api-operation:GET /api/xiaohongshu/get-user-faved-note-list/v1 -->
162
163
  - [笔记详情 (V1)](https://docs.justoneapi.com/zh/api/xiaohongshu-rednote/note-details-v1?utm_source=github.com&utm_medium=referral&utm_campaign=justoneapi_justoneapi_python&utm_content=repo_readme_api_list) <!-- api-operation:GET /api/xiaohongshu/get-note-detail/v1 --> <sub>[JSON](https://github.com/justoneapi-official/justoneapi-python/blob/main/docs/api-examples/getApiXiaohongshuGetNoteDetailV1.json)</sub>
163
164
  - [笔记详情 (V2)](https://docs.justoneapi.com/zh/api/xiaohongshu-rednote/note-details-v2?utm_source=github.com&utm_medium=referral&utm_campaign=justoneapi_justoneapi_python&utm_content=repo_readme_api_list) <!-- api-operation:GET /api/xiaohongshu/get-note-detail/v2 -->
164
165
  - [笔记详情 (V3)](https://docs.justoneapi.com/zh/api/xiaohongshu-rednote/note-details-v3?utm_source=github.com&utm_medium=referral&utm_campaign=justoneapi_justoneapi_python&utm_content=repo_readme_api_list) <!-- api-operation:GET /api/xiaohongshu/get-note-detail/v3 -->
@@ -0,0 +1 @@
1
+ __version__ = "3.0.83"
@@ -17,7 +17,6 @@ from justoneapi.generated.resources.jd import JdResource
17
17
  from justoneapi.generated.resources.kuaishou import KuaishouResource
18
18
  from justoneapi.generated.resources.linkedin import LinkedinResource
19
19
  from justoneapi.generated.resources.llm import LlmResource
20
- from justoneapi.generated.resources.pixabay import PixabayResource
21
20
  from justoneapi.generated.resources.qq_huxuan import QqHuxuanResource
22
21
  from justoneapi.generated.resources.reddit import RedditResource
23
22
  from justoneapi.generated.resources.search import SearchResource
@@ -28,7 +27,6 @@ from justoneapi.generated.resources.tiktok import TiktokResource
28
27
  from justoneapi.generated.resources.tiktok_shop import TiktokShopResource
29
28
  from justoneapi.generated.resources.toutiao import ToutiaoResource
30
29
  from justoneapi.generated.resources.twitter import TwitterResource
31
- from justoneapi.generated.resources.vcg import VcgResource
32
30
  from justoneapi.generated.resources.weibo import WeiboResource
33
31
  from justoneapi.generated.resources.weixin import WeixinResource
34
32
  from justoneapi.generated.resources.weixin_channels import WeixinChannelsResource
@@ -59,7 +57,6 @@ RESOURCE_CLASSES = {
59
57
  "kuaishou": KuaishouResource,
60
58
  "linkedin": LinkedinResource,
61
59
  "llm": LlmResource,
62
- "pixabay": PixabayResource,
63
60
  "qq_huxuan": QqHuxuanResource,
64
61
  "reddit": RedditResource,
65
62
  "search": SearchResource,
@@ -70,7 +67,6 @@ RESOURCE_CLASSES = {
70
67
  "tiktok_shop": TiktokShopResource,
71
68
  "toutiao": ToutiaoResource,
72
69
  "twitter": TwitterResource,
73
- "vcg": VcgResource,
74
70
  "weibo": WeiboResource,
75
71
  "weixin": WeixinResource,
76
72
  "weixin_channels": WeixinChannelsResource,
@@ -102,7 +98,6 @@ __all__ = [
102
98
  "KuaishouResource",
103
99
  "LinkedinResource",
104
100
  "LlmResource",
105
- "PixabayResource",
106
101
  "QqHuxuanResource",
107
102
  "RedditResource",
108
103
  "SearchResource",
@@ -113,7 +108,6 @@ __all__ = [
113
108
  "TiktokShopResource",
114
109
  "ToutiaoResource",
115
110
  "TwitterResource",
116
- "VcgResource",
117
111
  "WeiboResource",
118
112
  "WeixinResource",
119
113
  "WeixinChannelsResource",
@@ -337,6 +337,29 @@ class XiaohongshuResource(BaseResource):
337
337
  },
338
338
  )
339
339
 
340
+ def get_user_faved_note_list_v1(
341
+ self,
342
+ *,
343
+ user_id: str,
344
+ last_cursor: str | None = "",
345
+ ) -> ApiResponse[Any]:
346
+ """
347
+ User Favorited Notes
348
+
349
+ Retrieves a Xiaohongshu (RedNote) user's favorited notes by user ID with cursor pagination. Use it to review a user's saved content and research content interests.
350
+
351
+ Args:
352
+ user_id: Unique user identifier on Xiaohongshu.
353
+ last_cursor: For the next page, pass the cursor from the previous response. Omit or pass an empty value for the first page.
354
+ """
355
+ return self._get(
356
+ "/api/xiaohongshu/get-user-faved-note-list/v1",
357
+ {
358
+ "userId": user_id,
359
+ "lastCursor": last_cursor,
360
+ },
361
+ )
362
+
340
363
  def get_note_detail_v1(
341
364
  self,
342
365
  *,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: justoneapi
3
- Version: 3.0.81
3
+ Version: 3.0.83
4
4
  Summary: OpenAPI-driven Python SDK for Just One API
5
5
  Author-email: Just One API <support@justoneapi.com>
6
6
  Requires-Python: >=3.10
@@ -175,6 +175,7 @@ except BusinessError as exc:
175
175
  - [用户发布笔记 (V2)](https://docs.justoneapi.com/zh/api/xiaohongshu-rednote/user-published-notes-v2?utm_source=github.com&utm_medium=referral&utm_campaign=justoneapi_justoneapi_python&utm_content=repo_readme_api_list) <!-- api-operation:GET /api/xiaohongshu/get-user-note-list/v2 -->
176
176
  - [用户发布笔记 (V3)](https://docs.justoneapi.com/zh/api/xiaohongshu-rednote/user-published-notes-v3?utm_source=github.com&utm_medium=referral&utm_campaign=justoneapi_justoneapi_python&utm_content=repo_readme_api_list) <!-- api-operation:GET /api/xiaohongshu/get-user-note-list/v3 -->
177
177
  - [用户笔记 (V4)](https://docs.justoneapi.com/zh/api/xiaohongshu-rednote/user-notes-v4?utm_source=github.com&utm_medium=referral&utm_campaign=justoneapi_justoneapi_python&utm_content=repo_readme_api_list) <!-- api-operation:GET /api/xiaohongshu/get-user-note-list/v4 --> <sub>[JSON](https://github.com/justoneapi-official/justoneapi-python/blob/main/docs/api-examples/getApiXiaohongshuGetUserNoteListV4.json)</sub>
178
+ - [用户收藏的笔记 (V1)](https://docs.justoneapi.com/zh/api/xiaohongshu-rednote/user-favorited-notes-v1?utm_source=github.com&utm_medium=referral&utm_campaign=justoneapi_justoneapi_python&utm_content=repo_readme_api_list) <!-- api-operation:GET /api/xiaohongshu/get-user-faved-note-list/v1 -->
178
179
  - [笔记详情 (V1)](https://docs.justoneapi.com/zh/api/xiaohongshu-rednote/note-details-v1?utm_source=github.com&utm_medium=referral&utm_campaign=justoneapi_justoneapi_python&utm_content=repo_readme_api_list) <!-- api-operation:GET /api/xiaohongshu/get-note-detail/v1 --> <sub>[JSON](https://github.com/justoneapi-official/justoneapi-python/blob/main/docs/api-examples/getApiXiaohongshuGetNoteDetailV1.json)</sub>
179
180
  - [笔记详情 (V2)](https://docs.justoneapi.com/zh/api/xiaohongshu-rednote/note-details-v2?utm_source=github.com&utm_medium=referral&utm_campaign=justoneapi_justoneapi_python&utm_content=repo_readme_api_list) <!-- api-operation:GET /api/xiaohongshu/get-note-detail/v2 -->
180
181
  - [笔记详情 (V3)](https://docs.justoneapi.com/zh/api/xiaohongshu-rednote/note-details-v3?utm_source=github.com&utm_medium=referral&utm_campaign=justoneapi_justoneapi_python&utm_content=repo_readme_api_list) <!-- api-operation:GET /api/xiaohongshu/get-note-detail/v3 -->
@@ -36,7 +36,6 @@ justoneapi/generated/resources/jd.py
36
36
  justoneapi/generated/resources/kuaishou.py
37
37
  justoneapi/generated/resources/linkedin.py
38
38
  justoneapi/generated/resources/llm.py
39
- justoneapi/generated/resources/pixabay.py
40
39
  justoneapi/generated/resources/qq_huxuan.py
41
40
  justoneapi/generated/resources/reddit.py
42
41
  justoneapi/generated/resources/search.py
@@ -47,7 +46,6 @@ justoneapi/generated/resources/tiktok.py
47
46
  justoneapi/generated/resources/tiktok_shop.py
48
47
  justoneapi/generated/resources/toutiao.py
49
48
  justoneapi/generated/resources/twitter.py
50
- justoneapi/generated/resources/vcg.py
51
49
  justoneapi/generated/resources/weibo.py
52
50
  justoneapi/generated/resources/weixin.py
53
51
  justoneapi/generated/resources/weixin_channels.py
@@ -1,10 +1,16 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import json
3
4
  from pathlib import Path
4
5
 
6
+ import httpx
7
+ import pytest
8
+
9
+ from tools import sdk_codegen
5
10
  from tools.sdk_codegen import (
6
11
  build_diff_summary,
7
12
  collect_resources,
13
+ fetch_openapi,
8
14
  load_json,
9
15
  load_overrides,
10
16
  normalize_spec,
@@ -14,6 +20,111 @@ RAW_SPEC_PATH = Path("openapi/public-api.json")
14
20
  OVERRIDES_PATH = Path("openapi/sdk_overrides.yaml")
15
21
 
16
22
 
23
+ @pytest.fixture
24
+ def mock_openapi_fetch(monkeypatch):
25
+ outcomes = []
26
+ requests = []
27
+ delays = []
28
+
29
+ def handle(request):
30
+ requests.append(request)
31
+ outcome = outcomes.pop(0)
32
+ if isinstance(outcome, Exception):
33
+ raise outcome
34
+ return outcome
35
+
36
+ client_type = httpx.Client
37
+ monkeypatch.setattr(
38
+ sdk_codegen.httpx,
39
+ "Client",
40
+ lambda **kwargs: client_type(transport=httpx.MockTransport(handle), **kwargs),
41
+ )
42
+ monkeypatch.setattr(sdk_codegen.time, "sleep", delays.append)
43
+ return outcomes, requests, delays
44
+
45
+
46
+ @pytest.mark.parametrize("timeout_type", [httpx.ConnectTimeout, httpx.ReadTimeout])
47
+ @pytest.mark.parametrize("timeouts_before_success", [0, 1, 2])
48
+ def test_fetch_openapi_recovers_from_temporary_timeouts(
49
+ mock_openapi_fetch, timeout_type, timeouts_before_success
50
+ ):
51
+ outcomes, requests, delays = mock_openapi_fetch
52
+ spec = {"openapi": "3.0.3", "paths": {}}
53
+ outcomes.extend(
54
+ timeout_type("Temporary timeout") for _ in range(timeouts_before_success)
55
+ )
56
+ outcomes.append(httpx.Response(200, json=spec))
57
+
58
+ assert (
59
+ fetch_openapi("https://example.test/openapi", "test-user", "test-pass") == spec
60
+ )
61
+
62
+ assert len(requests) == timeouts_before_success + 1
63
+ assert delays == [2, 4][:timeouts_before_success]
64
+ assert all(request.method == "GET" for request in requests)
65
+ assert all(
66
+ request.headers["authorization"] == requests[0].headers["authorization"]
67
+ for request in requests
68
+ )
69
+
70
+
71
+ @pytest.mark.parametrize("timeout_type", [httpx.ConnectTimeout, httpx.ReadTimeout])
72
+ def test_fetch_openapi_raises_after_three_timeouts(mock_openapi_fetch, timeout_type):
73
+ outcomes, requests, delays = mock_openapi_fetch
74
+ last_error = timeout_type("Still unavailable")
75
+ outcomes.extend(
76
+ [
77
+ timeout_type("Temporary timeout"),
78
+ timeout_type("Temporary timeout"),
79
+ last_error,
80
+ ]
81
+ )
82
+
83
+ with pytest.raises(timeout_type) as caught:
84
+ fetch_openapi("https://example.test/openapi", "test-user", "test-pass")
85
+
86
+ assert caught.value is last_error
87
+ assert len(requests) == 3
88
+ assert delays == [2, 4]
89
+
90
+
91
+ @pytest.mark.parametrize("status_code", [401, 503])
92
+ def test_fetch_openapi_does_not_retry_http_errors(mock_openapi_fetch, status_code):
93
+ outcomes, requests, delays = mock_openapi_fetch
94
+ outcomes.append(httpx.Response(status_code))
95
+
96
+ with pytest.raises(httpx.HTTPStatusError):
97
+ fetch_openapi("https://example.test/openapi", "test-user", "test-pass")
98
+
99
+ assert len(requests) == 1
100
+ assert delays == []
101
+
102
+
103
+ def test_fetch_openapi_does_not_retry_invalid_json(mock_openapi_fetch):
104
+ outcomes, requests, delays = mock_openapi_fetch
105
+ outcomes.append(httpx.Response(200, text="not JSON"))
106
+
107
+ with pytest.raises(json.JSONDecodeError):
108
+ fetch_openapi("https://example.test/openapi", "test-user", "test-pass")
109
+
110
+ assert len(requests) == 1
111
+ assert delays == []
112
+
113
+
114
+ @pytest.mark.parametrize("error_type", [httpx.ConnectError, httpx.WriteTimeout])
115
+ def test_fetch_openapi_does_not_retry_other_transport_errors(
116
+ mock_openapi_fetch, error_type
117
+ ):
118
+ outcomes, requests, delays = mock_openapi_fetch
119
+ outcomes.append(error_type("Non-retryable transport failure"))
120
+
121
+ with pytest.raises(error_type):
122
+ fetch_openapi("https://example.test/openapi", "test-user", "test-pass")
123
+
124
+ assert len(requests) == 1
125
+ assert delays == []
126
+
127
+
17
128
  def count_operations(spec: dict) -> int:
18
129
  return sum(
19
130
  1
@@ -1 +0,0 @@
1
- __version__ = "3.0.81"
@@ -1,39 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from typing import Any
4
-
5
- from justoneapi._resource import BaseResource
6
- from justoneapi._response import ApiResponse
7
-
8
-
9
- class PixabayResource(BaseResource):
10
- """Generated resource for Pixabay."""
11
-
12
- def search_image_v1(
13
- self,
14
- *,
15
- keyword: str,
16
- limit: str | None = None,
17
- start_page: str | None = None,
18
- max_pages: str | None = None,
19
- ) -> ApiResponse[Any]:
20
- """
21
- Photo Search
22
-
23
- Searches public Pixabay photo result pages by keyword with a requested image count and page controls. Each result includes its Pixabay photo page, public contributor information when shown, and a source-provided image URL.
24
-
25
- Args:
26
- keyword: Photo search keyword, up to 100 characters without control characters.
27
- limit: Maximum number of unique photos to return.
28
- start_page: First result page to search, starting from 1.
29
- max_pages: Maximum number of pages to visit in this request. The last page must not exceed 10000.
30
- """
31
- return self._get(
32
- "/api/pixabay/search-image/v1",
33
- {
34
- "keyword": keyword,
35
- "limit": limit,
36
- "startPage": start_page,
37
- "maxPages": max_pages,
38
- },
39
- )
@@ -1,48 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from typing import Any
4
-
5
- from justoneapi._resource import BaseResource
6
- from justoneapi._response import ApiResponse
7
-
8
-
9
- class VcgResource(BaseResource):
10
- """Generated resource for VCG."""
11
-
12
- def search_image_v1(
13
- self,
14
- *,
15
- keyword: str,
16
- limit: str | None = None,
17
- start_page: str | None = None,
18
- max_pages: str | None = None,
19
- exclude_resource_ids: list[Any] | None = None,
20
- content_filter: str | None = "all",
21
- result_mode: str | None = "full",
22
- ) -> ApiResponse[Any]:
23
- """
24
- Image Search
25
-
26
- Searches VCG images by keyword with page controls, resource ID exclusions, and an optional 500px Select/Prime filter excluding AIGC. Use full image details for collection or candidate_ids for single-page ID inspection.
27
-
28
- Args:
29
- keyword: Image search keyword, up to 200 characters without control characters.
30
- limit: Maximum number of unique images to return, excluding the supplied resource IDs.
31
- start_page: First page to search, starting from 1. For continuation, use the next page returned by the previous request.
32
- max_pages: Maximum number of pages to visit in this request. The last requested page must not exceed 10000.
33
- exclude_resource_ids: Previously collected VCG resource IDs to exclude when continuing a search. Supply comma-separated IDs or repeat this query parameter.
34
- content_filter: Optional brand and AIGC search restriction. Keep this value unchanged across pagination and continuation. Available Values: - `all`: Keep the default search without additional brand or AIGC filters. - `selected_500px_no_aigc`: Select only 500px Select and 500px Prime, exclude AIGC using the site's filter, and retain best ordering. Do not expand to other brands when results run out.
35
- result_mode: Result mode: full returns normal image details; candidate_ids only inspects one page of resource IDs and requires limit 10000, maxPages 1, and no excluded resource IDs. A candidate inspection does not complete or advance an image search. Available Values: - `full`: Return the normal image search result with complete image details. - `candidate_ids`: Inspect resource IDs from one validated search page without image details. Requires limit 10000, maxPages 1, and no excluded resource IDs; this is not an image result or a completion receipt.
36
- """
37
- return self._get(
38
- "/api/vcg/search-image/v1",
39
- {
40
- "keyword": keyword,
41
- "limit": limit,
42
- "startPage": start_page,
43
- "maxPages": max_pages,
44
- "excludeResourceIds": exclude_resource_ids,
45
- "contentFilter": content_filter,
46
- "resultMode": result_mode,
47
- },
48
- )
File without changes
File without changes
File without changes
File without changes