deeprails 1.10.0__tar.gz → 1.11.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.

Potentially problematic release.


This version of deeprails might be problematic. Click here for more details.

Files changed (85) hide show
  1. deeprails-1.11.0/.release-please-manifest.json +3 -0
  2. {deeprails-1.10.0 → deeprails-1.11.0}/CHANGELOG.md +14 -0
  3. {deeprails-1.10.0 → deeprails-1.11.0}/PKG-INFO +18 -1
  4. {deeprails-1.10.0 → deeprails-1.11.0}/README.md +17 -0
  5. {deeprails-1.10.0 → deeprails-1.11.0}/api.md +12 -0
  6. {deeprails-1.10.0 → deeprails-1.11.0}/pyproject.toml +1 -1
  7. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_client.py +9 -1
  8. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_files.py +1 -1
  9. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_streaming.py +4 -6
  10. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_version.py +1 -1
  11. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/resources/__init__.py +14 -0
  12. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/resources/defend.py +19 -1
  13. deeprails-1.11.0/src/deeprails/resources/files.py +183 -0
  14. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/types/__init__.py +2 -0
  15. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/types/defend_create_workflow_params.py +14 -0
  16. deeprails-1.11.0/src/deeprails/types/file_response.py +25 -0
  17. deeprails-1.11.0/src/deeprails/types/file_upload_params.py +14 -0
  18. {deeprails-1.10.0 → deeprails-1.11.0}/tests/api_resources/test_defend.py +4 -0
  19. deeprails-1.11.0/tests/api_resources/test_files.py +92 -0
  20. deeprails-1.10.0/.release-please-manifest.json +0 -3
  21. {deeprails-1.10.0 → deeprails-1.11.0}/.gitignore +0 -0
  22. {deeprails-1.10.0 → deeprails-1.11.0}/CONTRIBUTING.md +0 -0
  23. {deeprails-1.10.0 → deeprails-1.11.0}/LICENSE +0 -0
  24. {deeprails-1.10.0 → deeprails-1.11.0}/bin/check-release-environment +0 -0
  25. {deeprails-1.10.0 → deeprails-1.11.0}/bin/publish-pypi +0 -0
  26. {deeprails-1.10.0 → deeprails-1.11.0}/examples/.keep +0 -0
  27. {deeprails-1.10.0 → deeprails-1.11.0}/noxfile.py +0 -0
  28. {deeprails-1.10.0 → deeprails-1.11.0}/release-please-config.json +0 -0
  29. {deeprails-1.10.0 → deeprails-1.11.0}/requirements-dev.lock +0 -0
  30. {deeprails-1.10.0 → deeprails-1.11.0}/requirements.lock +0 -0
  31. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/__init__.py +0 -0
  32. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_base_client.py +0 -0
  33. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_compat.py +0 -0
  34. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_constants.py +0 -0
  35. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_exceptions.py +0 -0
  36. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_models.py +0 -0
  37. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_qs.py +0 -0
  38. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_resource.py +0 -0
  39. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_response.py +0 -0
  40. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_types.py +0 -0
  41. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_utils/__init__.py +0 -0
  42. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_utils/_compat.py +0 -0
  43. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_utils/_datetime_parse.py +0 -0
  44. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_utils/_logs.py +0 -0
  45. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_utils/_proxy.py +0 -0
  46. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_utils/_reflection.py +0 -0
  47. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_utils/_resources_proxy.py +0 -0
  48. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_utils/_streams.py +0 -0
  49. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_utils/_sync.py +0 -0
  50. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_utils/_transform.py +0 -0
  51. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_utils/_typing.py +0 -0
  52. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/_utils/_utils.py +0 -0
  53. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/lib/.keep +0 -0
  54. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/py.typed +0 -0
  55. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/resources/monitor.py +0 -0
  56. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/types/defend_response.py +0 -0
  57. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/types/defend_submit_event_params.py +0 -0
  58. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/types/defend_update_workflow_params.py +0 -0
  59. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/types/monitor_create_params.py +0 -0
  60. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/types/monitor_detail_response.py +0 -0
  61. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/types/monitor_event_response.py +0 -0
  62. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/types/monitor_response.py +0 -0
  63. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/types/monitor_retrieve_params.py +0 -0
  64. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/types/monitor_submit_event_params.py +0 -0
  65. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/types/monitor_update_params.py +0 -0
  66. {deeprails-1.10.0 → deeprails-1.11.0}/src/deeprails/types/workflow_event_response.py +0 -0
  67. {deeprails-1.10.0 → deeprails-1.11.0}/tests/__init__.py +0 -0
  68. {deeprails-1.10.0 → deeprails-1.11.0}/tests/api_resources/__init__.py +0 -0
  69. {deeprails-1.10.0 → deeprails-1.11.0}/tests/api_resources/test_monitor.py +0 -0
  70. {deeprails-1.10.0 → deeprails-1.11.0}/tests/conftest.py +0 -0
  71. {deeprails-1.10.0 → deeprails-1.11.0}/tests/sample_file.txt +0 -0
  72. {deeprails-1.10.0 → deeprails-1.11.0}/tests/test_client.py +0 -0
  73. {deeprails-1.10.0 → deeprails-1.11.0}/tests/test_deepcopy.py +0 -0
  74. {deeprails-1.10.0 → deeprails-1.11.0}/tests/test_extract_files.py +0 -0
  75. {deeprails-1.10.0 → deeprails-1.11.0}/tests/test_files.py +0 -0
  76. {deeprails-1.10.0 → deeprails-1.11.0}/tests/test_models.py +0 -0
  77. {deeprails-1.10.0 → deeprails-1.11.0}/tests/test_qs.py +0 -0
  78. {deeprails-1.10.0 → deeprails-1.11.0}/tests/test_required_args.py +0 -0
  79. {deeprails-1.10.0 → deeprails-1.11.0}/tests/test_response.py +0 -0
  80. {deeprails-1.10.0 → deeprails-1.11.0}/tests/test_streaming.py +0 -0
  81. {deeprails-1.10.0 → deeprails-1.11.0}/tests/test_transform.py +0 -0
  82. {deeprails-1.10.0 → deeprails-1.11.0}/tests/test_utils/test_datetime_parse.py +0 -0
  83. {deeprails-1.10.0 → deeprails-1.11.0}/tests/test_utils/test_proxy.py +0 -0
  84. {deeprails-1.10.0 → deeprails-1.11.0}/tests/test_utils/test_typing.py +0 -0
  85. {deeprails-1.10.0 → deeprails-1.11.0}/tests/utils.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "1.11.0"
