dataify-sdk 1.1.0__tar.gz → 1.2.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 (91) hide show
  1. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/PKG-INFO +1 -1
  2. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/PYPI_RELEASE.md +18 -0
  3. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/pyproject.toml +1 -1
  4. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/__init__.py +1 -1
  5. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/__init__.py +3 -0
  6. dataify_sdk-1.2.0/src/dataify_sdk/tools/chatgptanswer.py +66 -0
  7. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/tests/test_tools/test_tool_modules.py +41 -13
  8. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/.gitignore +0 -0
  9. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/LICENSE +0 -0
  10. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/README.md +0 -0
  11. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/scripts/codegen.py +0 -0
  12. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/_codegen/__init__.py +0 -0
  13. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/_codegen/generate.py +0 -0
  14. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/client.py +0 -0
  15. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/errors.py +0 -0
  16. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/airbnbproduct.py +0 -0
  17. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/amazoncomment.py +0 -0
  18. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/amazonglobalproduct.py +0 -0
  19. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/amazonproduct.py +0 -0
  20. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/amazonproductlist.py +0 -0
  21. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/amazonseller.py +0 -0
  22. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/bingimages.py +0 -0
  23. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/bingmaps.py +0 -0
  24. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/bingnews.py +0 -0
  25. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/bingsearch.py +0 -0
  26. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/bingshopping.py +0 -0
  27. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/bingvideos.py +0 -0
  28. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/bookinghotellist.py +0 -0
  29. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/crunchbasecompany.py +0 -0
  30. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/duckduckgosearch.py +0 -0
  31. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/ebayinfo.py +0 -0
  32. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/facebookcomment.py +0 -0
  33. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/facebookevent.py +0 -0
  34. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/facebookpost.py +0 -0
  35. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/facebookprofile.py +0 -0
  36. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/githubrepository.py +0 -0
  37. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/glassdoorcompany.py +0 -0
  38. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/glassdoorjoblistings.py +0 -0
  39. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/googleaimode.py +0 -0
  40. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/googlefinance.py +0 -0
  41. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/googleflights.py +0 -0
  42. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/googlehotels.py +0 -0
  43. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/googleimages.py +0 -0
  44. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/googlejobs.py +0 -0
  45. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/googlelens.py +0 -0
  46. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/googlelocal.py +0 -0
  47. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/googlemapcomment.py +0 -0
  48. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/googlemapdetails.py +0 -0
  49. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/googlemaps.py +0 -0
  50. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/googlenews.py +0 -0
  51. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/googlepatents.py +0 -0
  52. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/googleplay.py +0 -0
  53. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/googleplaystoreinformation.py +0 -0
  54. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/googleplaystorereviews.py +0 -0
  55. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/googlescholar.py +0 -0
  56. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/googlesearch.py +0 -0
  57. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/googleshopping.py +0 -0
  58. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/googleshoppinginfo.py +0 -0
  59. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/googletrends.py +0 -0
  60. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/googlevideos.py +0 -0
  61. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/indeedcompaniesinfo.py +0 -0
  62. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/indeedjoblistings.py +0 -0
  63. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/instagramcomment.py +0 -0
  64. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/instagramprofiles.py +0 -0
  65. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/instagramreel.py +0 -0
  66. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/linkedincompanyinformation.py +0 -0
  67. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/linkedinjoblistingsinformation.py +0 -0
  68. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/redditcomment.py +0 -0
  69. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/redditposts.py +0 -0
  70. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/tiktokcomment.py +0 -0
  71. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/tiktokposts.py +0 -0
  72. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/tiktokprofiles.py +0 -0
  73. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/tiktokshop.py +0 -0
  74. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/twitterpost.py +0 -0
  75. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/twitterprofile.py +0 -0
  76. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/walmartproduct.py +0 -0
  77. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/yandexsearch.py +0 -0
  78. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/youtubeaudio.py +0 -0
  79. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/youtubecomment.py +0 -0
  80. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/youtubeproduct.py +0 -0
  81. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/youtubeprofiles.py +0 -0
  82. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/youtubetranscript.py +0 -0
  83. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/youtubevideo.py +0 -0
  84. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/youtubevideopost.py +0 -0
  85. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/src/dataify_sdk/tools/zillowproduct.py +0 -0
  86. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/tests/__init__.py +0 -0
  87. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/tests/conftest.py +0 -0
  88. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/tests/test_client/__init__.py +0 -0
  89. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/tests/test_client/test_http_client.py +0 -0
  90. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/tests/test_tools/__init__.py +0 -0
  91. {dataify_sdk-1.1.0 → dataify_sdk-1.2.0}/tests/test_tools/test_codegen.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: dataify-sdk
