diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 4101074..5f7bf25 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "5.3.0" + ".": "5.4.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 0e8db84..f9ac8b4 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 48 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/imagekit-inc%2Fimagekit-63aff1629530786015da3c86131afa8a9b60545d488884b77641f1d4b89c6e9d.yml -openapi_spec_hash: 586d357bd7e5217d240a99e0d83c6d1f -config_hash: 47cb702ee2cb52c58d803ae39ade9b44 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/imagekit-inc%2Fimagekit-70c42eda2bee929830b2537f758400a58dded1f1ef5686a286e2469c35a041a0.yml +openapi_spec_hash: cdaeed824e91657b45092765cf55eb42 +config_hash: e3c2679d25f6235381dfb11962fbf3d9 diff --git a/CHANGELOG.md b/CHANGELOG.md index 01525ca..df45abc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,35 @@ # Changelog +## 5.4.0 (2026-04-13) + +Full Changelog: [v5.3.0...v5.4.0](https://github.com/imagekit-developer/imagekit-python/compare/v5.3.0...v5.4.0) + +### Features + +* **api:** dam related webhook events ([8803680](https://github.com/imagekit-developer/imagekit-python/commit/8803680ae4bb3ea801d71520cc1354b7a1558bc6)) +* **api:** fix spec indentation ([1a2417d](https://github.com/imagekit-developer/imagekit-python/commit/1a2417d4336d1b9403eb1bc2b65187209fe833c7)) +* **api:** indentation fix ([6ad7341](https://github.com/imagekit-developer/imagekit-python/commit/6ad7341af30e43252519a3c44826be408323cbbe)) +* **api:** merge with main to bring back missing parameters ([a07e952](https://github.com/imagekit-developer/imagekit-python/commit/a07e95275e50dcd975f3ec816420eee7645ce223)) +* **api:** update webhook event names and remove DAM prefix ([bf9e082](https://github.com/imagekit-developer/imagekit-python/commit/bf9e082da50cea2f983b5bd88caca825e5039ec5)) + + +### Bug Fixes + +* **api:** extract shared schemas to prevent Go webhook union breaking changes ([9dcc234](https://github.com/imagekit-developer/imagekit-python/commit/9dcc234c1a5cd387a0989806819ced1b823277c0)) +* **api:** rename DamFile events to File for consistency ([16b113f](https://github.com/imagekit-developer/imagekit-python/commit/16b113f1e6f42b4ac1af43c4cf0567cae55f6ecf)) +* **client:** preserve hardcoded query params when merging with user params ([cbdc71f](https://github.com/imagekit-developer/imagekit-python/commit/cbdc71fee37ce26c0a05cabc55cb03b46c29b216)) +* ensure file data are only sent as 1 parameter ([aa0272a](https://github.com/imagekit-developer/imagekit-python/commit/aa0272a8fe212b1a841031d25fddaa49359ec9d9)) + + +### Documentation + +* improve examples ([bc9d18e](https://github.com/imagekit-developer/imagekit-python/commit/bc9d18e102e37ad28dfe7181cbc3b8323ed79cb2)) + + +### Refactors + +* AITags to singular AITag schema with array items pattern ([96ad1bb](https://github.com/imagekit-developer/imagekit-python/commit/96ad1bb10dbfdad7112d82f5b6cc7199429e0fe3)) + ## 5.3.0 (2026-04-06) Full Changelog: [v5.2.0...v5.3.0](https://github.com/imagekit-developer/imagekit-python/compare/v5.2.0...v5.3.0) diff --git a/api.md b/api.md index 2a17f3a..a331b68 100644 --- a/api.md +++ b/api.md @@ -265,6 +265,11 @@ Types: ```python from imagekitio.types import ( BaseWebhookEvent, + FileCreateEvent, + FileDeleteEvent, + FileUpdateEvent, + FileVersionCreateEvent, + FileVersionDeleteEvent, UploadPostTransformErrorEvent, UploadPostTransformSuccessEvent, UploadPreTransformErrorEvent, diff --git a/pyproject.toml b/pyproject.toml index f04a830..09cbd54 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "imagekitio" -version = "5.3.0" +version = "5.4.0" description = "The official Python library for the ImageKit API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/imagekitio/_base_client.py b/src/imagekitio/_base_client.py index 121c3d4..8be3f93 100644 --- a/src/imagekitio/_base_client.py +++ b/src/imagekitio/_base_client.py @@ -540,6 +540,10 @@ def _build_request( files = cast(HttpxRequestFiles, ForceMultipartDict()) prepared_url = self._prepare_url(options.url) + # preserve hard-coded query params from the url + if params and prepared_url.query: + params = {**dict(prepared_url.params.items()), **params} + prepared_url = prepared_url.copy_with(raw_path=prepared_url.raw_path.split(b"?", 1)[0]) if "_" in prepared_url.host: # work around https://github.com/encode/httpx/discussions/2880 kwargs["extensions"] = {"sni_hostname": prepared_url.host.replace("_", "-")} diff --git a/src/imagekitio/_utils/_utils.py b/src/imagekitio/_utils/_utils.py index eec7f4a..63b8cd6 100644 --- a/src/imagekitio/_utils/_utils.py +++ b/src/imagekitio/_utils/_utils.py @@ -86,8 +86,9 @@ def _extract_items( index += 1 if is_dict(obj): try: - # We are at the last entry in the path so we must remove the field - if (len(path)) == index: + # Remove the field if there are no more dict keys in the path, + # only "" traversal markers or end. + if all(p == "" for p in path[index:]): item = obj.pop(key) else: item = obj[key] diff --git a/src/imagekitio/_version.py b/src/imagekitio/_version.py index 7e78486..3d6ca86 100644 --- a/src/imagekitio/_version.py +++ b/src/imagekitio/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "imagekitio" -__version__ = "5.3.0" # x-release-please-version +__version__ = "5.4.0" # x-release-please-version diff --git a/src/imagekitio/types/__init__.py b/src/imagekitio/types/__init__.py index 180fe49..c5d8520 100644 --- a/src/imagekitio/types/__init__.py +++ b/src/imagekitio/types/__init__.py @@ -33,6 +33,9 @@ from .file_copy_params import FileCopyParams as FileCopyParams from .file_move_params import FileMoveParams as FileMoveParams from .asset_list_params import AssetListParams as AssetListParams +from .file_create_event import FileCreateEvent as FileCreateEvent +from .file_delete_event import FileDeleteEvent as FileDeleteEvent +from .file_update_event import FileUpdateEvent as FileUpdateEvent from .base_webhook_event import BaseWebhookEvent as BaseWebhookEvent from .file_copy_response import FileCopyResponse as FileCopyResponse from .file_move_response import FileMoveResponse as FileMoveResponse @@ -56,6 +59,8 @@ from .folder_create_response import FolderCreateResponse as FolderCreateResponse from .folder_delete_response import FolderDeleteResponse as FolderDeleteResponse from .folder_rename_response import FolderRenameResponse as FolderRenameResponse +from .file_version_create_event import FileVersionCreateEvent as FileVersionCreateEvent +from .file_version_delete_event import FileVersionDeleteEvent as FileVersionDeleteEvent from .update_file_request_param import UpdateFileRequestParam as UpdateFileRequestParam from .unsafe_unwrap_webhook_event import UnsafeUnwrapWebhookEvent as UnsafeUnwrapWebhookEvent from .saved_extension_create_params import SavedExtensionCreateParams as SavedExtensionCreateParams diff --git a/src/imagekitio/types/beta/v2/file_upload_response.py b/src/imagekitio/types/beta/v2/file_upload_response.py index 4696c05..ec9e134 100644 --- a/src/imagekitio/types/beta/v2/file_upload_response.py +++ b/src/imagekitio/types/beta/v2/file_upload_response.py @@ -12,6 +12,11 @@ class AITag(BaseModel): + """AI-generated tag associated with an image. + + These tags can be added using the `google-auto-tagging` or `aws-auto-tagging` extensions. + """ + confidence: Optional[float] = None """Confidence score of the tag.""" @@ -19,10 +24,9 @@ class AITag(BaseModel): """Name of the tag.""" source: Optional[str] = None - """Array of `AITags` associated with the image. + """Source of the tag. - If no `AITags` are set, it will be null. These tags can be added using the - `google-auto-tagging` or `aws-auto-tagging` extensions. + Possible values are `google-auto-tagging` and `aws-auto-tagging`. """ diff --git a/src/imagekitio/types/file.py b/src/imagekitio/types/file.py index 6a0e3a0..b83b0bc 100644 --- a/src/imagekitio/types/file.py +++ b/src/imagekitio/types/file.py @@ -12,6 +12,11 @@ class AITag(BaseModel): + """AI-generated tag associated with an image. + + These tags can be added using the `google-auto-tagging` or `aws-auto-tagging` extensions. + """ + confidence: Optional[float] = None """Confidence score of the tag.""" @@ -80,7 +85,7 @@ class SelectedFieldsSchema(BaseModel): class VersionInfo(BaseModel): - """An object with details of the file version.""" + """An object containing the file or file version's `id` (versionId) and `name`.""" id: Optional[str] = None """Unique identifier of the file version.""" @@ -93,7 +98,10 @@ class File(BaseModel): """Object containing details of a file or file version.""" ai_tags: Optional[List[AITag]] = FieldInfo(alias="AITags", default=None) - """An array of tags assigned to the file by auto tagging.""" + """Array of AI-generated tags associated with the image. + + If no AITags are set, it will be null. + """ audio_codec: Optional[str] = FieldInfo(alias="audioCodec", default=None) """The audio codec used in the video (only for video/audio).""" diff --git a/src/imagekitio/types/file_create_event.py b/src/imagekitio/types/file_create_event.py new file mode 100644 index 0000000..f58bd13 --- /dev/null +++ b/src/imagekitio/types/file_create_event.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from datetime import datetime +from typing_extensions import Literal + +from .file import File +from .base_webhook_event import BaseWebhookEvent + +__all__ = ["FileCreateEvent"] + + +class FileCreateEvent(BaseWebhookEvent): + """Triggered when a file is created.""" + + created_at: datetime + """Timestamp of when the event occurred in ISO8601 format.""" + + data: File + """Object containing details of a file or file version.""" + + type: Literal["file.created"] # type: ignore + """Type of the webhook event.""" diff --git a/src/imagekitio/types/file_delete_event.py b/src/imagekitio/types/file_delete_event.py new file mode 100644 index 0000000..ca50046 --- /dev/null +++ b/src/imagekitio/types/file_delete_event.py @@ -0,0 +1,28 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from datetime import datetime +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .base_webhook_event import BaseWebhookEvent + +__all__ = ["FileDeleteEvent", "FileDeleteEventData"] + + +class FileDeleteEventData(BaseModel): + file_id: str = FieldInfo(alias="fileId") + """The unique `fileId` of the deleted file.""" + + +class FileDeleteEvent(BaseWebhookEvent): + """Triggered when a file is deleted.""" + + created_at: datetime + """Timestamp of when the event occurred in ISO8601 format.""" + + data: FileDeleteEventData + + type: Literal["file.deleted"] # type: ignore + """Type of the webhook event.""" diff --git a/src/imagekitio/types/file_update_event.py b/src/imagekitio/types/file_update_event.py new file mode 100644 index 0000000..5bea418 --- /dev/null +++ b/src/imagekitio/types/file_update_event.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from datetime import datetime +from typing_extensions import Literal + +from .file import File +from .base_webhook_event import BaseWebhookEvent + +__all__ = ["FileUpdateEvent"] + + +class FileUpdateEvent(BaseWebhookEvent): + """Triggered when a file is updated.""" + + created_at: datetime + """Timestamp of when the event occurred in ISO8601 format.""" + + data: File + """Object containing details of a file or file version.""" + + type: Literal["file.updated"] # type: ignore + """Type of the webhook event.""" diff --git a/src/imagekitio/types/file_upload_response.py b/src/imagekitio/types/file_upload_response.py index a33b47e..5352231 100644 --- a/src/imagekitio/types/file_upload_response.py +++ b/src/imagekitio/types/file_upload_response.py @@ -12,6 +12,11 @@ class AITag(BaseModel): + """AI-generated tag associated with an image. + + These tags can be added using the `google-auto-tagging` or `aws-auto-tagging` extensions. + """ + confidence: Optional[float] = None """Confidence score of the tag.""" @@ -19,10 +24,9 @@ class AITag(BaseModel): """Name of the tag.""" source: Optional[str] = None - """Array of `AITags` associated with the image. + """Source of the tag. - If no `AITags` are set, it will be null. These tags can be added using the - `google-auto-tagging` or `aws-auto-tagging` extensions. + Possible values are `google-auto-tagging` and `aws-auto-tagging`. """ diff --git a/src/imagekitio/types/file_version_create_event.py b/src/imagekitio/types/file_version_create_event.py new file mode 100644 index 0000000..1d5425c --- /dev/null +++ b/src/imagekitio/types/file_version_create_event.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from datetime import datetime +from typing_extensions import Literal + +from .file import File +from .base_webhook_event import BaseWebhookEvent + +__all__ = ["FileVersionCreateEvent"] + + +class FileVersionCreateEvent(BaseWebhookEvent): + """Triggered when a file version is created.""" + + created_at: datetime + """Timestamp of when the event occurred in ISO8601 format.""" + + data: File + """Object containing details of a file or file version.""" + + type: Literal["file-version.created"] # type: ignore + """Type of the webhook event.""" diff --git a/src/imagekitio/types/file_version_delete_event.py b/src/imagekitio/types/file_version_delete_event.py new file mode 100644 index 0000000..9c01144 --- /dev/null +++ b/src/imagekitio/types/file_version_delete_event.py @@ -0,0 +1,31 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from datetime import datetime +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .base_webhook_event import BaseWebhookEvent + +__all__ = ["FileVersionDeleteEvent", "FileVersionDeleteEventData"] + + +class FileVersionDeleteEventData(BaseModel): + file_id: str = FieldInfo(alias="fileId") + """The unique `fileId` of the deleted file.""" + + version_id: str = FieldInfo(alias="versionId") + """The unique `versionId` of the deleted file version.""" + + +class FileVersionDeleteEvent(BaseWebhookEvent): + """Triggered when a file version is deleted.""" + + created_at: datetime + """Timestamp of when the event occurred in ISO8601 format.""" + + data: FileVersionDeleteEventData + + type: Literal["file-version.deleted"] # type: ignore + """Type of the webhook event.""" diff --git a/src/imagekitio/types/unsafe_unwrap_webhook_event.py b/src/imagekitio/types/unsafe_unwrap_webhook_event.py index 9ed05b3..7d10c69 100644 --- a/src/imagekitio/types/unsafe_unwrap_webhook_event.py +++ b/src/imagekitio/types/unsafe_unwrap_webhook_event.py @@ -4,6 +4,11 @@ from typing_extensions import Annotated, TypeAlias from .._utils import PropertyInfo +from .file_create_event import FileCreateEvent +from .file_delete_event import FileDeleteEvent +from .file_update_event import FileUpdateEvent +from .file_version_create_event import FileVersionCreateEvent +from .file_version_delete_event import FileVersionDeleteEvent from .upload_pre_transform_error_event import UploadPreTransformErrorEvent from .video_transformation_error_event import VideoTransformationErrorEvent from .video_transformation_ready_event import VideoTransformationReadyEvent @@ -23,6 +28,11 @@ UploadPreTransformErrorEvent, UploadPostTransformSuccessEvent, UploadPostTransformErrorEvent, + FileCreateEvent, + FileUpdateEvent, + FileDeleteEvent, + FileVersionCreateEvent, + FileVersionDeleteEvent, ], PropertyInfo(discriminator="type"), ] diff --git a/src/imagekitio/types/unwrap_webhook_event.py b/src/imagekitio/types/unwrap_webhook_event.py index e67355f..8614c55 100644 --- a/src/imagekitio/types/unwrap_webhook_event.py +++ b/src/imagekitio/types/unwrap_webhook_event.py @@ -4,6 +4,11 @@ from typing_extensions import Annotated, TypeAlias from .._utils import PropertyInfo +from .file_create_event import FileCreateEvent +from .file_delete_event import FileDeleteEvent +from .file_update_event import FileUpdateEvent +from .file_version_create_event import FileVersionCreateEvent +from .file_version_delete_event import FileVersionDeleteEvent from .upload_pre_transform_error_event import UploadPreTransformErrorEvent from .video_transformation_error_event import VideoTransformationErrorEvent from .video_transformation_ready_event import VideoTransformationReadyEvent @@ -23,6 +28,11 @@ UploadPreTransformErrorEvent, UploadPostTransformSuccessEvent, UploadPostTransformErrorEvent, + FileCreateEvent, + FileUpdateEvent, + FileDeleteEvent, + FileVersionCreateEvent, + FileVersionDeleteEvent, ], PropertyInfo(discriminator="type"), ] diff --git a/src/imagekitio/types/upload_pre_transform_success_event.py b/src/imagekitio/types/upload_pre_transform_success_event.py index 991baa1..dfa168f 100644 --- a/src/imagekitio/types/upload_pre_transform_success_event.py +++ b/src/imagekitio/types/upload_pre_transform_success_event.py @@ -22,6 +22,11 @@ class UploadPreTransformSuccessEventDataAITag(BaseModel): + """AI-generated tag associated with an image. + + These tags can be added using the `google-auto-tagging` or `aws-auto-tagging` extensions. + """ + confidence: Optional[float] = None """Confidence score of the tag.""" @@ -29,10 +34,9 @@ class UploadPreTransformSuccessEventDataAITag(BaseModel): """Name of the tag.""" source: Optional[str] = None - """Array of `AITags` associated with the image. + """Source of the tag. - If no `AITags` are set, it will be null. These tags can be added using the - `google-auto-tagging` or `aws-auto-tagging` extensions. + Possible values are `google-auto-tagging` and `aws-auto-tagging`. """ diff --git a/tests/api_resources/test_custom_metadata_fields.py b/tests/api_resources/test_custom_metadata_fields.py index 0a17495..ec73bab 100644 --- a/tests/api_resources/test_custom_metadata_fields.py +++ b/tests/api_resources/test_custom_metadata_fields.py @@ -39,7 +39,7 @@ def test_method_create_with_all_params(self, client: ImageKit) -> None: name="price", schema={ "type": "Number", - "default_value": "string", + "default_value": [True, 10, "Hello"], "is_value_required": True, "max_length": 0, "max_value": 3000, @@ -95,7 +95,7 @@ def test_method_update_with_all_params(self, client: ImageKit) -> None: id="id", label="price", schema={ - "default_value": "string", + "default_value": [True, 10, "Hello"], "is_value_required": True, "max_length": 0, "max_value": 3000, @@ -243,7 +243,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncImageKit) name="price", schema={ "type": "Number", - "default_value": "string", + "default_value": [True, 10, "Hello"], "is_value_required": True, "max_length": 0, "max_value": 3000, @@ -299,7 +299,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncImageKit) id="id", label="price", schema={ - "default_value": "string", + "default_value": [True, 10, "Hello"], "is_value_required": True, "max_length": 0, "max_value": 3000, diff --git a/tests/api_resources/test_dummy.py b/tests/api_resources/test_dummy.py index 655d6c5..0d49f45 100644 --- a/tests/api_resources/test_dummy.py +++ b/tests/api_resources/test_dummy.py @@ -192,7 +192,7 @@ def test_method_create_with_all_params(self, client: ImageKit) -> None: "inner_alignment": "left", "line_height": 0, "padding": 0, - "radius": 0, + "radius": "max", "rotation": 0, "typography": "typography", "width": 0, @@ -309,7 +309,7 @@ def test_method_create_with_all_params(self, client: ImageKit) -> None: "inner_alignment": "left", "line_height": 0, "padding": 0, - "radius": 0, + "radius": "max", "rotation": 0, "typography": "typography", "width": 0, @@ -367,7 +367,7 @@ def test_method_create_with_all_params(self, client: ImageKit) -> None: "inner_alignment": "left", "line_height": 0, "padding": 0, - "radius": 0, + "radius": "max", "rotation": 0, "typography": "typography", "width": 0, @@ -432,7 +432,7 @@ def test_method_create_with_all_params(self, client: ImageKit) -> None: "background": "background", "gradient": True, "height": 0, - "radius": 0, + "radius": "max", "width": 0, } ], @@ -442,7 +442,7 @@ def test_method_create_with_all_params(self, client: ImageKit) -> None: "background": "background", "gradient": True, "height": 0, - "radius": 0, + "radius": "max", "width": 0, }, src_options={ @@ -516,7 +516,7 @@ def test_method_create_with_all_params(self, client: ImageKit) -> None: "inner_alignment": "left", "line_height": 0, "padding": 0, - "radius": 0, + "radius": "max", "rotation": 0, "typography": "typography", "width": 0, @@ -615,7 +615,7 @@ def test_method_create_with_all_params(self, client: ImageKit) -> None: "inner_alignment": "left", "line_height": 0, "padding": 0, - "radius": 0, + "radius": "max", "rotation": 0, "typography": "typography", "width": 0, @@ -632,7 +632,7 @@ def test_method_create_with_all_params(self, client: ImageKit) -> None: "inner_alignment": "left", "line_height": 0, "padding": 0, - "radius": 0, + "radius": "max", "rotation": 0, "typography": "typography", "width": 0, @@ -701,7 +701,7 @@ def test_method_create_with_all_params(self, client: ImageKit) -> None: "inner_alignment": "left", "line_height": 0, "padding": 0, - "radius": 0, + "radius": "max", "rotation": 0, "typography": "typography", "width": 0, @@ -812,7 +812,7 @@ def test_method_create_with_all_params(self, client: ImageKit) -> None: "inner_alignment": "left", "line_height": 0, "padding": 0, - "radius": 0, + "radius": "max", "rotation": 0, "typography": "typography", "width": 0, @@ -1048,7 +1048,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncImageKit) "inner_alignment": "left", "line_height": 0, "padding": 0, - "radius": 0, + "radius": "max", "rotation": 0, "typography": "typography", "width": 0, @@ -1165,7 +1165,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncImageKit) "inner_alignment": "left", "line_height": 0, "padding": 0, - "radius": 0, + "radius": "max", "rotation": 0, "typography": "typography", "width": 0, @@ -1223,7 +1223,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncImageKit) "inner_alignment": "left", "line_height": 0, "padding": 0, - "radius": 0, + "radius": "max", "rotation": 0, "typography": "typography", "width": 0, @@ -1288,7 +1288,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncImageKit) "background": "background", "gradient": True, "height": 0, - "radius": 0, + "radius": "max", "width": 0, } ], @@ -1298,7 +1298,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncImageKit) "background": "background", "gradient": True, "height": 0, - "radius": 0, + "radius": "max", "width": 0, }, src_options={ @@ -1372,7 +1372,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncImageKit) "inner_alignment": "left", "line_height": 0, "padding": 0, - "radius": 0, + "radius": "max", "rotation": 0, "typography": "typography", "width": 0, @@ -1471,7 +1471,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncImageKit) "inner_alignment": "left", "line_height": 0, "padding": 0, - "radius": 0, + "radius": "max", "rotation": 0, "typography": "typography", "width": 0, @@ -1488,7 +1488,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncImageKit) "inner_alignment": "left", "line_height": 0, "padding": 0, - "radius": 0, + "radius": "max", "rotation": 0, "typography": "typography", "width": 0, @@ -1557,7 +1557,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncImageKit) "inner_alignment": "left", "line_height": 0, "padding": 0, - "radius": 0, + "radius": "max", "rotation": 0, "typography": "typography", "width": 0, @@ -1668,7 +1668,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncImageKit) "inner_alignment": "left", "line_height": 0, "padding": 0, - "radius": 0, + "radius": "max", "rotation": 0, "typography": "typography", "width": 0, diff --git a/tests/api_resources/test_files.py b/tests/api_resources/test_files.py index 0f6cdc4..62c3a21 100644 --- a/tests/api_resources/test_files.py +++ b/tests/api_resources/test_files.py @@ -110,7 +110,7 @@ def test_method_update_with_all_params_overload_1(self, client: ImageKit) -> Non "name": "saved-extension", }, ], - remove_ai_tags=["string"], + remove_ai_tags="all", tags=["tag1", "tag2"], webhook_url="https://example.com", ) @@ -663,7 +663,7 @@ async def test_method_update_with_all_params_overload_1(self, async_client: Asyn "name": "saved-extension", }, ], - remove_ai_tags=["string"], + remove_ai_tags="all", tags=["tag1", "tag2"], webhook_url="https://example.com", ) diff --git a/tests/test_client.py b/tests/test_client.py index 00e1367..3abbbf3 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -475,6 +475,30 @@ def test_default_query_option(self) -> None: client.close() + def test_hardcoded_query_params_in_url(self, client: ImageKit) -> None: + request = client._build_request(FinalRequestOptions(method="get", url="/foo?beta=true")) + url = httpx.URL(request.url) + assert dict(url.params) == {"beta": "true"} + + request = client._build_request( + FinalRequestOptions( + method="get", + url="/foo?beta=true", + params={"limit": "10", "page": "abc"}, + ) + ) + url = httpx.URL(request.url) + assert dict(url.params) == {"beta": "true", "limit": "10", "page": "abc"} + + request = client._build_request( + FinalRequestOptions( + method="get", + url="/files/a%2Fb?beta=true", + params={"limit": "10"}, + ) + ) + assert request.url.raw_path == b"/files/a%2Fb?beta=true&limit=10" + def test_request_extra_json(self, client: ImageKit) -> None: request = client._build_request( FinalRequestOptions( @@ -1455,6 +1479,30 @@ async def test_default_query_option(self) -> None: await client.close() + async def test_hardcoded_query_params_in_url(self, async_client: AsyncImageKit) -> None: + request = async_client._build_request(FinalRequestOptions(method="get", url="/foo?beta=true")) + url = httpx.URL(request.url) + assert dict(url.params) == {"beta": "true"} + + request = async_client._build_request( + FinalRequestOptions( + method="get", + url="/foo?beta=true", + params={"limit": "10", "page": "abc"}, + ) + ) + url = httpx.URL(request.url) + assert dict(url.params) == {"beta": "true", "limit": "10", "page": "abc"} + + request = async_client._build_request( + FinalRequestOptions( + method="get", + url="/files/a%2Fb?beta=true", + params={"limit": "10"}, + ) + ) + assert request.url.raw_path == b"/files/a%2Fb?beta=true&limit=10" + def test_request_extra_json(self, client: ImageKit) -> None: request = client._build_request( FinalRequestOptions( diff --git a/tests/test_extract_files.py b/tests/test_extract_files.py index 396cbd0..9b9780e 100644 --- a/tests/test_extract_files.py +++ b/tests/test_extract_files.py @@ -35,6 +35,15 @@ def test_multiple_files() -> None: assert query == {"documents": [{}, {}]} +def test_top_level_file_array() -> None: + query = {"files": [b"file one", b"file two"], "title": "hello"} + assert extract_files(query, paths=[["files", ""]]) == [ + ("files[]", b"file one"), + ("files[]", b"file two"), + ] + assert query == {"title": "hello"} + + @pytest.mark.parametrize( "query,paths,expected", [