diff --git a/.release-please-manifest.json b/.release-please-manifest.json index ba6c3483..f14b480a 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.1.0-alpha.1" + ".": "0.1.0-alpha.2" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 43fed307..97b6bcc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.1.0-alpha.2 (2025-01-16) + +Full Changelog: [v0.1.0-alpha.1...v0.1.0-alpha.2](https://github.com/cleanlab/codex-python/compare/v0.1.0-alpha.1...v0.1.0-alpha.2) + +### Features + +* **api:** api update ([#17](https://github.com/cleanlab/codex-python/issues/17)) ([c605871](https://github.com/cleanlab/codex-python/commit/c60587191744877e006ab15adf10f0e5fb7eb252)) + ## 0.1.0-alpha.1 (2025-01-14) Full Changelog: [v0.0.1-alpha.0...v0.1.0-alpha.1](https://github.com/cleanlab/codex-python/compare/v0.0.1-alpha.0...v0.1.0-alpha.1) diff --git a/README.md b/README.md index 7a8ff536..7b5fda1d 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ client = Codex() all_entries = [] # Automatically fetches more pages as needed. for entry in client.projects.entries.list( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ): # Do something with entry here all_entries.append(entry) @@ -118,7 +118,7 @@ async def main() -> None: all_entries = [] # Iterate through items across all pages, issuing requests as needed. async for entry in client.projects.entries.list( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ): all_entries.append(entry) print(all_entries) @@ -131,7 +131,7 @@ Alternatively, you can use the `.has_next_page()`, `.next_page_info()`, or `.get ```python first_page = await client.projects.entries.list( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) if first_page.has_next_page(): print(f"will fetch next page using these details: {first_page.next_page_info()}") @@ -145,7 +145,7 @@ Or just work directly with the returned data: ```python first_page = await client.projects.entries.list( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) for entry in first_page.entries: print(entry.id) diff --git a/api.md b/api.md index d4720cc2..48af8b68 100644 --- a/api.md +++ b/api.md @@ -108,7 +108,7 @@ Methods: - client.projects.access_keys.update(access_key_id, \*, project_id, \*\*params) -> AccessKeySchema - client.projects.access_keys.list(project_id) -> AccessKeyListResponse - client.projects.access_keys.delete(access_key_id, \*, project_id) -> None -- client.projects.access_keys.retrieve_project_id() -> AccessKeyRetrieveProjectIDResponse +- client.projects.access_keys.retrieve_project_id() -> str - client.projects.access_keys.revoke(access_key_id, \*, project_id) -> None ## Entries diff --git a/pyproject.toml b/pyproject.toml index 972e97dc..91eb985e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "codex-sdk" -version = "0.1.0-alpha.1" +version = "0.1.0-alpha.2" description = "The official Python library for the Codex API" dynamic = ["readme"] license = "MIT" diff --git a/src/codex/_version.py b/src/codex/_version.py index 96b3eab2..0ebe32a7 100644 --- a/src/codex/_version.py +++ b/src/codex/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "codex" -__version__ = "0.1.0-alpha.1" # x-release-please-version +__version__ = "0.1.0-alpha.2" # x-release-please-version diff --git a/src/codex/resources/projects/access_keys.py b/src/codex/resources/projects/access_keys.py index e282ad4f..8a580f49 100644 --- a/src/codex/resources/projects/access_keys.py +++ b/src/codex/resources/projects/access_keys.py @@ -24,7 +24,6 @@ from ...types.projects import access_key_create_params, access_key_update_params from ...types.projects.access_key_schema import AccessKeySchema from ...types.projects.access_key_list_response import AccessKeyListResponse -from ...types.projects.access_key_retrieve_project_id_response import AccessKeyRetrieveProjectIDResponse __all__ = ["AccessKeysResource", "AsyncAccessKeysResource"] @@ -51,7 +50,7 @@ def with_streaming_response(self) -> AccessKeysResourceWithStreamingResponse: def create( self, - project_id: int, + project_id: str, *, name: str, description: Optional[str] | NotGiven = NOT_GIVEN, @@ -75,6 +74,8 @@ def create( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") return self._post( f"/api/projects/{project_id}/access_keys/", body=maybe_transform( @@ -93,9 +94,9 @@ def create( def retrieve( self, - access_key_id: int, + access_key_id: str, *, - project_id: int, + project_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -115,6 +116,10 @@ def retrieve( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") + if not access_key_id: + raise ValueError(f"Expected a non-empty value for `access_key_id` but received {access_key_id!r}") return self._get( f"/api/projects/{project_id}/access_keys/{access_key_id}", options=make_request_options( @@ -125,9 +130,9 @@ def retrieve( def update( self, - access_key_id: int, + access_key_id: str, *, - project_id: int, + project_id: str, name: str, description: Optional[str] | NotGiven = NOT_GIVEN, expires_at: Union[str, datetime, None] | NotGiven = NOT_GIVEN, @@ -150,6 +155,10 @@ def update( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") + if not access_key_id: + raise ValueError(f"Expected a non-empty value for `access_key_id` but received {access_key_id!r}") return self._put( f"/api/projects/{project_id}/access_keys/{access_key_id}", body=maybe_transform( @@ -168,7 +177,7 @@ def update( def list( self, - project_id: int, + project_id: str, *, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -189,6 +198,8 @@ def list( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") return self._get( f"/api/projects/{project_id}/access_keys/", options=make_request_options( @@ -199,9 +210,9 @@ def list( def delete( self, - access_key_id: int, + access_key_id: str, *, - project_id: int, + project_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -221,6 +232,10 @@ def delete( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") + if not access_key_id: + raise ValueError(f"Expected a non-empty value for `access_key_id` but received {access_key_id!r}") extra_headers = {"Accept": "*/*", **(extra_headers or {})} return self._delete( f"/api/projects/{project_id}/access_keys/{access_key_id}", @@ -239,21 +254,21 @@ def retrieve_project_id( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> AccessKeyRetrieveProjectIDResponse: + ) -> str: """Get the project ID from an access key.""" return self._get( "/api/projects/id_from_access_key", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - cast_to=int, + cast_to=str, ) def revoke( self, - access_key_id: int, + access_key_id: str, *, - project_id: int, + project_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -273,6 +288,10 @@ def revoke( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") + if not access_key_id: + raise ValueError(f"Expected a non-empty value for `access_key_id` but received {access_key_id!r}") extra_headers = {"Accept": "*/*", **(extra_headers or {})} return self._post( f"/api/projects/{project_id}/access_keys/{access_key_id}/revoke", @@ -305,7 +324,7 @@ def with_streaming_response(self) -> AsyncAccessKeysResourceWithStreamingRespons async def create( self, - project_id: int, + project_id: str, *, name: str, description: Optional[str] | NotGiven = NOT_GIVEN, @@ -329,6 +348,8 @@ async def create( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") return await self._post( f"/api/projects/{project_id}/access_keys/", body=await async_maybe_transform( @@ -347,9 +368,9 @@ async def create( async def retrieve( self, - access_key_id: int, + access_key_id: str, *, - project_id: int, + project_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -369,6 +390,10 @@ async def retrieve( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") + if not access_key_id: + raise ValueError(f"Expected a non-empty value for `access_key_id` but received {access_key_id!r}") return await self._get( f"/api/projects/{project_id}/access_keys/{access_key_id}", options=make_request_options( @@ -379,9 +404,9 @@ async def retrieve( async def update( self, - access_key_id: int, + access_key_id: str, *, - project_id: int, + project_id: str, name: str, description: Optional[str] | NotGiven = NOT_GIVEN, expires_at: Union[str, datetime, None] | NotGiven = NOT_GIVEN, @@ -404,6 +429,10 @@ async def update( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") + if not access_key_id: + raise ValueError(f"Expected a non-empty value for `access_key_id` but received {access_key_id!r}") return await self._put( f"/api/projects/{project_id}/access_keys/{access_key_id}", body=await async_maybe_transform( @@ -422,7 +451,7 @@ async def update( async def list( self, - project_id: int, + project_id: str, *, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -443,6 +472,8 @@ async def list( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") return await self._get( f"/api/projects/{project_id}/access_keys/", options=make_request_options( @@ -453,9 +484,9 @@ async def list( async def delete( self, - access_key_id: int, + access_key_id: str, *, - project_id: int, + project_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -475,6 +506,10 @@ async def delete( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") + if not access_key_id: + raise ValueError(f"Expected a non-empty value for `access_key_id` but received {access_key_id!r}") extra_headers = {"Accept": "*/*", **(extra_headers or {})} return await self._delete( f"/api/projects/{project_id}/access_keys/{access_key_id}", @@ -493,21 +528,21 @@ async def retrieve_project_id( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> AccessKeyRetrieveProjectIDResponse: + ) -> str: """Get the project ID from an access key.""" return await self._get( "/api/projects/id_from_access_key", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - cast_to=int, + cast_to=str, ) async def revoke( self, - access_key_id: int, + access_key_id: str, *, - project_id: int, + project_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -527,6 +562,10 @@ async def revoke( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") + if not access_key_id: + raise ValueError(f"Expected a non-empty value for `access_key_id` but received {access_key_id!r}") extra_headers = {"Accept": "*/*", **(extra_headers or {})} return await self._post( f"/api/projects/{project_id}/access_keys/{access_key_id}/revoke", diff --git a/src/codex/resources/projects/entries.py b/src/codex/resources/projects/entries.py index 59bc9f7f..56c893c0 100644 --- a/src/codex/resources/projects/entries.py +++ b/src/codex/resources/projects/entries.py @@ -56,7 +56,7 @@ def with_streaming_response(self) -> EntriesResourceWithStreamingResponse: def create( self, - project_id: int, + project_id: str, *, question: str, answer: Optional[str] | NotGiven = NOT_GIVEN, @@ -79,6 +79,8 @@ def create( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") return self._post( f"/api/projects/{project_id}/entries/", body=maybe_transform( @@ -98,7 +100,7 @@ def retrieve( self, entry_id: str, *, - project_id: int, + project_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -118,6 +120,8 @@ def retrieve( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") if not entry_id: raise ValueError(f"Expected a non-empty value for `entry_id` but received {entry_id!r}") return self._get( @@ -132,7 +136,7 @@ def update( self, entry_id: str, *, - project_id: int, + project_id: str, answer: Optional[str] | NotGiven = NOT_GIVEN, question: Optional[str] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -154,6 +158,8 @@ def update( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") if not entry_id: raise ValueError(f"Expected a non-empty value for `entry_id` but received {entry_id!r}") return self._put( @@ -173,7 +179,7 @@ def update( def list( self, - project_id: int, + project_id: str, *, answered_only: bool | NotGiven = NOT_GIVEN, limit: int | NotGiven = NOT_GIVEN, @@ -200,6 +206,8 @@ def list( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") return self._get_api_list( f"/api/projects/{project_id}/entries/", page=SyncOffsetPageEntries[Entry], @@ -227,7 +235,7 @@ def delete( self, entry_id: str, *, - project_id: int, + project_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -247,6 +255,8 @@ def delete( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") if not entry_id: raise ValueError(f"Expected a non-empty value for `entry_id` but received {entry_id!r}") extra_headers = {"Accept": "*/*", **(extra_headers or {})} @@ -260,7 +270,7 @@ def delete( def add_question( self, - project_id: int, + project_id: str, *, question: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -285,6 +295,8 @@ def add_question( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") return self._post( f"/api/projects/{project_id}/entries/add_question", body=maybe_transform({"question": question}, entry_add_question_params.EntryAddQuestionParams), @@ -296,7 +308,7 @@ def add_question( def query( self, - project_id: int, + project_id: str, *, question: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -323,6 +335,8 @@ def query( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") return self._post( f"/api/projects/{project_id}/entries/query", body=maybe_transform({"question": question}, entry_query_params.EntryQueryParams), @@ -355,7 +369,7 @@ def with_streaming_response(self) -> AsyncEntriesResourceWithStreamingResponse: async def create( self, - project_id: int, + project_id: str, *, question: str, answer: Optional[str] | NotGiven = NOT_GIVEN, @@ -378,6 +392,8 @@ async def create( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") return await self._post( f"/api/projects/{project_id}/entries/", body=await async_maybe_transform( @@ -397,7 +413,7 @@ async def retrieve( self, entry_id: str, *, - project_id: int, + project_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -417,6 +433,8 @@ async def retrieve( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") if not entry_id: raise ValueError(f"Expected a non-empty value for `entry_id` but received {entry_id!r}") return await self._get( @@ -431,7 +449,7 @@ async def update( self, entry_id: str, *, - project_id: int, + project_id: str, answer: Optional[str] | NotGiven = NOT_GIVEN, question: Optional[str] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -453,6 +471,8 @@ async def update( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") if not entry_id: raise ValueError(f"Expected a non-empty value for `entry_id` but received {entry_id!r}") return await self._put( @@ -472,7 +492,7 @@ async def update( def list( self, - project_id: int, + project_id: str, *, answered_only: bool | NotGiven = NOT_GIVEN, limit: int | NotGiven = NOT_GIVEN, @@ -499,6 +519,8 @@ def list( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") return self._get_api_list( f"/api/projects/{project_id}/entries/", page=AsyncOffsetPageEntries[Entry], @@ -526,7 +548,7 @@ async def delete( self, entry_id: str, *, - project_id: int, + project_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -546,6 +568,8 @@ async def delete( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") if not entry_id: raise ValueError(f"Expected a non-empty value for `entry_id` but received {entry_id!r}") extra_headers = {"Accept": "*/*", **(extra_headers or {})} @@ -559,7 +583,7 @@ async def delete( async def add_question( self, - project_id: int, + project_id: str, *, question: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -584,6 +608,8 @@ async def add_question( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") return await self._post( f"/api/projects/{project_id}/entries/add_question", body=await async_maybe_transform({"question": question}, entry_add_question_params.EntryAddQuestionParams), @@ -595,7 +621,7 @@ async def add_question( async def query( self, - project_id: int, + project_id: str, *, question: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -622,6 +648,8 @@ async def query( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") return await self._post( f"/api/projects/{project_id}/entries/query", body=await async_maybe_transform({"question": question}, entry_query_params.EntryQueryParams), diff --git a/src/codex/resources/projects/projects.py b/src/codex/resources/projects/projects.py index d77e63a1..8a5f35a1 100644 --- a/src/codex/resources/projects/projects.py +++ b/src/codex/resources/projects/projects.py @@ -116,7 +116,7 @@ def create( def retrieve( self, - project_id: int, + project_id: str, *, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -137,6 +137,8 @@ def retrieve( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") return self._get( f"/api/projects/{project_id}", options=make_request_options( @@ -147,7 +149,7 @@ def retrieve( def update( self, - project_id: int, + project_id: str, *, config: project_update_params.Config, name: str, @@ -171,6 +173,8 @@ def update( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") return self._put( f"/api/projects/{project_id}", body=maybe_transform( @@ -224,7 +228,7 @@ def list( def delete( self, - project_id: int, + project_id: str, *, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -245,6 +249,8 @@ def delete( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") extra_headers = {"Accept": "*/*", **(extra_headers or {})} return self._delete( f"/api/projects/{project_id}", @@ -256,7 +262,7 @@ def delete( def export( self, - project_id: int, + project_id: str, *, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -277,6 +283,8 @@ def export( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") return self._get( f"/api/projects/{project_id}/export", options=make_request_options( @@ -359,7 +367,7 @@ async def create( async def retrieve( self, - project_id: int, + project_id: str, *, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -380,6 +388,8 @@ async def retrieve( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") return await self._get( f"/api/projects/{project_id}", options=make_request_options( @@ -390,7 +400,7 @@ async def retrieve( async def update( self, - project_id: int, + project_id: str, *, config: project_update_params.Config, name: str, @@ -414,6 +424,8 @@ async def update( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") return await self._put( f"/api/projects/{project_id}", body=await async_maybe_transform( @@ -469,7 +481,7 @@ async def list( async def delete( self, - project_id: int, + project_id: str, *, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -490,6 +502,8 @@ async def delete( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") extra_headers = {"Accept": "*/*", **(extra_headers or {})} return await self._delete( f"/api/projects/{project_id}", @@ -501,7 +515,7 @@ async def delete( async def export( self, - project_id: int, + project_id: str, *, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -522,6 +536,8 @@ async def export( timeout: Override the client-level default timeout for this request, in seconds """ + if not project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") return await self._get( f"/api/projects/{project_id}/export", options=make_request_options( diff --git a/src/codex/types/organization_schema_public.py b/src/codex/types/organization_schema_public.py index ed245c50..decc8559 100644 --- a/src/codex/types/organization_schema_public.py +++ b/src/codex/types/organization_schema_public.py @@ -1,6 +1,7 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from datetime import datetime +from typing_extensions import Literal from .._models import BaseModel @@ -14,4 +15,6 @@ class OrganizationSchemaPublic(BaseModel): name: str + payment_status: Literal["NULL", "FIRST_OVERAGE_LENIENT", "SECOND_OVERAGE_USAGE_BLOCKED"] + updated_at: datetime diff --git a/src/codex/types/project_return_schema.py b/src/codex/types/project_return_schema.py index 7f6b06a2..85312729 100644 --- a/src/codex/types/project_return_schema.py +++ b/src/codex/types/project_return_schema.py @@ -13,7 +13,7 @@ class Config(BaseModel): class ProjectReturnSchema(BaseModel): - id: int + id: str config: Config diff --git a/src/codex/types/projects/access_key_retrieve_project_id_response.py b/src/codex/types/projects/access_key_retrieve_project_id_response.py index 5659cd21..b7b53137 100644 --- a/src/codex/types/projects/access_key_retrieve_project_id_response.py +++ b/src/codex/types/projects/access_key_retrieve_project_id_response.py @@ -4,4 +4,4 @@ __all__ = ["AccessKeyRetrieveProjectIDResponse"] -AccessKeyRetrieveProjectIDResponse: TypeAlias = int +AccessKeyRetrieveProjectIDResponse: TypeAlias = str diff --git a/src/codex/types/projects/access_key_schema.py b/src/codex/types/projects/access_key_schema.py index 3e023aae..aaf5d0fe 100644 --- a/src/codex/types/projects/access_key_schema.py +++ b/src/codex/types/projects/access_key_schema.py @@ -10,7 +10,7 @@ class AccessKeySchema(BaseModel): - id: int + id: str token: str @@ -20,7 +20,7 @@ class AccessKeySchema(BaseModel): name: str - project_id: int + project_id: str status: Literal["active", "expired", "revoked"] diff --git a/src/codex/types/projects/access_key_update_params.py b/src/codex/types/projects/access_key_update_params.py index 2f40f335..f11e825f 100644 --- a/src/codex/types/projects/access_key_update_params.py +++ b/src/codex/types/projects/access_key_update_params.py @@ -12,7 +12,7 @@ class AccessKeyUpdateParams(TypedDict, total=False): - project_id: Required[int] + project_id: Required[str] name: Required[str] diff --git a/src/codex/types/projects/entry_update_params.py b/src/codex/types/projects/entry_update_params.py index 4a7c6527..0a676f31 100644 --- a/src/codex/types/projects/entry_update_params.py +++ b/src/codex/types/projects/entry_update_params.py @@ -9,7 +9,7 @@ class EntryUpdateParams(TypedDict, total=False): - project_id: Required[int] + project_id: Required[str] answer: Optional[str] diff --git a/tests/api_resources/projects/test_access_keys.py b/tests/api_resources/projects/test_access_keys.py index cdb893e6..6ec8ef9b 100644 --- a/tests/api_resources/projects/test_access_keys.py +++ b/tests/api_resources/projects/test_access_keys.py @@ -13,7 +13,6 @@ from codex.types.projects import ( AccessKeySchema, AccessKeyListResponse, - AccessKeyRetrieveProjectIDResponse, ) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -26,7 +25,7 @@ class TestAccessKeys: @parametrize def test_method_create(self, client: Codex) -> None: access_key = client.projects.access_keys.create( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", name="name", ) assert_matches_type(AccessKeySchema, access_key, path=["response"]) @@ -35,7 +34,7 @@ def test_method_create(self, client: Codex) -> None: @parametrize def test_method_create_with_all_params(self, client: Codex) -> None: access_key = client.projects.access_keys.create( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", name="name", description="description", expires_at=parse_datetime("2019-12-27T18:11:19.117Z"), @@ -46,7 +45,7 @@ def test_method_create_with_all_params(self, client: Codex) -> None: @parametrize def test_raw_response_create(self, client: Codex) -> None: response = client.projects.access_keys.with_raw_response.create( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", name="name", ) @@ -59,7 +58,7 @@ def test_raw_response_create(self, client: Codex) -> None: @parametrize def test_streaming_response_create(self, client: Codex) -> None: with client.projects.access_keys.with_streaming_response.create( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", name="name", ) as response: assert not response.is_closed @@ -70,12 +69,21 @@ def test_streaming_response_create(self, client: Codex) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + def test_path_params_create(self, client: Codex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + client.projects.access_keys.with_raw_response.create( + project_id="", + name="name", + ) + @pytest.mark.skip() @parametrize def test_method_retrieve(self, client: Codex) -> None: access_key = client.projects.access_keys.retrieve( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert_matches_type(AccessKeySchema, access_key, path=["response"]) @@ -83,8 +91,8 @@ def test_method_retrieve(self, client: Codex) -> None: @parametrize def test_raw_response_retrieve(self, client: Codex) -> None: response = client.projects.access_keys.with_raw_response.retrieve( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -96,8 +104,8 @@ def test_raw_response_retrieve(self, client: Codex) -> None: @parametrize def test_streaming_response_retrieve(self, client: Codex) -> None: with client.projects.access_keys.with_streaming_response.retrieve( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -107,12 +115,27 @@ def test_streaming_response_retrieve(self, client: Codex) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + def test_path_params_retrieve(self, client: Codex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + client.projects.access_keys.with_raw_response.retrieve( + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `access_key_id` but received ''"): + client.projects.access_keys.with_raw_response.retrieve( + access_key_id="", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + @pytest.mark.skip() @parametrize def test_method_update(self, client: Codex) -> None: access_key = client.projects.access_keys.update( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", name="name", ) assert_matches_type(AccessKeySchema, access_key, path=["response"]) @@ -121,8 +144,8 @@ def test_method_update(self, client: Codex) -> None: @parametrize def test_method_update_with_all_params(self, client: Codex) -> None: access_key = client.projects.access_keys.update( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", name="name", description="description", expires_at=parse_datetime("2019-12-27T18:11:19.117Z"), @@ -133,8 +156,8 @@ def test_method_update_with_all_params(self, client: Codex) -> None: @parametrize def test_raw_response_update(self, client: Codex) -> None: response = client.projects.access_keys.with_raw_response.update( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", name="name", ) @@ -147,8 +170,8 @@ def test_raw_response_update(self, client: Codex) -> None: @parametrize def test_streaming_response_update(self, client: Codex) -> None: with client.projects.access_keys.with_streaming_response.update( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", name="name", ) as response: assert not response.is_closed @@ -159,11 +182,28 @@ def test_streaming_response_update(self, client: Codex) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + def test_path_params_update(self, client: Codex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + client.projects.access_keys.with_raw_response.update( + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="", + name="name", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `access_key_id` but received ''"): + client.projects.access_keys.with_raw_response.update( + access_key_id="", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + name="name", + ) + @pytest.mark.skip() @parametrize def test_method_list(self, client: Codex) -> None: access_key = client.projects.access_keys.list( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert_matches_type(AccessKeyListResponse, access_key, path=["response"]) @@ -171,7 +211,7 @@ def test_method_list(self, client: Codex) -> None: @parametrize def test_raw_response_list(self, client: Codex) -> None: response = client.projects.access_keys.with_raw_response.list( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -183,7 +223,7 @@ def test_raw_response_list(self, client: Codex) -> None: @parametrize def test_streaming_response_list(self, client: Codex) -> None: with client.projects.access_keys.with_streaming_response.list( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -193,12 +233,20 @@ def test_streaming_response_list(self, client: Codex) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + def test_path_params_list(self, client: Codex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + client.projects.access_keys.with_raw_response.list( + "", + ) + @pytest.mark.skip() @parametrize def test_method_delete(self, client: Codex) -> None: access_key = client.projects.access_keys.delete( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert access_key is None @@ -206,8 +254,8 @@ def test_method_delete(self, client: Codex) -> None: @parametrize def test_raw_response_delete(self, client: Codex) -> None: response = client.projects.access_keys.with_raw_response.delete( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -219,8 +267,8 @@ def test_raw_response_delete(self, client: Codex) -> None: @parametrize def test_streaming_response_delete(self, client: Codex) -> None: with client.projects.access_keys.with_streaming_response.delete( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -230,11 +278,26 @@ def test_streaming_response_delete(self, client: Codex) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + def test_path_params_delete(self, client: Codex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + client.projects.access_keys.with_raw_response.delete( + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `access_key_id` but received ''"): + client.projects.access_keys.with_raw_response.delete( + access_key_id="", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + @pytest.mark.skip() @parametrize def test_method_retrieve_project_id(self, client: Codex) -> None: access_key = client.projects.access_keys.retrieve_project_id() - assert_matches_type(AccessKeyRetrieveProjectIDResponse, access_key, path=["response"]) + assert_matches_type(str, access_key, path=["response"]) @pytest.mark.skip() @parametrize @@ -244,7 +307,7 @@ def test_raw_response_retrieve_project_id(self, client: Codex) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" access_key = response.parse() - assert_matches_type(AccessKeyRetrieveProjectIDResponse, access_key, path=["response"]) + assert_matches_type(str, access_key, path=["response"]) @pytest.mark.skip() @parametrize @@ -254,7 +317,7 @@ def test_streaming_response_retrieve_project_id(self, client: Codex) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" access_key = response.parse() - assert_matches_type(AccessKeyRetrieveProjectIDResponse, access_key, path=["response"]) + assert_matches_type(str, access_key, path=["response"]) assert cast(Any, response.is_closed) is True @@ -262,8 +325,8 @@ def test_streaming_response_retrieve_project_id(self, client: Codex) -> None: @parametrize def test_method_revoke(self, client: Codex) -> None: access_key = client.projects.access_keys.revoke( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert access_key is None @@ -271,8 +334,8 @@ def test_method_revoke(self, client: Codex) -> None: @parametrize def test_raw_response_revoke(self, client: Codex) -> None: response = client.projects.access_keys.with_raw_response.revoke( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -284,8 +347,8 @@ def test_raw_response_revoke(self, client: Codex) -> None: @parametrize def test_streaming_response_revoke(self, client: Codex) -> None: with client.projects.access_keys.with_streaming_response.revoke( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -295,6 +358,21 @@ def test_streaming_response_revoke(self, client: Codex) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + def test_path_params_revoke(self, client: Codex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + client.projects.access_keys.with_raw_response.revoke( + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `access_key_id` but received ''"): + client.projects.access_keys.with_raw_response.revoke( + access_key_id="", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + class TestAsyncAccessKeys: parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @@ -303,7 +381,7 @@ class TestAsyncAccessKeys: @parametrize async def test_method_create(self, async_client: AsyncCodex) -> None: access_key = await async_client.projects.access_keys.create( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", name="name", ) assert_matches_type(AccessKeySchema, access_key, path=["response"]) @@ -312,7 +390,7 @@ async def test_method_create(self, async_client: AsyncCodex) -> None: @parametrize async def test_method_create_with_all_params(self, async_client: AsyncCodex) -> None: access_key = await async_client.projects.access_keys.create( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", name="name", description="description", expires_at=parse_datetime("2019-12-27T18:11:19.117Z"), @@ -323,7 +401,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCodex) -> @parametrize async def test_raw_response_create(self, async_client: AsyncCodex) -> None: response = await async_client.projects.access_keys.with_raw_response.create( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", name="name", ) @@ -336,7 +414,7 @@ async def test_raw_response_create(self, async_client: AsyncCodex) -> None: @parametrize async def test_streaming_response_create(self, async_client: AsyncCodex) -> None: async with async_client.projects.access_keys.with_streaming_response.create( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", name="name", ) as response: assert not response.is_closed @@ -347,12 +425,21 @@ async def test_streaming_response_create(self, async_client: AsyncCodex) -> None assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + async def test_path_params_create(self, async_client: AsyncCodex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + await async_client.projects.access_keys.with_raw_response.create( + project_id="", + name="name", + ) + @pytest.mark.skip() @parametrize async def test_method_retrieve(self, async_client: AsyncCodex) -> None: access_key = await async_client.projects.access_keys.retrieve( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert_matches_type(AccessKeySchema, access_key, path=["response"]) @@ -360,8 +447,8 @@ async def test_method_retrieve(self, async_client: AsyncCodex) -> None: @parametrize async def test_raw_response_retrieve(self, async_client: AsyncCodex) -> None: response = await async_client.projects.access_keys.with_raw_response.retrieve( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -373,8 +460,8 @@ async def test_raw_response_retrieve(self, async_client: AsyncCodex) -> None: @parametrize async def test_streaming_response_retrieve(self, async_client: AsyncCodex) -> None: async with async_client.projects.access_keys.with_streaming_response.retrieve( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -384,12 +471,27 @@ async def test_streaming_response_retrieve(self, async_client: AsyncCodex) -> No assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncCodex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + await async_client.projects.access_keys.with_raw_response.retrieve( + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `access_key_id` but received ''"): + await async_client.projects.access_keys.with_raw_response.retrieve( + access_key_id="", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + @pytest.mark.skip() @parametrize async def test_method_update(self, async_client: AsyncCodex) -> None: access_key = await async_client.projects.access_keys.update( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", name="name", ) assert_matches_type(AccessKeySchema, access_key, path=["response"]) @@ -398,8 +500,8 @@ async def test_method_update(self, async_client: AsyncCodex) -> None: @parametrize async def test_method_update_with_all_params(self, async_client: AsyncCodex) -> None: access_key = await async_client.projects.access_keys.update( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", name="name", description="description", expires_at=parse_datetime("2019-12-27T18:11:19.117Z"), @@ -410,8 +512,8 @@ async def test_method_update_with_all_params(self, async_client: AsyncCodex) -> @parametrize async def test_raw_response_update(self, async_client: AsyncCodex) -> None: response = await async_client.projects.access_keys.with_raw_response.update( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", name="name", ) @@ -424,8 +526,8 @@ async def test_raw_response_update(self, async_client: AsyncCodex) -> None: @parametrize async def test_streaming_response_update(self, async_client: AsyncCodex) -> None: async with async_client.projects.access_keys.with_streaming_response.update( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", name="name", ) as response: assert not response.is_closed @@ -436,11 +538,28 @@ async def test_streaming_response_update(self, async_client: AsyncCodex) -> None assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + async def test_path_params_update(self, async_client: AsyncCodex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + await async_client.projects.access_keys.with_raw_response.update( + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="", + name="name", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `access_key_id` but received ''"): + await async_client.projects.access_keys.with_raw_response.update( + access_key_id="", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + name="name", + ) + @pytest.mark.skip() @parametrize async def test_method_list(self, async_client: AsyncCodex) -> None: access_key = await async_client.projects.access_keys.list( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert_matches_type(AccessKeyListResponse, access_key, path=["response"]) @@ -448,7 +567,7 @@ async def test_method_list(self, async_client: AsyncCodex) -> None: @parametrize async def test_raw_response_list(self, async_client: AsyncCodex) -> None: response = await async_client.projects.access_keys.with_raw_response.list( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -460,7 +579,7 @@ async def test_raw_response_list(self, async_client: AsyncCodex) -> None: @parametrize async def test_streaming_response_list(self, async_client: AsyncCodex) -> None: async with async_client.projects.access_keys.with_streaming_response.list( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -470,12 +589,20 @@ async def test_streaming_response_list(self, async_client: AsyncCodex) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + async def test_path_params_list(self, async_client: AsyncCodex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + await async_client.projects.access_keys.with_raw_response.list( + "", + ) + @pytest.mark.skip() @parametrize async def test_method_delete(self, async_client: AsyncCodex) -> None: access_key = await async_client.projects.access_keys.delete( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert access_key is None @@ -483,8 +610,8 @@ async def test_method_delete(self, async_client: AsyncCodex) -> None: @parametrize async def test_raw_response_delete(self, async_client: AsyncCodex) -> None: response = await async_client.projects.access_keys.with_raw_response.delete( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -496,8 +623,8 @@ async def test_raw_response_delete(self, async_client: AsyncCodex) -> None: @parametrize async def test_streaming_response_delete(self, async_client: AsyncCodex) -> None: async with async_client.projects.access_keys.with_streaming_response.delete( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -507,11 +634,26 @@ async def test_streaming_response_delete(self, async_client: AsyncCodex) -> None assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + async def test_path_params_delete(self, async_client: AsyncCodex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + await async_client.projects.access_keys.with_raw_response.delete( + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `access_key_id` but received ''"): + await async_client.projects.access_keys.with_raw_response.delete( + access_key_id="", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + @pytest.mark.skip() @parametrize async def test_method_retrieve_project_id(self, async_client: AsyncCodex) -> None: access_key = await async_client.projects.access_keys.retrieve_project_id() - assert_matches_type(AccessKeyRetrieveProjectIDResponse, access_key, path=["response"]) + assert_matches_type(str, access_key, path=["response"]) @pytest.mark.skip() @parametrize @@ -521,7 +663,7 @@ async def test_raw_response_retrieve_project_id(self, async_client: AsyncCodex) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" access_key = await response.parse() - assert_matches_type(AccessKeyRetrieveProjectIDResponse, access_key, path=["response"]) + assert_matches_type(str, access_key, path=["response"]) @pytest.mark.skip() @parametrize @@ -531,7 +673,7 @@ async def test_streaming_response_retrieve_project_id(self, async_client: AsyncC assert response.http_request.headers.get("X-Stainless-Lang") == "python" access_key = await response.parse() - assert_matches_type(AccessKeyRetrieveProjectIDResponse, access_key, path=["response"]) + assert_matches_type(str, access_key, path=["response"]) assert cast(Any, response.is_closed) is True @@ -539,8 +681,8 @@ async def test_streaming_response_retrieve_project_id(self, async_client: AsyncC @parametrize async def test_method_revoke(self, async_client: AsyncCodex) -> None: access_key = await async_client.projects.access_keys.revoke( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert access_key is None @@ -548,8 +690,8 @@ async def test_method_revoke(self, async_client: AsyncCodex) -> None: @parametrize async def test_raw_response_revoke(self, async_client: AsyncCodex) -> None: response = await async_client.projects.access_keys.with_raw_response.revoke( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -561,8 +703,8 @@ async def test_raw_response_revoke(self, async_client: AsyncCodex) -> None: @parametrize async def test_streaming_response_revoke(self, async_client: AsyncCodex) -> None: async with async_client.projects.access_keys.with_streaming_response.revoke( - access_key_id=0, - project_id=0, + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -571,3 +713,18 @@ async def test_streaming_response_revoke(self, async_client: AsyncCodex) -> None assert access_key is None assert cast(Any, response.is_closed) is True + + @pytest.mark.skip() + @parametrize + async def test_path_params_revoke(self, async_client: AsyncCodex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + await async_client.projects.access_keys.with_raw_response.revoke( + access_key_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `access_key_id` but received ''"): + await async_client.projects.access_keys.with_raw_response.revoke( + access_key_id="", + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) diff --git a/tests/api_resources/projects/test_entries.py b/tests/api_resources/projects/test_entries.py index e1c36e3b..5b51ec12 100644 --- a/tests/api_resources/projects/test_entries.py +++ b/tests/api_resources/projects/test_entries.py @@ -24,7 +24,7 @@ class TestEntries: @parametrize def test_method_create(self, client: Codex) -> None: entry = client.projects.entries.create( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", question="question", ) assert_matches_type(Entry, entry, path=["response"]) @@ -33,7 +33,7 @@ def test_method_create(self, client: Codex) -> None: @parametrize def test_method_create_with_all_params(self, client: Codex) -> None: entry = client.projects.entries.create( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", question="question", answer="answer", ) @@ -43,7 +43,7 @@ def test_method_create_with_all_params(self, client: Codex) -> None: @parametrize def test_raw_response_create(self, client: Codex) -> None: response = client.projects.entries.with_raw_response.create( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", question="question", ) @@ -56,7 +56,7 @@ def test_raw_response_create(self, client: Codex) -> None: @parametrize def test_streaming_response_create(self, client: Codex) -> None: with client.projects.entries.with_streaming_response.create( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", question="question", ) as response: assert not response.is_closed @@ -67,12 +67,21 @@ def test_streaming_response_create(self, client: Codex) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + def test_path_params_create(self, client: Codex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + client.projects.entries.with_raw_response.create( + project_id="", + question="question", + ) + @pytest.mark.skip() @parametrize def test_method_retrieve(self, client: Codex) -> None: entry = client.projects.entries.retrieve( entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert_matches_type(Entry, entry, path=["response"]) @@ -81,7 +90,7 @@ def test_method_retrieve(self, client: Codex) -> None: def test_raw_response_retrieve(self, client: Codex) -> None: response = client.projects.entries.with_raw_response.retrieve( entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -94,7 +103,7 @@ def test_raw_response_retrieve(self, client: Codex) -> None: def test_streaming_response_retrieve(self, client: Codex) -> None: with client.projects.entries.with_streaming_response.retrieve( entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -107,10 +116,16 @@ def test_streaming_response_retrieve(self, client: Codex) -> None: @pytest.mark.skip() @parametrize def test_path_params_retrieve(self, client: Codex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + client.projects.entries.with_raw_response.retrieve( + entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="", + ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `entry_id` but received ''"): client.projects.entries.with_raw_response.retrieve( entry_id="", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) @pytest.mark.skip() @@ -118,7 +133,7 @@ def test_path_params_retrieve(self, client: Codex) -> None: def test_method_update(self, client: Codex) -> None: entry = client.projects.entries.update( entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert_matches_type(Entry, entry, path=["response"]) @@ -127,7 +142,7 @@ def test_method_update(self, client: Codex) -> None: def test_method_update_with_all_params(self, client: Codex) -> None: entry = client.projects.entries.update( entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", answer="answer", question="question", ) @@ -138,7 +153,7 @@ def test_method_update_with_all_params(self, client: Codex) -> None: def test_raw_response_update(self, client: Codex) -> None: response = client.projects.entries.with_raw_response.update( entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -151,7 +166,7 @@ def test_raw_response_update(self, client: Codex) -> None: def test_streaming_response_update(self, client: Codex) -> None: with client.projects.entries.with_streaming_response.update( entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -164,17 +179,23 @@ def test_streaming_response_update(self, client: Codex) -> None: @pytest.mark.skip() @parametrize def test_path_params_update(self, client: Codex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + client.projects.entries.with_raw_response.update( + entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="", + ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `entry_id` but received ''"): client.projects.entries.with_raw_response.update( entry_id="", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) @pytest.mark.skip() @parametrize def test_method_list(self, client: Codex) -> None: entry = client.projects.entries.list( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert_matches_type(SyncOffsetPageEntries[Entry], entry, path=["response"]) @@ -182,7 +203,7 @@ def test_method_list(self, client: Codex) -> None: @parametrize def test_method_list_with_all_params(self, client: Codex) -> None: entry = client.projects.entries.list( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", answered_only=True, limit=1, offset=0, @@ -196,7 +217,7 @@ def test_method_list_with_all_params(self, client: Codex) -> None: @parametrize def test_raw_response_list(self, client: Codex) -> None: response = client.projects.entries.with_raw_response.list( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -208,7 +229,7 @@ def test_raw_response_list(self, client: Codex) -> None: @parametrize def test_streaming_response_list(self, client: Codex) -> None: with client.projects.entries.with_streaming_response.list( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -218,12 +239,20 @@ def test_streaming_response_list(self, client: Codex) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + def test_path_params_list(self, client: Codex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + client.projects.entries.with_raw_response.list( + project_id="", + ) + @pytest.mark.skip() @parametrize def test_method_delete(self, client: Codex) -> None: entry = client.projects.entries.delete( entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert entry is None @@ -232,7 +261,7 @@ def test_method_delete(self, client: Codex) -> None: def test_raw_response_delete(self, client: Codex) -> None: response = client.projects.entries.with_raw_response.delete( entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -245,7 +274,7 @@ def test_raw_response_delete(self, client: Codex) -> None: def test_streaming_response_delete(self, client: Codex) -> None: with client.projects.entries.with_streaming_response.delete( entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -258,17 +287,23 @@ def test_streaming_response_delete(self, client: Codex) -> None: @pytest.mark.skip() @parametrize def test_path_params_delete(self, client: Codex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + client.projects.entries.with_raw_response.delete( + entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="", + ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `entry_id` but received ''"): client.projects.entries.with_raw_response.delete( entry_id="", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) @pytest.mark.skip() @parametrize def test_method_add_question(self, client: Codex) -> None: entry = client.projects.entries.add_question( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", question="question", ) assert_matches_type(Entry, entry, path=["response"]) @@ -277,7 +312,7 @@ def test_method_add_question(self, client: Codex) -> None: @parametrize def test_raw_response_add_question(self, client: Codex) -> None: response = client.projects.entries.with_raw_response.add_question( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", question="question", ) @@ -290,7 +325,7 @@ def test_raw_response_add_question(self, client: Codex) -> None: @parametrize def test_streaming_response_add_question(self, client: Codex) -> None: with client.projects.entries.with_streaming_response.add_question( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", question="question", ) as response: assert not response.is_closed @@ -301,11 +336,20 @@ def test_streaming_response_add_question(self, client: Codex) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + def test_path_params_add_question(self, client: Codex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + client.projects.entries.with_raw_response.add_question( + project_id="", + question="question", + ) + @pytest.mark.skip() @parametrize def test_method_query(self, client: Codex) -> None: entry = client.projects.entries.query( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", question="question", ) assert_matches_type(Optional[Entry], entry, path=["response"]) @@ -314,7 +358,7 @@ def test_method_query(self, client: Codex) -> None: @parametrize def test_raw_response_query(self, client: Codex) -> None: response = client.projects.entries.with_raw_response.query( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", question="question", ) @@ -327,7 +371,7 @@ def test_raw_response_query(self, client: Codex) -> None: @parametrize def test_streaming_response_query(self, client: Codex) -> None: with client.projects.entries.with_streaming_response.query( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", question="question", ) as response: assert not response.is_closed @@ -338,6 +382,15 @@ def test_streaming_response_query(self, client: Codex) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + def test_path_params_query(self, client: Codex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + client.projects.entries.with_raw_response.query( + project_id="", + question="question", + ) + class TestAsyncEntries: parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @@ -346,7 +399,7 @@ class TestAsyncEntries: @parametrize async def test_method_create(self, async_client: AsyncCodex) -> None: entry = await async_client.projects.entries.create( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", question="question", ) assert_matches_type(Entry, entry, path=["response"]) @@ -355,7 +408,7 @@ async def test_method_create(self, async_client: AsyncCodex) -> None: @parametrize async def test_method_create_with_all_params(self, async_client: AsyncCodex) -> None: entry = await async_client.projects.entries.create( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", question="question", answer="answer", ) @@ -365,7 +418,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCodex) -> @parametrize async def test_raw_response_create(self, async_client: AsyncCodex) -> None: response = await async_client.projects.entries.with_raw_response.create( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", question="question", ) @@ -378,7 +431,7 @@ async def test_raw_response_create(self, async_client: AsyncCodex) -> None: @parametrize async def test_streaming_response_create(self, async_client: AsyncCodex) -> None: async with async_client.projects.entries.with_streaming_response.create( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", question="question", ) as response: assert not response.is_closed @@ -389,12 +442,21 @@ async def test_streaming_response_create(self, async_client: AsyncCodex) -> None assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + async def test_path_params_create(self, async_client: AsyncCodex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + await async_client.projects.entries.with_raw_response.create( + project_id="", + question="question", + ) + @pytest.mark.skip() @parametrize async def test_method_retrieve(self, async_client: AsyncCodex) -> None: entry = await async_client.projects.entries.retrieve( entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert_matches_type(Entry, entry, path=["response"]) @@ -403,7 +465,7 @@ async def test_method_retrieve(self, async_client: AsyncCodex) -> None: async def test_raw_response_retrieve(self, async_client: AsyncCodex) -> None: response = await async_client.projects.entries.with_raw_response.retrieve( entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -416,7 +478,7 @@ async def test_raw_response_retrieve(self, async_client: AsyncCodex) -> None: async def test_streaming_response_retrieve(self, async_client: AsyncCodex) -> None: async with async_client.projects.entries.with_streaming_response.retrieve( entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -429,10 +491,16 @@ async def test_streaming_response_retrieve(self, async_client: AsyncCodex) -> No @pytest.mark.skip() @parametrize async def test_path_params_retrieve(self, async_client: AsyncCodex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + await async_client.projects.entries.with_raw_response.retrieve( + entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="", + ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `entry_id` but received ''"): await async_client.projects.entries.with_raw_response.retrieve( entry_id="", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) @pytest.mark.skip() @@ -440,7 +508,7 @@ async def test_path_params_retrieve(self, async_client: AsyncCodex) -> None: async def test_method_update(self, async_client: AsyncCodex) -> None: entry = await async_client.projects.entries.update( entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert_matches_type(Entry, entry, path=["response"]) @@ -449,7 +517,7 @@ async def test_method_update(self, async_client: AsyncCodex) -> None: async def test_method_update_with_all_params(self, async_client: AsyncCodex) -> None: entry = await async_client.projects.entries.update( entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", answer="answer", question="question", ) @@ -460,7 +528,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCodex) -> async def test_raw_response_update(self, async_client: AsyncCodex) -> None: response = await async_client.projects.entries.with_raw_response.update( entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -473,7 +541,7 @@ async def test_raw_response_update(self, async_client: AsyncCodex) -> None: async def test_streaming_response_update(self, async_client: AsyncCodex) -> None: async with async_client.projects.entries.with_streaming_response.update( entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -486,17 +554,23 @@ async def test_streaming_response_update(self, async_client: AsyncCodex) -> None @pytest.mark.skip() @parametrize async def test_path_params_update(self, async_client: AsyncCodex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + await async_client.projects.entries.with_raw_response.update( + entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="", + ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `entry_id` but received ''"): await async_client.projects.entries.with_raw_response.update( entry_id="", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) @pytest.mark.skip() @parametrize async def test_method_list(self, async_client: AsyncCodex) -> None: entry = await async_client.projects.entries.list( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert_matches_type(AsyncOffsetPageEntries[Entry], entry, path=["response"]) @@ -504,7 +578,7 @@ async def test_method_list(self, async_client: AsyncCodex) -> None: @parametrize async def test_method_list_with_all_params(self, async_client: AsyncCodex) -> None: entry = await async_client.projects.entries.list( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", answered_only=True, limit=1, offset=0, @@ -518,7 +592,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCodex) -> No @parametrize async def test_raw_response_list(self, async_client: AsyncCodex) -> None: response = await async_client.projects.entries.with_raw_response.list( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -530,7 +604,7 @@ async def test_raw_response_list(self, async_client: AsyncCodex) -> None: @parametrize async def test_streaming_response_list(self, async_client: AsyncCodex) -> None: async with async_client.projects.entries.with_streaming_response.list( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -540,12 +614,20 @@ async def test_streaming_response_list(self, async_client: AsyncCodex) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + async def test_path_params_list(self, async_client: AsyncCodex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + await async_client.projects.entries.with_raw_response.list( + project_id="", + ) + @pytest.mark.skip() @parametrize async def test_method_delete(self, async_client: AsyncCodex) -> None: entry = await async_client.projects.entries.delete( entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert entry is None @@ -554,7 +636,7 @@ async def test_method_delete(self, async_client: AsyncCodex) -> None: async def test_raw_response_delete(self, async_client: AsyncCodex) -> None: response = await async_client.projects.entries.with_raw_response.delete( entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -567,7 +649,7 @@ async def test_raw_response_delete(self, async_client: AsyncCodex) -> None: async def test_streaming_response_delete(self, async_client: AsyncCodex) -> None: async with async_client.projects.entries.with_streaming_response.delete( entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -580,17 +662,23 @@ async def test_streaming_response_delete(self, async_client: AsyncCodex) -> None @pytest.mark.skip() @parametrize async def test_path_params_delete(self, async_client: AsyncCodex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + await async_client.projects.entries.with_raw_response.delete( + entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + project_id="", + ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `entry_id` but received ''"): await async_client.projects.entries.with_raw_response.delete( entry_id="", - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) @pytest.mark.skip() @parametrize async def test_method_add_question(self, async_client: AsyncCodex) -> None: entry = await async_client.projects.entries.add_question( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", question="question", ) assert_matches_type(Entry, entry, path=["response"]) @@ -599,7 +687,7 @@ async def test_method_add_question(self, async_client: AsyncCodex) -> None: @parametrize async def test_raw_response_add_question(self, async_client: AsyncCodex) -> None: response = await async_client.projects.entries.with_raw_response.add_question( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", question="question", ) @@ -612,7 +700,7 @@ async def test_raw_response_add_question(self, async_client: AsyncCodex) -> None @parametrize async def test_streaming_response_add_question(self, async_client: AsyncCodex) -> None: async with async_client.projects.entries.with_streaming_response.add_question( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", question="question", ) as response: assert not response.is_closed @@ -623,11 +711,20 @@ async def test_streaming_response_add_question(self, async_client: AsyncCodex) - assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + async def test_path_params_add_question(self, async_client: AsyncCodex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + await async_client.projects.entries.with_raw_response.add_question( + project_id="", + question="question", + ) + @pytest.mark.skip() @parametrize async def test_method_query(self, async_client: AsyncCodex) -> None: entry = await async_client.projects.entries.query( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", question="question", ) assert_matches_type(Optional[Entry], entry, path=["response"]) @@ -636,7 +733,7 @@ async def test_method_query(self, async_client: AsyncCodex) -> None: @parametrize async def test_raw_response_query(self, async_client: AsyncCodex) -> None: response = await async_client.projects.entries.with_raw_response.query( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", question="question", ) @@ -649,7 +746,7 @@ async def test_raw_response_query(self, async_client: AsyncCodex) -> None: @parametrize async def test_streaming_response_query(self, async_client: AsyncCodex) -> None: async with async_client.projects.entries.with_streaming_response.query( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", question="question", ) as response: assert not response.is_closed @@ -659,3 +756,12 @@ async def test_streaming_response_query(self, async_client: AsyncCodex) -> None: assert_matches_type(Optional[Entry], entry, path=["response"]) assert cast(Any, response.is_closed) is True + + @pytest.mark.skip() + @parametrize + async def test_path_params_query(self, async_client: AsyncCodex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + await async_client.projects.entries.with_raw_response.query( + project_id="", + question="question", + ) diff --git a/tests/api_resources/test_projects.py b/tests/api_resources/test_projects.py index 388601d2..1f1f707b 100644 --- a/tests/api_resources/test_projects.py +++ b/tests/api_resources/test_projects.py @@ -75,7 +75,7 @@ def test_streaming_response_create(self, client: Codex) -> None: @parametrize def test_method_retrieve(self, client: Codex) -> None: project = client.projects.retrieve( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert_matches_type(ProjectReturnSchema, project, path=["response"]) @@ -83,7 +83,7 @@ def test_method_retrieve(self, client: Codex) -> None: @parametrize def test_raw_response_retrieve(self, client: Codex) -> None: response = client.projects.with_raw_response.retrieve( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -95,7 +95,7 @@ def test_raw_response_retrieve(self, client: Codex) -> None: @parametrize def test_streaming_response_retrieve(self, client: Codex) -> None: with client.projects.with_streaming_response.retrieve( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -105,11 +105,19 @@ def test_streaming_response_retrieve(self, client: Codex) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + def test_path_params_retrieve(self, client: Codex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + client.projects.with_raw_response.retrieve( + "", + ) + @pytest.mark.skip() @parametrize def test_method_update(self, client: Codex) -> None: project = client.projects.update( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", config={}, name="name", ) @@ -119,7 +127,7 @@ def test_method_update(self, client: Codex) -> None: @parametrize def test_method_update_with_all_params(self, client: Codex) -> None: project = client.projects.update( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", config={"max_distance": 0}, name="name", description="description", @@ -130,7 +138,7 @@ def test_method_update_with_all_params(self, client: Codex) -> None: @parametrize def test_raw_response_update(self, client: Codex) -> None: response = client.projects.with_raw_response.update( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", config={}, name="name", ) @@ -144,7 +152,7 @@ def test_raw_response_update(self, client: Codex) -> None: @parametrize def test_streaming_response_update(self, client: Codex) -> None: with client.projects.with_streaming_response.update( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", config={}, name="name", ) as response: @@ -156,6 +164,16 @@ def test_streaming_response_update(self, client: Codex) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + def test_path_params_update(self, client: Codex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + client.projects.with_raw_response.update( + project_id="", + config={}, + name="name", + ) + @pytest.mark.skip() @parametrize def test_method_list(self, client: Codex) -> None: @@ -194,7 +212,7 @@ def test_streaming_response_list(self, client: Codex) -> None: @parametrize def test_method_delete(self, client: Codex) -> None: project = client.projects.delete( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert project is None @@ -202,7 +220,7 @@ def test_method_delete(self, client: Codex) -> None: @parametrize def test_raw_response_delete(self, client: Codex) -> None: response = client.projects.with_raw_response.delete( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -214,7 +232,7 @@ def test_raw_response_delete(self, client: Codex) -> None: @parametrize def test_streaming_response_delete(self, client: Codex) -> None: with client.projects.with_streaming_response.delete( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -224,11 +242,19 @@ def test_streaming_response_delete(self, client: Codex) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + def test_path_params_delete(self, client: Codex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + client.projects.with_raw_response.delete( + "", + ) + @pytest.mark.skip() @parametrize def test_method_export(self, client: Codex) -> None: project = client.projects.export( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert_matches_type(object, project, path=["response"]) @@ -236,7 +262,7 @@ def test_method_export(self, client: Codex) -> None: @parametrize def test_raw_response_export(self, client: Codex) -> None: response = client.projects.with_raw_response.export( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -248,7 +274,7 @@ def test_raw_response_export(self, client: Codex) -> None: @parametrize def test_streaming_response_export(self, client: Codex) -> None: with client.projects.with_streaming_response.export( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -258,6 +284,14 @@ def test_streaming_response_export(self, client: Codex) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + def test_path_params_export(self, client: Codex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + client.projects.with_raw_response.export( + "", + ) + class TestAsyncProjects: parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @@ -317,7 +351,7 @@ async def test_streaming_response_create(self, async_client: AsyncCodex) -> None @parametrize async def test_method_retrieve(self, async_client: AsyncCodex) -> None: project = await async_client.projects.retrieve( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert_matches_type(ProjectReturnSchema, project, path=["response"]) @@ -325,7 +359,7 @@ async def test_method_retrieve(self, async_client: AsyncCodex) -> None: @parametrize async def test_raw_response_retrieve(self, async_client: AsyncCodex) -> None: response = await async_client.projects.with_raw_response.retrieve( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -337,7 +371,7 @@ async def test_raw_response_retrieve(self, async_client: AsyncCodex) -> None: @parametrize async def test_streaming_response_retrieve(self, async_client: AsyncCodex) -> None: async with async_client.projects.with_streaming_response.retrieve( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -347,11 +381,19 @@ async def test_streaming_response_retrieve(self, async_client: AsyncCodex) -> No assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncCodex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + await async_client.projects.with_raw_response.retrieve( + "", + ) + @pytest.mark.skip() @parametrize async def test_method_update(self, async_client: AsyncCodex) -> None: project = await async_client.projects.update( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", config={}, name="name", ) @@ -361,7 +403,7 @@ async def test_method_update(self, async_client: AsyncCodex) -> None: @parametrize async def test_method_update_with_all_params(self, async_client: AsyncCodex) -> None: project = await async_client.projects.update( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", config={"max_distance": 0}, name="name", description="description", @@ -372,7 +414,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCodex) -> @parametrize async def test_raw_response_update(self, async_client: AsyncCodex) -> None: response = await async_client.projects.with_raw_response.update( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", config={}, name="name", ) @@ -386,7 +428,7 @@ async def test_raw_response_update(self, async_client: AsyncCodex) -> None: @parametrize async def test_streaming_response_update(self, async_client: AsyncCodex) -> None: async with async_client.projects.with_streaming_response.update( - project_id=0, + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", config={}, name="name", ) as response: @@ -398,6 +440,16 @@ async def test_streaming_response_update(self, async_client: AsyncCodex) -> None assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + async def test_path_params_update(self, async_client: AsyncCodex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + await async_client.projects.with_raw_response.update( + project_id="", + config={}, + name="name", + ) + @pytest.mark.skip() @parametrize async def test_method_list(self, async_client: AsyncCodex) -> None: @@ -436,7 +488,7 @@ async def test_streaming_response_list(self, async_client: AsyncCodex) -> None: @parametrize async def test_method_delete(self, async_client: AsyncCodex) -> None: project = await async_client.projects.delete( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert project is None @@ -444,7 +496,7 @@ async def test_method_delete(self, async_client: AsyncCodex) -> None: @parametrize async def test_raw_response_delete(self, async_client: AsyncCodex) -> None: response = await async_client.projects.with_raw_response.delete( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -456,7 +508,7 @@ async def test_raw_response_delete(self, async_client: AsyncCodex) -> None: @parametrize async def test_streaming_response_delete(self, async_client: AsyncCodex) -> None: async with async_client.projects.with_streaming_response.delete( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -466,11 +518,19 @@ async def test_streaming_response_delete(self, async_client: AsyncCodex) -> None assert cast(Any, response.is_closed) is True + @pytest.mark.skip() + @parametrize + async def test_path_params_delete(self, async_client: AsyncCodex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + await async_client.projects.with_raw_response.delete( + "", + ) + @pytest.mark.skip() @parametrize async def test_method_export(self, async_client: AsyncCodex) -> None: project = await async_client.projects.export( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert_matches_type(object, project, path=["response"]) @@ -478,7 +538,7 @@ async def test_method_export(self, async_client: AsyncCodex) -> None: @parametrize async def test_raw_response_export(self, async_client: AsyncCodex) -> None: response = await async_client.projects.with_raw_response.export( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -490,7 +550,7 @@ async def test_raw_response_export(self, async_client: AsyncCodex) -> None: @parametrize async def test_streaming_response_export(self, async_client: AsyncCodex) -> None: async with async_client.projects.with_streaming_response.export( - 0, + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -499,3 +559,11 @@ async def test_streaming_response_export(self, async_client: AsyncCodex) -> None assert_matches_type(object, project, path=["response"]) assert cast(Any, response.is_closed) is True + + @pytest.mark.skip() + @parametrize + async def test_path_params_export(self, async_client: AsyncCodex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + await async_client.projects.with_raw_response.export( + "", + )