codeset 0.1.0a11__tar.gz → 0.1.0a13__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 codeset might be problematic. Click here for more details.

Files changed (95) hide show
  1. {codeset-0.1.0a11 → codeset-0.1.0a13}/.gitignore +0 -1
  2. codeset-0.1.0a13/.release-please-manifest.json +3 -0
  3. {codeset-0.1.0a11 → codeset-0.1.0a13}/CHANGELOG.md +28 -0
  4. {codeset-0.1.0a11 → codeset-0.1.0a13}/PKG-INFO +1 -1
  5. {codeset-0.1.0a11 → codeset-0.1.0a13}/api.md +2 -2
  6. {codeset-0.1.0a11 → codeset-0.1.0a13}/pyproject.toml +1 -1
  7. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_base_client.py +4 -1
  8. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_files.py +4 -4
  9. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_models.py +24 -3
  10. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_version.py +1 -1
  11. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/resources/sessions/sessions.py +96 -70
  12. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/types/__init__.py +2 -2
  13. codeset-0.1.0a13/src/codeset/types/session_str_replace_params.py +18 -0
  14. codeset-0.1.0a13/src/codeset/types/session_str_replace_response.py +13 -0
  15. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/types/sessions/job_status.py +1 -1
  16. {codeset-0.1.0a11 → codeset-0.1.0a13}/tests/api_resources/test_sessions.py +109 -93
  17. {codeset-0.1.0a11 → codeset-0.1.0a13}/tests/test_models.py +28 -1
  18. codeset-0.1.0a11/.release-please-manifest.json +0 -3
  19. codeset-0.1.0a11/src/codeset/types/session_apply_diff_params.py +0 -12
  20. codeset-0.1.0a11/src/codeset/types/session_apply_diff_response.py +0 -13
  21. {codeset-0.1.0a11 → codeset-0.1.0a13}/CONTRIBUTING.md +0 -0
  22. {codeset-0.1.0a11 → codeset-0.1.0a13}/LICENSE +0 -0
  23. {codeset-0.1.0a11 → codeset-0.1.0a13}/README.md +0 -0
  24. {codeset-0.1.0a11 → codeset-0.1.0a13}/SECURITY.md +0 -0
  25. {codeset-0.1.0a11 → codeset-0.1.0a13}/bin/check-release-environment +0 -0
  26. {codeset-0.1.0a11 → codeset-0.1.0a13}/bin/publish-pypi +0 -0
  27. {codeset-0.1.0a11 → codeset-0.1.0a13}/examples/.keep +0 -0
  28. {codeset-0.1.0a11 → codeset-0.1.0a13}/mypy.ini +0 -0
  29. {codeset-0.1.0a11 → codeset-0.1.0a13}/noxfile.py +0 -0
  30. {codeset-0.1.0a11 → codeset-0.1.0a13}/release-please-config.json +0 -0
  31. {codeset-0.1.0a11 → codeset-0.1.0a13}/requirements-dev.lock +0 -0
  32. {codeset-0.1.0a11 → codeset-0.1.0a13}/requirements.lock +0 -0
  33. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/__init__.py +0 -0
  34. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_client.py +0 -0
  35. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_compat.py +0 -0
  36. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_constants.py +0 -0
  37. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_exceptions.py +0 -0
  38. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_qs.py +0 -0
  39. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_resource.py +0 -0
  40. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_response.py +0 -0
  41. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_streaming.py +0 -0
  42. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_types.py +0 -0
  43. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_utils/__init__.py +0 -0
  44. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_utils/_logs.py +0 -0
  45. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_utils/_proxy.py +0 -0
  46. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_utils/_reflection.py +0 -0
  47. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_utils/_resources_proxy.py +0 -0
  48. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_utils/_streams.py +0 -0
  49. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_utils/_sync.py +0 -0
  50. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_utils/_transform.py +0 -0
  51. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_utils/_typing.py +0 -0
  52. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/_utils/_utils.py +0 -0
  53. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/lib/.keep +0 -0
  54. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/py.typed +0 -0
  55. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/resources/__init__.py +0 -0
  56. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/resources/health.py +0 -0
  57. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/resources/samples.py +0 -0
  58. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/resources/sessions/__init__.py +0 -0
  59. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/resources/sessions/verify.py +0 -0
  60. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/types/container_info.py +0 -0
  61. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/types/error_info.py +0 -0
  62. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/types/health_check_response.py +0 -0
  63. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/types/sample_download_params.py +0 -0
  64. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/types/sample_list_response.py +0 -0
  65. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/types/session.py +0 -0
  66. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/types/session_close_response.py +0 -0
  67. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/types/session_create_params.py +0 -0
  68. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/types/session_create_response.py +0 -0
  69. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/types/session_execute_command_params.py +0 -0
  70. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/types/session_execute_command_response.py +0 -0
  71. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/types/session_list_response.py +0 -0
  72. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/types/session_status.py +0 -0
  73. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/types/sessions/__init__.py +0 -0
  74. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/types/sessions/verify_start_response.py +0 -0
  75. {codeset-0.1.0a11 → codeset-0.1.0a13}/src/codeset/types/sessions/verify_status_response.py +0 -0
  76. {codeset-0.1.0a11 → codeset-0.1.0a13}/tests/__init__.py +0 -0
  77. {codeset-0.1.0a11 → codeset-0.1.0a13}/tests/api_resources/__init__.py +0 -0
  78. {codeset-0.1.0a11 → codeset-0.1.0a13}/tests/api_resources/sessions/__init__.py +0 -0
  79. {codeset-0.1.0a11 → codeset-0.1.0a13}/tests/api_resources/sessions/test_verify.py +0 -0
  80. {codeset-0.1.0a11 → codeset-0.1.0a13}/tests/api_resources/test_health.py +0 -0
  81. {codeset-0.1.0a11 → codeset-0.1.0a13}/tests/api_resources/test_samples.py +0 -0
  82. {codeset-0.1.0a11 → codeset-0.1.0a13}/tests/conftest.py +0 -0
  83. {codeset-0.1.0a11 → codeset-0.1.0a13}/tests/sample_file.txt +0 -0
  84. {codeset-0.1.0a11 → codeset-0.1.0a13}/tests/test_client.py +0 -0
  85. {codeset-0.1.0a11 → codeset-0.1.0a13}/tests/test_deepcopy.py +0 -0
  86. {codeset-0.1.0a11 → codeset-0.1.0a13}/tests/test_extract_files.py +0 -0
  87. {codeset-0.1.0a11 → codeset-0.1.0a13}/tests/test_files.py +0 -0
  88. {codeset-0.1.0a11 → codeset-0.1.0a13}/tests/test_qs.py +0 -0
  89. {codeset-0.1.0a11 → codeset-0.1.0a13}/tests/test_required_args.py +0 -0
  90. {codeset-0.1.0a11 → codeset-0.1.0a13}/tests/test_response.py +0 -0
  91. {codeset-0.1.0a11 → codeset-0.1.0a13}/tests/test_streaming.py +0 -0
  92. {codeset-0.1.0a11 → codeset-0.1.0a13}/tests/test_transform.py +0 -0
  93. {codeset-0.1.0a11 → codeset-0.1.0a13}/tests/test_utils/test_proxy.py +0 -0
  94. {codeset-0.1.0a11 → codeset-0.1.0a13}/tests/test_utils/test_typing.py +0 -0
  95. {codeset-0.1.0a11 → codeset-0.1.0a13}/tests/utils.py +0 -0
