nimble_python 0.6.0__tar.gz → 0.8.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 (86) hide show
  1. nimble_python-0.8.0/.release-please-manifest.json +3 -0
  2. {nimble_python-0.6.0 → nimble_python-0.8.0}/CHANGELOG.md +16 -0
  3. {nimble_python-0.6.0 → nimble_python-0.8.0}/PKG-INFO +1 -1
  4. {nimble_python-0.6.0 → nimble_python-0.8.0}/api.md +2 -1
  5. {nimble_python-0.6.0 → nimble_python-0.8.0}/pyproject.toml +1 -1
  6. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_client.py +225 -4
  7. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_version.py +1 -1
  8. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/types/__init__.py +2 -0
  9. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/types/client_extract_params.py +1 -1
  10. nimble_python-0.8.0/src/nimble_python/types/client_search_params.py +79 -0
  11. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/types/extract_response.py +4 -1
  12. nimble_python-0.8.0/src/nimble_python/types/search_response.py +94 -0
  13. {nimble_python-0.6.0 → nimble_python-0.8.0}/tests/api_resources/test_client.py +119 -1
  14. nimble_python-0.6.0/.release-please-manifest.json +0 -3
  15. {nimble_python-0.6.0 → nimble_python-0.8.0}/.gitignore +0 -0
  16. {nimble_python-0.6.0 → nimble_python-0.8.0}/CONTRIBUTING.md +0 -0
  17. {nimble_python-0.6.0 → nimble_python-0.8.0}/LICENSE +0 -0
  18. {nimble_python-0.6.0 → nimble_python-0.8.0}/README.md +0 -0
  19. {nimble_python-0.6.0 → nimble_python-0.8.0}/SECURITY.md +0 -0
  20. {nimble_python-0.6.0 → nimble_python-0.8.0}/bin/check-release-environment +0 -0
  21. {nimble_python-0.6.0 → nimble_python-0.8.0}/bin/publish-pypi +0 -0
  22. {nimble_python-0.6.0 → nimble_python-0.8.0}/examples/.keep +0 -0
  23. {nimble_python-0.6.0 → nimble_python-0.8.0}/release-please-config.json +0 -0
  24. {nimble_python-0.6.0 → nimble_python-0.8.0}/requirements-dev.lock +0 -0
  25. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/__init__.py +0 -0
  26. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_base_client.py +0 -0
  27. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_compat.py +0 -0
  28. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_constants.py +0 -0
  29. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_exceptions.py +0 -0
  30. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_files.py +0 -0
  31. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_models.py +0 -0
  32. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_qs.py +0 -0
  33. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_resource.py +0 -0
  34. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_response.py +0 -0
  35. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_streaming.py +0 -0
  36. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_types.py +0 -0
  37. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_utils/__init__.py +0 -0
  38. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_utils/_compat.py +0 -0
  39. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_utils/_datetime_parse.py +0 -0
  40. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_utils/_json.py +0 -0
  41. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_utils/_logs.py +0 -0
  42. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_utils/_proxy.py +0 -0
  43. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_utils/_reflection.py +0 -0
  44. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_utils/_resources_proxy.py +0 -0
  45. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_utils/_streams.py +0 -0
  46. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_utils/_sync.py +0 -0
  47. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_utils/_transform.py +0 -0
  48. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_utils/_typing.py +0 -0
  49. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/_utils/_utils.py +0 -0
  50. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/lib/.keep +0 -0
  51. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/py.typed +0 -0
  52. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/resources/__init__.py +0 -0
  53. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/resources/agents.py +0 -0
  54. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/resources/crawl.py +0 -0
  55. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/types/agent_get_response.py +0 -0
  56. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/types/agent_list_params.py +0 -0
  57. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/types/agent_list_response.py +0 -0
  58. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/types/client_map_params.py +0 -0
  59. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/types/crawl_list_params.py +0 -0
  60. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/types/crawl_list_response.py +0 -0
  61. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/types/crawl_status_response.py +0 -0
  62. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/types/crawl_terminate_response.py +0 -0
  63. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimble_python/types/map_response.py +0 -0
  64. {nimble_python-0.6.0 → nimble_python-0.8.0}/src/nimbleway/lib/.keep +0 -0
  65. {nimble_python-0.6.0 → nimble_python-0.8.0}/tests/__init__.py +0 -0
  66. {nimble_python-0.6.0 → nimble_python-0.8.0}/tests/api_resources/__init__.py +0 -0
  67. {nimble_python-0.6.0 → nimble_python-0.8.0}/tests/api_resources/test_agents.py +0 -0
  68. {nimble_python-0.6.0 → nimble_python-0.8.0}/tests/api_resources/test_crawl.py +0 -0
  69. {nimble_python-0.6.0 → nimble_python-0.8.0}/tests/conftest.py +0 -0
  70. {nimble_python-0.6.0 → nimble_python-0.8.0}/tests/sample_file.txt +0 -0
  71. {nimble_python-0.6.0 → nimble_python-0.8.0}/tests/test_client.py +0 -0
  72. {nimble_python-0.6.0 → nimble_python-0.8.0}/tests/test_deepcopy.py +0 -0
  73. {nimble_python-0.6.0 → nimble_python-0.8.0}/tests/test_extract_files.py +0 -0
  74. {nimble_python-0.6.0 → nimble_python-0.8.0}/tests/test_files.py +0 -0
  75. {nimble_python-0.6.0 → nimble_python-0.8.0}/tests/test_models.py +0 -0
  76. {nimble_python-0.6.0 → nimble_python-0.8.0}/tests/test_qs.py +0 -0
  77. {nimble_python-0.6.0 → nimble_python-0.8.0}/tests/test_required_args.py +0 -0
  78. {nimble_python-0.6.0 → nimble_python-0.8.0}/tests/test_response.py +0 -0
  79. {nimble_python-0.6.0 → nimble_python-0.8.0}/tests/test_streaming.py +0 -0
  80. {nimble_python-0.6.0 → nimble_python-0.8.0}/tests/test_transform.py +0 -0
  81. {nimble_python-0.6.0 → nimble_python-0.8.0}/tests/test_utils/test_datetime_parse.py +0 -0
  82. {nimble_python-0.6.0 → nimble_python-0.8.0}/tests/test_utils/test_json.py +0 -0
  83. {nimble_python-0.6.0 → nimble_python-0.8.0}/tests/test_utils/test_proxy.py +0 -0
  84. {nimble_python-0.6.0 → nimble_python-0.8.0}/tests/test_utils/test_typing.py +0 -0
  85. {nimble_python-0.6.0 → nimble_python-0.8.0}/tests/utils.py +0 -0
  86. {nimble_python-0.6.0 → nimble_python-0.8.0}/uv.lock +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.8.0"