3
- Version: 1.1.0
3
+ Version: 1.2.0
4
4
  Summary: Python SDK that calls the Dataify upstream REST API directly (no MCP layer) — web scrapers and search engines.
5
5
  Project-URL: Homepage, https://dashboard.dataify.com
6
6
  Project-URL: Repository, https://github.com/dataify/dataify-sdk
@@ -87,6 +87,22 @@ username: __token__
87
87
  password: TestPyPI token
88
88
  ```
89
89
 
90
+ 如果看到 `WARNING This environment is not supported for trusted publishing`,本机发布时可以忽略,继续用上面的 token 登录即可。
91
+
92
+ 如果返回 `403 Forbidden`,先执行:
93
+
94
+ ```powershell
95
+ python -m twine upload --repository testpypi --verbose dist/*
96
+ ```
97
+
98
+ 常见原因:
99
+
100
+ - 用了正式 PyPI token;TestPyPI 必须用 TestPyPI 单独创建的 token。
101
+ - token 对应账号不是 `dataify-sdk` 在 TestPyPI 上的 owner/maintainer。
102
+ - 项目级 token 只能上传已有项目;首次创建项目建议用 TestPyPI 账号级 token。
103
+ - TestPyPI 账号邮箱未验证。
104
+ - 版本号或文件已上传过,换一个新版本号后重新构建。
105
+
90
106
  ## 10. 从 TestPyPI 安装验证
91
107
 
92
108
  ```powershell
@@ -111,6 +127,8 @@ username: __token__
111
127
  password: PyPI token
112
128
  ```
113
129
 
130
+ 如果看到 `WARNING This environment is not supported for trusted publishing`,本机发布时可以忽略,继续用上面的 token 登录即可。
131
+
114
132
  ## 12. 从正式 PyPI 安装验证
115
133
 
116
134
  ```powershell
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "dataify-sdk"
7
- version = "1.1.0"
7
+ version = "1.2.0"
8
8
  description = "Python SDK that calls the Dataify upstream REST API directly (no MCP layer) — web scrapers and search engines."
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -31,7 +31,7 @@ from dataify_sdk.errors import (
31
31
  DataifyTimeoutError,
32
32
  )
33
33
 
34
- __version__ = "1.1.0"
34
+ __version__ = "1.2.0"
35
35
 
36
36
 
37
37
 
@@ -15,6 +15,7 @@ from dataify_sdk.tools.bingsearch import bing_search
15
15
  from dataify_sdk.tools.bingshopping import bing_shopping
16
16
  from dataify_sdk.tools.bingvideos import bing_videos
17
17
  from dataify_sdk.tools.bookinghotellist import booking_hotellist_by_url
18
+ from dataify_sdk.tools.chatgptanswer import chatgpt_answer_by_keywords, chatgpt_answer_by_url
18
19
  from dataify_sdk.tools.crunchbasecompany import crunchbase_company_by_url, crunchbase_company_by_keywords
19
20
  from dataify_sdk.tools.duckduckgosearch import duckduckgo_search
20
21
  from dataify_sdk.tools.ebayinfo import ebay_ebay_by_url, ebay_ebay_by_category_url, ebay_ebay_by_keywords, ebay_ebay_by_listurl
@@ -94,6 +95,8 @@ __all__ = [
94
95
  'bing_shopping',
95
96
  'bing_videos',
96
97
  'booking_hotellist_by_url',
98
+ 'chatgpt_answer_by_keywords',
99
+ 'chatgpt_answer_by_url',
97
100
  'crunchbase_company_by_url',
98
101
  'crunchbase_company_by_keywords',
99
102
  'duckduckgo_search',
@@ -0,0 +1,66 @@
1
+ """Auto-generated Dataify tool functions. Do not edit by hand.
2
+
3
+ Generated from the Go reference project by ``dataify_sdk._codegen.generate``.
4
+ Each function calls the Dataify upstream REST API directly (no MCP layer).
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import json
10
+ from typing import Any
11
+
12
+ from dataify_sdk.client import DataifyClient, get_default_client
13
+
14
+
15
+ def _client(client: DataifyClient | None) -> DataifyClient:
16
+ return client if client is not None else get_default_client()
17
+
18
+ def chatgpt_answer_by_keywords(file_name: str = '{{TasksID}}', search_terms: str = 'pizza', client: DataifyClient | None = None) -> dict[str, Any]:
19
+ """当用户需要 ChatGPT 答案、ChatGPT 回答内容、ChatGPT 提问结果、AI 回答文本、引用来源链接、相关推荐问题、答案生成时间、模型版本,与采集、抓取、爬取、获取、提取等动词组合时触发。复用一个工具提交 ChatGPT 答案采集 Builder 任务,支持 chatgpt_answer_by-keywords(通过搜索关键词采集)和 chatgpt_answer_by-url(通过 URL 采集)。
20
+
21
+ 上游接口: Scraper Builder (POST /builder?platform=1)
22
+ spider_name: chatgpt.com
23
+ spider_id: chatgpt_answer_by-keywords
24
+
25
+ Parameters
26
+ ----------
27
+ search_terms: 搜索关键词,该参数用于指定向 ChatGPT 提问并采集答案的关键词。用于 chatgpt_answer_by-keywords。 [默认: pizza]
28
+ file_name: Builder file_name 字段。不传默认为 {{TasksID}}。 [默认: {{TasksID}}]
29
+ client: 可选 DataifyClient 实例;不传则使用默认 client(优先读取 DATAIFY_API_TOKEN, 兼容 DATAIFY_TOKEN)。
30
+ """
31
+ params_obj = {
32
+ "search_terms": search_terms,
33
+ }
34
+ spider_parameters = json.dumps([params_obj], ensure_ascii=False)
35
+ return _client(client).request_scraper(
36
+ spider_name='chatgpt.com',
37
+ spider_id='chatgpt_answer_by-keywords',
38
+ spider_parameters=spider_parameters,
39
+ file_name=file_name,
40
+ )
41
+
42
+
43
+ def chatgpt_answer_by_url(chatgpt_url: str = '', file_name: str = '{{TasksID}}', client: DataifyClient | None = None) -> dict[str, Any]:
44
+ """当用户需要 ChatGPT 答案、ChatGPT 回答内容、ChatGPT 提问结果、AI 回答文本、引用来源链接、相关推荐问题、答案生成时间、模型版本,与采集、抓取、爬取、获取、提取等动词组合时触发。复用一个工具提交 ChatGPT 答案采集 Builder 任务,支持 chatgpt_answer_by-keywords(通过搜索关键词采集)和 chatgpt_answer_by-url(通过 URL 采集)。
45
+
46
+ 上游接口: Scraper Builder (POST /builder?platform=1)
47
+ spider_name: chatgpt.com
48
+ spider_id: chatgpt_answer_by-url
49
+
50
+ Parameters
51
+ ----------
52
+ chatgpt_url: ChatGPT 页面 URL,该参数用于指定待采集答案的 ChatGPT 访问 URL。用于 chatgpt_answer_by-url。 [默认: (空)]
53
+ file_name: Builder file_name 字段。不传默认为 {{TasksID}}。 [默认: {{TasksID}}]
54
+ client: 可选 DataifyClient 实例;不传则使用默认 client(优先读取 DATAIFY_API_TOKEN, 兼容 DATAIFY_TOKEN)。
55
+ """
56
+ params_obj = {
57
+ "chatgpt_url": chatgpt_url,
58
+ }
59
+ spider_parameters = json.dumps([params_obj], ensure_ascii=False)
60
+ return _client(client).request_scraper(
61
+ spider_name='chatgpt.com',
62
+ spider_id='chatgpt_answer_by-url',
63
+ spider_parameters=spider_parameters,
64
+ file_name=file_name,
65
+ )
66
+
@@ -27,10 +27,10 @@ def test_module_imports(module):
27
27
 
28
28
  def test_function_count():
29
29
  mods = _all_modules()
30
- assert len(mods) == 70
30
+ assert len(mods) == 71
31
31
  import dataify_sdk.tools as pkg
32
32
 
33
- assert len(pkg.__all__) == 113
33
+ assert len(pkg.__all__) == 115
34
34
 
35
35
 
36
36
  def test_amazon_product_by_asin_request(captured_request):
@@ -45,6 +45,34 @@ def test_amazon_product_by_asin_request(captured_request):
45
45
  assert json.loads(form["spider_parameters"]) == [{"asin": "B0X"}]
46
46
 
47
47
 
48
+ def test_chatgpt_answer_by_url_request(captured_request):
49
+ from dataify_sdk.tools.chatgptanswer import chatgpt_answer_by_url
50
+
51
+ chatgpt_answer_by_url(
52
+ chatgpt_url="https://chatgpt.com/?q=pizza", client=DataifyClient(token="t")
53
+ )
54
+ req = captured_request["req"]
55
+ assert req.full_url.endswith("/builder?platform=1")
56
+ form = decode_form(req)
57
+ assert form["spider_id"] == "chatgpt_answer_by-url"
58
+ assert form["spider_name"] == "chatgpt.com"
59
+ assert json.loads(form["spider_parameters"]) == [
60
+ {"chatgpt_url": "https://chatgpt.com/?q=pizza"}
61
+ ]
62
+
63
+
64
+ def test_chatgpt_answer_by_keywords_request(captured_request):
65
+ from dataify_sdk.tools.chatgptanswer import chatgpt_answer_by_keywords
66
+
67
+ chatgpt_answer_by_keywords(search_terms="pizza", client=DataifyClient(token="t"))
68
+ req = captured_request["req"]
69
+ assert req.full_url.endswith("/builder?platform=1")
70
+ form = decode_form(req)
71
+ assert form["spider_id"] == "chatgpt_answer_by-keywords"
72
+ assert form["spider_name"] == "chatgpt.com"
73
+ assert json.loads(form["spider_parameters"]) == [{"search_terms": "pizza"}]
74
+
75
+
48
76
  def test_google_search_request(captured_request):
49
77
  from dataify_sdk.tools.googlesearch import google_search
50
78
 
@@ -57,14 +85,14 @@ def test_google_search_request(captured_request):
57
85
  assert "gl" not in form # empty dropped
58
86
 
59
87
 
60
- def test_default_client_uses_env(monkeypatch, captured_request):
61
- monkeypatch.setenv("DATAIFY_API_TOKEN", "env-token")
62
- from dataify_sdk.tools.twitterpost import twitter_post_by_profileurl
63
-
64
- # no client passed -> default client reads DATAIFY_API_TOKEN
65
- twitter_post_by_profileurl(url="https://x.com/foo")
66
- req = captured_request["req"]
67
- assert req.full_url.endswith("/builder?platform=1")
68
- form = decode_form(req)
69
- assert json.loads(form["spider_parameters"]) == [{"url": "https://x.com/foo"}]
70
- assert req.get_header("Authorization") == "Bearer env-token"
88
+ def test_default_client_uses_env(monkeypatch, captured_request):
89
+ monkeypatch.setenv("DATAIFY_API_TOKEN", "env-token")
90
+ from dataify_sdk.tools.twitterpost import twitter_post_by_profileurl
91
+
92
+ # no client passed -> default client reads DATAIFY_API_TOKEN
93
+ twitter_post_by_profileurl(url="https://x.com/foo")
94
+ req = captured_request["req"]
95
+ assert req.full_url.endswith("/builder?platform=1")
96
+ form = decode_form(req)
97
+ assert json.loads(form["spider_parameters"]) == [{"url": "https://x.com/foo"}]
98
+ assert req.get_header("Authorization") == "Bearer env-token"
File without changes
File without changes
File without changes