diff --git a/.release-please-manifest.json b/.release-please-manifest.json index f14b480a..aaf968a1 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.1.0-alpha.2" + ".": "0.1.0-alpha.3" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 97b6bcc9..b61d323f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 0.1.0-alpha.3 (2025-01-17) + +Full Changelog: [v0.1.0-alpha.2...v0.1.0-alpha.3](https://github.com/cleanlab/codex-python/compare/v0.1.0-alpha.2...v0.1.0-alpha.3) + +### Features + +* **api:** api update ([#22](https://github.com/cleanlab/codex-python/issues/22)) ([b449c29](https://github.com/cleanlab/codex-python/commit/b449c298833d9e9fafbde06a0fc8ab3bbd833ef8)) + + +### Chores + +* **internal:** codegen related update ([#20](https://github.com/cleanlab/codex-python/issues/20)) ([e6cdd0b](https://github.com/cleanlab/codex-python/commit/e6cdd0b42010f768b59843b2b7704943cabcfadb)) + ## 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) diff --git a/mypy.ini b/mypy.ini index 88ad64a6..92f9243b 100644 --- a/mypy.ini +++ b/mypy.ini @@ -41,7 +41,7 @@ cache_fine_grained = True # ``` # Changing this codegen to make mypy happy would increase complexity # and would not be worth it. -disable_error_code = func-returns-value +disable_error_code = func-returns-value,overload-cannot-match # https://github.com/python/mypy/issues/12162 [mypy.overrides] diff --git a/pyproject.toml b/pyproject.toml index 91eb985e..9cfbc410 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "codex-sdk" -version = "0.1.0-alpha.2" +version = "0.1.0-alpha.3" description = "The official Python library for the Codex API" dynamic = ["readme"] license = "MIT" diff --git a/requirements-dev.lock b/requirements-dev.lock index 47eb5e34..ef078719 100644 --- a/requirements-dev.lock +++ b/requirements-dev.lock @@ -48,7 +48,7 @@ markdown-it-py==3.0.0 # via rich mdurl==0.1.2 # via markdown-it-py -mypy==1.13.0 +mypy==1.14.1 mypy-extensions==1.0.0 # via mypy nest-asyncio==1.6.0 @@ -68,7 +68,7 @@ pydantic-core==2.27.1 # via pydantic pygments==2.18.0 # via rich -pyright==1.1.390 +pyright==1.1.392.post0 pytest==8.3.3 # via pytest-asyncio pytest-asyncio==0.24.0 diff --git a/src/codex/_response.py b/src/codex/_response.py index b63926f4..174baacd 100644 --- a/src/codex/_response.py +++ b/src/codex/_response.py @@ -210,7 +210,13 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T: raise ValueError(f"Subclasses of httpx.Response cannot be passed to `cast_to`") return cast(R, response) - if inspect.isclass(origin) and not issubclass(origin, BaseModel) and issubclass(origin, pydantic.BaseModel): + if ( + inspect.isclass( + origin # pyright: ignore[reportUnknownArgumentType] + ) + and not issubclass(origin, BaseModel) + and issubclass(origin, pydantic.BaseModel) + ): raise TypeError("Pydantic models must subclass our base model type, e.g. `from codex import BaseModel`") if ( diff --git a/src/codex/_version.py b/src/codex/_version.py index 0ebe32a7..4d9fa623 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.2" # x-release-please-version +__version__ = "0.1.0-alpha.3" # x-release-please-version diff --git a/src/codex/resources/projects/projects.py b/src/codex/resources/projects/projects.py index 8a5f35a1..de366ee8 100644 --- a/src/codex/resources/projects/projects.py +++ b/src/codex/resources/projects/projects.py @@ -3,6 +3,7 @@ from __future__ import annotations from typing import Optional +from typing_extensions import Literal import httpx @@ -195,6 +196,12 @@ def list( self, *, organization_id: str, + include_entry_counts: bool | NotGiven = NOT_GIVEN, + limit: int | NotGiven = NOT_GIVEN, + offset: int | NotGiven = NOT_GIVEN, + order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN, + query: Optional[str] | NotGiven = NOT_GIVEN, + sort: Literal["created_at", "updated_at"] | NotGiven = NOT_GIVEN, # 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,7 +228,18 @@ def list( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=maybe_transform({"organization_id": organization_id}, project_list_params.ProjectListParams), + query=maybe_transform( + { + "organization_id": organization_id, + "include_entry_counts": include_entry_counts, + "limit": limit, + "offset": offset, + "order": order, + "query": query, + "sort": sort, + }, + project_list_params.ProjectListParams, + ), ), cast_to=ProjectListResponse, ) @@ -446,6 +464,12 @@ async def list( self, *, organization_id: str, + include_entry_counts: bool | NotGiven = NOT_GIVEN, + limit: int | NotGiven = NOT_GIVEN, + offset: int | NotGiven = NOT_GIVEN, + order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN, + query: Optional[str] | NotGiven = NOT_GIVEN, + sort: Literal["created_at", "updated_at"] | NotGiven = NOT_GIVEN, # 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, @@ -473,7 +497,16 @@ async def list( extra_body=extra_body, timeout=timeout, query=await async_maybe_transform( - {"organization_id": organization_id}, project_list_params.ProjectListParams + { + "organization_id": organization_id, + "include_entry_counts": include_entry_counts, + "limit": limit, + "offset": offset, + "order": order, + "query": query, + "sort": sort, + }, + project_list_params.ProjectListParams, ), ), cast_to=ProjectListResponse, diff --git a/src/codex/types/project_list_params.py b/src/codex/types/project_list_params.py index 5ca07a82..c2589598 100644 --- a/src/codex/types/project_list_params.py +++ b/src/codex/types/project_list_params.py @@ -2,10 +2,23 @@ from __future__ import annotations -from typing_extensions import Required, TypedDict +from typing import Optional +from typing_extensions import Literal, Required, TypedDict __all__ = ["ProjectListParams"] class ProjectListParams(TypedDict, total=False): organization_id: Required[str] + + include_entry_counts: bool + + limit: int + + offset: int + + order: Literal["asc", "desc"] + + query: Optional[str] + + sort: Literal["created_at", "updated_at"] diff --git a/src/codex/types/project_list_response.py b/src/codex/types/project_list_response.py index 9667cf81..84aafa98 100644 --- a/src/codex/types/project_list_response.py +++ b/src/codex/types/project_list_response.py @@ -1,10 +1,38 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List -from typing_extensions import TypeAlias +from typing import List, Optional +from datetime import datetime -from .project_return_schema import ProjectReturnSchema +from .._models import BaseModel -__all__ = ["ProjectListResponse"] +__all__ = ["ProjectListResponse", "Project", "ProjectConfig"] -ProjectListResponse: TypeAlias = List[ProjectReturnSchema] + +class ProjectConfig(BaseModel): + max_distance: Optional[float] = None + + +class Project(BaseModel): + id: str + + config: ProjectConfig + + created_at: datetime + + created_by_user_id: str + + name: str + + organization_id: str + + updated_at: datetime + + description: Optional[str] = None + + unanswered_entries_count: Optional[int] = None + + +class ProjectListResponse(BaseModel): + projects: List[Project] + + total_count: int diff --git a/src/codex/types/projects/entry.py b/src/codex/types/projects/entry.py index bfa7d278..d3e1fc5f 100644 --- a/src/codex/types/projects/entry.py +++ b/src/codex/types/projects/entry.py @@ -9,12 +9,12 @@ class Entry(BaseModel): - id: str - created_at: datetime question: str + id: Optional[str] = None + answer: Optional[str] = None answered_at: Optional[datetime] = None diff --git a/src/codex/types/users/user_schema_public.py b/src/codex/types/users/user_schema_public.py index 9becf37d..6d35550b 100644 --- a/src/codex/types/users/user_schema_public.py +++ b/src/codex/types/users/user_schema_public.py @@ -15,3 +15,5 @@ class UserSchemaPublic(BaseModel): email: str name: Optional[str] = None + + email_verified: Optional[bool] = None diff --git a/tests/api_resources/test_projects.py b/tests/api_resources/test_projects.py index 1f1f707b..10d23461 100644 --- a/tests/api_resources/test_projects.py +++ b/tests/api_resources/test_projects.py @@ -182,6 +182,20 @@ def test_method_list(self, client: Codex) -> None: ) assert_matches_type(ProjectListResponse, project, path=["response"]) + @pytest.mark.skip() + @parametrize + def test_method_list_with_all_params(self, client: Codex) -> None: + project = client.projects.list( + organization_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + include_entry_counts=True, + limit=0, + offset=0, + order="asc", + query="query", + sort="created_at", + ) + assert_matches_type(ProjectListResponse, project, path=["response"]) + @pytest.mark.skip() @parametrize def test_raw_response_list(self, client: Codex) -> None: @@ -458,6 +472,20 @@ async def test_method_list(self, async_client: AsyncCodex) -> None: ) assert_matches_type(ProjectListResponse, project, path=["response"]) + @pytest.mark.skip() + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCodex) -> None: + project = await async_client.projects.list( + organization_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + include_entry_counts=True, + limit=0, + offset=0, + order="asc", + query="query", + sort="created_at", + ) + assert_matches_type(ProjectListResponse, project, path=["response"]) + @pytest.mark.skip() @parametrize async def test_raw_response_list(self, async_client: AsyncCodex) -> None: