search1api 0.3.0__tar.gz → 0.5.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.
- search1api-0.5.0/CHANGELOG.md +9 -0
- {search1api-0.3.0 → search1api-0.5.0}/PKG-INFO +28 -2
- {search1api-0.3.0 → search1api-0.5.0}/README.md +27 -1
- {search1api-0.3.0 → search1api-0.5.0}/openapi/search1api.openapi.json +412 -10
- {search1api-0.3.0 → search1api-0.5.0}/pyproject.toml +1 -1
- {search1api-0.3.0 → search1api-0.5.0}/src/search1api/__init__.py +1 -1
- {search1api-0.3.0 → search1api-0.5.0}/src/search1api/client.py +77 -0
- {search1api-0.3.0 → search1api-0.5.0}/src/search1api/types.py +71 -3
- {search1api-0.3.0 → search1api-0.5.0}/tests/test_client.py +110 -0
- {search1api-0.3.0 → search1api-0.5.0}/.github/workflows/ci.yml +0 -0
- {search1api-0.3.0 → search1api-0.5.0}/.github/workflows/release.yml +0 -0
- {search1api-0.3.0 → search1api-0.5.0}/.gitignore +0 -0
- {search1api-0.3.0 → search1api-0.5.0}/LICENSE +0 -0
- {search1api-0.3.0 → search1api-0.5.0}/openapi/README.md +0 -0
- {search1api-0.3.0 → search1api-0.5.0}/src/search1api/errors.py +0 -0
- {search1api-0.3.0 → search1api-0.5.0}/src/search1api/py.typed +0 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.5.0 - 2026-11-03
|
|
4
|
+
|
|
5
|
+
Adds `maps(query, ...)` on `Search1API` and `AsyncSearch1API` for `POST /maps`: one Google Maps page of up to 20 places with name, place ID and Maps link, plus address, phone, website, rating, review count, coordinates and opening hours when available. Keyword arguments: `country`, `language`, `location` (`latitude`, `longitude`, optional `zoom`), `page` (1-6, pages after the first need `location`) and `max_results`. 3 credits per completed page; API key or OAuth only. The bundled OpenAPI snapshot also records the 50-item batch limit for search, news and crawl.
|
|
6
|
+
|
|
7
|
+
## 0.4.0 - 2026-10-12
|
|
8
|
+
|
|
9
|
+
Breaking: search/news engine-specific fields move from each result's top level to optional `metadata` (`kind`, `stars`, `language`, `num_comments`, `points`, `story_url`). Read e.g. `result.metadata.stars` instead of `result.stars`. `published_date` stays at the top level. No legacy field aliases.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: search1api
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Official Python client for Search1API
|
|
5
5
|
Project-URL: Homepage, https://s1.dev
|
|
6
6
|
Project-URL: Documentation, https://s1.dev/docs/integrations/sdks
|
|
@@ -81,7 +81,11 @@ for result in response["results"]:
|
|
|
81
81
|
`bingcn`, `yandex`, `reddit`, `github`, `arxiv`, `wikipedia`, or `grokipedia`.
|
|
82
82
|
`page` requests a later results page on engines with native pagination
|
|
83
83
|
(`bing`, `bingcn`, `baidu`, `grokipedia`). Results carry `published_date` when the source
|
|
84
|
-
exposes one.
|
|
84
|
+
exposes one. Engine-specific fields are in each result's optional `metadata`:
|
|
85
|
+
GitHub uses `metadata.kind`, `metadata.stars`, `metadata.language`, and
|
|
86
|
+
`metadata.num_comments`; Hacker News news results use `metadata.story_url`,
|
|
87
|
+
`metadata.points`, and `metadata.num_comments`. The former top-level paths
|
|
88
|
+
are removed in 0.4.0; `published_date` stays at the top level.
|
|
85
89
|
|
|
86
90
|
Use the client as a context manager when it owns the HTTP connection pool:
|
|
87
91
|
|
|
@@ -117,6 +121,28 @@ A completed request costs 5 credits. Ask is not available with pay-per-request
|
|
|
117
121
|
payments, and its default timeout is 45 seconds. Use `search` when you already
|
|
118
122
|
know which engine and keywords you want.
|
|
119
123
|
|
|
124
|
+
## Maps
|
|
125
|
+
|
|
126
|
+
`maps` searches Google Maps and returns one page of up to 20 places. Each place
|
|
127
|
+
has a name, place ID and Maps link, plus address, phone, website, rating,
|
|
128
|
+
review count, coordinates and opening hours when available:
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
places = client.maps(
|
|
132
|
+
"coffee shops",
|
|
133
|
+
location={"latitude": 40.7455, "longitude": -74.0083, "zoom": 15},
|
|
134
|
+
max_results=10,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
for place in places["results"]:
|
|
138
|
+
print(place["name"], place.get("rating"), place.get("address"))
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
A completed page costs 3 credits, including a confirmed empty page.
|
|
142
|
+
`max_results` only trims the page and does not lower the price. Request `page`
|
|
143
|
+
2-6 with the same query and `location` for more places; each page is billed
|
|
144
|
+
separately. Maps is not available with pay-per-request payments.
|
|
145
|
+
|
|
120
146
|
## Deepcrawl
|
|
121
147
|
|
|
122
148
|
`deepcrawl` starts a task and waits for it to finish:
|
|
@@ -30,7 +30,11 @@ for result in response["results"]:
|
|
|
30
30
|
`bingcn`, `yandex`, `reddit`, `github`, `arxiv`, `wikipedia`, or `grokipedia`.
|
|
31
31
|
`page` requests a later results page on engines with native pagination
|
|
32
32
|
(`bing`, `bingcn`, `baidu`, `grokipedia`). Results carry `published_date` when the source
|
|
33
|
-
exposes one.
|
|
33
|
+
exposes one. Engine-specific fields are in each result's optional `metadata`:
|
|
34
|
+
GitHub uses `metadata.kind`, `metadata.stars`, `metadata.language`, and
|
|
35
|
+
`metadata.num_comments`; Hacker News news results use `metadata.story_url`,
|
|
36
|
+
`metadata.points`, and `metadata.num_comments`. The former top-level paths
|
|
37
|
+
are removed in 0.4.0; `published_date` stays at the top level.
|
|
34
38
|
|
|
35
39
|
Use the client as a context manager when it owns the HTTP connection pool:
|
|
36
40
|
|
|
@@ -66,6 +70,28 @@ A completed request costs 5 credits. Ask is not available with pay-per-request
|
|
|
66
70
|
payments, and its default timeout is 45 seconds. Use `search` when you already
|
|
67
71
|
know which engine and keywords you want.
|
|
68
72
|
|
|
73
|
+
## Maps
|
|
74
|
+
|
|
75
|
+
`maps` searches Google Maps and returns one page of up to 20 places. Each place
|
|
76
|
+
has a name, place ID and Maps link, plus address, phone, website, rating,
|
|
77
|
+
review count, coordinates and opening hours when available:
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
places = client.maps(
|
|
81
|
+
"coffee shops",
|
|
82
|
+
location={"latitude": 40.7455, "longitude": -74.0083, "zoom": 15},
|
|
83
|
+
max_results=10,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
for place in places["results"]:
|
|
87
|
+
print(place["name"], place.get("rating"), place.get("address"))
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
A completed page costs 3 credits, including a confirmed empty page.
|
|
91
|
+
`max_results` only trims the page and does not lower the price. Request `page`
|
|
92
|
+
2-6 with the same query and `location` for more places; each page is billed
|
|
93
|
+
separately. Maps is not available with pay-per-request payments.
|
|
94
|
+
|
|
69
95
|
## Deepcrawl
|
|
70
96
|
|
|
71
97
|
`deepcrawl` starts a task and waits for it to finish:
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"title": "Search1API",
|
|
5
5
|
"description": "Web search, news, crawling, screenshot, and content extraction APIs for AI agents. Supports pay-per-request via MPP and x402 protocols.",
|
|
6
6
|
"version": "1.0.0",
|
|
7
|
-
"x-guidance": "Search1API provides web search, news aggregation, URL crawling, webpage screenshots, sitemap extraction, trending topics, content extraction, and deep crawling. All paid endpoints accept POST with a JSON body. Use POST /search with a \"query\" field for web search. Use POST /news with a \"query\" field for news. Use POST /ask with a natural-language \"query\" to have Search1API choose the engines and time window and return only relevant results (API key only). Use POST /crawl with a \"url\" field to crawl a page. Use POST /screenshot with a \"url\" field to render a PNG, JPEG, or WebP image. Use POST /sitemap with a \"url\" field to extract sitemap URLs. Use POST /trending with a \"search_service\" field for trends. Use POST /extract with a \"url\" field for structured content extraction. Use POST /deepcrawl with a \"url\" field for deep multi-page crawling."
|
|
7
|
+
"x-guidance": "Search1API provides web search, Maps place discovery, news aggregation, URL crawling, webpage screenshots, sitemap extraction, trending topics, content extraction, and deep crawling. All paid endpoints accept POST with a JSON body. Use POST /search with a \"query\" field for web search. Use POST /maps with a \"query\" and optional location coordinates to discover Google Maps places (API key only). Use POST /news with a \"query\" field for news. Use POST /ask with a natural-language \"query\" to have Search1API choose the engines and time window and return only relevant results (API key only). Use POST /crawl with a \"url\" field to crawl a page. Use POST /screenshot with a \"url\" field to render a PNG, JPEG, or WebP image. Use POST /sitemap with a \"url\" field to extract sitemap URLs. Use POST /trending with a \"search_service\" field for trends. Use POST /extract with a \"url\" field for structured content extraction. Use POST /deepcrawl with a \"url\" field for deep multi-page crawling."
|
|
8
8
|
},
|
|
9
9
|
"x-discovery": {
|
|
10
10
|
"ownershipProofs": []
|
|
@@ -159,6 +159,212 @@
|
|
|
159
159
|
],
|
|
160
160
|
"additionalProperties": false
|
|
161
161
|
},
|
|
162
|
+
"MapsResponse": {
|
|
163
|
+
"type": "object",
|
|
164
|
+
"properties": {
|
|
165
|
+
"searchParameters": {
|
|
166
|
+
"type": "object",
|
|
167
|
+
"properties": {
|
|
168
|
+
"query": {
|
|
169
|
+
"type": "string",
|
|
170
|
+
"minLength": 1,
|
|
171
|
+
"maxLength": 1000,
|
|
172
|
+
"description": "Google Maps search phrase; leading and trailing whitespace is removed."
|
|
173
|
+
},
|
|
174
|
+
"country": {
|
|
175
|
+
"type": "string",
|
|
176
|
+
"pattern": "^[a-zA-Z]{2}$",
|
|
177
|
+
"default": "us",
|
|
178
|
+
"description": "Two-letter country code, normalized to lowercase. Defaults to us."
|
|
179
|
+
},
|
|
180
|
+
"language": {
|
|
181
|
+
"type": "string",
|
|
182
|
+
"pattern": "^[a-z]{2,3}(-[a-zA-Z]{2,4})?$",
|
|
183
|
+
"default": "en",
|
|
184
|
+
"description": "Result language, for example en, de or zh-CN. Defaults to en."
|
|
185
|
+
},
|
|
186
|
+
"location": {
|
|
187
|
+
"type": "object",
|
|
188
|
+
"properties": {
|
|
189
|
+
"latitude": {
|
|
190
|
+
"type": "number",
|
|
191
|
+
"minimum": -90,
|
|
192
|
+
"maximum": 90
|
|
193
|
+
},
|
|
194
|
+
"longitude": {
|
|
195
|
+
"type": "number",
|
|
196
|
+
"minimum": -180,
|
|
197
|
+
"maximum": 180
|
|
198
|
+
},
|
|
199
|
+
"zoom": {
|
|
200
|
+
"type": "number",
|
|
201
|
+
"minimum": 3,
|
|
202
|
+
"maximum": 30,
|
|
203
|
+
"default": 14
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
"required": [
|
|
207
|
+
"latitude",
|
|
208
|
+
"longitude"
|
|
209
|
+
],
|
|
210
|
+
"additionalProperties": false,
|
|
211
|
+
"description": "Search origin coordinates and map zoom (default 14). Required for page > 1. Latitude must be -90 to 90, longitude -180 to 180, and zoom 3 to 30. Example: {\"latitude\":40.7455,\"longitude\":-74.0083,\"zoom\":15}."
|
|
212
|
+
},
|
|
213
|
+
"page": {
|
|
214
|
+
"type": "integer",
|
|
215
|
+
"minimum": 1,
|
|
216
|
+
"maximum": 6,
|
|
217
|
+
"default": 1,
|
|
218
|
+
"description": "Page number, 1–6; default 1. Accepts an integer or canonical integer string such as \"2\". Empty strings use the default. Pages after the first require location."
|
|
219
|
+
},
|
|
220
|
+
"max_results": {
|
|
221
|
+
"type": "integer",
|
|
222
|
+
"minimum": 1,
|
|
223
|
+
"maximum": 20,
|
|
224
|
+
"default": 20,
|
|
225
|
+
"description": "Maximum places to return from this page, 1–20; default 20. Accepts an integer or canonical integer string such as \"10\". Empty strings use the default. Truncation does not reduce the page charge or carry places to the next page."
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
"required": [
|
|
229
|
+
"query"
|
|
230
|
+
],
|
|
231
|
+
"additionalProperties": false
|
|
232
|
+
},
|
|
233
|
+
"results": {
|
|
234
|
+
"type": "array",
|
|
235
|
+
"items": {
|
|
236
|
+
"type": "object",
|
|
237
|
+
"properties": {
|
|
238
|
+
"position": {
|
|
239
|
+
"type": "integer",
|
|
240
|
+
"minimum": 1,
|
|
241
|
+
"description": "Position in the requested native page, offset by earlier page capacities. Gaps can remain after filtering or deduplication; this is not a stable SEO rank."
|
|
242
|
+
},
|
|
243
|
+
"name": {
|
|
244
|
+
"type": "string",
|
|
245
|
+
"minLength": 1,
|
|
246
|
+
"description": "Business or place name."
|
|
247
|
+
},
|
|
248
|
+
"place_id": {
|
|
249
|
+
"type": "string",
|
|
250
|
+
"minLength": 1,
|
|
251
|
+
"description": "Google Maps place identifier, also used to deduplicate this page."
|
|
252
|
+
},
|
|
253
|
+
"maps_url": {
|
|
254
|
+
"type": "string",
|
|
255
|
+
"format": "uri",
|
|
256
|
+
"description": "Public Google Maps link for this place."
|
|
257
|
+
},
|
|
258
|
+
"address": {
|
|
259
|
+
"type": "string"
|
|
260
|
+
},
|
|
261
|
+
"phone": {
|
|
262
|
+
"type": "string"
|
|
263
|
+
},
|
|
264
|
+
"website": {
|
|
265
|
+
"type": "string",
|
|
266
|
+
"format": "uri"
|
|
267
|
+
},
|
|
268
|
+
"thumbnail": {
|
|
269
|
+
"type": "string",
|
|
270
|
+
"format": "uri"
|
|
271
|
+
},
|
|
272
|
+
"category": {
|
|
273
|
+
"type": "string"
|
|
274
|
+
},
|
|
275
|
+
"categories": {
|
|
276
|
+
"type": "array",
|
|
277
|
+
"items": {
|
|
278
|
+
"type": "string"
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
"rating": {
|
|
282
|
+
"type": "number",
|
|
283
|
+
"minimum": 0,
|
|
284
|
+
"maximum": 5
|
|
285
|
+
},
|
|
286
|
+
"review_count": {
|
|
287
|
+
"type": "integer",
|
|
288
|
+
"minimum": 0,
|
|
289
|
+
"maximum": 9007199254740991
|
|
290
|
+
},
|
|
291
|
+
"coordinates": {
|
|
292
|
+
"type": "object",
|
|
293
|
+
"properties": {
|
|
294
|
+
"latitude": {
|
|
295
|
+
"type": "number",
|
|
296
|
+
"minimum": -90,
|
|
297
|
+
"maximum": 90
|
|
298
|
+
},
|
|
299
|
+
"longitude": {
|
|
300
|
+
"type": "number",
|
|
301
|
+
"minimum": -180,
|
|
302
|
+
"maximum": 180
|
|
303
|
+
}
|
|
304
|
+
},
|
|
305
|
+
"required": [
|
|
306
|
+
"latitude",
|
|
307
|
+
"longitude"
|
|
308
|
+
],
|
|
309
|
+
"additionalProperties": false
|
|
310
|
+
},
|
|
311
|
+
"opening_hours": {
|
|
312
|
+
"type": "object",
|
|
313
|
+
"properties": {
|
|
314
|
+
"monday": {
|
|
315
|
+
"type": "string"
|
|
316
|
+
},
|
|
317
|
+
"tuesday": {
|
|
318
|
+
"type": "string"
|
|
319
|
+
},
|
|
320
|
+
"wednesday": {
|
|
321
|
+
"type": "string"
|
|
322
|
+
},
|
|
323
|
+
"thursday": {
|
|
324
|
+
"type": "string"
|
|
325
|
+
},
|
|
326
|
+
"friday": {
|
|
327
|
+
"type": "string"
|
|
328
|
+
},
|
|
329
|
+
"saturday": {
|
|
330
|
+
"type": "string"
|
|
331
|
+
},
|
|
332
|
+
"sunday": {
|
|
333
|
+
"type": "string"
|
|
334
|
+
}
|
|
335
|
+
},
|
|
336
|
+
"additionalProperties": false,
|
|
337
|
+
"description": "Opening hours by weekday, as displayed by the source; omitted when unavailable."
|
|
338
|
+
},
|
|
339
|
+
"open_state": {
|
|
340
|
+
"type": "string",
|
|
341
|
+
"description": "Source display text for the current opening state, not a normalized boolean."
|
|
342
|
+
},
|
|
343
|
+
"price": {
|
|
344
|
+
"type": "string",
|
|
345
|
+
"description": "Source display text for the business price range, not a numeric amount or normalized currency."
|
|
346
|
+
},
|
|
347
|
+
"description": {
|
|
348
|
+
"type": "string"
|
|
349
|
+
}
|
|
350
|
+
},
|
|
351
|
+
"required": [
|
|
352
|
+
"position",
|
|
353
|
+
"name",
|
|
354
|
+
"place_id",
|
|
355
|
+
"maps_url"
|
|
356
|
+
],
|
|
357
|
+
"additionalProperties": false
|
|
358
|
+
},
|
|
359
|
+
"maxItems": 20
|
|
360
|
+
}
|
|
361
|
+
},
|
|
362
|
+
"required": [
|
|
363
|
+
"searchParameters",
|
|
364
|
+
"results"
|
|
365
|
+
],
|
|
366
|
+
"additionalProperties": false
|
|
367
|
+
},
|
|
162
368
|
"NewsParameters": {
|
|
163
369
|
"type": "object",
|
|
164
370
|
"properties": {
|
|
@@ -348,6 +554,16 @@
|
|
|
348
554
|
"description": "When the page was published, as ISO 8601: `YYYY-MM-DD` when only the day is known (web search engines), or `YYYY-MM-DDTHH:MM:SSZ` in UTC when the source carries a time (x, reddit, github, arxiv, youtube, bilibili, wechat, news feeds). Omitted when the source exposes no date, so treat it as optional per result.",
|
|
349
555
|
"example": "2026-09-03"
|
|
350
556
|
},
|
|
557
|
+
"metadata": {
|
|
558
|
+
"$ref": "#/components/schemas/SearchResultMetadata"
|
|
559
|
+
}
|
|
560
|
+
},
|
|
561
|
+
"additionalProperties": true
|
|
562
|
+
},
|
|
563
|
+
"SearchResultMetadata": {
|
|
564
|
+
"type": "object",
|
|
565
|
+
"description": "Optional engine-specific fields. Omitted when none apply. GitHub and Reddit fields appear on POST /search; Hacker News fields appear on POST /news.",
|
|
566
|
+
"properties": {
|
|
351
567
|
"kind": {
|
|
352
568
|
"type": "string",
|
|
353
569
|
"enum": [
|
|
@@ -360,20 +576,20 @@
|
|
|
360
576
|
},
|
|
361
577
|
"stars": {
|
|
362
578
|
"type": "integer",
|
|
363
|
-
"description": "Stargazer count of a `github` repository result (`kind: \"repo\"`)."
|
|
579
|
+
"description": "Stargazer count of a `github` repository result (`metadata.kind: \"repo\"`)."
|
|
364
580
|
},
|
|
365
581
|
"language": {
|
|
366
582
|
"type": "string",
|
|
367
|
-
"description": "Primary language of a `github` repository result (`kind: \"repo\"`). Omitted when GitHub reports none."
|
|
583
|
+
"description": "Primary language of a `github` repository result (`metadata.kind: \"repo\"`). Omitted when GitHub reports none."
|
|
368
584
|
},
|
|
369
585
|
"num_comments": {
|
|
370
586
|
"type": "integer",
|
|
371
|
-
"description": "Comment count on a `github` issue, pull request or discussion, or on a `hackernews` thread (POST /news)."
|
|
587
|
+
"description": "Comment count on a `github` issue, pull request or discussion, on a `reddit` post, or on a `hackernews` thread (POST /news)."
|
|
372
588
|
},
|
|
373
589
|
"story_url": {
|
|
374
590
|
"type": "string",
|
|
375
591
|
"format": "uri",
|
|
376
|
-
"description": "POST /news with `search_service: \"hackernews\"` only: the submitted article. `link` is the Hacker News discussion thread; `story_url` is
|
|
592
|
+
"description": "POST /news with `search_service: \"hackernews\"` only: the submitted article. `link` is the Hacker News discussion thread; `metadata.story_url` is omitted for Ask HN / Show HN text posts."
|
|
377
593
|
},
|
|
378
594
|
"points": {
|
|
379
595
|
"type": "integer",
|
|
@@ -631,7 +847,7 @@
|
|
|
631
847
|
"properties": {
|
|
632
848
|
"search_query": {
|
|
633
849
|
"type": "string",
|
|
634
|
-
"description": "
|
|
850
|
+
"description": "Query sent to the first engine in `sources`. Each engine searches its own span of the request words, without platform names; the time window is applied as a filter."
|
|
635
851
|
},
|
|
636
852
|
"sources": {
|
|
637
853
|
"type": "array",
|
|
@@ -652,7 +868,7 @@
|
|
|
652
868
|
"year",
|
|
653
869
|
null
|
|
654
870
|
],
|
|
655
|
-
"description": "Publication window applied, or null for none."
|
|
871
|
+
"description": "Publication window applied, or null for none. year means the past 365 days, not the current calendar year."
|
|
656
872
|
}
|
|
657
873
|
}
|
|
658
874
|
},
|
|
@@ -954,6 +1170,189 @@
|
|
|
954
1170
|
}
|
|
955
1171
|
},
|
|
956
1172
|
"paths": {
|
|
1173
|
+
"/maps": {
|
|
1174
|
+
"post": {
|
|
1175
|
+
"operationId": "maps",
|
|
1176
|
+
"summary": "Search Google Maps for local businesses and places",
|
|
1177
|
+
"description": "Discover businesses and places with names, place IDs and public Maps links, plus addresses, contact details, ratings, review counts, coordinates and opening hours when available. Optional result fields are omitted when unavailable. Use POST /search for webpages and POST /crawl to read a business website.\n\nEach request fetches one Google Maps page of up to 20 places. page is 1-based (1–6); page > 1 requires location coordinates. max_results only truncates that page and does not change the price or carry unused places into the next page. Send the same query, country, language and location with the next page number for another separately billed request. There is no automatic pagination, retry or filling from another engine. Results can change between requests; an empty or short page does not guarantee that no later results exist.\n\nThe response contains searchParameters and results, following the single-request format of POST /search and POST /news. searchParameters includes the requested page and normalized defaults. Result positions preserve native page order with possible gaps, not a stable SEO rank. A short or empty results array does not assert a total count or a next page.\n\nA confirmed empty page is completed and charged. Technical failures return an error and release the credit reservation. GET /usage separately returns the remaining account balance.\n\nAccount credits only; no batch requests or payment protocols. Unknown fields are rejected; validation failures return 422 with errors entries containing field, message and code. Normal account limits apply (200 requests per minute). Set your client timeout above 20 seconds. SDK and MCP methods are not included in this release. Costs 3 credits per request.",
|
|
1178
|
+
"tags": [
|
|
1179
|
+
"Maps"
|
|
1180
|
+
],
|
|
1181
|
+
"responses": {
|
|
1182
|
+
"200": {
|
|
1183
|
+
"description": "Successful response",
|
|
1184
|
+
"content": {
|
|
1185
|
+
"application/json": {
|
|
1186
|
+
"schema": {
|
|
1187
|
+
"$ref": "#/components/schemas/MapsResponse"
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
},
|
|
1192
|
+
"400": {
|
|
1193
|
+
"description": "Bad Request",
|
|
1194
|
+
"content": {
|
|
1195
|
+
"application/json": {
|
|
1196
|
+
"schema": {
|
|
1197
|
+
"$ref": "#/components/schemas/ApiError"
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
},
|
|
1202
|
+
"401": {
|
|
1203
|
+
"description": "Unauthorized",
|
|
1204
|
+
"content": {
|
|
1205
|
+
"application/json": {
|
|
1206
|
+
"schema": {
|
|
1207
|
+
"$ref": "#/components/schemas/ApiError"
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
},
|
|
1212
|
+
"402": {
|
|
1213
|
+
"description": "Payment Required",
|
|
1214
|
+
"content": {
|
|
1215
|
+
"application/problem+json": {
|
|
1216
|
+
"schema": {
|
|
1217
|
+
"$ref": "#/components/schemas/ApiError"
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
},
|
|
1222
|
+
"422": {
|
|
1223
|
+
"description": "Validation Error",
|
|
1224
|
+
"content": {
|
|
1225
|
+
"application/json": {
|
|
1226
|
+
"schema": {
|
|
1227
|
+
"$ref": "#/components/schemas/ApiError"
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
},
|
|
1232
|
+
"429": {
|
|
1233
|
+
"description": "Too Many Requests",
|
|
1234
|
+
"content": {
|
|
1235
|
+
"application/json": {
|
|
1236
|
+
"schema": {
|
|
1237
|
+
"$ref": "#/components/schemas/ApiError"
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
},
|
|
1242
|
+
"500": {
|
|
1243
|
+
"description": "Internal Server Error",
|
|
1244
|
+
"content": {
|
|
1245
|
+
"application/json": {
|
|
1246
|
+
"schema": {
|
|
1247
|
+
"$ref": "#/components/schemas/ApiError"
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
},
|
|
1252
|
+
"502": {
|
|
1253
|
+
"description": "Bad Gateway",
|
|
1254
|
+
"content": {
|
|
1255
|
+
"application/json": {
|
|
1256
|
+
"schema": {
|
|
1257
|
+
"$ref": "#/components/schemas/ApiError"
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
},
|
|
1262
|
+
"503": {
|
|
1263
|
+
"description": "Service Unavailable",
|
|
1264
|
+
"content": {
|
|
1265
|
+
"application/json": {
|
|
1266
|
+
"schema": {
|
|
1267
|
+
"$ref": "#/components/schemas/ApiError"
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
},
|
|
1273
|
+
"security": [
|
|
1274
|
+
{
|
|
1275
|
+
"bearerAuth": []
|
|
1276
|
+
}
|
|
1277
|
+
],
|
|
1278
|
+
"requestBody": {
|
|
1279
|
+
"required": true,
|
|
1280
|
+
"content": {
|
|
1281
|
+
"application/json": {
|
|
1282
|
+
"schema": {
|
|
1283
|
+
"type": "object",
|
|
1284
|
+
"properties": {
|
|
1285
|
+
"query": {
|
|
1286
|
+
"type": "string",
|
|
1287
|
+
"minLength": 1,
|
|
1288
|
+
"maxLength": 1000,
|
|
1289
|
+
"description": "Google Maps search phrase; leading and trailing whitespace is removed.",
|
|
1290
|
+
"example": "coffee in Manhattan"
|
|
1291
|
+
},
|
|
1292
|
+
"country": {
|
|
1293
|
+
"type": "string",
|
|
1294
|
+
"pattern": "^[a-zA-Z]{2}$",
|
|
1295
|
+
"default": "us",
|
|
1296
|
+
"description": "Two-letter country code, normalized to lowercase. Defaults to us."
|
|
1297
|
+
},
|
|
1298
|
+
"language": {
|
|
1299
|
+
"type": "string",
|
|
1300
|
+
"pattern": "^[a-z]{2,3}(-[a-zA-Z]{2,4})?$",
|
|
1301
|
+
"default": "en",
|
|
1302
|
+
"description": "Result language, for example en, de or zh-CN. Defaults to en."
|
|
1303
|
+
},
|
|
1304
|
+
"location": {
|
|
1305
|
+
"type": "object",
|
|
1306
|
+
"properties": {
|
|
1307
|
+
"latitude": {
|
|
1308
|
+
"type": "number",
|
|
1309
|
+
"minimum": -90,
|
|
1310
|
+
"maximum": 90
|
|
1311
|
+
},
|
|
1312
|
+
"longitude": {
|
|
1313
|
+
"type": "number",
|
|
1314
|
+
"minimum": -180,
|
|
1315
|
+
"maximum": 180
|
|
1316
|
+
},
|
|
1317
|
+
"zoom": {
|
|
1318
|
+
"type": "number",
|
|
1319
|
+
"minimum": 3,
|
|
1320
|
+
"maximum": 30,
|
|
1321
|
+
"default": 14
|
|
1322
|
+
}
|
|
1323
|
+
},
|
|
1324
|
+
"required": [
|
|
1325
|
+
"latitude",
|
|
1326
|
+
"longitude"
|
|
1327
|
+
],
|
|
1328
|
+
"additionalProperties": false,
|
|
1329
|
+
"description": "Search origin coordinates and map zoom (default 14). Required for page > 1. Latitude must be -90 to 90, longitude -180 to 180, and zoom 3 to 30. Example: {\"latitude\":40.7455,\"longitude\":-74.0083,\"zoom\":15}."
|
|
1330
|
+
},
|
|
1331
|
+
"page": {
|
|
1332
|
+
"type": "integer",
|
|
1333
|
+
"minimum": 1,
|
|
1334
|
+
"maximum": 6,
|
|
1335
|
+
"default": 1,
|
|
1336
|
+
"description": "Page number, 1–6; default 1. Accepts an integer or canonical integer string such as \"2\". Empty strings use the default. Pages after the first require location."
|
|
1337
|
+
},
|
|
1338
|
+
"max_results": {
|
|
1339
|
+
"type": "integer",
|
|
1340
|
+
"minimum": 1,
|
|
1341
|
+
"maximum": 20,
|
|
1342
|
+
"default": 20,
|
|
1343
|
+
"description": "Maximum places to return from this page, 1–20; default 20. Accepts an integer or canonical integer string such as \"10\". Empty strings use the default. Truncation does not reduce the page charge or carry places to the next page."
|
|
1344
|
+
}
|
|
1345
|
+
},
|
|
1346
|
+
"required": [
|
|
1347
|
+
"query"
|
|
1348
|
+
],
|
|
1349
|
+
"additionalProperties": false
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
},
|
|
957
1356
|
"/feedback": {
|
|
958
1357
|
"post": {
|
|
959
1358
|
"operationId": "feedback",
|
|
@@ -1739,7 +2138,8 @@
|
|
|
1739
2138
|
],
|
|
1740
2139
|
"additionalProperties": false
|
|
1741
2140
|
},
|
|
1742
|
-
"minItems": 1
|
|
2141
|
+
"minItems": 1,
|
|
2142
|
+
"maxItems": 50
|
|
1743
2143
|
}
|
|
1744
2144
|
]
|
|
1745
2145
|
}
|
|
@@ -2015,7 +2415,8 @@
|
|
|
2015
2415
|
],
|
|
2016
2416
|
"additionalProperties": false
|
|
2017
2417
|
},
|
|
2018
|
-
"minItems": 1
|
|
2418
|
+
"minItems": 1,
|
|
2419
|
+
"maxItems": 50
|
|
2019
2420
|
}
|
|
2020
2421
|
]
|
|
2021
2422
|
}
|
|
@@ -2332,7 +2733,8 @@
|
|
|
2332
2733
|
],
|
|
2333
2734
|
"additionalProperties": false
|
|
2334
2735
|
},
|
|
2335
|
-
"minItems": 1
|
|
2736
|
+
"minItems": 1,
|
|
2737
|
+
"maxItems": 50
|
|
2336
2738
|
}
|
|
2337
2739
|
]
|
|
2338
2740
|
}
|
|
@@ -33,6 +33,8 @@ from .types import (
|
|
|
33
33
|
FeedbackCategory,
|
|
34
34
|
FeedbackResponse,
|
|
35
35
|
HealthResponse,
|
|
36
|
+
MapsLocation,
|
|
37
|
+
MapsResponse,
|
|
36
38
|
NewsEngine,
|
|
37
39
|
NewsRequest,
|
|
38
40
|
NewsResponse,
|
|
@@ -64,6 +66,27 @@ def _compact(payload: Mapping[str, Any]) -> Dict[str, Any]:
|
|
|
64
66
|
return {key: value for key, value in payload.items() if value is not None}
|
|
65
67
|
|
|
66
68
|
|
|
69
|
+
def _maps_payload(
|
|
70
|
+
query: str,
|
|
71
|
+
*,
|
|
72
|
+
country: Optional[str],
|
|
73
|
+
language: Optional[str],
|
|
74
|
+
location: Optional[MapsLocation],
|
|
75
|
+
page: Optional[int],
|
|
76
|
+
max_results: Optional[int],
|
|
77
|
+
) -> Dict[str, Any]:
|
|
78
|
+
return _compact(
|
|
79
|
+
{
|
|
80
|
+
"query": query,
|
|
81
|
+
"country": country,
|
|
82
|
+
"language": language,
|
|
83
|
+
"location": dict(location) if location is not None else None,
|
|
84
|
+
"page": page,
|
|
85
|
+
"max_results": max_results,
|
|
86
|
+
}
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
|
|
67
90
|
def _search_payload(
|
|
68
91
|
query: str,
|
|
69
92
|
*,
|
|
@@ -321,6 +344,30 @@ class Search1API(_ClientConfig):
|
|
|
321
344
|
self._request_json("POST", "/ask", json={"query": query}, timeout=timeout),
|
|
322
345
|
)
|
|
323
346
|
|
|
347
|
+
def maps(
|
|
348
|
+
self,
|
|
349
|
+
query: str,
|
|
350
|
+
*,
|
|
351
|
+
country: Optional[str] = None,
|
|
352
|
+
language: Optional[str] = None,
|
|
353
|
+
location: Optional[MapsLocation] = None,
|
|
354
|
+
page: Optional[int] = None,
|
|
355
|
+
max_results: Optional[int] = None,
|
|
356
|
+
) -> MapsResponse:
|
|
357
|
+
"""Google Maps place search: one page of up to 20 places.
|
|
358
|
+
|
|
359
|
+
A completed page costs 3 credits. Pages after the first need ``location``.
|
|
360
|
+
"""
|
|
361
|
+
payload = _maps_payload(
|
|
362
|
+
query,
|
|
363
|
+
country=country,
|
|
364
|
+
language=language,
|
|
365
|
+
location=location,
|
|
366
|
+
page=page,
|
|
367
|
+
max_results=max_results,
|
|
368
|
+
)
|
|
369
|
+
return cast(MapsResponse, self._request_json("POST", "/maps", json=payload))
|
|
370
|
+
|
|
324
371
|
def crawl(
|
|
325
372
|
self, url: str, *, enable_fallback: Optional[bool] = None
|
|
326
373
|
) -> CrawlResponse:
|
|
@@ -683,6 +730,36 @@ class AsyncSearch1API(_ClientConfig):
|
|
|
683
730
|
),
|
|
684
731
|
)
|
|
685
732
|
|
|
733
|
+
async def maps(
|
|
734
|
+
self,
|
|
735
|
+
query: str,
|
|
736
|
+
*,
|
|
737
|
+
country: Optional[str] = None,
|
|
738
|
+
language: Optional[str] = None,
|
|
739
|
+
location: Optional[MapsLocation] = None,
|
|
740
|
+
page: Optional[int] = None,
|
|
741
|
+
max_results: Optional[int] = None,
|
|
742
|
+
) -> MapsResponse:
|
|
743
|
+
"""Google Maps place search: one page of up to 20 places.
|
|
744
|
+
|
|
745
|
+
A completed page costs 3 credits. Pages after the first need ``location``.
|
|
746
|
+
"""
|
|
747
|
+
return cast(
|
|
748
|
+
MapsResponse,
|
|
749
|
+
await self._request_json(
|
|
750
|
+
"POST",
|
|
751
|
+
"/maps",
|
|
752
|
+
json=_maps_payload(
|
|
753
|
+
query,
|
|
754
|
+
country=country,
|
|
755
|
+
language=language,
|
|
756
|
+
location=location,
|
|
757
|
+
page=page,
|
|
758
|
+
max_results=max_results,
|
|
759
|
+
),
|
|
760
|
+
),
|
|
761
|
+
)
|
|
762
|
+
|
|
686
763
|
async def crawl(
|
|
687
764
|
self, url: str, *, enable_fallback: Optional[bool] = None
|
|
688
765
|
) -> CrawlResponse:
|
|
@@ -54,9 +54,7 @@ class SearchResultRequired(TypedDict):
|
|
|
54
54
|
snippet: str
|
|
55
55
|
|
|
56
56
|
|
|
57
|
-
class
|
|
58
|
-
content: str
|
|
59
|
-
published_date: str
|
|
57
|
+
class SearchResultMetadata(TypedDict, total=False):
|
|
60
58
|
kind: Literal["repo", "issue", "pr", "discussion"]
|
|
61
59
|
stars: int
|
|
62
60
|
language: str
|
|
@@ -65,6 +63,12 @@ class SearchResult(SearchResultRequired, total=False):
|
|
|
65
63
|
story_url: str
|
|
66
64
|
|
|
67
65
|
|
|
66
|
+
class SearchResult(SearchResultRequired, total=False):
|
|
67
|
+
content: str
|
|
68
|
+
published_date: str
|
|
69
|
+
metadata: SearchResultMetadata
|
|
70
|
+
|
|
71
|
+
|
|
68
72
|
class SearchResponseRequired(TypedDict):
|
|
69
73
|
searchParameters: SearchRequest
|
|
70
74
|
results: List[SearchResult]
|
|
@@ -122,6 +126,70 @@ class AskResponse(TypedDict):
|
|
|
122
126
|
errors: List[AskError]
|
|
123
127
|
|
|
124
128
|
|
|
129
|
+
class MapsLocationRequired(TypedDict):
|
|
130
|
+
latitude: float
|
|
131
|
+
longitude: float
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
class MapsLocation(MapsLocationRequired, total=False):
|
|
135
|
+
zoom: float
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class MapsCoordinates(TypedDict):
|
|
139
|
+
latitude: float
|
|
140
|
+
longitude: float
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class MapsOpeningHours(TypedDict, total=False):
|
|
144
|
+
monday: str
|
|
145
|
+
tuesday: str
|
|
146
|
+
wednesday: str
|
|
147
|
+
thursday: str
|
|
148
|
+
friday: str
|
|
149
|
+
saturday: str
|
|
150
|
+
sunday: str
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class MapsPlaceRequired(TypedDict):
|
|
154
|
+
position: int
|
|
155
|
+
name: str
|
|
156
|
+
place_id: str
|
|
157
|
+
maps_url: str
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class MapsPlace(MapsPlaceRequired, total=False):
|
|
161
|
+
address: str
|
|
162
|
+
phone: str
|
|
163
|
+
website: str
|
|
164
|
+
thumbnail: str
|
|
165
|
+
category: str
|
|
166
|
+
categories: List[str]
|
|
167
|
+
rating: float
|
|
168
|
+
review_count: int
|
|
169
|
+
coordinates: MapsCoordinates
|
|
170
|
+
opening_hours: MapsOpeningHours
|
|
171
|
+
open_state: str
|
|
172
|
+
price: str
|
|
173
|
+
description: str
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class MapsParametersRequired(TypedDict):
|
|
177
|
+
query: str
|
|
178
|
+
country: str
|
|
179
|
+
language: str
|
|
180
|
+
page: int
|
|
181
|
+
max_results: int
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
class MapsParameters(MapsParametersRequired, total=False):
|
|
185
|
+
location: MapsLocation
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
class MapsResponse(TypedDict):
|
|
189
|
+
searchParameters: MapsParameters
|
|
190
|
+
results: List[MapsPlace]
|
|
191
|
+
|
|
192
|
+
|
|
125
193
|
FeedbackCategory = Literal["bug", "feature_request", "docs", "other"]
|
|
126
194
|
|
|
127
195
|
|
|
@@ -24,6 +24,39 @@ def test_requires_api_key(monkeypatch):
|
|
|
24
24
|
Search1API()
|
|
25
25
|
|
|
26
26
|
|
|
27
|
+
@pytest.mark.parametrize("method", ["search", "news"])
|
|
28
|
+
@pytest.mark.parametrize("asynchronous", [False, True])
|
|
29
|
+
def test_preserves_nested_metadata(method, asynchronous):
|
|
30
|
+
body = {
|
|
31
|
+
"searchParameters": {"query": "q"},
|
|
32
|
+
"results": [
|
|
33
|
+
{
|
|
34
|
+
"title": "Thread",
|
|
35
|
+
"link": "https://example.com/thread",
|
|
36
|
+
"snippet": "Discussion",
|
|
37
|
+
"published_date": "2026-10-12",
|
|
38
|
+
"metadata": {"num_comments": 0},
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
}
|
|
42
|
+
transport = httpx.MockTransport(lambda request: json_response(200, body, request))
|
|
43
|
+
|
|
44
|
+
async def run():
|
|
45
|
+
async with httpx.AsyncClient(transport=transport) as http_client:
|
|
46
|
+
async with AsyncSearch1API("test-key", client=http_client) as client:
|
|
47
|
+
return await getattr(client, method)("q")
|
|
48
|
+
|
|
49
|
+
if asynchronous:
|
|
50
|
+
response = asyncio.run(run())
|
|
51
|
+
else:
|
|
52
|
+
with httpx.Client(transport=transport) as http_client:
|
|
53
|
+
with Search1API("test-key", client=http_client) as client:
|
|
54
|
+
response = getattr(client, method)("q")
|
|
55
|
+
assert response == body
|
|
56
|
+
assert response["results"][0]["metadata"]["num_comments"] == 0
|
|
57
|
+
assert "num_comments" not in response["results"][0]
|
|
58
|
+
|
|
59
|
+
|
|
27
60
|
def test_rejects_invalid_retry_and_timeout_settings():
|
|
28
61
|
with pytest.raises(Search1APIConfigurationError, match="max_retries"):
|
|
29
62
|
Search1API("test-key", max_retries=-1)
|
|
@@ -272,6 +305,82 @@ def test_ask_sends_only_the_query_with_a_longer_timeout():
|
|
|
272
305
|
http_client.close()
|
|
273
306
|
|
|
274
307
|
|
|
308
|
+
def test_maps_sends_location_and_paging():
|
|
309
|
+
seen = []
|
|
310
|
+
body = {
|
|
311
|
+
"searchParameters": {
|
|
312
|
+
"query": "coffee shops",
|
|
313
|
+
"country": "us",
|
|
314
|
+
"language": "en",
|
|
315
|
+
"location": {"latitude": 40.7455, "longitude": -74.0083, "zoom": 15},
|
|
316
|
+
"page": 2,
|
|
317
|
+
"max_results": 5,
|
|
318
|
+
},
|
|
319
|
+
"results": [
|
|
320
|
+
{
|
|
321
|
+
"position": 21,
|
|
322
|
+
"name": "Example Coffee",
|
|
323
|
+
"place_id": "ChIJ123",
|
|
324
|
+
"maps_url": "https://www.google.com/maps/search/?api=1&query=Example",
|
|
325
|
+
"rating": 4.6,
|
|
326
|
+
}
|
|
327
|
+
],
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
def handler(request):
|
|
331
|
+
seen.append(request)
|
|
332
|
+
return json_response(200, body, request)
|
|
333
|
+
|
|
334
|
+
http_client = httpx.Client(transport=httpx.MockTransport(handler))
|
|
335
|
+
client = Search1API("test-key", client=http_client)
|
|
336
|
+
|
|
337
|
+
response = client.maps(
|
|
338
|
+
"coffee shops",
|
|
339
|
+
location={"latitude": 40.7455, "longitude": -74.0083, "zoom": 15},
|
|
340
|
+
page=2,
|
|
341
|
+
max_results=5,
|
|
342
|
+
)
|
|
343
|
+
|
|
344
|
+
assert response == body
|
|
345
|
+
assert str(seen[0].url) == "https://api.search1api.com/maps"
|
|
346
|
+
assert json.loads(seen[0].content) == {
|
|
347
|
+
"query": "coffee shops",
|
|
348
|
+
"location": {"latitude": 40.7455, "longitude": -74.0083, "zoom": 15},
|
|
349
|
+
"page": 2,
|
|
350
|
+
"max_results": 5,
|
|
351
|
+
}
|
|
352
|
+
http_client.close()
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
def test_async_maps():
|
|
356
|
+
async def run():
|
|
357
|
+
async def handler(request):
|
|
358
|
+
assert json.loads(request.content) == {"query": "ramen", "country": "jp"}
|
|
359
|
+
return json_response(
|
|
360
|
+
200,
|
|
361
|
+
{
|
|
362
|
+
"searchParameters": {
|
|
363
|
+
"query": "ramen",
|
|
364
|
+
"country": "jp",
|
|
365
|
+
"language": "en",
|
|
366
|
+
"page": 1,
|
|
367
|
+
"max_results": 20,
|
|
368
|
+
},
|
|
369
|
+
"results": [],
|
|
370
|
+
},
|
|
371
|
+
request,
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
http_client = httpx.AsyncClient(transport=httpx.MockTransport(handler))
|
|
375
|
+
client = AsyncSearch1API("test-key", client=http_client)
|
|
376
|
+
try:
|
|
377
|
+
assert (await client.maps("ramen", country="jp"))["results"] == []
|
|
378
|
+
finally:
|
|
379
|
+
await http_client.aclose()
|
|
380
|
+
|
|
381
|
+
asyncio.run(run())
|
|
382
|
+
|
|
383
|
+
|
|
275
384
|
def test_feedback_is_sent_once_without_retries():
|
|
276
385
|
calls = []
|
|
277
386
|
|
|
@@ -376,6 +485,7 @@ def test_sdk_covers_every_public_openapi_operation():
|
|
|
376
485
|
"extract": "extract",
|
|
377
486
|
"feedback": "feedback",
|
|
378
487
|
"health": "health",
|
|
488
|
+
"maps": "maps",
|
|
379
489
|
"news": "news",
|
|
380
490
|
"search": "search",
|
|
381
491
|
"screenshot": "screenshot",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|