3
+ }
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.11.0 (2025-10-30)
4
+
5
+ Full Changelog: [v1.10.0...v1.11.0](https://github.com/deeprails/deeprails-sdk-python/compare/v1.10.0...v1.11.0)
6
+
7
+ ### Features
8
+
9
+ * **api:** Add file and web search as extended ai capabilities ([fc2bb8d](https://github.com/deeprails/deeprails-sdk-python/commit/fc2bb8d0ce8f111279583398469ae9bc0d11d474))
10
+ * **api:** manual updates ([236c2a9](https://github.com/deeprails/deeprails-sdk-python/commit/236c2a923f7bcaa08f92a799be9ca725a0a3b53b))
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * **client:** close streams without requiring full consumption ([db832f6](https://github.com/deeprails/deeprails-sdk-python/commit/db832f6e4067940c762e5d0be9d57cbaf72c7309))
16
+
3
17
  ## 1.10.0 (2025-10-29)
4
18
 
5
19
  Full Changelog: [v1.9.0...v1.10.0](https://github.com/deeprails/deeprails-sdk-python/compare/v1.9.0...v1.10.0)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: deeprails
3
- Version: 1.10.0
3
+ Version: 1.11.0
4
4
  Summary: The official Python library for the deeprails API
5
5
  Project-URL: Homepage, https://docs.deeprails.com/
6
6
  Project-URL: Repository, https://github.com/deeprails/deeprails-sdk-python
@@ -181,6 +181,23 @@ workflow_event_response = client.defend.submit_event(
181
181
  print(workflow_event_response.model_input)
182
182
  ```
183
183
 
184
+ ## File uploads
185
+
186
+ Request parameters that correspond to file uploads can be passed as `bytes`, or a [`PathLike`](https://docs.python.org/3/library/os.html#os.PathLike) instance or a tuple of `(filename, contents, media type)`.
187
+
188
+ ```python
189
+ from pathlib import Path
190
+ from deeprails import Deeprails
191
+
192
+ client = Deeprails()
193
+
194
+ client.files.upload(
195
+ file=Path("/path/to/file"),
196
+ )
197
+ ```
198
+
199
+ The async client uses the exact same interface. If you pass a [`PathLike`](https://docs.python.org/3/library/os.html#os.PathLike) instance, the file contents will be read asynchronously automatically.
200
+
184
201
  ## Handling errors
185
202
 
186
203
  When the library is unable to connect to the API (for example, due to network connection problems or a timeout), a subclass of `deeprails.APIConnectionError` is raised.
@@ -146,6 +146,23 @@ workflow_event_response = client.defend.submit_event(
146
146
  print(workflow_event_response.model_input)
147
147
  ```
148
148
 
149
+ ## File uploads
150
+
151
+ Request parameters that correspond to file uploads can be passed as `bytes`, or a [`PathLike`](https://docs.python.org/3/library/os.html#os.PathLike) instance or a tuple of `(filename, contents, media type)`.
152
+
153
+ ```python
154
+ from pathlib import Path
155
+ from deeprails import Deeprails
156
+
157
+ client = Deeprails()
158
+
159
+ client.files.upload(
160
+ file=Path("/path/to/file"),
161
+ )
162
+ ```
163
+
164
+ The async client uses the exact same interface. If you pass a [`PathLike`](https://docs.python.org/3/library/os.html#os.PathLike) instance, the file contents will be read asynchronously automatically.
165
+
149
166
  ## Handling errors
150
167
 
151
168
  When the library is unable to connect to the API (for example, due to network connection problems or a timeout), a subclass of `deeprails.APIConnectionError` is raised.
@@ -28,3 +28,15 @@ Methods:
28
28
  - <code title="get /monitor/{monitor_id}">client.monitor.<a href="./src/deeprails/resources/monitor.py">retrieve</a>(monitor_id, \*\*<a href="src/deeprails/types/monitor_retrieve_params.py">params</a>) -> <a href="./src/deeprails/types/monitor_detail_response.py">MonitorDetailResponse</a></code>
29
29
  - <code title="put /monitor/{monitor_id}">client.monitor.<a href="./src/deeprails/resources/monitor.py">update</a>(monitor_id, \*\*<a href="src/deeprails/types/monitor_update_params.py">params</a>) -> <a href="./src/deeprails/types/monitor_response.py">MonitorResponse</a></code>
30
30
  - <code title="post /monitor/{monitor_id}/events">client.monitor.<a href="./src/deeprails/resources/monitor.py">submit_event</a>(monitor_id, \*\*<a href="src/deeprails/types/monitor_submit_event_params.py">params</a>) -> <a href="./src/deeprails/types/monitor_event_response.py">MonitorEventResponse</a></code>
31
+
32
+ # Files
33
+
34
+ Types:
35
+
36
+ ```python
37
+ from deeprails.types import FileResponse
38
+ ```
39
+
40
+ Methods:
41
+
42
+ - <code title="post /files/upload">client.files.<a href="./src/deeprails/resources/files.py">upload</a>(\*\*<a href="src/deeprails/types/file_upload_params.py">params</a>) -> <a href="./src/deeprails/types/file_response.py">FileResponse</a></code>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "deeprails"
3
- version = "1.10.0"
3
+ version = "1.11.0"
4
4
  description = "The official Python library for the deeprails API"
5
5
  dynamic = ["readme"]
6
6
  license = "Apache-2.0"
@@ -21,7 +21,7 @@ from ._types import (
21
21
  )
22
22
  from ._utils import is_given, get_async_library
23
23
  from ._version import __version__
24
- from .resources import defend, monitor
24
+ from .resources import files, defend, monitor
25
25
  from ._streaming import Stream as Stream, AsyncStream as AsyncStream
26
26
  from ._exceptions import APIStatusError, DeeprailsError
27
27
  from ._base_client import (
@@ -45,6 +45,7 @@ __all__ = [
45
45
  class Deeprails(SyncAPIClient):
46
46
  defend: defend.DefendResource
47
47
  monitor: monitor.MonitorResource
48
+ files: files.FilesResource
48
49
  with_raw_response: DeeprailsWithRawResponse
49
50
  with_streaming_response: DeeprailsWithStreamedResponse
50
51
 
@@ -104,6 +105,7 @@ class Deeprails(SyncAPIClient):
104
105
 
105
106
  self.defend = defend.DefendResource(self)
106
107
  self.monitor = monitor.MonitorResource(self)
108
+ self.files = files.FilesResource(self)
107
109
  self.with_raw_response = DeeprailsWithRawResponse(self)
108
110
  self.with_streaming_response = DeeprailsWithStreamedResponse(self)
109
111
 
@@ -215,6 +217,7 @@ class Deeprails(SyncAPIClient):
215
217
  class AsyncDeeprails(AsyncAPIClient):
216
218
  defend: defend.AsyncDefendResource
217
219
  monitor: monitor.AsyncMonitorResource
220
+ files: files.AsyncFilesResource
218
221
  with_raw_response: AsyncDeeprailsWithRawResponse
219
222
  with_streaming_response: AsyncDeeprailsWithStreamedResponse
220
223
 
@@ -274,6 +277,7 @@ class AsyncDeeprails(AsyncAPIClient):
274
277
 
275
278
  self.defend = defend.AsyncDefendResource(self)
276
279
  self.monitor = monitor.AsyncMonitorResource(self)
280
+ self.files = files.AsyncFilesResource(self)
277
281
  self.with_raw_response = AsyncDeeprailsWithRawResponse(self)
278
282
  self.with_streaming_response = AsyncDeeprailsWithStreamedResponse(self)
279
283
 
@@ -386,24 +390,28 @@ class DeeprailsWithRawResponse:
386
390
  def __init__(self, client: Deeprails) -> None:
387
391
  self.defend = defend.DefendResourceWithRawResponse(client.defend)
388
392
  self.monitor = monitor.MonitorResourceWithRawResponse(client.monitor)
393
+ self.files = files.FilesResourceWithRawResponse(client.files)
389
394
 
390
395
 
391
396
  class AsyncDeeprailsWithRawResponse:
392
397
  def __init__(self, client: AsyncDeeprails) -> None:
393
398
  self.defend = defend.AsyncDefendResourceWithRawResponse(client.defend)
394
399
  self.monitor = monitor.AsyncMonitorResourceWithRawResponse(client.monitor)
400
+ self.files = files.AsyncFilesResourceWithRawResponse(client.files)
395
401
 
396
402
 
397
403
  class DeeprailsWithStreamedResponse:
398
404
  def __init__(self, client: Deeprails) -> None:
399
405
  self.defend = defend.DefendResourceWithStreamingResponse(client.defend)
400
406
  self.monitor = monitor.MonitorResourceWithStreamingResponse(client.monitor)
407
+ self.files = files.FilesResourceWithStreamingResponse(client.files)
401
408
 
402
409
 
403
410
  class AsyncDeeprailsWithStreamedResponse:
404
411
  def __init__(self, client: AsyncDeeprails) -> None:
405
412
  self.defend = defend.AsyncDefendResourceWithStreamingResponse(client.defend)
406
413
  self.monitor = monitor.AsyncMonitorResourceWithStreamingResponse(client.monitor)
414
+ self.files = files.AsyncFilesResourceWithStreamingResponse(client.files)
407
415
 
408
416
 
409
417
  Client = Deeprails
@@ -34,7 +34,7 @@ def assert_is_file_content(obj: object, *, key: str | None = None) -> None:
34
34
  if not is_file_content(obj):
35
35
  prefix = f"Expected entry at `{key}`" if key is not None else f"Expected file input `{obj!r}`"
36
36
  raise RuntimeError(
37
- f"{prefix} to be bytes, an io.IOBase instance, PathLike or a tuple but received {type(obj)} instead."
37
+ f"{prefix} to be bytes, an io.IOBase instance, PathLike or a tuple but received {type(obj)} instead. See https://github.com/deeprails/deeprails-sdk-python/tree/main#file-uploads"
38
38
  ) from None
39
39
 
40
40
 
@@ -57,9 +57,8 @@ class Stream(Generic[_T]):
57
57
  for sse in iterator:
58
58
  yield process_data(data=sse.json(), cast_to=cast_to, response=response)
59
59
 
60
- # Ensure the entire stream is consumed
61
- for _sse in iterator:
62
- ...
60
+ # As we might not fully consume the response stream, we need to close it explicitly
61
+ response.close()
63
62
 
64
63
  def __enter__(self) -> Self:
65
64
  return self
@@ -121,9 +120,8 @@ class AsyncStream(Generic[_T]):
121
120
  async for sse in iterator:
122
121
  yield process_data(data=sse.json(), cast_to=cast_to, response=response)
123
122
 
124
- # Ensure the entire stream is consumed
125
- async for _sse in iterator:
126
- ...
123
+ # As we might not fully consume the response stream, we need to close it explicitly
124
+ await response.aclose()
127
125
 
128
126
  async def __aenter__(self) -> Self:
129
127
  return self
@@ -1,4 +1,4 @@
1
1
  # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
2
 
3
3
  __title__ = "deeprails"
4
- __version__ = "1.10.0" # x-release-please-version
4
+ __version__ = "1.11.0" # x-release-please-version
@@ -1,5 +1,13 @@
1
1
  # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
2
 
3
+ from .files import (
4
+ FilesResource,
5
+ AsyncFilesResource,
6
+ FilesResourceWithRawResponse,
7
+ AsyncFilesResourceWithRawResponse,
8
+ FilesResourceWithStreamingResponse,
9
+ AsyncFilesResourceWithStreamingResponse,
10
+ )
3
11
  from .defend import (
4
12
  DefendResource,
5
13
  AsyncDefendResource,
@@ -30,4 +38,10 @@ __all__ = [
30
38
  "AsyncMonitorResourceWithRawResponse",
31
39
  "MonitorResourceWithStreamingResponse",
32
40
  "AsyncMonitorResourceWithStreamingResponse",
41
+ "FilesResource",
42
+ "AsyncFilesResource",
43
+ "FilesResourceWithRawResponse",
44
+ "AsyncFilesResourceWithRawResponse",
45
+ "FilesResourceWithStreamingResponse",
46
+ "AsyncFilesResourceWithStreamingResponse",
33
47
  ]
@@ -8,7 +8,7 @@ from typing_extensions import Literal
8
8
  import httpx
9
9
 
10
10
  from ..types import defend_submit_event_params, defend_create_workflow_params, defend_update_workflow_params
11
- from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
11
+ from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
12
12
  from .._utils import maybe_transform, async_maybe_transform
13
13
  from .._compat import cached_property
14
14
  from .._resource import SyncAPIResource, AsyncAPIResource
@@ -54,7 +54,9 @@ class DefendResource(SyncAPIResource):
54
54
  automatic_hallucination_tolerance_levels: Dict[str, Literal["low", "medium", "high"]] | Omit = omit,
55
55
  custom_hallucination_threshold_values: Dict[str, float] | Omit = omit,
56
56
  description: str | Omit = omit,
57
+ file_search: SequenceNotStr[str] | Omit = omit,
57
58
  max_improvement_attempts: int | Omit = omit,
59
+ web_search: bool | Omit = omit,
58
60
  # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
59
61
  # The extra values given here take precedence over values defined on the client or passed to this method.
60
62
  extra_headers: Headers | None = None,
@@ -92,9 +94,14 @@ class DefendResource(SyncAPIResource):
92
94
 
93
95
  description: Description for the workflow.
94
96
 
97
+ file_search: An array of file IDs to search in the workflow's evaluations. Files must be
98
+ uploaded via the DeepRails API first.
99
+
95
100
  max_improvement_attempts: Max. number of improvement action retries until a given event passes the
96
101
  guardrails. Defaults to 10.
97
102
 
103
+ web_search: Whether to enable web search for this workflow's evaluations. Defaults to false.
104
+
98
105
  extra_headers: Send extra headers
99
106
 
100
107
  extra_query: Add additional query parameters to the request
@@ -113,7 +120,9 @@ class DefendResource(SyncAPIResource):
113
120
  "automatic_hallucination_tolerance_levels": automatic_hallucination_tolerance_levels,
114
121
  "custom_hallucination_threshold_values": custom_hallucination_threshold_values,
115
122
  "description": description,
123
+ "file_search": file_search,
116
124
  "max_improvement_attempts": max_improvement_attempts,
125
+ "web_search": web_search,
117
126
  },
118
127
  defend_create_workflow_params.DefendCreateWorkflowParams,
119
128
  ),
@@ -332,7 +341,9 @@ class AsyncDefendResource(AsyncAPIResource):
332
341
  automatic_hallucination_tolerance_levels: Dict[str, Literal["low", "medium", "high"]] | Omit = omit,
333
342
  custom_hallucination_threshold_values: Dict[str, float] | Omit = omit,
334
343
  description: str | Omit = omit,
344
+ file_search: SequenceNotStr[str] | Omit = omit,
335
345
  max_improvement_attempts: int | Omit = omit,
346
+ web_search: bool | Omit = omit,
336
347
  # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
337
348
  # The extra values given here take precedence over values defined on the client or passed to this method.
338
349
  extra_headers: Headers | None = None,
@@ -370,9 +381,14 @@ class AsyncDefendResource(AsyncAPIResource):
370
381
 
371
382
  description: Description for the workflow.
372
383
 
384
+ file_search: An array of file IDs to search in the workflow's evaluations. Files must be
385
+ uploaded via the DeepRails API first.
386
+
373
387
  max_improvement_attempts: Max. number of improvement action retries until a given event passes the
374
388
  guardrails. Defaults to 10.
375
389
 
390
+ web_search: Whether to enable web search for this workflow's evaluations. Defaults to false.
391
+
376
392
  extra_headers: Send extra headers
377
393
 
378
394
  extra_query: Add additional query parameters to the request
@@ -391,7 +407,9 @@ class AsyncDefendResource(AsyncAPIResource):
391
407
  "automatic_hallucination_tolerance_levels": automatic_hallucination_tolerance_levels,
392
408
  "custom_hallucination_threshold_values": custom_hallucination_threshold_values,
393
409
  "description": description,
410
+ "file_search": file_search,
394
411
  "max_improvement_attempts": max_improvement_attempts,
412
+ "web_search": web_search,
395
413
  },
396
414
  defend_create_workflow_params.DefendCreateWorkflowParams,
397
415
  ),
@@ -0,0 +1,183 @@
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 Mapping, cast
6
+
7
+ import httpx
8
+
9
+ from ..types import file_upload_params
10
+ from .._types import Body, Query, Headers, NotGiven, FileTypes, not_given
11
+ from .._utils import extract_files, maybe_transform, deepcopy_minimal, async_maybe_transform
12
+ from .._compat import cached_property
13
+ from .._resource import SyncAPIResource, AsyncAPIResource
14
+ from .._response import (
15
+ to_raw_response_wrapper,
16
+ to_streamed_response_wrapper,
17
+ async_to_raw_response_wrapper,
18
+ async_to_streamed_response_wrapper,
19
+ )
20
+ from .._base_client import make_request_options
21
+ from ..types.file_response import FileResponse
22
+
23
+ __all__ = ["FilesResource", "AsyncFilesResource"]
24
+
25
+
26
+ class FilesResource(SyncAPIResource):
27
+ @cached_property
28
+ def with_raw_response(self) -> FilesResourceWithRawResponse:
29
+ """
30
+ This property can be used as a prefix for any HTTP method call to return
31
+ the raw response object instead of the parsed content.
32
+
33
+ For more information, see https://www.github.com/deeprails/deeprails-sdk-python#accessing-raw-response-data-eg-headers
34
+ """
35
+ return FilesResourceWithRawResponse(self)
36
+
37
+ @cached_property
38
+ def with_streaming_response(self) -> FilesResourceWithStreamingResponse:
39
+ """
40
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
41
+
42
+ For more information, see https://www.github.com/deeprails/deeprails-sdk-python#with_streaming_response
43
+ """
44
+ return FilesResourceWithStreamingResponse(self)
45
+
46
+ def upload(
47
+ self,
48
+ *,
49
+ file: FileTypes,
50
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
51
+ # The extra values given here take precedence over values defined on the client or passed to this method.
52
+ extra_headers: Headers | None = None,
53
+ extra_query: Query | None = None,
54
+ extra_body: Body | None = None,
55
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
56
+ ) -> FileResponse:
57
+ """
58
+ Use this endpoint to upload a file to the DeepRails API
59
+
60
+ Args:
61
+ file: The contents of the file to upload.
62
+
63
+ extra_headers: Send extra headers
64
+
65
+ extra_query: Add additional query parameters to the request
66
+
67
+ extra_body: Add additional JSON properties to the request
68
+
69
+ timeout: Override the client-level default timeout for this request, in seconds
70
+ """
71
+ body = deepcopy_minimal({"file": file})
72
+ files = extract_files(cast(Mapping[str, object], body), paths=[["file"]])
73
+ # It should be noted that the actual Content-Type header that will be
74
+ # sent to the server will contain a `boundary` parameter, e.g.
75
+ # multipart/form-data; boundary=---abc--
76
+ extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
77
+ return self._post(
78
+ "/files/upload",
79
+ body=maybe_transform(body, file_upload_params.FileUploadParams),
80
+ files=files,
81
+ options=make_request_options(
82
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
83
+ ),
84
+ cast_to=FileResponse,
85
+ )
86
+
87
+
88
+ class AsyncFilesResource(AsyncAPIResource):
89
+ @cached_property
90
+ def with_raw_response(self) -> AsyncFilesResourceWithRawResponse:
91
+ """
92
+ This property can be used as a prefix for any HTTP method call to return
93
+ the raw response object instead of the parsed content.
94
+
95
+ For more information, see https://www.github.com/deeprails/deeprails-sdk-python#accessing-raw-response-data-eg-headers
96
+ """
97
+ return AsyncFilesResourceWithRawResponse(self)
98
+
99
+ @cached_property
100
+ def with_streaming_response(self) -> AsyncFilesResourceWithStreamingResponse:
101
+ """
102
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
103
+
104
+ For more information, see https://www.github.com/deeprails/deeprails-sdk-python#with_streaming_response
105
+ """
106
+ return AsyncFilesResourceWithStreamingResponse(self)
107
+
108
+ async def upload(
109
+ self,
110
+ *,
111
+ file: FileTypes,
112
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
113
+ # The extra values given here take precedence over values defined on the client or passed to this method.
114
+ extra_headers: Headers | None = None,
115
+ extra_query: Query | None = None,
116
+ extra_body: Body | None = None,
117
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
118
+ ) -> FileResponse:
119
+ """
120
+ Use this endpoint to upload a file to the DeepRails API
121
+
122
+ Args:
123
+ file: The contents of the file to upload.
124
+
125
+ extra_headers: Send extra headers
126
+
127
+ extra_query: Add additional query parameters to the request
128
+
129
+ extra_body: Add additional JSON properties to the request
130
+
131
+ timeout: Override the client-level default timeout for this request, in seconds
132
+ """
133
+ body = deepcopy_minimal({"file": file})
134
+ files = extract_files(cast(Mapping[str, object], body), paths=[["file"]])
135
+ # It should be noted that the actual Content-Type header that will be
136
+ # sent to the server will contain a `boundary` parameter, e.g.
137
+ # multipart/form-data; boundary=---abc--
138
+ extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
139
+ return await self._post(
140
+ "/files/upload",
141
+ body=await async_maybe_transform(body, file_upload_params.FileUploadParams),
142
+ files=files,
143
+ options=make_request_options(
144
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
145
+ ),
146
+ cast_to=FileResponse,
147
+ )
148
+
149
+
150
+ class FilesResourceWithRawResponse:
151
+ def __init__(self, files: FilesResource) -> None:
152
+ self._files = files
153
+
154
+ self.upload = to_raw_response_wrapper(
155
+ files.upload,
156
+ )
157
+
158
+
159
+ class AsyncFilesResourceWithRawResponse:
160
+ def __init__(self, files: AsyncFilesResource) -> None:
161
+ self._files = files
162
+
163
+ self.upload = async_to_raw_response_wrapper(
164
+ files.upload,
165
+ )
166
+
167
+
168
+ class FilesResourceWithStreamingResponse:
169
+ def __init__(self, files: FilesResource) -> None:
170
+ self._files = files
171
+
172
+ self.upload = to_streamed_response_wrapper(
173
+ files.upload,
174
+ )
175
+
176
+
177
+ class AsyncFilesResourceWithStreamingResponse:
178
+ def __init__(self, files: AsyncFilesResource) -> None:
179
+ self._files = files
180
+
181
+ self.upload = async_to_streamed_response_wrapper(
182
+ files.upload,
183
+ )
@@ -2,8 +2,10 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ from .file_response import FileResponse as FileResponse
5
6
  from .defend_response import DefendResponse as DefendResponse
6
7
  from .monitor_response import MonitorResponse as MonitorResponse
8
+ from .file_upload_params import FileUploadParams as FileUploadParams
7
9
  from .monitor_create_params import MonitorCreateParams as MonitorCreateParams
8
10
  from .monitor_update_params import MonitorUpdateParams as MonitorUpdateParams
9
11
  from .monitor_event_response import MonitorEventResponse as MonitorEventResponse
@@ -5,6 +5,8 @@ from __future__ import annotations
5
5
  from typing import Dict
6
6
  from typing_extensions import Literal, Required, TypedDict
7
7
 
8
+ from .._types import SequenceNotStr
9
+
8
10
  __all__ = ["DefendCreateWorkflowParams"]
9
11
 
10
12
 
@@ -48,9 +50,21 @@ class DefendCreateWorkflowParams(TypedDict, total=False):
48
50
  description: str
49
51
  """Description for the workflow."""
50
52
 
53
+ file_search: SequenceNotStr[str]
54
+ """An array of file IDs to search in the workflow's evaluations.
55
+
56
+ Files must be uploaded via the DeepRails API first.
57
+ """
58
+
51
59
  max_improvement_attempts: int
52
60
  """Max.
53
61
 
54
62
  number of improvement action retries until a given event passes the guardrails.
55
63
  Defaults to 10.
56
64
  """
65
+
66
+ web_search: bool
67
+ """Whether to enable web search for this workflow's evaluations.
68
+
69
+ Defaults to false.
70
+ """
@@ -0,0 +1,25 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from typing import Optional
4
+ from datetime import datetime
5
+
6
+ from .._models import BaseModel
7
+
8
+ __all__ = ["FileResponse"]
9
+
10
+
11
+ class FileResponse(BaseModel):
12
+ created_at: Optional[datetime] = None
13
+ """The time the file was created in UTC."""
14
+
15
+ file_id: Optional[str] = None
16
+ """A unique file ID."""
17
+
18
+ file_name: Optional[str] = None
19
+ """Name of the file."""
20
+
21
+ file_path: Optional[str] = None
22
+ """Path to the s3 bucket where the file is stored."""
23
+
24
+ updated_at: Optional[datetime] = None
25
+ """The most recent time the file was modified in UTC."""
@@ -0,0 +1,14 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing_extensions import Required, TypedDict
6
+
7
+ from .._types import FileTypes
8
+
9
+ __all__ = ["FileUploadParams"]
10
+
11
+
12
+ class FileUploadParams(TypedDict, total=False):
13
+ file: Required[FileTypes]
14
+ """The contents of the file to upload."""
@@ -40,7 +40,9 @@ class TestDefend:
40
40
  type="automatic",
41
41
  automatic_hallucination_tolerance_levels={"correctness": "low"},
42
42
  description="description",
43
+ file_search=["string"],
43
44
  max_improvement_attempts=2,
45
+ web_search=True,
44
46
  )
45
47
  assert_matches_type(DefendResponse, defend, path=["response"])
46
48
 
@@ -323,7 +325,9 @@ class TestAsyncDefend:
323
325
  type="automatic",
324
326
  automatic_hallucination_tolerance_levels={"correctness": "low"},
325
327
  description="description",
328
+ file_search=["string"],
326
329
  max_improvement_attempts=2,
330
+ web_search=True,
327
331
  )
328
332
  assert_matches_type(DefendResponse, defend, path=["response"])
329
333
 
@@ -0,0 +1,92 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from typing import Any, cast
7
+
8
+ import pytest
9
+
10
+ from deeprails import Deeprails, AsyncDeeprails
11
+ from tests.utils import assert_matches_type
12
+ from deeprails.types import FileResponse
13
+
14
+ base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
15
+
16
+
17
+ class TestFiles:
18
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
19
+
20
+ @pytest.mark.skip(reason="Prism tests are disabled")
21
+ @parametrize
22
+ def test_method_upload(self, client: Deeprails) -> None:
23
+ file = client.files.upload(
24
+ file=b"raw file contents",
25
+ )
26
+ assert_matches_type(FileResponse, file, path=["response"])
27
+
28
+ @pytest.mark.skip(reason="Prism tests are disabled")
29
+ @parametrize
30
+ def test_raw_response_upload(self, client: Deeprails) -> None:
31
+ response = client.files.with_raw_response.upload(
32
+ file=b"raw file contents",
33
+ )
34
+
35
+ assert response.is_closed is True
36
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
37
+ file = response.parse()
38
+ assert_matches_type(FileResponse, file, path=["response"])
39
+
40
+ @pytest.mark.skip(reason="Prism tests are disabled")
41
+ @parametrize
42
+ def test_streaming_response_upload(self, client: Deeprails) -> None:
43
+ with client.files.with_streaming_response.upload(
44
+ file=b"raw file contents",
45
+ ) as response:
46
+ assert not response.is_closed
47
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
48
+
49
+ file = response.parse()
50
+ assert_matches_type(FileResponse, file, path=["response"])
51
+
52
+ assert cast(Any, response.is_closed) is True
53
+
54
+
55
+ class TestAsyncFiles:
56
+ parametrize = pytest.mark.parametrize(
57
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
58
+ )
59
+
60
+ @pytest.mark.skip(reason="Prism tests are disabled")
61
+ @parametrize
62
+ async def test_method_upload(self, async_client: AsyncDeeprails) -> None:
63
+ file = await async_client.files.upload(
64
+ file=b"raw file contents",
65
+ )
66
+ assert_matches_type(FileResponse, file, path=["response"])
67
+
68
+ @pytest.mark.skip(reason="Prism tests are disabled")
69
+ @parametrize
70
+ async def test_raw_response_upload(self, async_client: AsyncDeeprails) -> None:
71
+ response = await async_client.files.with_raw_response.upload(
72
+ file=b"raw file contents",
73
+ )
74
+
75
+ assert response.is_closed is True
76
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
77
+ file = await response.parse()
78
+ assert_matches_type(FileResponse, file, path=["response"])
79
+
80
+ @pytest.mark.skip(reason="Prism tests are disabled")
81
+ @parametrize
82
+ async def test_streaming_response_upload(self, async_client: AsyncDeeprails) -> None:
83
+ async with async_client.files.with_streaming_response.upload(
84
+ file=b"raw file contents",
85
+ ) as response:
86
+ assert not response.is_closed
87
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
88
+
89
+ file = await response.parse()
90
+ assert_matches_type(FileResponse, file, path=["response"])
91
+
92
+ assert cast(Any, response.is_closed) is True
@@ -1,3 +0,0 @@
1
- {
2
- ".": "1.10.0"
3
- }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes