nimble_python 0.12.0__py3-none-any.whl → 0.13.0__py3-none-any.whl

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.
nimble_python/_client.py CHANGED
@@ -60,10 +60,11 @@ from .types.extract_async_response import ExtractAsyncResponse
60
60
  from .types.extract_batch_response import ExtractBatchResponse
61
61
 
62
62
  if TYPE_CHECKING:
63
- from .resources import agent, crawl, tasks
63
+ from .resources import agent, crawl, tasks, batches
64
64
  from .resources.agent import AgentResource, AsyncAgentResource
65
65
  from .resources.crawl import CrawlResource, AsyncCrawlResource
66
66
  from .resources.tasks import TasksResource, AsyncTasksResource
67
+ from .resources.batches import BatchesResource, AsyncBatchesResource
67
68
 
68
69
  __all__ = ["Timeout", "Transport", "ProxiesTypes", "RequestOptions", "Nimble", "AsyncNimble", "Client", "AsyncClient"]
69
70
 
@@ -137,6 +138,12 @@ class Nimble(SyncAPIClient):
137
138
 
138
139
  return TasksResource(self)
139
140
 
141
+ @cached_property
142
+ def batches(self) -> BatchesResource:
143
+ from .resources.batches import BatchesResource
144
+
145
+ return BatchesResource(self)
146
+
140
147
  @cached_property
141
148
  def with_raw_response(self) -> NimbleWithRawResponse:
142
149
  return NimbleWithRawResponse(self)
@@ -3331,6 +3338,12 @@ class AsyncNimble(AsyncAPIClient):
3331
3338
 
3332
3339
  return AsyncTasksResource(self)
3333
3340
 
3341
+ @cached_property
3342
+ def batches(self) -> AsyncBatchesResource:
3343
+ from .resources.batches import AsyncBatchesResource
3344
+
3345
+ return AsyncBatchesResource(self)
3346
+
3334
3347
  @cached_property
3335
3348
  def with_raw_response(self) -> AsyncNimbleWithRawResponse:
3336
3349
  return AsyncNimbleWithRawResponse(self)
@@ -6496,6 +6509,12 @@ class NimbleWithRawResponse:
6496
6509
 
6497
6510
  return TasksResourceWithRawResponse(self._client.tasks)
6498
6511
 
6512
+ @cached_property
6513
+ def batches(self) -> batches.BatchesResourceWithRawResponse:
6514
+ from .resources.batches import BatchesResourceWithRawResponse
6515
+
6516
+ return BatchesResourceWithRawResponse(self._client.batches)
6517
+
6499
6518
 
6500
6519
  class AsyncNimbleWithRawResponse:
6501
6520
  _client: AsyncNimble
@@ -6537,6 +6556,12 @@ class AsyncNimbleWithRawResponse:
6537
6556
 
6538
6557
  return AsyncTasksResourceWithRawResponse(self._client.tasks)
6539
6558
 
6559
+ @cached_property
6560
+ def batches(self) -> batches.AsyncBatchesResourceWithRawResponse:
6561
+ from .resources.batches import AsyncBatchesResourceWithRawResponse
6562
+
6563
+ return AsyncBatchesResourceWithRawResponse(self._client.batches)
6564
+
6540
6565
 
6541
6566
  class NimbleWithStreamedResponse:
6542
6567
  _client: Nimble
@@ -6578,6 +6603,12 @@ class NimbleWithStreamedResponse:
6578
6603
 
6579
6604
  return TasksResourceWithStreamingResponse(self._client.tasks)
6580
6605
 
6606
+ @cached_property
6607
+ def batches(self) -> batches.BatchesResourceWithStreamingResponse:
6608
+ from .resources.batches import BatchesResourceWithStreamingResponse
6609
+
6610
+ return BatchesResourceWithStreamingResponse(self._client.batches)
6611
+
6581
6612
 
6582
6613
  class AsyncNimbleWithStreamedResponse:
6583
6614
  _client: AsyncNimble
@@ -6619,6 +6650,12 @@ class AsyncNimbleWithStreamedResponse:
6619
6650
 
6620
6651
  return AsyncTasksResourceWithStreamingResponse(self._client.tasks)
6621
6652
 
6653
+ @cached_property
6654
+ def batches(self) -> batches.AsyncBatchesResourceWithStreamingResponse:
6655
+ from .resources.batches import AsyncBatchesResourceWithStreamingResponse
6656
+
6657
+ return AsyncBatchesResourceWithStreamingResponse(self._client.batches)
6658
+
6622
6659
 
6623
6660
  Client = Nimble
6624
6661
 
@@ -1,3 +1,4 @@
1
+ from ._path import path_template as path_template
1
2
  from ._sync import asyncify as asyncify
2
3
  from ._proxy import LazyProxy as LazyProxy
