Skip to content

Commit f141f87

Browse files
authored
Merge pull request #18 from ArkHQ-io/release-please--branches--main--changes--next
release: 0.15.0
2 parents e6c57b0 + 17b79ec commit f141f87

20 files changed

Lines changed: 260 additions & 94 deletions

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "0.14.0"
2+
".": "0.15.0"
33
}

.stats.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 35
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/ark%2Fark-1949bcfc8775c97eca880428dc93e9f97aa91144bef82584027ede5089bb2e19.yml
3-
openapi_spec_hash: 0aa367455a067b701f18ef7892b6c7e9
4-
config_hash: 373e654f8034a40c42234eee9ebefbb9
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/ark%2Fark-39b91ffd46b6e41924f8465ffaaff6ba3c200a68daa513d4f1eb1e4b29aba78f.yml
3+
openapi_spec_hash: 542dd50007316698c83e8b0bdd5e40e2
4+
config_hash: 77a3908ee910a8019f5831d3a3d53c18

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# Changelog
22

3+
## 0.15.0 (2026-01-30)
4+
5+
Full Changelog: [v0.14.0...v0.15.0](https://github.com/ArkHQ-io/ark-python/compare/v0.14.0...v0.15.0)
6+
7+
### Features
8+
9+
* **api:** api update ([0f5c166](https://github.com/ArkHQ-io/ark-python/commit/0f5c1666d7c02d1f18096610716be6cb2c39a281))
10+
* **api:** api update ([f128894](https://github.com/ArkHQ-io/ark-python/commit/f128894ef84fffa757424b4b1684f7e4eebf4629))
11+
* **api:** manual updates ([bcc7230](https://github.com/ArkHQ-io/ark-python/commit/bcc72308bfbfd6bfd6cefc6df9e1019637ce1b02))
12+
* **api:** manual updates ([378cd65](https://github.com/ArkHQ-io/ark-python/commit/378cd65aadfd41edd36f4d82ad3ea12d95ec8f0c))
13+
* **api:** manual updates ([edb503c](https://github.com/ArkHQ-io/ark-python/commit/edb503c58439ac4face4260cf1e6794cab79f8bb))
14+
* **client:** add custom JSON encoder for extended type support ([ff51eb2](https://github.com/ArkHQ-io/ark-python/commit/ff51eb229a2eda74e3bc8c16d5f7f43758dc5c31))
15+
316
## 0.14.0 (2026-01-29)
417

518
Full Changelog: [v0.13.0...v0.14.0](https://github.com/ArkHQ-io/ark-python/compare/v0.13.0...v0.14.0)

api.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ from ark.types import (
2222

2323
Methods:
2424

25-
- <code title="get /emails/{emailId}">client.emails.<a href="./src/ark/resources/emails.py">retrieve</a>(email_id, \*\*<a href="src/ark/types/email_retrieve_params.py">params</a>) -> <a href="./src/ark/types/email_retrieve_response.py">EmailRetrieveResponse</a></code>
25+
- <code title="get /emails/{id}">client.emails.<a href="./src/ark/resources/emails.py">retrieve</a>(id, \*\*<a href="src/ark/types/email_retrieve_params.py">params</a>) -> <a href="./src/ark/types/email_retrieve_response.py">EmailRetrieveResponse</a></code>
2626
- <code title="get /emails">client.emails.<a href="./src/ark/resources/emails.py">list</a>(\*\*<a href="src/ark/types/email_list_params.py">params</a>) -> <a href="./src/ark/types/email_list_response.py">SyncPageNumberPagination[EmailListResponse]</a></code>
27-
- <code title="get /emails/{emailId}/deliveries">client.emails.<a href="./src/ark/resources/emails.py">retrieve_deliveries</a>(email_id) -> <a href="./src/ark/types/email_retrieve_deliveries_response.py">EmailRetrieveDeliveriesResponse</a></code>
28-
- <code title="post /emails/{emailId}/retry">client.emails.<a href="./src/ark/resources/emails.py">retry</a>(email_id) -> <a href="./src/ark/types/email_retry_response.py">EmailRetryResponse</a></code>
27+
- <code title="get /emails/{id}/deliveries">client.emails.<a href="./src/ark/resources/emails.py">retrieve_deliveries</a>(id) -> <a href="./src/ark/types/email_retrieve_deliveries_response.py">EmailRetrieveDeliveriesResponse</a></code>
28+
- <code title="post /emails/{id}/retry">client.emails.<a href="./src/ark/resources/emails.py">retry</a>(id) -> <a href="./src/ark/types/email_retry_response.py">EmailRetryResponse</a></code>
2929
- <code title="post /emails">client.emails.<a href="./src/ark/resources/emails.py">send</a>(\*\*<a href="src/ark/types/email_send_params.py">params</a>) -> <a href="./src/ark/types/email_send_response.py">EmailSendResponse</a></code>
3030
- <code title="post /emails/batch">client.emails.<a href="./src/ark/resources/emails.py">send_batch</a>(\*\*<a href="src/ark/types/email_send_batch_params.py">params</a>) -> <a href="./src/ark/types/email_send_batch_response.py">EmailSendBatchResponse</a></code>
3131
- <code title="post /emails/raw">client.emails.<a href="./src/ark/resources/emails.py">send_raw</a>(\*\*<a href="src/ark/types/email_send_raw_params.py">params</a>) -> <a href="./src/ark/types/email_send_raw_response.py">EmailSendRawResponse</a></code>

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "ark-email"
3-
version = "0.14.0"
3+
version = "0.15.0"
44
description = "The official Python library for the ark API"
55
dynamic = ["readme"]
66
license = "Apache-2.0"

src/ark/_base_client.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
APIConnectionError,
8787
APIResponseValidationError,
8888
)
89+
from ._utils._json import openapi_dumps
8990

9091
log: logging.Logger = logging.getLogger(__name__)
9192

@@ -554,8 +555,10 @@ def _build_request(
554555
kwargs["content"] = options.content
555556
elif isinstance(json_data, bytes):
556557
kwargs["content"] = json_data
557-
else:
558-
kwargs["json"] = json_data if is_given(json_data) else None
558+
elif not files:
559+
# Don't set content when JSON is sent as multipart/form-data,
560+
# since httpx's content param overrides other body arguments
561+
kwargs["content"] = openapi_dumps(json_data) if is_given(json_data) and json_data is not None else None
559562
kwargs["files"] = files
560563
else:
561564
headers.pop("Content-Type", None)

src/ark/_compat.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ def model_dump(
139139
exclude_defaults: bool = False,
140140
warnings: bool = True,
141141
mode: Literal["json", "python"] = "python",
142+
by_alias: bool | None = None,
142143
) -> dict[str, Any]:
143144
if (not PYDANTIC_V1) or hasattr(model, "model_dump"):
144145
return model.model_dump(
@@ -148,13 +149,12 @@ def model_dump(
148149
exclude_defaults=exclude_defaults,
149150
# warnings are not supported in Pydantic v1
150151
warnings=True if PYDANTIC_V1 else warnings,
152+
by_alias=by_alias,
151153
)
152154
return cast(
153155
"dict[str, Any]",
154156
model.dict( # pyright: ignore[reportDeprecated, reportUnnecessaryCast]
155-
exclude=exclude,
156-
exclude_unset=exclude_unset,
157-
exclude_defaults=exclude_defaults,
157+
exclude=exclude, exclude_unset=exclude_unset, exclude_defaults=exclude_defaults, by_alias=bool(by_alias)
158158
),
159159
)
160160

src/ark/_utils/_json.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import json
2+
from typing import Any
3+
from datetime import datetime
4+
from typing_extensions import override
5+
6+
import pydantic
7+
8+
from .._compat import model_dump
9+
10+
11+
def openapi_dumps(obj: Any) -> bytes:
12+
"""
13+
Serialize an object to UTF-8 encoded JSON bytes.
14+
15+
Extends the standard json.dumps with support for additional types
16+
commonly used in the SDK, such as `datetime`, `pydantic.BaseModel`, etc.
17+
"""
18+
return json.dumps(
19+
obj,
20+
cls=_CustomEncoder,
21+
# Uses the same defaults as httpx's JSON serialization
22+
ensure_ascii=False,
23+
separators=(",", ":"),
24+
allow_nan=False,
25+
).encode()
26+
27+
28+
class _CustomEncoder(json.JSONEncoder):
29+
@override
30+
def default(self, o: Any) -> Any:
31+
if isinstance(o, datetime):
32+
return o.isoformat()
33+
if isinstance(o, pydantic.BaseModel):
34+
return model_dump(o, exclude_unset=True, mode="json", by_alias=True)
35+
return super().default(o)

src/ark/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
22

33
__title__ = "ark"
4-
__version__ = "0.14.0" # x-release-please-version
4+
__version__ = "0.15.0" # x-release-please-version

src/ark/resources/emails.py

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def with_streaming_response(self) -> EmailsResourceWithStreamingResponse:
5959

6060
def retrieve(
6161
self,
62-
email_id: str,
62+
id: str,
6363
*,
6464
expand: str | Omit = omit,
6565
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -96,10 +96,10 @@ def retrieve(
9696
9797
timeout: Override the client-level default timeout for this request, in seconds
9898
"""
99-
if not email_id:
100-
raise ValueError(f"Expected a non-empty value for `email_id` but received {email_id!r}")
99+
if not id:
100+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
101101
return self._get(
102-
f"/emails/{email_id}",
102+
f"/emails/{id}",
103103
options=make_request_options(
104104
extra_headers=extra_headers,
105105
extra_query=extra_query,
@@ -200,7 +200,7 @@ def list(
200200

201201
def retrieve_deliveries(
202202
self,
203-
email_id: str,
203+
id: str,
204204
*,
205205
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
206206
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -243,8 +243,8 @@ def retrieve_deliveries(
243243
244244
### Can Retry Manually
245245
246-
Indicates whether you can call `POST /emails/{emailId}/retry` to manually retry
247-
the email. This is `true` when the raw message content is still available (not
246+
Indicates whether you can call `POST /emails/{id}/retry` to manually retry the
247+
email. This is `true` when the raw message content is still available (not
248248
expired due to retention policy).
249249
250250
Args:
@@ -256,10 +256,10 @@ def retrieve_deliveries(
256256
257257
timeout: Override the client-level default timeout for this request, in seconds
258258
"""
259-
if not email_id:
260-
raise ValueError(f"Expected a non-empty value for `email_id` but received {email_id!r}")
259+
if not id:
260+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
261261
return self._get(
262-
f"/emails/{email_id}/deliveries",
262+
f"/emails/{id}/deliveries",
263263
options=make_request_options(
264264
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
265265
),
@@ -268,7 +268,7 @@ def retrieve_deliveries(
268268

269269
def retry(
270270
self,
271-
email_id: str,
271+
id: str,
272272
*,
273273
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
274274
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -293,10 +293,10 @@ def retry(
293293
294294
timeout: Override the client-level default timeout for this request, in seconds
295295
"""
296-
if not email_id:
297-
raise ValueError(f"Expected a non-empty value for `email_id` but received {email_id!r}")
296+
if not id:
297+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
298298
return self._post(
299-
f"/emails/{email_id}/retry",
299+
f"/emails/{id}/retry",
300300
options=make_request_options(
301301
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
302302
),
@@ -575,7 +575,7 @@ def with_streaming_response(self) -> AsyncEmailsResourceWithStreamingResponse:
575575

576576
async def retrieve(
577577
self,
578-
email_id: str,
578+
id: str,
579579
*,
580580
expand: str | Omit = omit,
581581
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -612,10 +612,10 @@ async def retrieve(
612612
613613
timeout: Override the client-level default timeout for this request, in seconds
614614
"""
615-
if not email_id:
616-
raise ValueError(f"Expected a non-empty value for `email_id` but received {email_id!r}")
615+
if not id:
616+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
617617
return await self._get(
618-
f"/emails/{email_id}",
618+
f"/emails/{id}",
619619
options=make_request_options(
620620
extra_headers=extra_headers,
621621
extra_query=extra_query,
@@ -716,7 +716,7 @@ def list(
716716

717717
async def retrieve_deliveries(
718718
self,
719-
email_id: str,
719+
id: str,
720720
*,
721721
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
722722
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -759,8 +759,8 @@ async def retrieve_deliveries(
759759
760760
### Can Retry Manually
761761
762-
Indicates whether you can call `POST /emails/{emailId}/retry` to manually retry
763-
the email. This is `true` when the raw message content is still available (not
762+
Indicates whether you can call `POST /emails/{id}/retry` to manually retry the
763+
email. This is `true` when the raw message content is still available (not
764764
expired due to retention policy).
765765
766766
Args:
@@ -772,10 +772,10 @@ async def retrieve_deliveries(
772772
773773
timeout: Override the client-level default timeout for this request, in seconds
774774
"""
775-
if not email_id:
776-
raise ValueError(f"Expected a non-empty value for `email_id` but received {email_id!r}")
775+
if not id:
776+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
777777
return await self._get(
778-
f"/emails/{email_id}/deliveries",
778+
f"/emails/{id}/deliveries",
779779
options=make_request_options(
780780
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
781781
),
@@ -784,7 +784,7 @@ async def retrieve_deliveries(
784784

785785
async def retry(
786786
self,
787-
email_id: str,
787+
id: str,
788788
*,
789789
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
790790
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -809,10 +809,10 @@ async def retry(
809809
810810
timeout: Override the client-level default timeout for this request, in seconds
811811
"""
812-
if not email_id:
813-
raise ValueError(f"Expected a non-empty value for `email_id` but received {email_id!r}")
812+
if not id:
813+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
814814
return await self._post(
815-
f"/emails/{email_id}/retry",
815+
f"/emails/{id}/retry",
816816
options=make_request_options(
817817
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
818818
),

0 commit comments

Comments
 (0)