3
+ }
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.8.0 (2026-02-17)
4
+
5
+ Full Changelog: [v0.7.0...v0.8.0](https://github.com/Nimbleway/nimble-python/compare/v0.7.0...v0.8.0)
6
+
7
+ ### Features
8
+
9
+ * **api:** api update ([d89a46f](https://github.com/Nimbleway/nimble-python/commit/d89a46fdb87ac1bc68f4279f2b168c4dca4616e0))
10
+
11
+ ## 0.7.0 (2026-02-15)
12
+
13
+ Full Changelog: [v0.6.0...v0.7.0](https://github.com/Nimbleway/nimble-python/compare/v0.6.0...v0.7.0)
14
+
15
+ ### Features
16
+
17
+ * **api:** re-add search ([072bc34](https://github.com/Nimbleway/nimble-python/commit/072bc340f7aa7fc719c7778de6bd47ee3812e567))
18
+
3
19
  ## 0.6.0 (2026-02-15)
4
20
 
5
21
  Full Changelog: [v0.5.0...v0.6.0](https://github.com/Nimbleway/nimble-python/compare/v0.5.0...v0.6.0)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: nimble_python
3
- Version: 0.6.0
3
+ Version: 0.8.0
4
4
  Summary: The official Python library for the nimble API
5
5
  Project-URL: Homepage, https://github.com/Nimbleway/nimble-python
6
6
  Project-URL: Repository, https://github.com/Nimbleway/nimble-python
@@ -3,13 +3,14 @@
3
3
  Types:
4
4
 
5
5
  ```python
6
- from nimble_python.types import ExtractResponse, MapResponse
6
+ from nimble_python.types import ExtractResponse, MapResponse, SearchResponse
7
7
  ```
8
8
 
9
9
  Methods:
10
10
 
11
11
  - <code title="post /v1/extract">client.<a href="./src/nimble_python/_client.py">extract</a>(\*\*<a href="src/nimble_python/types/client_extract_params.py">params</a>) -> <a href="./src/nimble_python/types/extract_response.py">ExtractResponse</a></code>
12
12
  - <code title="post /v1/map">client.<a href="./src/nimble_python/_client.py">map</a>(\*\*<a href="src/nimble_python/types/client_map_params.py">params</a>) -> <a href="./src/nimble_python/types/map_response.py">MapResponse</a></code>
13
+ - <code title="post /v1/search">client.<a href="./src/nimble_python/_client.py">search</a>(\*\*<a href="src/nimble_python/types/client_search_params.py">params</a>) -> <a href="./src/nimble_python/types/search_response.py">SearchResponse</a></code>
13
14
 
14
15
  # Agents
15
16
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "nimble_python"
3
- version = "0.6.0"
3
+ version = "0.8.0"
4
4
  description = "The official Python library for the nimble API"
5
5
  dynamic = ["readme"]
6
6
  license = "Apache-2.0"
@@ -3,14 +3,14 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import os
6
- from typing import TYPE_CHECKING, Any, Dict, List, Union, Mapping, Iterable
6
+ from typing import TYPE_CHECKING, Any, Dict, List, Union, Mapping, Iterable, Optional
7
7
  from typing_extensions import Self, Literal, override
8
8
 
9
9
  import httpx
10
10
 
11
11
  from . import _exceptions
12
12
  from ._qs import Querystring
13
- from .types import client_map_params, client_extract_params
13
+ from .types import client_map_params, client_search_params, client_extract_params
14
14
  from ._types import (
15
15
  Body,
16
16
  Omit,
@@ -48,6 +48,7 @@ from ._base_client import (
48
48
  make_request_options,
49
49
  )
50
50
  from .types.map_response import MapResponse
51
+ from .types.search_response import SearchResponse
51
52
  from .types.extract_response import ExtractResponse
52
53
 
53
54
  if TYPE_CHECKING:
@@ -477,7 +478,7 @@ class Nimble(SyncAPIClient):
477
478
  device: Literal["desktop", "mobile", "tablet"] | Omit = omit,
478
479
  driver: Literal["vx6", "vx8", "vx8-pro", "vx10", "vx10-pro", "vx12", "vx12-pro"] | Omit = omit,
479
480
  expected_status_codes: Iterable[int] | Omit = omit,
480
- formats: List[Literal["html", "markdown"]] | Omit = omit,
481
+ formats: List[Literal["html", "markdown", "screenshot"]] | Omit = omit,
481
482
  headers: Dict[str, Union[str, SequenceNotStr[str], None]] | Omit = omit,
482
483
  http2: bool | Omit = omit,
483
484
  is_xhr: bool | Omit = omit,
@@ -2047,6 +2048,110 @@ class Nimble(SyncAPIClient):
2047
2048
  cast_to=MapResponse,
2048
2049
  )
2049
2050
 
2051
+ def search(
2052
+ self,
2053
+ *,
2054
+ query: str,
2055
+ content_type: Optional[SequenceNotStr[str]] | Omit = omit,
2056
+ country: str | Omit = omit,
2057
+ deep_search: bool | Omit = omit,
2058
+ end_date: Optional[str] | Omit = omit,
2059
+ exclude_domains: Optional[SequenceNotStr[str]] | Omit = omit,
2060
+ include_answer: bool | Omit = omit,
2061
+ include_domains: Optional[SequenceNotStr[str]] | Omit = omit,
2062
+ locale: str | Omit = omit,
2063
+ max_subagents: int | Omit = omit,
2064
+ num_results: int | Omit = omit,
2065
+ parsing_type: Literal["plain_text", "markdown", "simplified_html"] | Omit = omit,
2066
+ search_engine: Optional[Literal["google_search", "google_sge", "bing_search", "yandex_search"]] | Omit = omit,
2067
+ start_date: Optional[str] | Omit = omit,
2068
+ time_range: Optional[Literal["hour", "day", "week", "month", "year"]] | Omit = omit,
2069
+ topic: Union[str, SequenceNotStr[str]] | Omit = omit,
2070
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
2071
+ # The extra values given here take precedence over values defined on the client or passed to this method.
2072
+ extra_headers: Headers | None = None,
2073
+ extra_query: Query | None = None,
2074
+ extra_body: Body | None = None,
2075
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
2076
+ ) -> SearchResponse:
2077
+ """
2078
+ Search
2079
+
2080
+ Args:
2081
+ query: Search query string
2082
+
2083
+ content_type: Filter by content type (only supported with focus=general). Supports semantic
2084
+ groups ('documents', 'spreadsheets', 'presentations') and specific formats
2085
+ ('pdf', 'docx', 'xlsx', etc.)
2086
+
2087
+ deep_search: If True, fetches and extracts full page content for each search result. If
2088
+ False, returns only metadata (title, snippet, URL)
2089
+
2090
+ end_date: Filter results before this date (format: YYYY-MM-DD or YYYY)
2091
+
2092
+ exclude_domains: List of domains to exclude from search results. Maximum 50 domains.
2093
+
2094
+ include_answer: Generate LLM answer summary based on search result snippets (works with both
2095
+ deep_search=True and False)
2096
+
2097
+ include_domains: List of domains to include in search results. Maximum 50 domains.
2098
+
2099
+ max_subagents: Maximum number of subagents to execute in parallel for WSA focus modes
2100
+ (shopping, social, geo). Ignored for traditional SERP focus modes. Default: 3,
2101
+ Range: 1-10.
2102
+
2103
+ num_results: Maximum number of results to return (actual count may be less)
2104
+
2105
+ parsing_type: Output format: plain_text, markdown, or simplified_html
2106
+
2107
+ search_engine: Enum representing the search engines supported by Nimble ⚠️ DEPRECATED: This
2108
+ parameter is ignored. Use 'focus' parameter instead.
2109
+
2110
+ start_date: Filter results after this date (format: YYYY-MM-DD or YYYY)
2111
+
2112
+ time_range: Time range filters passed to Webit SERP API as 'time' parameter.
2113
+
2114
+ topic: Search focus/specialization. Can be a single focus mode (e.g., 'shopping',
2115
+ 'social') or a list of explicit subagent names (e.g., ['amazon_serp',
2116
+ 'target_serp'])
2117
+
2118
+ extra_headers: Send extra headers
2119
+
2120
+ extra_query: Add additional query parameters to the request
2121
+
2122
+ extra_body: Add additional JSON properties to the request
2123
+
2124
+ timeout: Override the client-level default timeout for this request, in seconds
2125
+ """
2126
+ return self.post(
2127
+ "/v1/search",
2128
+ body=maybe_transform(
2129
+ {
2130
+ "query": query,
2131
+ "content_type": content_type,
2132
+ "country": country,
2133
+ "deep_search": deep_search,
2134
+ "end_date": end_date,
2135
+ "exclude_domains": exclude_domains,
2136
+ "include_answer": include_answer,
2137
+ "include_domains": include_domains,
2138
+ "locale": locale,
2139
+ "max_subagents": max_subagents,
2140
+ "num_results": num_results,
2141
+ "parsing_type": parsing_type,
2142
+ "search_engine": search_engine,
2143
+ "start_date": start_date,
2144
+ "time_range": time_range,
2145
+ "topic": topic,
2146
+ },
2147
+ client_search_params.ClientSearchParams,
2148
+ ),
2149
+ options=make_request_options(
2150
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
2151
+ ),
2152
+ cast_to=SearchResponse,
2153
+ )
2154
+
2050
2155
  @override
2051
2156
  def _make_status_error(
2052
2157
  self,
@@ -2500,7 +2605,7 @@ class AsyncNimble(AsyncAPIClient):
2500
2605
  device: Literal["desktop", "mobile", "tablet"] | Omit = omit,
2501
2606
  driver: Literal["vx6", "vx8", "vx8-pro", "vx10", "vx10-pro", "vx12", "vx12-pro"] | Omit = omit,
2502
2607
  expected_status_codes: Iterable[int] | Omit = omit,
2503
- formats: List[Literal["html", "markdown"]] | Omit = omit,
2608
+ formats: List[Literal["html", "markdown", "screenshot"]] | Omit = omit,
2504
2609
  headers: Dict[str, Union[str, SequenceNotStr[str], None]] | Omit = omit,
2505
2610
  http2: bool | Omit = omit,
2506
2611
  is_xhr: bool | Omit = omit,
@@ -4070,6 +4175,110 @@ class AsyncNimble(AsyncAPIClient):
4070
4175
  cast_to=MapResponse,
4071
4176
  )
4072
4177
 
4178
+ async def search(
4179
+ self,
4180
+ *,
4181
+ query: str,
4182
+ content_type: Optional[SequenceNotStr[str]] | Omit = omit,
4183
+ country: str | Omit = omit,
4184
+ deep_search: bool | Omit = omit,
4185
+ end_date: Optional[str] | Omit = omit,
4186
+ exclude_domains: Optional[SequenceNotStr[str]] | Omit = omit,
4187
+ include_answer: bool | Omit = omit,
4188
+ include_domains: Optional[SequenceNotStr[str]] | Omit = omit,
4189
+ locale: str | Omit = omit,
4190
+ max_subagents: int | Omit = omit,
4191
+ num_results: int | Omit = omit,
4192
+ parsing_type: Literal["plain_text", "markdown", "simplified_html"] | Omit = omit,
4193
+ search_engine: Optional[Literal["google_search", "google_sge", "bing_search", "yandex_search"]] | Omit = omit,
4194
+ start_date: Optional[str] | Omit = omit,
4195
+ time_range: Optional[Literal["hour", "day", "week", "month", "year"]] | Omit = omit,
4196
+ topic: Union[str, SequenceNotStr[str]] | Omit = omit,
4197
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
4198
+ # The extra values given here take precedence over values defined on the client or passed to this method.
4199
+ extra_headers: Headers | None = None,
4200
+ extra_query: Query | None = None,
4201
+ extra_body: Body | None = None,
4202
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
4203
+ ) -> SearchResponse:
4204
+ """
4205
+ Search
4206
+
4207
+ Args:
4208
+ query: Search query string
4209
+
4210
+ content_type: Filter by content type (only supported with focus=general). Supports semantic
4211
+ groups ('documents', 'spreadsheets', 'presentations') and specific formats
4212
+ ('pdf', 'docx', 'xlsx', etc.)
4213
+
4214
+ deep_search: If True, fetches and extracts full page content for each search result. If
4215
+ False, returns only metadata (title, snippet, URL)
4216
+
4217
+ end_date: Filter results before this date (format: YYYY-MM-DD or YYYY)
4218
+
4219
+ exclude_domains: List of domains to exclude from search results. Maximum 50 domains.
4220
+
4221
+ include_answer: Generate LLM answer summary based on search result snippets (works with both
4222
+ deep_search=True and False)
4223
+
4224
+ include_domains: List of domains to include in search results. Maximum 50 domains.
4225
+
4226
+ max_subagents: Maximum number of subagents to execute in parallel for WSA focus modes
4227
+ (shopping, social, geo). Ignored for traditional SERP focus modes. Default: 3,
4228
+ Range: 1-10.
4229
+
4230
+ num_results: Maximum number of results to return (actual count may be less)
4231
+
4232
+ parsing_type: Output format: plain_text, markdown, or simplified_html
4233
+
4234
+ search_engine: Enum representing the search engines supported by Nimble ⚠️ DEPRECATED: This
4235
+ parameter is ignored. Use 'focus' parameter instead.
4236
+
4237
+ start_date: Filter results after this date (format: YYYY-MM-DD or YYYY)
4238
+
4239
+ time_range: Time range filters passed to Webit SERP API as 'time' parameter.
4240
+
4241
+ topic: Search focus/specialization. Can be a single focus mode (e.g., 'shopping',
4242
+ 'social') or a list of explicit subagent names (e.g., ['amazon_serp',
4243
+ 'target_serp'])
4244
+
4245
+ extra_headers: Send extra headers
4246
+
4247
+ extra_query: Add additional query parameters to the request
4248
+
4249
+ extra_body: Add additional JSON properties to the request
4250
+
4251
+ timeout: Override the client-level default timeout for this request, in seconds
4252
+ """
4253
+ return await self.post(
4254
+ "/v1/search",
4255
+ body=await async_maybe_transform(
4256
+ {
4257
+ "query": query,
4258
+ "content_type": content_type,
4259
+ "country": country,
4260
+ "deep_search": deep_search,
4261
+ "end_date": end_date,
4262
+ "exclude_domains": exclude_domains,
4263
+ "include_answer": include_answer,
4264
+ "include_domains": include_domains,
4265
+ "locale": locale,
4266
+ "max_subagents": max_subagents,
4267
+ "num_results": num_results,
4268
+ "parsing_type": parsing_type,
4269
+ "search_engine": search_engine,
4270
+ "start_date": start_date,
4271
+ "time_range": time_range,
4272
+ "topic": topic,
4273
+ },
4274
+ client_search_params.ClientSearchParams,
4275
+ ),
4276
+ options=make_request_options(
4277
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
4278
+ ),
4279
+ cast_to=SearchResponse,
4280
+ )
4281
+
4073
4282
  @override
4074
4283
  def _make_status_error(
4075
4284
  self,
@@ -4116,6 +4325,9 @@ class NimbleWithRawResponse:
4116
4325
  self.map = to_raw_response_wrapper(
4117
4326
  client.map,
4118
4327
  )
4328
+ self.search = to_raw_response_wrapper(
4329
+ client.search,
4330
+ )
4119
4331
 
4120
4332
  @cached_property
4121
4333
  def agents(self) -> agents.AgentsResourceWithRawResponse:
@@ -4142,6 +4354,9 @@ class AsyncNimbleWithRawResponse:
4142
4354
  self.map = async_to_raw_response_wrapper(
4143
4355
  client.map,
4144
4356
  )
4357
+ self.search = async_to_raw_response_wrapper(
4358
+ client.search,
4359
+ )
4145
4360
 
4146
4361
  @cached_property
4147
4362
  def agents(self) -> agents.AsyncAgentsResourceWithRawResponse:
@@ -4168,6 +4383,9 @@ class NimbleWithStreamedResponse:
4168
4383
  self.map = to_streamed_response_wrapper(
4169
4384
  client.map,
4170
4385
  )
4386
+ self.search = to_streamed_response_wrapper(
4387
+ client.search,
4388
+ )
4171
4389
 
4172
4390
  @cached_property
4173
4391
  def agents(self) -> agents.AgentsResourceWithStreamingResponse:
@@ -4194,6 +4412,9 @@ class AsyncNimbleWithStreamedResponse:
4194
4412
  self.map = async_to_streamed_response_wrapper(
4195
4413
  client.map,
4196
4414
  )
4415
+ self.search = async_to_streamed_response_wrapper(
4416
+ client.search,
4417
+ )
4197
4418
 
4198
4419
  @cached_property
4199
4420
  def agents(self) -> agents.AsyncAgentsResourceWithStreamingResponse:
@@ -1,4 +1,4 @@
1
1
  # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
2
 
3
3
  __title__ = "nimble_python"
4
- __version__ = "0.6.0" # x-release-please-version
4
+ __version__ = "0.8.0" # x-release-please-version
@@ -3,6 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  from .map_response import MapResponse as MapResponse
6
+ from .search_response import SearchResponse as SearchResponse
6
7
  from .extract_response import ExtractResponse as ExtractResponse
7
8
  from .agent_list_params import AgentListParams as AgentListParams
8
9
  from .client_map_params import ClientMapParams as ClientMapParams
@@ -10,6 +11,7 @@ from .crawl_list_params import CrawlListParams as CrawlListParams
10
11
  from .agent_get_response import AgentGetResponse as AgentGetResponse
11
12
  from .agent_list_response import AgentListResponse as AgentListResponse
12
13
  from .crawl_list_response import CrawlListResponse as CrawlListResponse
14
+ from .client_search_params import ClientSearchParams as ClientSearchParams
13
15
  from .client_extract_params import ClientExtractParams as ClientExtractParams
14
16
  from .crawl_status_response import CrawlStatusResponse as CrawlStatusResponse
15
17
  from .crawl_terminate_response import CrawlTerminateResponse as CrawlTerminateResponse
@@ -343,7 +343,7 @@ class ClientExtractParams(TypedDict, total=False):
343
343
  expected_status_codes: Iterable[int]
344
344
  """Expected HTTP status codes for successful requests"""
345
345
 
346
- formats: List[Literal["html", "markdown"]]
346
+ formats: List[Literal["html", "markdown", "screenshot"]]
347
347
  """List of acceptable response formats in order of preference"""
348
348
 
349
349
  headers: Dict[str, Union[str, SequenceNotStr[str], None]]
@@ -0,0 +1,79 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Union, Optional
6
+ from typing_extensions import Literal, Required, TypedDict
7
+
8
+ from .._types import SequenceNotStr
9
+
10
+ __all__ = ["ClientSearchParams"]
11
+
12
+
13
+ class ClientSearchParams(TypedDict, total=False):
14
+ query: Required[str]
15
+ """Search query string"""
16
+
17
+ content_type: Optional[SequenceNotStr[str]]
18
+ """Filter by content type (only supported with focus=general).
19
+
20
+ Supports semantic groups ('documents', 'spreadsheets', 'presentations') and
21
+ specific formats ('pdf', 'docx', 'xlsx', etc.)
22
+ """
23
+
24
+ country: str
25
+
26
+ deep_search: bool
27
+ """If True, fetches and extracts full page content for each search result.
28
+
29
+ If False, returns only metadata (title, snippet, URL)
30
+ """
31
+
32
+ end_date: Optional[str]
33
+ """Filter results before this date (format: YYYY-MM-DD or YYYY)"""
34
+
35
+ exclude_domains: Optional[SequenceNotStr[str]]
36
+ """List of domains to exclude from search results. Maximum 50 domains."""
37
+
38
+ include_answer: bool
39
+ """
40
+ Generate LLM answer summary based on search result snippets (works with both
41
+ deep_search=True and False)
42
+ """
43
+
44
+ include_domains: Optional[SequenceNotStr[str]]
45
+ """List of domains to include in search results. Maximum 50 domains."""
46
+
47
+ locale: str
48
+
49
+ max_subagents: int
50
+ """
51
+ Maximum number of subagents to execute in parallel for WSA focus modes
52
+ (shopping, social, geo). Ignored for traditional SERP focus modes. Default: 3,
53
+ Range: 1-10.
54
+ """
55
+
56
+ num_results: int
57
+ """Maximum number of results to return (actual count may be less)"""
58
+
59
+ parsing_type: Literal["plain_text", "markdown", "simplified_html"]
60
+ """Output format: plain_text, markdown, or simplified_html"""
61
+
62
+ search_engine: Optional[Literal["google_search", "google_sge", "bing_search", "yandex_search"]]
63
+ """
64
+ Enum representing the search engines supported by Nimble ⚠️ DEPRECATED: This
65
+ parameter is ignored. Use 'focus' parameter instead.
66
+ """
67
+
68
+ start_date: Optional[str]
69
+ """Filter results after this date (format: YYYY-MM-DD or YYYY)"""
70
+
71
+ time_range: Optional[Literal["hour", "day", "week", "month", "year"]]
72
+ """Time range filters passed to Webit SERP API as 'time' parameter."""
73
+
74
+ topic: Union[str, SequenceNotStr[str]]
75
+ """Search focus/specialization.
76
+
77
+ Can be a single focus mode (e.g., 'shopping', 'social') or a list of explicit
78
+ subagent names (e.g., ['amazon_serp', 'target_serp'])
79
+ """
@@ -253,7 +253,10 @@ class Data(BaseModel):
253
253
  """The list of redirects that occurred during the task."""
254
254
 
255
255
  screenshots: Optional[List[object]] = None
256
- """The screenshots from browser actions taken during the task."""
256
+ """
257
+ Screenshots taken during the task, from browser actions, or the screenshot
258
+ format.
259
+ """
257
260
 
258
261
 
259
262
  class Metadata(BaseModel):
@@ -0,0 +1,94 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from typing import Dict, List, Union, Optional
4
+ from typing_extensions import TypeAlias
5
+
6
+ from .._models import BaseModel
7
+
8
+ __all__ = [
9
+ "SearchResponse",
10
+ "Result",
11
+ "ResultMetadata",
12
+ "ResultMetadataSerpMetadata",
13
+ "ResultMetadataWsaMetadata",
14
+ "AnswerCitation",
15
+ ]
16
+
17
+
18
+ class ResultMetadataSerpMetadata(BaseModel):
19
+ """Metadata for SERP-based search results (general, news, location)."""
20
+
21
+ country: str
22
+
23
+ entity_type: str
24
+
25
+ locale: str
26
+
27
+ position: int
28
+
29
+ driver: Optional[str] = None
30
+
31
+
32
+ class ResultMetadataWsaMetadata(BaseModel):
33
+ """Metadata for WSA-based search results."""
34
+
35
+ agent_name: str
36
+
37
+
38
+ ResultMetadata: TypeAlias = Union[ResultMetadataSerpMetadata, ResultMetadataWsaMetadata]
39
+
40
+
41
+ class Result(BaseModel):
42
+ """Unified result model for all search types (SERP and WSA).
43
+
44
+ This model provides a consistent structure for search results,
45
+ with platform-specific data in additional_data and typed metadata.
46
+ """
47
+
48
+ content: str
49
+
50
+ description: str
51
+
52
+ metadata: ResultMetadata
53
+ """Metadata for SERP-based search results (general, news, location)."""
54
+
55
+ title: str
56
+
57
+ url: str
58
+
59
+ additional_data: Optional[Dict[str, object]] = None
60
+ """Platform-specific fields (e.g., price, rating, publish_date).
61
+
62
+ Omitted from response when no extra data.
63
+ """
64
+
65
+
66
+ class AnswerCitation(BaseModel):
67
+ """Citation model that maps citation markers to result indices."""
68
+
69
+ marker: int
70
+ """Citation marker number (e.g., 1 for [1])"""
71
+
72
+ result_index: int
73
+ """Zero-based index into the results array"""
74
+
75
+
76
+ class SearchResponse(BaseModel):
77
+ """Response model from SearchService with results and optional LLM answer.
78
+
79
+ Note: request_id is always a valid UUID generated internally by the middleware,
80
+ so no validation is needed.
81
+ """
82
+
83
+ request_id: str
84
+ """Unique identifier for this request (UUID)"""
85
+
86
+ results: List[Result]
87
+
88
+ total_results: int
89
+ """Number of results returned"""
90
+
91
+ answer: Optional[str] = None
92
+
93
+ answer_citations: Optional[List[AnswerCitation]] = None
94
+ """Citations mapping citation markers to result indices"""
@@ -9,7 +9,11 @@ import pytest
9
9
 
10
10
  from tests.utils import assert_matches_type
11
11
  from nimble_python import Nimble, AsyncNimble
12
- from nimble_python.types import MapResponse, ExtractResponse
12
+ from nimble_python.types import (
13
+ MapResponse,
14
+ SearchResponse,
15
+ ExtractResponse,
16
+ )
13
17
 
14
18
  base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
15
19
 
@@ -217,6 +221,63 @@ class TestClient:
217
221
 
218
222
  assert cast(Any, response.is_closed) is True
219
223
 
224
+ @pytest.mark.skip(reason="Prism tests are disabled")
225
+ @parametrize
226
+ def test_method_search(self, client: Nimble) -> None:
227
+ client_ = client.search(
228
+ query="x",
229
+ )
230
+ assert_matches_type(SearchResponse, client_, path=["response"])
231
+
232
+ @pytest.mark.skip(reason="Prism tests are disabled")
233
+ @parametrize
234
+ def test_method_search_with_all_params(self, client: Nimble) -> None:
235
+ client_ = client.search(
236
+ query="x",
237
+ content_type=["string"],
238
+ country="country",
239
+ deep_search=True,
240
+ end_date="end_date",
241
+ exclude_domains=["string"],
242
+ include_answer=True,
243
+ include_domains=["string"],
244
+ locale="locale",
245
+ max_subagents=1,
246
+ num_results=1,
247
+ parsing_type="plain_text",
248
+ search_engine="google_search",
249
+ start_date="start_date",
250
+ time_range="hour",
251
+ topic="string",
252
+ )
253
+ assert_matches_type(SearchResponse, client_, path=["response"])
254
+
255
+ @pytest.mark.skip(reason="Prism tests are disabled")
256
+ @parametrize
257
+ def test_raw_response_search(self, client: Nimble) -> None:
258
+ response = client.with_raw_response.search(
259
+ query="x",
260
+ )
261
+
262
+ assert response.is_closed is True
263
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
264
+ client_ = response.parse()
265
+ assert_matches_type(SearchResponse, client_, path=["response"])
266
+
267
+ @pytest.mark.skip(reason="Prism tests are disabled")
268
+ @parametrize
269
+ def test_streaming_response_search(self, client: Nimble) -> None:
270
+ with client.with_streaming_response.search(
271
+ query="x",
272
+ ) as response:
273
+ assert not response.is_closed
274
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
275
+
276
+ client_ = response.parse()
277
+ assert_matches_type(SearchResponse, client_, path=["response"])
278
+
279
+ assert cast(Any, response.is_closed) is True
280
+
220
281
 
221
282
  class TestAsyncClient:
222
283
  parametrize = pytest.mark.parametrize(
@@ -422,3 +483,60 @@ class TestAsyncClient:
422
483
  assert_matches_type(MapResponse, client, path=["response"])
423
484
 
424
485
  assert cast(Any, response.is_closed) is True
486
+
487
+ @pytest.mark.skip(reason="Prism tests are disabled")
488
+ @parametrize
489
+ async def test_method_search(self, async_client: AsyncNimble) -> None:
490
+ client = await async_client.search(
491
+ query="x",
492
+ )
493
+ assert_matches_type(SearchResponse, client, path=["response"])
494
+
495
+ @pytest.mark.skip(reason="Prism tests are disabled")
496
+ @parametrize
497
+ async def test_method_search_with_all_params(self, async_client: AsyncNimble) -> None:
498
+ client = await async_client.search(
499
+ query="x",
500
+ content_type=["string"],
501
+ country="country",
502
+ deep_search=True,
503
+ end_date="end_date",
504
+ exclude_domains=["string"],
505
+ include_answer=True,
506
+ include_domains=["string"],
507
+ locale="locale",
508
+ max_subagents=1,
509
+ num_results=1,
510
+ parsing_type="plain_text",
511
+ search_engine="google_search",
512
+ start_date="start_date",
513
+ time_range="hour",
514
+ topic="string",
515
+ )
516
+ assert_matches_type(SearchResponse, client, path=["response"])
517
+
518
+ @pytest.mark.skip(reason="Prism tests are disabled")
519
+ @parametrize
520
+ async def test_raw_response_search(self, async_client: AsyncNimble) -> None:
521
+ response = await async_client.with_raw_response.search(
522
+ query="x",
523
+ )
524
+
525
+ assert response.is_closed is True
526
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
527
+ client = await response.parse()
528
+ assert_matches_type(SearchResponse, client, path=["response"])
529
+
530
+ @pytest.mark.skip(reason="Prism tests are disabled")
531
+ @parametrize
532
+ async def test_streaming_response_search(self, async_client: AsyncNimble) -> None:
533
+ async with async_client.with_streaming_response.search(
534
+ query="x",
535
+ ) as response:
536
+ assert not response.is_closed
537
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
538
+
539
+ client = await response.parse()
540
+ assert_matches_type(SearchResponse, client, path=["response"])
541
+
542
+ assert cast(Any, response.is_closed) is True
@@ -1,3 +0,0 @@
1
- {
2
- ".": "0.6.0"
3
- }
File without changes
File without changes
File without changes
File without changes
File without changes