3
4
  from ._utils import (
@@ -0,0 +1,127 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+ from typing import (
5
+ Any,
6
+ Mapping,
7
+ Callable,
8
+ )
9
+ from urllib.parse import quote
10
+
11
+ # Matches '.' or '..' where each dot is either literal or percent-encoded (%2e / %2E).
12
+ _DOT_SEGMENT_RE = re.compile(r"^(?:\.|%2[eE]){1,2}$")
13
+
14
+ _PLACEHOLDER_RE = re.compile(r"\{(\w+)\}")
15
+
16
+
17
+ def _quote_path_segment_part(value: str) -> str:
18
+ """Percent-encode `value` for use in a URI path segment.
19
+
20
+ Considers characters not in `pchar` set from RFC 3986 §3.3 to be unsafe.
21
+ https://datatracker.ietf.org/doc/html/rfc3986#section-3.3
22
+ """
23
+ # quote() already treats unreserved characters (letters, digits, and -._~)
24
+ # as safe, so we only need to add sub-delims, ':', and '@'.
25
+ # Notably, unlike the default `safe` for quote(), / is unsafe and must be quoted.
26
+ return quote(value, safe="!$&'()*+,;=:@")
27
+
28
+
29
+ def _quote_query_part(value: str) -> str:
30
+ """Percent-encode `value` for use in a URI query string.
31
+
32
+ Considers &, = and characters not in `query` set from RFC 3986 §3.4 to be unsafe.
33
+ https://datatracker.ietf.org/doc/html/rfc3986#section-3.4
34
+ """
35
+ return quote(value, safe="!$'()*+,;:@/?")
36
+
37
+
38
+ def _quote_fragment_part(value: str) -> str:
39
+ """Percent-encode `value` for use in a URI fragment.
40
+
41
+ Considers characters not in `fragment` set from RFC 3986 §3.5 to be unsafe.
42
+ https://datatracker.ietf.org/doc/html/rfc3986#section-3.5
43
+ """
44
+ return quote(value, safe="!$&'()*+,;=:@/?")
45
+
46
+
47
+ def _interpolate(
48
+ template: str,
49
+ values: Mapping[str, Any],
50
+ quoter: Callable[[str], str],
51
+ ) -> str:
52
+ """Replace {name} placeholders in `template`, quoting each value with `quoter`.
53
+
54
+ Placeholder names are looked up in `values`.
55
+
56
+ Raises:
57
+ KeyError: If a placeholder is not found in `values`.
58
+ """
59
+ # re.split with a capturing group returns alternating
60
+ # [text, name, text, name, ..., text] elements.
61
+ parts = _PLACEHOLDER_RE.split(template)
62
+
63
+ for i in range(1, len(parts), 2):
64
+ name = parts[i]
65
+ if name not in values:
66
+ raise KeyError(f"a value for placeholder {{{name}}} was not provided")
67
+ val = values[name]
68
+ if val is None:
69
+ parts[i] = "null"
70
+ elif isinstance(val, bool):
71
+ parts[i] = "true" if val else "false"
72
+ else:
73
+ parts[i] = quoter(str(values[name]))
74
+
75
+ return "".join(parts)
76
+
77
+
78
+ def path_template(template: str, /, **kwargs: Any) -> str:
79
+ """Interpolate {name} placeholders in `template` from keyword arguments.
80
+
81
+ Args:
82
+ template: The template string containing {name} placeholders.
83
+ **kwargs: Keyword arguments to interpolate into the template.
84
+
85
+ Returns:
86
+ The template with placeholders interpolated and percent-encoded.
87
+
88
+ Safe characters for percent-encoding are dependent on the URI component.
89
+ Placeholders in path and fragment portions are percent-encoded where the `segment`
90
+ and `fragment` sets from RFC 3986 respectively are considered safe.
91
+ Placeholders in the query portion are percent-encoded where the `query` set from
92
+ RFC 3986 §3.3 is considered safe except for = and & characters.
93
+
94
+ Raises:
95
+ KeyError: If a placeholder is not found in `kwargs`.
96
+ ValueError: If resulting path contains /./ or /../ segments (including percent-encoded dot-segments).
97
+ """
98
+ # Split the template into path, query, and fragment portions.
99
+ fragment_template: str | None = None
100
+ query_template: str | None = None
101
+
102
+ rest = template
103
+ if "#" in rest:
104
+ rest, fragment_template = rest.split("#", 1)
105
+ if "?" in rest:
106
+ rest, query_template = rest.split("?", 1)
107
+ path_template = rest
108
+
109
+ # Interpolate each portion with the appropriate quoting rules.
110
+ path_result = _interpolate(path_template, kwargs, _quote_path_segment_part)
111
+
112
+ # Reject dot-segments (. and ..) in the final assembled path. The check
113
+ # runs after interpolation so that adjacent placeholders or a mix of static
114
+ # text and placeholders that together form a dot-segment are caught.
115
+ # Also reject percent-encoded dot-segments to protect against incorrectly
116
+ # implemented normalization in servers/proxies.
117
+ for segment in path_result.split("/"):
118
+ if _DOT_SEGMENT_RE.match(segment):
119
+ raise ValueError(f"Constructed path {path_result!r} contains dot-segment {segment!r} which is not allowed")
120
+
121
+ result = path_result
122
+ if query_template is not None:
123
+ result += "?" + _interpolate(query_template, kwargs, _quote_query_part)
124
+ if fragment_template is not None:
125
+ result += "#" + _interpolate(fragment_template, kwargs, _quote_fragment_part)
126
+
127
+ return result
nimble_python/_version.py CHANGED
@@ -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.12.0" # x-release-please-version
4
+ __version__ = "0.13.0" # x-release-please-version
@@ -24,6 +24,14 @@ from .tasks import (
24
24
  TasksResourceWithStreamingResponse,
25
25
  AsyncTasksResourceWithStreamingResponse,
26
26
  )
27
+ from .batches import (
28
+ BatchesResource,
29
+ AsyncBatchesResource,
30
+ BatchesResourceWithRawResponse,
31
+ AsyncBatchesResourceWithRawResponse,
32
+ BatchesResourceWithStreamingResponse,
33
+ AsyncBatchesResourceWithStreamingResponse,
34
+ )
27
35
 
28
36
  __all__ = [
29
37
  "AgentResource",
@@ -44,4 +52,10 @@ __all__ = [
44
52
  "AsyncTasksResourceWithRawResponse",
45
53
  "TasksResourceWithStreamingResponse",
46
54
  "AsyncTasksResourceWithStreamingResponse",
55
+ "BatchesResource",
56
+ "AsyncBatchesResource",
57
+ "BatchesResourceWithRawResponse",
58
+ "AsyncBatchesResourceWithRawResponse",
59
+ "BatchesResourceWithStreamingResponse",
60
+ "AsyncBatchesResourceWithStreamingResponse",
47
61
  ]
@@ -9,7 +9,7 @@ import httpx
9
9
 
10
10
  from ..types import agent_run_params, agent_list_params, agent_run_async_params
11
11
  from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
12
- from .._utils import maybe_transform, async_maybe_transform
12
+ from .._utils import path_template, maybe_transform, async_maybe_transform
13
13
  from .._compat import cached_property
14
14
  from .._resource import SyncAPIResource, AsyncAPIResource
15
15
  from .._response import (
@@ -131,7 +131,7 @@ class AgentResource(SyncAPIResource):
131
131
  if not template_name:
132
132
  raise ValueError(f"Expected a non-empty value for `template_name` but received {template_name!r}")
133
133
  return self._get(
134
- f"/v1/agents/{template_name}",
134
+ path_template("/v1/agents/{template_name}", template_name=template_name),
135
135
  options=make_request_options(
136
136
  extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
137
137
  ),
@@ -345,7 +345,7 @@ class AsyncAgentResource(AsyncAPIResource):
345
345
  if not template_name:
346
346
  raise ValueError(f"Expected a non-empty value for `template_name` but received {template_name!r}")
347
347
  return await self._get(
348
- f"/v1/agents/{template_name}",
348
+ path_template("/v1/agents/{template_name}", template_name=template_name),
349
349
  options=make_request_options(
350
350
  extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
351
351
  ),
@@ -0,0 +1,305 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from __future__ import annotations
4
+
5
+ import httpx
6
+
7
+ from .._types import Body, Query, Headers, NoneType, NotGiven, not_given
8
+ from .._utils import path_template
9
+ from .._compat import cached_property
10
+ from .._resource import SyncAPIResource, AsyncAPIResource
11
+ from .._response import (
12
+ to_raw_response_wrapper,
13
+ to_streamed_response_wrapper,
14
+ async_to_raw_response_wrapper,
15
+ async_to_streamed_response_wrapper,
16
+ )
17
+ from .._base_client import make_request_options
18
+ from ..types.batch_get_response import BatchGetResponse
19
+ from ..types.batch_progress_response import BatchProgressResponse
20
+
21
+ __all__ = ["BatchesResource", "AsyncBatchesResource"]
22
+
23
+
24
+ class BatchesResource(SyncAPIResource):
25
+ @cached_property
26
+ def with_raw_response(self) -> BatchesResourceWithRawResponse:
27
+ """
28
+ This property can be used as a prefix for any HTTP method call to return
29
+ the raw response object instead of the parsed content.
30
+
31
+ For more information, see https://www.github.com/Nimbleway/nimble-python#accessing-raw-response-data-eg-headers
32
+ """
33
+ return BatchesResourceWithRawResponse(self)
34
+
35
+ @cached_property
36
+ def with_streaming_response(self) -> BatchesResourceWithStreamingResponse:
37
+ """
38
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
39
+
40
+ For more information, see https://www.github.com/Nimbleway/nimble-python#with_streaming_response
41
+ """
42
+ return BatchesResourceWithStreamingResponse(self)
43
+
44
+ def list(
45
+ self,
46
+ *,
47
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
48
+ # The extra values given here take precedence over values defined on the client or passed to this method.
49
+ extra_headers: Headers | None = None,
50
+ extra_query: Query | None = None,
51
+ extra_body: Body | None = None,
52
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
53
+ ) -> None:
54
+ """Retrieve a paginated list of batches for the authenticated account."""
55
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
56
+ return self._get(
57
+ "/v1/batches",
58
+ options=make_request_options(
59
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
60
+ ),
61
+ cast_to=NoneType,
62
+ )
63
+
64
+ def get(
65
+ self,
66
+ batch_id: str,
67
+ *,
68
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
69
+ # The extra values given here take precedence over values defined on the client or passed to this method.
70
+ extra_headers: Headers | None = None,
71
+ extra_query: Query | None = None,
72
+ extra_body: Body | None = None,
73
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
74
+ ) -> BatchGetResponse:
75
+ """
76
+ Retrieve the details of a batch including all its tasks and completion status.
77
+
78
+ Args:
79
+ batch_id: The unique identifier of the batch.
80
+
81
+ extra_headers: Send extra headers
82
+
83
+ extra_query: Add additional query parameters to the request
84
+
85
+ extra_body: Add additional JSON properties to the request
86
+
87
+ timeout: Override the client-level default timeout for this request, in seconds
88
+ """
89
+ if not batch_id:
90
+ raise ValueError(f"Expected a non-empty value for `batch_id` but received {batch_id!r}")
91
+ return self._get(
92
+ path_template("/v1/batches/{batch_id}", batch_id=batch_id),
93
+ options=make_request_options(
94
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
95
+ ),
96
+ cast_to=BatchGetResponse,
97
+ )
98
+
99
+ def progress(
100
+ self,
101
+ batch_id: str,
102
+ *,
103
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
104
+ # The extra values given here take precedence over values defined on the client or passed to this method.
105
+ extra_headers: Headers | None = None,
106
+ extra_query: Query | None = None,
107
+ extra_body: Body | None = None,
108
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
109
+ ) -> BatchProgressResponse:
110
+ """
111
+ Retrieve lightweight progress information for a batch without fetching all task
112
+ details.
113
+
114
+ Args:
115
+ batch_id: The unique identifier of the batch.
116
+
117
+ extra_headers: Send extra headers
118
+
119
+ extra_query: Add additional query parameters to the request
120
+
121
+ extra_body: Add additional JSON properties to the request
122
+
123
+ timeout: Override the client-level default timeout for this request, in seconds
124
+ """
125
+ if not batch_id:
126
+ raise ValueError(f"Expected a non-empty value for `batch_id` but received {batch_id!r}")
127
+ return self._get(
128
+ path_template("/v1/batches/{batch_id}/progress", batch_id=batch_id),
129
+ options=make_request_options(
130
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
131
+ ),
132
+ cast_to=BatchProgressResponse,
133
+ )
134
+
135
+
136
+ class AsyncBatchesResource(AsyncAPIResource):
137
+ @cached_property
138
+ def with_raw_response(self) -> AsyncBatchesResourceWithRawResponse:
139
+ """
140
+ This property can be used as a prefix for any HTTP method call to return
141
+ the raw response object instead of the parsed content.
142
+
143
+ For more information, see https://www.github.com/Nimbleway/nimble-python#accessing-raw-response-data-eg-headers
144
+ """
145
+ return AsyncBatchesResourceWithRawResponse(self)
146
+
147
+ @cached_property
148
+ def with_streaming_response(self) -> AsyncBatchesResourceWithStreamingResponse:
149
+ """
150
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
151
+
152
+ For more information, see https://www.github.com/Nimbleway/nimble-python#with_streaming_response
153
+ """
154
+ return AsyncBatchesResourceWithStreamingResponse(self)
155
+
156
+ async def list(
157
+ self,
158
+ *,
159
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
160
+ # The extra values given here take precedence over values defined on the client or passed to this method.
161
+ extra_headers: Headers | None = None,
162
+ extra_query: Query | None = None,
163
+ extra_body: Body | None = None,
164
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
165
+ ) -> None:
166
+ """Retrieve a paginated list of batches for the authenticated account."""
167
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
168
+ return await self._get(
169
+ "/v1/batches",
170
+ options=make_request_options(
171
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
172
+ ),
173
+ cast_to=NoneType,
174
+ )
175
+
176
+ async def get(
177
+ self,
178
+ batch_id: str,
179
+ *,
180
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
181
+ # The extra values given here take precedence over values defined on the client or passed to this method.
182
+ extra_headers: Headers | None = None,
183
+ extra_query: Query | None = None,
184
+ extra_body: Body | None = None,
185
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
186
+ ) -> BatchGetResponse:
187
+ """
188
+ Retrieve the details of a batch including all its tasks and completion status.
189
+
190
+ Args:
191
+ batch_id: The unique identifier of the batch.
192
+
193
+ extra_headers: Send extra headers
194
+
195
+ extra_query: Add additional query parameters to the request
196
+
197
+ extra_body: Add additional JSON properties to the request
198
+
199
+ timeout: Override the client-level default timeout for this request, in seconds
200
+ """
201
+ if not batch_id:
202
+ raise ValueError(f"Expected a non-empty value for `batch_id` but received {batch_id!r}")
203
+ return await self._get(
204
+ path_template("/v1/batches/{batch_id}", batch_id=batch_id),
205
+ options=make_request_options(
206
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
207
+ ),
208
+ cast_to=BatchGetResponse,
209
+ )
210
+
211
+ async def progress(
212
+ self,
213
+ batch_id: str,
214
+ *,
215
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
216
+ # The extra values given here take precedence over values defined on the client or passed to this method.
217
+ extra_headers: Headers | None = None,
218
+ extra_query: Query | None = None,
219
+ extra_body: Body | None = None,
220
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
221
+ ) -> BatchProgressResponse:
222
+ """
223
+ Retrieve lightweight progress information for a batch without fetching all task
224
+ details.
225
+
226
+ Args:
227
+ batch_id: The unique identifier of the batch.
228
+
229
+ extra_headers: Send extra headers
230
+
231
+ extra_query: Add additional query parameters to the request
232
+
233
+ extra_body: Add additional JSON properties to the request
234
+
235
+ timeout: Override the client-level default timeout for this request, in seconds
236
+ """
237
+ if not batch_id:
238
+ raise ValueError(f"Expected a non-empty value for `batch_id` but received {batch_id!r}")
239
+ return await self._get(
240
+ path_template("/v1/batches/{batch_id}/progress", batch_id=batch_id),
241
+ options=make_request_options(
242
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
243
+ ),
244
+ cast_to=BatchProgressResponse,
245
+ )
246
+
247
+
248
+ class BatchesResourceWithRawResponse:
249
+ def __init__(self, batches: BatchesResource) -> None:
250
+ self._batches = batches
251
+
252
+ self.list = to_raw_response_wrapper(
253
+ batches.list,
254
+ )
255
+ self.get = to_raw_response_wrapper(
256
+ batches.get,
257
+ )
258
+ self.progress = to_raw_response_wrapper(
259
+ batches.progress,
260
+ )
261
+
262
+
263
+ class AsyncBatchesResourceWithRawResponse:
264
+ def __init__(self, batches: AsyncBatchesResource) -> None:
265
+ self._batches = batches
266
+
267
+ self.list = async_to_raw_response_wrapper(
268
+ batches.list,
269
+ )
270
+ self.get = async_to_raw_response_wrapper(
271
+ batches.get,
272
+ )
273
+ self.progress = async_to_raw_response_wrapper(
274
+ batches.progress,
275
+ )
276
+
277
+
278
+ class BatchesResourceWithStreamingResponse:
279
+ def __init__(self, batches: BatchesResource) -> None:
280
+ self._batches = batches
281
+
282
+ self.list = to_streamed_response_wrapper(
283
+ batches.list,
284
+ )
285
+ self.get = to_streamed_response_wrapper(
286
+ batches.get,
287
+ )
288
+ self.progress = to_streamed_response_wrapper(
289
+ batches.progress,
290
+ )
291
+
292
+
293
+ class AsyncBatchesResourceWithStreamingResponse:
294
+ def __init__(self, batches: AsyncBatchesResource) -> None:
295
+ self._batches = batches
296
+
297
+ self.list = async_to_streamed_response_wrapper(
298
+ batches.list,
299
+ )
300
+ self.get = async_to_streamed_response_wrapper(
301
+ batches.get,
302
+ )
303
+ self.progress = async_to_streamed_response_wrapper(
304
+ batches.progress,
305
+ )
@@ -9,7 +9,7 @@ import httpx
9
9
 
10
10
  from ..types import crawl_run_params, crawl_list_params
11
11
  from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
12
- from .._utils import maybe_transform, async_maybe_transform
12
+ from .._utils import path_template, maybe_transform, async_maybe_transform
13
13
  from .._compat import cached_property
14
14
  from .._resource import SyncAPIResource, AsyncAPIResource
15
15
  from .._response import (
@@ -211,7 +211,7 @@ class CrawlResource(SyncAPIResource):
211
211
  if not id:
212
212
  raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
213
213
  return self._get(
214
- f"/v1/crawl/{id}",
214
+ path_template("/v1/crawl/{id}", id=id),
215
215
  options=make_request_options(
216
216
  extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
217
217
  ),
@@ -246,7 +246,7 @@ class CrawlResource(SyncAPIResource):
246
246
  if not id:
247
247
  raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
248
248
  return self._delete(
249
- f"/v1/crawl/{id}",
249
+ path_template("/v1/crawl/{id}", id=id),
250
250
  options=make_request_options(
251
251
  extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
252
252
  ),
@@ -438,7 +438,7 @@ class AsyncCrawlResource(AsyncAPIResource):
438
438
  if not id:
439
439
  raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
440
440
  return await self._get(
441
- f"/v1/crawl/{id}",
441
+ path_template("/v1/crawl/{id}", id=id),
442
442
  options=make_request_options(
443
443
  extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
444
444
  ),
@@ -473,7 +473,7 @@ class AsyncCrawlResource(AsyncAPIResource):
473
473
  if not id:
474
474
  raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
475
475
  return await self._delete(
476
- f"/v1/crawl/{id}",
476
+ path_template("/v1/crawl/{id}", id=id),
477
477
  options=make_request_options(
478
478
  extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
479
479
  ),
@@ -6,7 +6,7 @@ import httpx
6
6
 
7
7
  from ..types import task_list_params
8
8
  from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
9
- from .._utils import maybe_transform, async_maybe_transform
9
+ from .._utils import path_template, maybe_transform, async_maybe_transform
10
10
  from .._compat import cached_property
11
11
  from .._resource import SyncAPIResource, AsyncAPIResource
12
12
  from .._response import (
@@ -117,7 +117,7 @@ class TasksResource(SyncAPIResource):
117
117
  if not task_id:
118
118
  raise ValueError(f"Expected a non-empty value for `task_id` but received {task_id!r}")
119
119
  return self._get(
120
- f"/v1/tasks/{task_id}",
120
+ path_template("/v1/tasks/{task_id}", task_id=task_id),
121
121
  options=make_request_options(
122
122
  extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
123
123
  ),
@@ -152,7 +152,7 @@ class TasksResource(SyncAPIResource):
152
152
  if not task_id:
153
153
  raise ValueError(f"Expected a non-empty value for `task_id` but received {task_id!r}")
154
154
  return self._get(
155
- f"/v1/tasks/{task_id}/results",
155
+ path_template("/v1/tasks/{task_id}/results", task_id=task_id),
156
156
  options=make_request_options(
157
157
  extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
158
158
  ),
@@ -254,7 +254,7 @@ class AsyncTasksResource(AsyncAPIResource):
254
254
  if not task_id:
255
255
  raise ValueError(f"Expected a non-empty value for `task_id` but received {task_id!r}")
256
256
  return await self._get(
257
- f"/v1/tasks/{task_id}",
257
+ path_template("/v1/tasks/{task_id}", task_id=task_id),
258
258
  options=make_request_options(
259
259
  extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
260
260
  ),
@@ -289,7 +289,7 @@ class AsyncTasksResource(AsyncAPIResource):
289
289
  if not task_id:
290
290
  raise ValueError(f"Expected a non-empty value for `task_id` but received {task_id!r}")
291
291
  return await self._get(
292
- f"/v1/tasks/{task_id}/results",
292
+ path_template("/v1/tasks/{task_id}/results", task_id=task_id),
293
293
  options=make_request_options(
294
294
  extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
295
295
  ),
@@ -29,6 +29,7 @@ from .crawl_list_params import CrawlListParams as CrawlListParams
29
29
  from .task_get_response import TaskGetResponse as TaskGetResponse
30
30
  from .agent_get_response import AgentGetResponse as AgentGetResponse
31
31
  from .agent_run_response import AgentRunResponse as AgentRunResponse
32
+ from .batch_get_response import BatchGetResponse as BatchGetResponse
32
33
  from .crawl_run_response import CrawlRunResponse as CrawlRunResponse
33
34
  from .task_list_response import TaskListResponse as TaskListResponse
34
35
  from .agent_list_response import AgentListResponse as AgentListResponse
@@ -40,6 +41,7 @@ from .task_results_response import TaskResultsResponse as TaskResultsResponse
40
41
  from .agent_run_async_params import AgentRunAsyncParams as AgentRunAsyncParams
41
42
  from .extract_async_response import ExtractAsyncResponse as ExtractAsyncResponse
42
43
  from .extract_batch_response import ExtractBatchResponse as ExtractBatchResponse
44
+ from .batch_progress_response import BatchProgressResponse as BatchProgressResponse
43
45
  from .agent_run_async_response import AgentRunAsyncResponse as AgentRunAsyncResponse
44
46
  from .crawl_terminate_response import CrawlTerminateResponse as CrawlTerminateResponse
45
47
  from .client_extract_async_params import ClientExtractAsyncParams as ClientExtractAsyncParams
@@ -0,0 +1,82 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from typing import List, Optional
4
+ from typing_extensions import Literal
5
+
6
+ from pydantic import Field as FieldInfo
7
+
8
+ from .._models import BaseModel
9
+
10
+ __all__ = ["BatchGetResponse", "Task"]
11
+
12
+
13
+ class Task(BaseModel):
14
+ id: str
15
+ """Unique task identifier."""
16
+
17
+ api_query: object = FieldInfo(alias="_query")
18
+
19
+ created_at: str
20
+ """Timestamp when the task was created."""
21
+
22
+ input: object
23
+ """Original input data for the task."""
24
+
25
+ state: Literal["pending", "success", "error"]
26
+ """Current state of the task."""
27
+
28
+ status_url: str
29
+ """URL for checking the task status."""
30
+
31
+ account_name: Optional[str] = None
32
+ """Account name that owns the task."""
33
+
34
+ api_type: Optional[Literal["web", "serp", "ecommerce", "social", "media", "agent", "extract"]] = None
35
+
36
+ batch_id: Optional[str] = None
37
+ """Batch ID if this task is part of a batch."""
38
+
39
+ download_url: Optional[str] = None
40
+ """URL for downloading the task results."""
41
+
42
+ error: Optional[str] = None
43
+ """Error message if the task failed."""
44
+
45
+ error_type: Optional[str] = None
46
+ """Classification of the error type."""
47
+
48
+ modified_at: Optional[str] = None
49
+ """Timestamp when the task was last modified."""
50
+
51
+ output_url: Optional[str] = None
52
+ """Storage location of the output data."""
53
+
54
+ status_code: Optional[float] = None
55
+ """HTTP status code from the task execution."""
56
+
57
+
58
+ class BatchGetResponse(BaseModel):
59
+ """Response containing batch details with all tasks."""
60
+
61
+ id: str
62
+ """Unique identifier for the batch."""
63
+
64
+ completed: bool
65
+ """Whether all tasks in the batch have finished."""
66
+
67
+ completed_count: float
68
+ """Number of tasks that have completed so far."""
69
+
70
+ created_at: str
71
+ """ISO timestamp when the batch was created."""
72
+
73
+ progress: float
74
+ """Completion ratio between 0 and 1."""
75
+
76
+ status: Literal["success"]
77
+
78
+ tasks: List[Optional[Task]]
79
+ """List of tasks in the batch."""
80
+
81
+ completed_at: Optional[str] = None
82
+ """ISO timestamp when the batch completed."""
@@ -0,0 +1,29 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from typing import Optional
4
+ from typing_extensions import Literal
5
+
6
+ from .._models import BaseModel
7
+
8
+ __all__ = ["BatchProgressResponse"]
9
+
10
+
11
+ class BatchProgressResponse(BaseModel):
12
+ """Lightweight batch progress without task details."""
13
+
14
+ id: str
15
+ """Unique identifier for the batch."""
16
+
17
+ completed: bool
18
+ """Whether all tasks in the batch have finished."""
19
+
20
+ completed_count: float
21
+ """Number of tasks that have completed so far."""
22
+
23
+ progress: float
24
+ """Completion ratio between 0 and 1."""
25
+
26
+ status: Literal["success"]
27
+
28
+ completed_at: Optional[str] = None
29
+ """ISO timestamp when the batch completed."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: nimble_python
3
- Version: 0.12.0
3
+ Version: 0.13.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
@@ -1,6 +1,6 @@
1
1
  nimble_python/__init__.py,sha256=QWpm5I50gjoMEPPXsRiT0i3aqvsJby6NegnPHYrhCfs,2645
2
2
  nimble_python/_base_client.py,sha256=IR2D-rcC7Lz8L2c0xH_4dOX50NJEgUK0IzpKAbK11FU,73665
3
- nimble_python/_client.py,sha256=7IPr-Y-Uh3Fq6i2K4gewRF4C48HBI1JBrWK_nMWU3Lc,161446
3
+ nimble_python/_client.py,sha256=_GMgzEZcpnxPgOW9acL5pBkSUTIQ_TfvGQ9WvniKUsI,162827
4
4
  nimble_python/_compat.py,sha256=_9guQfzYnL3DNtudX5W7T2cdSskx89B5AFfhPQDxMUk,6811
5
5
  nimble_python/_constants.py,sha256=giUwuSKDnpjRLaHvgzErnXB3CSYjKMaI5xnBQJI-23s,464
6
6
  nimble_python/_exceptions.py,sha256=x1M0s_wI9jkJ5ARR07APUuDZfxl7BjQ53snlFU-jAoQ,3220
@@ -11,13 +11,14 @@ nimble_python/_resource.py,sha256=TDtzjUMbNHRGQNq-4HJqce3T3THBD5Q7ESrONYPvKdI,11
11
11
  nimble_python/_response.py,sha256=hrLOCn3D0gCapH31eR9BVOgBpTYliUTVUsdeWc1J76A,28983
12
12
  nimble_python/_streaming.py,sha256=StqGzUAIG9gQNCkRQnEAbN3IyiX4hDdCp2QR7_DANw8,10550
13
13
  nimble_python/_types.py,sha256=ZhbxWgjPQAqNY4ePn8aUJV26mm5oDBrZqskA1XyjlQ0,7601
14
- nimble_python/_version.py,sha256=x8_94XEGAlMP0yPgP6rjCT98zGwLvbd88UV75ts5Olg,166
14
+ nimble_python/_version.py,sha256=TcQZZa0vIO5XcLn_ZZyy_q1SpsidGKGndL4HCzqDrM4,166
15
15
  nimble_python/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
- nimble_python/_utils/__init__.py,sha256=7fch0GT9zpNnErbciSpUNa-SjTxxjY6kxHxKMOM4AGs,2305
16
+ nimble_python/_utils/__init__.py,sha256=DJEWihdzRWrZI23vwocBkgvZCwn9iG7yV0c_9vKaysU,2355
17
17
  nimble_python/_utils/_compat.py,sha256=33246eDcl3pwL6kWsEhVuT4Akrd8gZEW9LPTm465ohk,1231
18
18
  nimble_python/_utils/_datetime_parse.py,sha256=bABTs0Bc6rabdFvnIwXjEhWL15TcRgWZ_6XGTqN8xUk,4204
19
19
  nimble_python/_utils/_json.py,sha256=bl95uuIWwgSfXX-gP1trK_lDAPwJujYfJ05Cxo2SEC4,962
20
20
  nimble_python/_utils/_logs.py,sha256=3AXiQXDxC6I4wW59jczmelNgZhO00lEDtVTBTDCRX_8,788
21
+ nimble_python/_utils/_path.py,sha256=Dk294levuJXP5e4m20YRDDZFPl7zegXvc9Kb3dUCwJI,4701
21
22
  nimble_python/_utils/_proxy.py,sha256=aglnj2yBTDyGX9Akk2crZHrl10oqRmceUy2Zp008XEs,1975
22
23
  nimble_python/_utils/_reflection.py,sha256=ZmGkIgT_PuwedyNBrrKGbxoWtkpytJNU1uU4QHnmEMU,1364
23
24
  nimble_python/_utils/_resources_proxy.py,sha256=PKCHRwjhwNIH5920LKi6DV8tnyPvYnEcutvqUmCxq6I,624
@@ -27,11 +28,12 @@ nimble_python/_utils/_transform.py,sha256=NjCzmnfqYrsAikUHQig6N9QfuTVbKipuP3ur9m
27
28
  nimble_python/_utils/_typing.py,sha256=N_5PPuFNsaygbtA_npZd98SVN1LQQvFTKL6bkWPBZGU,4786
28
29
  nimble_python/_utils/_utils.py,sha256=ugfUaneOK7I8h9b3656flwf5u_kthY0gvNuqvgOLoSU,12252
29
30
  nimble_python/lib/.keep,sha256=wuNrz-5SXo3jJaJOJgz4vFHM41YH_g20F5cRQo0vLes,224
30
- nimble_python/resources/__init__.py,sha256=Tw4jTo3742_EIeLVKIni8RmOPpeKwqLF168u9bQ5Fps,1413
31
- nimble_python/resources/agent.py,sha256=YjMJdOjB56f0AKNb0q1dUBdTMKhHIHkMi9pFVjCf-Cc,18987
32
- nimble_python/resources/crawl.py,sha256=QfzBxaqBMj_kyxtNxLozRm-gCWXDHvU0vGwVrra6TlM,20552
33
- nimble_python/resources/tasks.py,sha256=hkJB_TMtdu5-vwLWgz2s1Fb3HfZ8Nk9aHmUrBDJlNfg,12882
34
- nimble_python/types/__init__.py,sha256=XJtnVvQtC-1dYR_jMV5_xZs5t8jrnhi1XTzI95n0YNA,2592
31
+ nimble_python/resources/__init__.py,sha256=Wh5Ns-DfhwV5B1NL1sauYogLEctZiqtJxLuEVQzUvVw,1876
32
+ nimble_python/resources/agent.py,sha256=HDsKDK7zYFSplZcG9pVFAdvEptZJ2t2A5XRqx3IT7s4,19088
33
+ nimble_python/resources/batches.py,sha256=LxPXo7mpDcXmtJAv7prVnDpJHkhHypix6ZNSxh9kpQU,11688
34
+ nimble_python/resources/crawl.py,sha256=GOMDGANIPAfay-J3ujW9ghlK-h-aIy99ChIKRN-pZK8,20651
35
+ nimble_python/resources/tasks.py,sha256=8rV6YZNpx8rq_83L8UZvt7HlPlRhY8SGrbVQAFDjBtM,13021
36
+ nimble_python/types/__init__.py,sha256=al8UTqmM7bIeUUKbqDTHc6-23McbQAmVjF12tfN8r5g,2745
35
37
  nimble_python/types/agent_get_response.py,sha256=qQtjNztWHGWGJ_LKLn2-VtQlzv2AfkPvu0QaADRXqIg,1131
36
38
  nimble_python/types/agent_list_params.py,sha256=yUwgtiXrzfEXd3I--X_ISovY2BSHKXDvFZ2XUCUR9ew,670
37
39
  nimble_python/types/agent_list_response.py,sha256=kBEVOD9nlby5QsfaDkjPLXDJyQotph3HBo321jP8rb4,599
@@ -39,6 +41,8 @@ nimble_python/types/agent_run_async_params.py,sha256=vaDEeQx9X1XWJlUcLSa0Bht0c65
39
41
  nimble_python/types/agent_run_async_response.py,sha256=aawcjhtW6FaWxIPcg-l-1yIhsQDLUoYOaoSf_MLJ67s,321
40
42
  nimble_python/types/agent_run_params.py,sha256=WbmK8oa-Iv0QS1I8X6AAXhrbbMPzNACV5IHSq8rdwGg,365
41
43
  nimble_python/types/agent_run_response.py,sha256=xvHQbGDhgaWyZy4gcNMfYEQ4YLSUVRiF54Qm2SwIE2g,8036
44
+ nimble_python/types/batch_get_response.py,sha256=5MIDHw3xt4UPdZY7eeYMDTJHbvyP4fCWNFMOLmuxcGM,2117
45
+ nimble_python/types/batch_progress_response.py,sha256=oHEHXclc0NnI3TiGMalfElhZ15rfvR7nZRub9Gg_nqs,726
42
46
  nimble_python/types/client_extract_async_params.py,sha256=RMRSJB--VkxfuMBrf_zFan7dyp08GitRkRfuz6ON1RI,19328
43
47
  nimble_python/types/client_extract_batch_params.py,sha256=S9xPUAjDlpdbTuIaqUXQYWLEETkHwH8F645omihIMqw,19961
44
48
  nimble_python/types/client_extract_params.py,sha256=BH0nixa69BoJr1EfRTLvzIqhIqyj1DN0G68o61g_W5g,18968
@@ -87,7 +91,7 @@ nimble_python/types/shared_params/scroll_action.py,sha256=6PJMWVc9JhjyrXeAsFnvHR
87
91
  nimble_python/types/shared_params/wait_action.py,sha256=2jlVgNNZcC2M9tka3xbmLkDocCJuoX_1qIGOmd6a2DU,1046
88
92
  nimble_python/types/shared_params/wait_for_element_action.py,sha256=cKhvFe09G2aQBFKBXg00S43ykQqgNyTLYR1DoJmDvTA,1364
89
93
  nimble_python/types/shared_params/wait_for_navigation_action.py,sha256=oPAK3OxZObqJjDEh9v0_q1ntHfWqgtXOp_k-oX8ZiHE,1257
90
- nimble_python-0.12.0.dist-info/METADATA,sha256=LKH3JASu-yC5XletWN_XsIgCEBOC97zCsT-XqISgNqE,15816
91
- nimble_python-0.12.0.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
92
- nimble_python-0.12.0.dist-info/licenses/LICENSE,sha256=khtIpaYdgNbXXcmzsxlSL_iKmh160uTREZTiMQKCB24,11336
93
- nimble_python-0.12.0.dist-info/RECORD,,
94
+ nimble_python-0.13.0.dist-info/METADATA,sha256=uWvrB1XoHTU8i_6rqk1kdANTn2qKd1Q6SZ0k1JqvX-0,15816
95
+ nimble_python-0.13.0.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
96
+ nimble_python-0.13.0.dist-info/licenses/LICENSE,sha256=khtIpaYdgNbXXcmzsxlSL_iKmh160uTREZTiMQKCB24,11336
97
+ nimble_python-0.13.0.dist-info/RECORD,,