@@ -1,5 +1,4 @@
1
1
  .prism.log
2
- .vscode
3
2
  _dev
4
3
 
5
4
  __pycache__
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.1.0-alpha.13"
3
+ }
@@ -1,5 +1,33 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.0-alpha.13 (2025-07-31)
4
+
5
+ Full Changelog: [v0.1.0-alpha.12...v0.1.0-alpha.13](https://github.com/codeset-ai/codeset-sdk/compare/v0.1.0-alpha.12...v0.1.0-alpha.13)
6
+
7
+ ### Features
8
+
9
+ * **client:** support file upload requests ([dc5d6ec](https://github.com/codeset-ai/codeset-sdk/commit/dc5d6ecd367c436d22ec66da68a906abc978382f))
10
+
11
+
12
+ ### Chores
13
+
14
+ * **project:** add settings file for vscode ([31f4a90](https://github.com/codeset-ai/codeset-sdk/commit/31f4a909e7e7e9699a47c15c9cbee3536929e512))
15
+
16
+ ## 0.1.0-alpha.12 (2025-07-23)
17
+
18
+ Full Changelog: [v0.1.0-alpha.11...v0.1.0-alpha.12](https://github.com/codeset-ai/codeset-sdk/compare/v0.1.0-alpha.11...v0.1.0-alpha.12)
19
+
20
+ ### Features
21
+
22
+ * **api:** api update ([f967221](https://github.com/codeset-ai/codeset-sdk/commit/f967221ede186215eac4438fd42013ae45758645))
23
+ * **api:** manual updates ([abe522a](https://github.com/codeset-ai/codeset-sdk/commit/abe522a3197a58bf8529df02f7959edc05b38e10))
24
+
25
+
26
+ ### Bug Fixes
27
+
28
+ * **parsing:** ignore empty metadata ([e06bcfc](https://github.com/codeset-ai/codeset-sdk/commit/e06bcfce4747daad7ebe9db900b5f8f737f22354))
29
+ * **parsing:** parse extra field types ([3b16904](https://github.com/codeset-ai/codeset-sdk/commit/3b169046c797a7cbe98f9dc8b543921dffca5c21))
30
+
3
31
  ## 0.1.0-alpha.11 (2025-07-20)
4
32
 
5
33
  Full Changelog: [v0.1.0-alpha.10...v0.1.0-alpha.11](https://github.com/codeset-ai/codeset-sdk/compare/v0.1.0-alpha.10...v0.1.0-alpha.11)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: codeset
3
- Version: 0.1.0a11
3
+ Version: 0.1.0a13
4
4
  Summary: The official Python library for the codeset API
5
5
  Project-URL: Homepage, https://github.com/codeset-ai/codeset-sdk
6
6
  Project-URL: Repository, https://github.com/codeset-ai/codeset-sdk
@@ -35,9 +35,9 @@ from codeset.types import (
35
35
  SessionStatus,
36
36
  SessionCreateResponse,
37
37
  SessionListResponse,
38
- SessionApplyDiffResponse,
39
38
  SessionCloseResponse,
40
39
  SessionExecuteCommandResponse,
40
+ SessionStrReplaceResponse,
41
41
  )
42
42
  ```
43
43
 
@@ -46,9 +46,9 @@ Methods:
46
46
  - <code title="post /sessions">client.sessions.<a href="./src/codeset/resources/sessions/sessions.py">create</a>(\*\*<a href="src/codeset/types/session_create_params.py">params</a>) -> <a href="./src/codeset/types/session_create_response.py">SessionCreateResponse</a></code>
47
47
  - <code title="get /sessions/{session_id}">client.sessions.<a href="./src/codeset/resources/sessions/sessions.py">retrieve</a>(session_id) -> <a href="./src/codeset/types/session.py">Session</a></code>
48
48
  - <code title="get /sessions">client.sessions.<a href="./src/codeset/resources/sessions/sessions.py">list</a>() -> <a href="./src/codeset/types/session_list_response.py">SessionListResponse</a></code>
49
- - <code title="post /sessions/{session_id}/apply">client.sessions.<a href="./src/codeset/resources/sessions/sessions.py">apply_diff</a>(session_id, \*\*<a href="src/codeset/types/session_apply_diff_params.py">params</a>) -> <a href="./src/codeset/types/session_apply_diff_response.py">SessionApplyDiffResponse</a></code>
50
49
  - <code title="delete /sessions/{session_id}">client.sessions.<a href="./src/codeset/resources/sessions/sessions.py">close</a>(session_id) -> <a href="./src/codeset/types/session_close_response.py">SessionCloseResponse</a></code>
51
50
  - <code title="post /sessions/{session_id}/exec">client.sessions.<a href="./src/codeset/resources/sessions/sessions.py">execute_command</a>(session_id, \*\*<a href="src/codeset/types/session_execute_command_params.py">params</a>) -> <a href="./src/codeset/types/session_execute_command_response.py">SessionExecuteCommandResponse</a></code>
51
+ - <code title="post /sessions/{session_id}/str_replace">client.sessions.<a href="./src/codeset/resources/sessions/sessions.py">str_replace</a>(session_id, \*\*<a href="src/codeset/types/session_str_replace_params.py">params</a>) -> <a href="./src/codeset/types/session_str_replace_response.py">SessionStrReplaceResponse</a></code>
52
52
 
53
53
  ## Verify
54
54
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "codeset"
3
- version = "0.1.0-alpha.11"
3
+ version = "0.1.0-alpha.13"
4
4
  description = "The official Python library for the codeset API"
5
5
  dynamic = ["readme"]
6
6
  license = "Apache-2.0"
@@ -532,7 +532,10 @@ class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]):
532
532
  is_body_allowed = options.method.lower() != "get"
533
533
 
534
534
  if is_body_allowed:
535
- kwargs["json"] = json_data if is_given(json_data) else None
535
+ if isinstance(json_data, bytes):
536
+ kwargs["content"] = json_data
537
+ else:
538
+ kwargs["json"] = json_data if is_given(json_data) else None
536
539
  kwargs["files"] = files
537
540
  else:
538
541
  headers.pop("Content-Type", None)
@@ -69,12 +69,12 @@ def _transform_file(file: FileTypes) -> HttpxFileTypes:
69
69
  return file
70
70
 
71
71
  if is_tuple_t(file):
72
- return (file[0], _read_file_content(file[1]), *file[2:])
72
+ return (file[0], read_file_content(file[1]), *file[2:])
73
73
 
74
74
  raise TypeError(f"Expected file types input to be a FileContent type or to be a tuple")
75
75
 
76
76
 
77
- def _read_file_content(file: FileContent) -> HttpxFileContent:
77
+ def read_file_content(file: FileContent) -> HttpxFileContent:
78
78
  if isinstance(file, os.PathLike):
79
79
  return pathlib.Path(file).read_bytes()
80
80
  return file
@@ -111,12 +111,12 @@ async def _async_transform_file(file: FileTypes) -> HttpxFileTypes:
111
111
  return file
112
112
 
113
113
  if is_tuple_t(file):
114
- return (file[0], await _async_read_file_content(file[1]), *file[2:])
114
+ return (file[0], await async_read_file_content(file[1]), *file[2:])
115
115
 
116
116
  raise TypeError(f"Expected file types input to be a FileContent type or to be a tuple")
117
117
 
118
118
 
119
- async def _async_read_file_content(file: FileContent) -> HttpxFileContent:
119
+ async def async_read_file_content(file: FileContent) -> HttpxFileContent:
120
120
  if isinstance(file, os.PathLike):
121
121
  return await anyio.Path(file).read_bytes()
122
122
 
@@ -208,14 +208,18 @@ class BaseModel(pydantic.BaseModel):
208
208
  else:
209
209
  fields_values[name] = field_get_default(field)
210
210
 
211
+ extra_field_type = _get_extra_fields_type(__cls)
212
+
211
213
  _extra = {}
212
214
  for key, value in values.items():
213
215
  if key not in model_fields:
216
+ parsed = construct_type(value=value, type_=extra_field_type) if extra_field_type is not None else value
217
+
214
218
  if PYDANTIC_V2:
215
- _extra[key] = value
219
+ _extra[key] = parsed
216
220
  else:
217
221
  _fields_set.add(key)
218
- fields_values[key] = value
222
+ fields_values[key] = parsed
219
223
 
220
224
  object.__setattr__(m, "__dict__", fields_values)
221
225
 
@@ -370,6 +374,23 @@ def _construct_field(value: object, field: FieldInfo, key: str) -> object:
370
374
  return construct_type(value=value, type_=type_, metadata=getattr(field, "metadata", None))
371
375
 
372
376
 
377
+ def _get_extra_fields_type(cls: type[pydantic.BaseModel]) -> type | None:
378
+ if not PYDANTIC_V2:
379
+ # TODO
380
+ return None
381
+
382
+ schema = cls.__pydantic_core_schema__
383
+ if schema["type"] == "model":
384
+ fields = schema["schema"]
385
+ if fields["type"] == "model-fields":
386
+ extras = fields.get("extras_schema")
387
+ if extras and "cls" in extras:
388
+ # mypy can't narrow the type
389
+ return extras["cls"] # type: ignore[no-any-return]
390
+
391
+ return None
392
+
393
+
373
394
  def is_basemodel(type_: type) -> bool:
374
395
  """Returns whether or not the given type is either a `BaseModel` or a union of `BaseModel`"""
375
396
  if is_union(type_):
@@ -439,7 +460,7 @@ def construct_type(*, value: object, type_: object, metadata: Optional[List[Any]
439
460
  type_ = type_.__value__ # type: ignore[unreachable]
440
461
 
441
462
  # unwrap `Annotated[T, ...]` -> `T`
442
- if metadata is not None:
463
+ if metadata is not None and len(metadata) > 0:
443
464
  meta: tuple[Any, ...] = tuple(metadata)
444
465
  elif is_annotated_type(type_):
445
466
  meta = get_args(type_)[1:]
@@ -1,4 +1,4 @@
1
1
  # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
2
 
3
3
  __title__ = "codeset"
4
- __version__ = "0.1.0-alpha.11" # x-release-please-version
4
+ __version__ = "0.1.0-alpha.13" # x-release-please-version
@@ -12,7 +12,7 @@ from .verify import (
12
12
  VerifyResourceWithStreamingResponse,
13
13
  AsyncVerifyResourceWithStreamingResponse,
14
14
  )
15
- from ...types import session_create_params, session_apply_diff_params, session_execute_command_params
15
+ from ...types import session_create_params, session_str_replace_params, session_execute_command_params
16
16
  from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven
17
17
  from ..._utils import maybe_transform, async_maybe_transform
18
18
  from ..._compat import cached_property
@@ -28,7 +28,7 @@ from ...types.session import Session
28
28
  from ...types.session_list_response import SessionListResponse
29
29
  from ...types.session_close_response import SessionCloseResponse
30
30
  from ...types.session_create_response import SessionCreateResponse
31
- from ...types.session_apply_diff_response import SessionApplyDiffResponse
31
+ from ...types.session_str_replace_response import SessionStrReplaceResponse
32
32
  from ...types.session_execute_command_response import SessionExecuteCommandResponse
33
33
 
34
34
  __all__ = ["SessionsResource", "AsyncSessionsResource"]
@@ -157,24 +157,21 @@ class SessionsResource(SyncAPIResource):
157
157
  cast_to=SessionListResponse,
158
158
  )
159
159
 
160
- def apply_diff(
160
+ def close(
161
161
  self,
162
162
  session_id: str,
163
163
  *,
164
- diff: str,
165
164
  # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
166
165
  # The extra values given here take precedence over values defined on the client or passed to this method.
167
166
  extra_headers: Headers | None = None,
168
167
  extra_query: Query | None = None,
169
168
  extra_body: Body | None = None,
170
169
  timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
171
- ) -> SessionApplyDiffResponse:
170
+ ) -> SessionCloseResponse:
172
171
  """
173
- Apply a diff in an environment
172
+ Close/delete an environment session
174
173
 
175
174
  Args:
176
- diff: The diff to be applied, in unified format.
177
-
178
175
  extra_headers: Send extra headers
179
176
 
180
177
  extra_query: Add additional query parameters to the request
@@ -185,30 +182,35 @@ class SessionsResource(SyncAPIResource):
185
182
  """
186
183
  if not session_id:
187
184
  raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
188
- return self._post(
189
- f"/sessions/{session_id}/apply",
190
- body=maybe_transform({"diff": diff}, session_apply_diff_params.SessionApplyDiffParams),
185
+ return self._delete(
186
+ f"/sessions/{session_id}",
191
187
  options=make_request_options(
192
188
  extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
193
189
  ),
194
- cast_to=SessionApplyDiffResponse,
190
+ cast_to=SessionCloseResponse,
195
191
  )
196
192
 
197
- def close(
193
+ def execute_command(
198
194
  self,
199
195
  session_id: str,
200
196
  *,
197
+ command: str,
198
+ command_timeout: int | NotGiven = NOT_GIVEN,
201
199
  # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
202
200
  # The extra values given here take precedence over values defined on the client or passed to this method.
203
201
  extra_headers: Headers | None = None,
204
202
  extra_query: Query | None = None,
205
203
  extra_body: Body | None = None,
206
204
  timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
207
- ) -> SessionCloseResponse:
205
+ ) -> SessionExecuteCommandResponse:
208
206
  """
209
- Close/delete an environment session
207
+ Execute a bash command in an environment
210
208
 
211
209
  Args:
210
+ command: The bash command to execute.
211
+
212
+ command_timeout: Timeout for command execution in seconds (default: 300).
213
+
212
214
  extra_headers: Send extra headers
213
215
 
214
216
  extra_query: Add additional query parameters to the request
@@ -219,34 +221,44 @@ class SessionsResource(SyncAPIResource):
219
221
  """
220
222
  if not session_id:
221
223
  raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
222
- return self._delete(
223
- f"/sessions/{session_id}",
224
+ return self._post(
225
+ f"/sessions/{session_id}/exec",
226
+ body=maybe_transform(
227
+ {
228
+ "command": command,
229
+ "command_timeout": command_timeout,
230
+ },
231
+ session_execute_command_params.SessionExecuteCommandParams,
232
+ ),
224
233
  options=make_request_options(
225
234
  extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
226
235
  ),
227
- cast_to=SessionCloseResponse,
236
+ cast_to=SessionExecuteCommandResponse,
228
237
  )
229
238
 
230
- def execute_command(
239
+ def str_replace(
231
240
  self,
232
241
  session_id: str,
233
242
  *,
234
- command: str,
235
- command_timeout: int | NotGiven = NOT_GIVEN,
243
+ file_path: str,
244
+ str_to_insert: str,
245
+ str_to_replace: str,
236
246
  # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
237
247
  # The extra values given here take precedence over values defined on the client or passed to this method.
238
248
  extra_headers: Headers | None = None,
239
249
  extra_query: Query | None = None,
240
250
  extra_body: Body | None = None,
241
251
  timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
242
- ) -> SessionExecuteCommandResponse:
252
+ ) -> SessionStrReplaceResponse:
243
253
  """
244
- Execute a bash command in an environment
254
+ Replace a string in a file within the session environment
245
255
 
246
256
  Args:
247
- command: The bash command to execute.
257
+ file_path: Path to the file where replacement should be performed.
248
258
 
249
- command_timeout: Timeout for command execution in seconds (default: 300).
259
+ str_to_insert: String to insert as replacement.
260
+
261
+ str_to_replace: String to be replaced.
250
262
 
251
263
  extra_headers: Send extra headers
252
264
 
@@ -259,18 +271,19 @@ class SessionsResource(SyncAPIResource):
259
271
  if not session_id:
260
272
  raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
261
273
  return self._post(
262
- f"/sessions/{session_id}/exec",
274
+ f"/sessions/{session_id}/str_replace",
263
275
  body=maybe_transform(
264
276
  {
265
- "command": command,
266
- "command_timeout": command_timeout,
277
+ "file_path": file_path,
278
+ "str_to_insert": str_to_insert,
279
+ "str_to_replace": str_to_replace,
267
280
  },
268
- session_execute_command_params.SessionExecuteCommandParams,
281
+ session_str_replace_params.SessionStrReplaceParams,
269
282
  ),
270
283
  options=make_request_options(
271
284
  extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
272
285
  ),
273
- cast_to=SessionExecuteCommandResponse,
286
+ cast_to=SessionStrReplaceResponse,
274
287
  )
275
288
 
276
289
 
@@ -397,24 +410,21 @@ class AsyncSessionsResource(AsyncAPIResource):
397
410
  cast_to=SessionListResponse,
398
411
  )
399
412
 
400
- async def apply_diff(
413
+ async def close(
401
414
  self,
402
415
  session_id: str,
403
416
  *,
404
- diff: str,
405
417
  # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
406
418
  # The extra values given here take precedence over values defined on the client or passed to this method.
407
419
  extra_headers: Headers | None = None,
408
420
  extra_query: Query | None = None,
409
421
  extra_body: Body | None = None,
410
422
  timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
411
- ) -> SessionApplyDiffResponse:
423
+ ) -> SessionCloseResponse:
412
424
  """
413
- Apply a diff in an environment
425
+ Close/delete an environment session
414
426
 
415
427
  Args:
416
- diff: The diff to be applied, in unified format.
417
-
418
428
  extra_headers: Send extra headers
419
429
 
420
430
  extra_query: Add additional query parameters to the request
@@ -425,30 +435,35 @@ class AsyncSessionsResource(AsyncAPIResource):
425
435
  """
426
436
  if not session_id:
427
437
  raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
428
- return await self._post(
429
- f"/sessions/{session_id}/apply",
430
- body=await async_maybe_transform({"diff": diff}, session_apply_diff_params.SessionApplyDiffParams),
438
+ return await self._delete(
439
+ f"/sessions/{session_id}",
431
440
  options=make_request_options(
432
441
  extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
433
442
  ),
434
- cast_to=SessionApplyDiffResponse,
443
+ cast_to=SessionCloseResponse,
435
444
  )
436
445
 
437
- async def close(
446
+ async def execute_command(
438
447
  self,
439
448
  session_id: str,
440
449
  *,
450
+ command: str,
451
+ command_timeout: int | NotGiven = NOT_GIVEN,
441
452
  # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
442
453
  # The extra values given here take precedence over values defined on the client or passed to this method.
443
454
  extra_headers: Headers | None = None,
444
455
  extra_query: Query | None = None,
445
456
  extra_body: Body | None = None,
446
457
  timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
447
- ) -> SessionCloseResponse:
458
+ ) -> SessionExecuteCommandResponse:
448
459
  """
449
- Close/delete an environment session
460
+ Execute a bash command in an environment
450
461
 
451
462
  Args:
463
+ command: The bash command to execute.
464
+
465
+ command_timeout: Timeout for command execution in seconds (default: 300).
466
+
452
467
  extra_headers: Send extra headers
453
468
 
454
469
  extra_query: Add additional query parameters to the request
@@ -459,34 +474,44 @@ class AsyncSessionsResource(AsyncAPIResource):
459
474
  """
460
475
  if not session_id:
461
476
  raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
462
- return await self._delete(
463
- f"/sessions/{session_id}",
477
+ return await self._post(
478
+ f"/sessions/{session_id}/exec",
479
+ body=await async_maybe_transform(
480
+ {
481
+ "command": command,
482
+ "command_timeout": command_timeout,
483
+ },
484
+ session_execute_command_params.SessionExecuteCommandParams,
485
+ ),
464
486
  options=make_request_options(
465
487
  extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
466
488
  ),
467
- cast_to=SessionCloseResponse,
489
+ cast_to=SessionExecuteCommandResponse,
468
490
  )
469
491
 
470
- async def execute_command(
492
+ async def str_replace(
471
493
  self,
472
494
  session_id: str,
473
495
  *,
474
- command: str,
475
- command_timeout: int | NotGiven = NOT_GIVEN,
496
+ file_path: str,
497
+ str_to_insert: str,
498
+ str_to_replace: str,
476
499
  # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
477
500
  # The extra values given here take precedence over values defined on the client or passed to this method.
478
501
  extra_headers: Headers | None = None,
479
502
  extra_query: Query | None = None,
480
503
  extra_body: Body | None = None,
481
504
  timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
482
- ) -> SessionExecuteCommandResponse:
505
+ ) -> SessionStrReplaceResponse:
483
506
  """
484
- Execute a bash command in an environment
507
+ Replace a string in a file within the session environment
485
508
 
486
509
  Args:
487
- command: The bash command to execute.
510
+ file_path: Path to the file where replacement should be performed.
488
511
 
489
- command_timeout: Timeout for command execution in seconds (default: 300).
512
+ str_to_insert: String to insert as replacement.
513
+
514
+ str_to_replace: String to be replaced.
490
515
 
491
516
  extra_headers: Send extra headers
492
517
 
@@ -499,18 +524,19 @@ class AsyncSessionsResource(AsyncAPIResource):
499
524
  if not session_id:
500
525
  raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
501
526
  return await self._post(
502
- f"/sessions/{session_id}/exec",
527
+ f"/sessions/{session_id}/str_replace",
503
528
  body=await async_maybe_transform(
504
529
  {
505
- "command": command,
506
- "command_timeout": command_timeout,
530
+ "file_path": file_path,
531
+ "str_to_insert": str_to_insert,
532
+ "str_to_replace": str_to_replace,
507
533
  },
508
- session_execute_command_params.SessionExecuteCommandParams,
534
+ session_str_replace_params.SessionStrReplaceParams,
509
535
  ),
510
536
  options=make_request_options(
511
537
  extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
512
538
  ),
513
- cast_to=SessionExecuteCommandResponse,
539
+ cast_to=SessionStrReplaceResponse,
514
540
  )
515
541
 
516
542
 
@@ -527,15 +553,15 @@ class SessionsResourceWithRawResponse:
527
553
  self.list = to_raw_response_wrapper(
528
554
  sessions.list,
529
555
  )
530
- self.apply_diff = to_raw_response_wrapper(
531
- sessions.apply_diff,
532
- )
533
556
  self.close = to_raw_response_wrapper(
534
557
  sessions.close,
535
558
  )
536
559
  self.execute_command = to_raw_response_wrapper(
537
560
  sessions.execute_command,
538
561
  )
562
+ self.str_replace = to_raw_response_wrapper(
563
+ sessions.str_replace,
564
+ )
539
565
 
540
566
  @cached_property
541
567
  def verify(self) -> VerifyResourceWithRawResponse:
@@ -555,15 +581,15 @@ class AsyncSessionsResourceWithRawResponse:
555
581
  self.list = async_to_raw_response_wrapper(
556
582
  sessions.list,
557
583
  )
558
- self.apply_diff = async_to_raw_response_wrapper(
559
- sessions.apply_diff,
560
- )
561
584
  self.close = async_to_raw_response_wrapper(
562
585
  sessions.close,
563
586
  )
564
587
  self.execute_command = async_to_raw_response_wrapper(
565
588
  sessions.execute_command,
566
589
  )
590
+ self.str_replace = async_to_raw_response_wrapper(
591
+ sessions.str_replace,
592
+ )
567
593
 
568
594
  @cached_property
569
595
  def verify(self) -> AsyncVerifyResourceWithRawResponse:
@@ -583,15 +609,15 @@ class SessionsResourceWithStreamingResponse:
583
609
  self.list = to_streamed_response_wrapper(
584
610
  sessions.list,
585
611
  )
586
- self.apply_diff = to_streamed_response_wrapper(
587
- sessions.apply_diff,
588
- )
589
612
  self.close = to_streamed_response_wrapper(
590
613
  sessions.close,
591
614
  )
592
615
  self.execute_command = to_streamed_response_wrapper(
593
616
  sessions.execute_command,
594
617
  )
618
+ self.str_replace = to_streamed_response_wrapper(
619
+ sessions.str_replace,
620
+ )
595
621
 
596
622
  @cached_property
597
623
  def verify(self) -> VerifyResourceWithStreamingResponse:
@@ -611,15 +637,15 @@ class AsyncSessionsResourceWithStreamingResponse:
611
637
  self.list = async_to_streamed_response_wrapper(
612
638
  sessions.list,
613
639
  )
614
- self.apply_diff = async_to_streamed_response_wrapper(
615
- sessions.apply_diff,
616
- )
617
640
  self.close = async_to_streamed_response_wrapper(
618
641
  sessions.close,
619
642
  )
620
643
  self.execute_command = async_to_streamed_response_wrapper(
621
644
  sessions.execute_command,
622
645
  )
646
+ self.str_replace = async_to_streamed_response_wrapper(
647
+ sessions.str_replace,
648
+ )
623
649
 
624
650
  @cached_property
625
651
  def verify(self) -> AsyncVerifyResourceWithStreamingResponse:
@@ -13,7 +13,7 @@ from .session_list_response import SessionListResponse as SessionListResponse
13
13
  from .sample_download_params import SampleDownloadParams as SampleDownloadParams
14
14
  from .session_close_response import SessionCloseResponse as SessionCloseResponse
15
15
  from .session_create_response import SessionCreateResponse as SessionCreateResponse
16
- from .session_apply_diff_params import SessionApplyDiffParams as SessionApplyDiffParams
17
- from .session_apply_diff_response import SessionApplyDiffResponse as SessionApplyDiffResponse
16
+ from .session_str_replace_params import SessionStrReplaceParams as SessionStrReplaceParams
17
+ from .session_str_replace_response import SessionStrReplaceResponse as SessionStrReplaceResponse
18
18
  from .session_execute_command_params import SessionExecuteCommandParams as SessionExecuteCommandParams
19
19
  from .session_execute_command_response import SessionExecuteCommandResponse as SessionExecuteCommandResponse
@@ -0,0 +1,18 @@
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
+ __all__ = ["SessionStrReplaceParams"]
8
+
9
+
10
+ class SessionStrReplaceParams(TypedDict, total=False):
11
+ file_path: Required[str]
12
+ """Path to the file where replacement should be performed."""
13
+
14
+ str_to_insert: Required[str]
15
+ """String to insert as replacement."""
16
+
17
+ str_to_replace: Required[str]
18
+ """String to be replaced."""
@@ -0,0 +1,13 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from .._models import BaseModel
4
+
5
+ __all__ = ["SessionStrReplaceResponse"]
6
+
7
+
8
+ class SessionStrReplaceResponse(BaseModel):
9
+ message: str
10
+ """Details about the string replacement operation."""
11
+
12
+ success: bool
13
+ """Whether the string replacement was successful."""
@@ -4,4 +4,4 @@ from typing_extensions import Literal, TypeAlias
4
4
 
5
5
  __all__ = ["JobStatus"]
6
6
 
7
- JobStatus: TypeAlias = Literal["pending", "starting", "applying_diff", "running", "completed", "error", "cancelled"]
7
+ JobStatus: TypeAlias = Literal["pending", "starting", "running", "completed", "error", "cancelled"]
@@ -14,7 +14,7 @@ from codeset.types import (
14
14
  SessionListResponse,
15
15
  SessionCloseResponse,
16
16
  SessionCreateResponse,
17
- SessionApplyDiffResponse,
17
+ SessionStrReplaceResponse,
18
18
  SessionExecuteCommandResponse,
19
19
  )
20
20
 
@@ -141,52 +141,6 @@ class TestSessions:
141
141
 
142
142
  assert cast(Any, response.is_closed) is True
143
143
 
144
- @pytest.mark.skip()
145
- @parametrize
146
- def test_method_apply_diff(self, client: Codeset) -> None:
147
- session = client.sessions.apply_diff(
148
- session_id="session_id",
149
- diff="diff",
150
- )
151
- assert_matches_type(SessionApplyDiffResponse, session, path=["response"])
152
-
153
- @pytest.mark.skip()
154
- @parametrize
155
- def test_raw_response_apply_diff(self, client: Codeset) -> None:
156
- response = client.sessions.with_raw_response.apply_diff(
157
- session_id="session_id",
158
- diff="diff",
159
- )
160
-
161
- assert response.is_closed is True
162
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
163
- session = response.parse()
164
- assert_matches_type(SessionApplyDiffResponse, session, path=["response"])
165
-
166
- @pytest.mark.skip()
167
- @parametrize
168
- def test_streaming_response_apply_diff(self, client: Codeset) -> None:
169
- with client.sessions.with_streaming_response.apply_diff(
170
- session_id="session_id",
171
- diff="diff",
172
- ) as response:
173
- assert not response.is_closed
174
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
175
-
176
- session = response.parse()
177
- assert_matches_type(SessionApplyDiffResponse, session, path=["response"])
178
-
179
- assert cast(Any, response.is_closed) is True
180
-
181
- @pytest.mark.skip()
182
- @parametrize
183
- def test_path_params_apply_diff(self, client: Codeset) -> None:
184
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
185
- client.sessions.with_raw_response.apply_diff(
186
- session_id="",
187
- diff="diff",
188
- )
189
-
190
144
  @pytest.mark.skip()
191
145
  @parametrize
192
146
  def test_method_close(self, client: Codeset) -> None:
@@ -285,6 +239,60 @@ class TestSessions:
285
239
  command="command",
286
240
  )
287
241
 
242
+ @pytest.mark.skip()
243
+ @parametrize
244
+ def test_method_str_replace(self, client: Codeset) -> None:
245
+ session = client.sessions.str_replace(
246
+ session_id="session_id",
247
+ file_path="file_path",
248
+ str_to_insert="str_to_insert",
249
+ str_to_replace="str_to_replace",
250
+ )
251
+ assert_matches_type(SessionStrReplaceResponse, session, path=["response"])
252
+
253
+ @pytest.mark.skip()
254
+ @parametrize
255
+ def test_raw_response_str_replace(self, client: Codeset) -> None:
256
+ response = client.sessions.with_raw_response.str_replace(
257
+ session_id="session_id",
258
+ file_path="file_path",
259
+ str_to_insert="str_to_insert",
260
+ str_to_replace="str_to_replace",
261
+ )
262
+
263
+ assert response.is_closed is True
264
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
265
+ session = response.parse()
266
+ assert_matches_type(SessionStrReplaceResponse, session, path=["response"])
267
+
268
+ @pytest.mark.skip()
269
+ @parametrize
270
+ def test_streaming_response_str_replace(self, client: Codeset) -> None:
271
+ with client.sessions.with_streaming_response.str_replace(
272
+ session_id="session_id",
273
+ file_path="file_path",
274
+ str_to_insert="str_to_insert",
275
+ str_to_replace="str_to_replace",
276
+ ) as response:
277
+ assert not response.is_closed
278
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
279
+
280
+ session = response.parse()
281
+ assert_matches_type(SessionStrReplaceResponse, session, path=["response"])
282
+
283
+ assert cast(Any, response.is_closed) is True
284
+
285
+ @pytest.mark.skip()
286
+ @parametrize
287
+ def test_path_params_str_replace(self, client: Codeset) -> None:
288
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
289
+ client.sessions.with_raw_response.str_replace(
290
+ session_id="",
291
+ file_path="file_path",
292
+ str_to_insert="str_to_insert",
293
+ str_to_replace="str_to_replace",
294
+ )
295
+
288
296
 
289
297
  class TestAsyncSessions:
290
298
  parametrize = pytest.mark.parametrize(
@@ -408,52 +416,6 @@ class TestAsyncSessions:
408
416
 
409
417
  assert cast(Any, response.is_closed) is True
410
418
 
411
- @pytest.mark.skip()
412
- @parametrize
413
- async def test_method_apply_diff(self, async_client: AsyncCodeset) -> None:
414
- session = await async_client.sessions.apply_diff(
415
- session_id="session_id",
416
- diff="diff",
417
- )
418
- assert_matches_type(SessionApplyDiffResponse, session, path=["response"])
419
-
420
- @pytest.mark.skip()
421
- @parametrize
422
- async def test_raw_response_apply_diff(self, async_client: AsyncCodeset) -> None:
423
- response = await async_client.sessions.with_raw_response.apply_diff(
424
- session_id="session_id",
425
- diff="diff",
426
- )
427
-
428
- assert response.is_closed is True
429
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
430
- session = await response.parse()
431
- assert_matches_type(SessionApplyDiffResponse, session, path=["response"])
432
-
433
- @pytest.mark.skip()
434
- @parametrize
435
- async def test_streaming_response_apply_diff(self, async_client: AsyncCodeset) -> None:
436
- async with async_client.sessions.with_streaming_response.apply_diff(
437
- session_id="session_id",
438
- diff="diff",
439
- ) as response:
440
- assert not response.is_closed
441
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
442
-
443
- session = await response.parse()
444
- assert_matches_type(SessionApplyDiffResponse, session, path=["response"])
445
-
446
- assert cast(Any, response.is_closed) is True
447
-
448
- @pytest.mark.skip()
449
- @parametrize
450
- async def test_path_params_apply_diff(self, async_client: AsyncCodeset) -> None:
451
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
452
- await async_client.sessions.with_raw_response.apply_diff(
453
- session_id="",
454
- diff="diff",
455
- )
456
-
457
419
  @pytest.mark.skip()
458
420
  @parametrize
459
421
  async def test_method_close(self, async_client: AsyncCodeset) -> None:
@@ -551,3 +513,57 @@ class TestAsyncSessions:
551
513
  session_id="",
552
514
  command="command",
553
515
  )
516
+
517
+ @pytest.mark.skip()
518
+ @parametrize
519
+ async def test_method_str_replace(self, async_client: AsyncCodeset) -> None:
520
+ session = await async_client.sessions.str_replace(
521
+ session_id="session_id",
522
+ file_path="file_path",
523
+ str_to_insert="str_to_insert",
524
+ str_to_replace="str_to_replace",
525
+ )
526
+ assert_matches_type(SessionStrReplaceResponse, session, path=["response"])
527
+
528
+ @pytest.mark.skip()
529
+ @parametrize
530
+ async def test_raw_response_str_replace(self, async_client: AsyncCodeset) -> None:
531
+ response = await async_client.sessions.with_raw_response.str_replace(
532
+ session_id="session_id",
533
+ file_path="file_path",
534
+ str_to_insert="str_to_insert",
535
+ str_to_replace="str_to_replace",
536
+ )
537
+
538
+ assert response.is_closed is True
539
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
540
+ session = await response.parse()
541
+ assert_matches_type(SessionStrReplaceResponse, session, path=["response"])
542
+
543
+ @pytest.mark.skip()
544
+ @parametrize
545
+ async def test_streaming_response_str_replace(self, async_client: AsyncCodeset) -> None:
546
+ async with async_client.sessions.with_streaming_response.str_replace(
547
+ session_id="session_id",
548
+ file_path="file_path",
549
+ str_to_insert="str_to_insert",
550
+ str_to_replace="str_to_replace",
551
+ ) as response:
552
+ assert not response.is_closed
553
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
554
+
555
+ session = await response.parse()
556
+ assert_matches_type(SessionStrReplaceResponse, session, path=["response"])
557
+
558
+ assert cast(Any, response.is_closed) is True
559
+
560
+ @pytest.mark.skip()
561
+ @parametrize
562
+ async def test_path_params_str_replace(self, async_client: AsyncCodeset) -> None:
563
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
564
+ await async_client.sessions.with_raw_response.str_replace(
565
+ session_id="",
566
+ file_path="file_path",
567
+ str_to_insert="str_to_insert",
568
+ str_to_replace="str_to_replace",
569
+ )
@@ -1,5 +1,5 @@
1
1
  import json
2
- from typing import Any, Dict, List, Union, Optional, cast
2
+ from typing import TYPE_CHECKING, Any, Dict, List, Union, Optional, cast
3
3
  from datetime import datetime, timezone
4
4
  from typing_extensions import Literal, Annotated, TypeAliasType
5
5
 
@@ -934,3 +934,30 @@ def test_nested_discriminated_union() -> None:
934
934
  )
935
935
  assert isinstance(model, Type1)
936
936
  assert isinstance(model.value, InnerType2)
937
+
938
+
939
+ @pytest.mark.skipif(not PYDANTIC_V2, reason="this is only supported in pydantic v2 for now")
940
+ def test_extra_properties() -> None:
941
+ class Item(BaseModel):
942
+ prop: int
943
+
944
+ class Model(BaseModel):
945
+ __pydantic_extra__: Dict[str, Item] = Field(init=False) # pyright: ignore[reportIncompatibleVariableOverride]
946
+
947
+ other: str
948
+
949
+ if TYPE_CHECKING:
950
+
951
+ def __getattr__(self, attr: str) -> Item: ...
952
+
953
+ model = construct_type(
954
+ type_=Model,
955
+ value={
956
+ "a": {"prop": 1},
957
+ "other": "foo",
958
+ },
959
+ )
960
+ assert isinstance(model, Model)
961
+ assert model.a.prop == 1
962
+ assert isinstance(model.a, Item)
963
+ assert model.other == "foo"
@@ -1,3 +0,0 @@
1
- {
2
- ".": "0.1.0-alpha.11"
3
- }
@@ -1,12 +0,0 @@
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
- __all__ = ["SessionApplyDiffParams"]
8
-
9
-
10
- class SessionApplyDiffParams(TypedDict, total=False):
11
- diff: Required[str]
12
- """The diff to be applied, in unified format."""
@@ -1,13 +0,0 @@
1
- # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
-
3
- from .._models import BaseModel
4
-
5
- __all__ = ["SessionApplyDiffResponse"]
6
-
7
-
8
- class SessionApplyDiffResponse(BaseModel):
9
- message: str
10
- """Details about the diff application."""
11
-
12
- success: bool
13
- """Whether the diff was applied successfully."""
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
File without changes
File without changes