Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ jobs:
- name: Get GitHub OIDC Token
if: github.repository == 'stainless-sdks/gcore-python'
id: github-oidc
uses: actions/github-script@v6
uses: actions/github-script@v8
with:
script: core.setOutput('github_token', await core.getIDToken());

Expand Down
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.30.0"
".": "0.31.0"
}
6 changes: 3 additions & 3 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 645
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-2d64161889a53046ca5e593a772328a5290246c3d74f8c07fed1037feae1bdbc.yml
openapi_spec_hash: 2360d25764d74e6972cf600fcd20fd4e
config_hash: e9e5b750687e9071d8b606963f0ffd6d
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-58d9afa7f8342ead022bd8fa12bb8abbeb9c0fb1e16f052ee6c4a59fae373e27.yml
openapi_spec_hash: 2ae4db03cfc907be71d44288503838d7
config_hash: 8d4711ed72633b7443249124a49781da
32 changes: 32 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,37 @@
# Changelog

## 0.31.0 (2026-01-30)

Full Changelog: [v0.30.0...v0.31.0](https://github.com/G-Core/gcore-python/compare/v0.30.0...v0.31.0)

### ⚠ BREAKING CHANGES

* **cdn:** rename resource to cdn_resource
* **api:** change type casing from Cdn* to CDN*

### Features

* **api:** aggregated API specs update ([cd35cbf](https://github.com/G-Core/gcore-python/commit/cd35cbf266cf598045a8a4f8ebf3cf7cd8340092))
* **api:** aggregated API specs update ([a7076d0](https://github.com/G-Core/gcore-python/commit/a7076d04fa78e4ea71b148ef8c10d0013536e904))
* **api:** manual upload of aggregated API specs ([47734d2](https://github.com/G-Core/gcore-python/commit/47734d2b4fcd22875d2ec80b2b0453600b912eca))
* **api:** refactor(cdn)!: change type casing from Cdn* to CDN* ([4ea3f5c](https://github.com/G-Core/gcore-python/commit/4ea3f5c23afe085bf5c8b25dadfb1bcd1899edfe))
* **client:** add custom JSON encoder for extended type support ([b0c58f9](https://github.com/G-Core/gcore-python/commit/b0c58f9f042c3e67b63d99bded8179c943d29711))


### Bug Fixes

* **client:** internal references to CDN types ([13f5d35](https://github.com/G-Core/gcore-python/commit/13f5d3512b170ee9db3757768cbafb44831c61c4))


### Chores

* **ci:** upgrade `actions/github-script` ([a2328c0](https://github.com/G-Core/gcore-python/commit/a2328c02b6d94f8af8cdeb7dbc72d81f1e2d17d0))


### Refactors

* **cdn:** rename resource to cdn_resource ([aff2220](https://github.com/G-Core/gcore-python/commit/aff2220ee6c6d14566007e54136de563fa5df3e8))

## 0.30.0 (2026-01-22)

Full Changelog: [v0.29.0...v0.30.0](https://github.com/G-Core/gcore-python/compare/v0.29.0...v0.30.0)
Expand Down
84 changes: 42 additions & 42 deletions api.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "gcore"
version = "0.30.0"
version = "0.31.0"
description = "The official Python library for the gcore API"
dynamic = ["readme"]
license = "Apache-2.0"
Expand Down
7 changes: 5 additions & 2 deletions src/gcore/_base_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
APIConnectionError,
APIResponseValidationError,
)
from ._utils._json import openapi_dumps

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

Expand Down Expand Up @@ -554,8 +555,10 @@ def _build_request(
kwargs["content"] = options.content
elif isinstance(json_data, bytes):
kwargs["content"] = json_data
else:
kwargs["json"] = json_data if is_given(json_data) else None
elif not files:
# Don't set content when JSON is sent as multipart/form-data,
# since httpx's content param overrides other body arguments
kwargs["content"] = openapi_dumps(json_data) if is_given(json_data) and json_data is not None else None
kwargs["files"] = files
else:
headers.pop("Content-Type", None)
Expand Down
16 changes: 8 additions & 8 deletions src/gcore/_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class Gcore(SyncAPIClient):
security: security.SecurityResource
dns: dns.DNSResource
storage: storage.StorageResource
cdn: cdn.CdnResource
cdn: cdn.CDNResource
with_raw_response: GcoreWithRawResponse
with_streaming_response: GcoreWithStreamedResponse

Expand Down Expand Up @@ -143,7 +143,7 @@ def __init__(
self.security = security.SecurityResource(self)
self.dns = dns.DNSResource(self)
self.storage = storage.StorageResource(self)
self.cdn = cdn.CdnResource(self)
self.cdn = cdn.CDNResource(self)
self.with_raw_response = GcoreWithRawResponse(self)
self.with_streaming_response = GcoreWithStreamedResponse(self)

Expand Down Expand Up @@ -287,7 +287,7 @@ class AsyncGcore(AsyncAPIClient):
security: security.AsyncSecurityResource
dns: dns.AsyncDNSResource
storage: storage.AsyncStorageResource
cdn: cdn.AsyncCdnResource
cdn: cdn.AsyncCDNResource
with_raw_response: AsyncGcoreWithRawResponse
with_streaming_response: AsyncGcoreWithStreamedResponse

Expand Down Expand Up @@ -380,7 +380,7 @@ def __init__(
self.security = security.AsyncSecurityResource(self)
self.dns = dns.AsyncDNSResource(self)
self.storage = storage.AsyncStorageResource(self)
self.cdn = cdn.AsyncCdnResource(self)
self.cdn = cdn.AsyncCDNResource(self)
self.with_raw_response = AsyncGcoreWithRawResponse(self)
self.with_streaming_response = AsyncGcoreWithStreamedResponse(self)

Expand Down Expand Up @@ -525,7 +525,7 @@ def __init__(self, client: Gcore) -> None:
self.security = security.SecurityResourceWithRawResponse(client.security)
self.dns = dns.DNSResourceWithRawResponse(client.dns)
self.storage = storage.StorageResourceWithRawResponse(client.storage)
self.cdn = cdn.CdnResourceWithRawResponse(client.cdn)
self.cdn = cdn.CDNResourceWithRawResponse(client.cdn)


class AsyncGcoreWithRawResponse:
Expand All @@ -538,7 +538,7 @@ def __init__(self, client: AsyncGcore) -> None:
self.security = security.AsyncSecurityResourceWithRawResponse(client.security)
self.dns = dns.AsyncDNSResourceWithRawResponse(client.dns)
self.storage = storage.AsyncStorageResourceWithRawResponse(client.storage)
self.cdn = cdn.AsyncCdnResourceWithRawResponse(client.cdn)
self.cdn = cdn.AsyncCDNResourceWithRawResponse(client.cdn)


class GcoreWithStreamedResponse:
Expand All @@ -551,7 +551,7 @@ def __init__(self, client: Gcore) -> None:
self.security = security.SecurityResourceWithStreamingResponse(client.security)
self.dns = dns.DNSResourceWithStreamingResponse(client.dns)
self.storage = storage.StorageResourceWithStreamingResponse(client.storage)
self.cdn = cdn.CdnResourceWithStreamingResponse(client.cdn)
self.cdn = cdn.CDNResourceWithStreamingResponse(client.cdn)


class AsyncGcoreWithStreamedResponse:
Expand All @@ -564,7 +564,7 @@ def __init__(self, client: AsyncGcore) -> None:
self.security = security.AsyncSecurityResourceWithStreamingResponse(client.security)
self.dns = dns.AsyncDNSResourceWithStreamingResponse(client.dns)
self.storage = storage.AsyncStorageResourceWithStreamingResponse(client.storage)
self.cdn = cdn.AsyncCdnResourceWithStreamingResponse(client.cdn)
self.cdn = cdn.AsyncCDNResourceWithStreamingResponse(client.cdn)


Client = Gcore
Expand Down
6 changes: 3 additions & 3 deletions src/gcore/_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ def model_dump(
exclude_defaults: bool = False,
warnings: bool = True,
mode: Literal["json", "python"] = "python",
by_alias: bool | None = None,
) -> dict[str, Any]:
if (not PYDANTIC_V1) or hasattr(model, "model_dump"):
return model.model_dump(
Expand All @@ -148,13 +149,12 @@ def model_dump(
exclude_defaults=exclude_defaults,
# warnings are not supported in Pydantic v1
warnings=True if PYDANTIC_V1 else warnings,
by_alias=by_alias,
)
return cast(
"dict[str, Any]",
model.dict( # pyright: ignore[reportDeprecated, reportUnnecessaryCast]
exclude=exclude,
exclude_unset=exclude_unset,
exclude_defaults=exclude_defaults,
exclude=exclude, exclude_unset=exclude_unset, exclude_defaults=exclude_defaults, by_alias=bool(by_alias)
),
)

Expand Down
35 changes: 35 additions & 0 deletions src/gcore/_utils/_json.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import json
from typing import Any
from datetime import datetime
from typing_extensions import override

import pydantic

from .._compat import model_dump


def openapi_dumps(obj: Any) -> bytes:
"""
Serialize an object to UTF-8 encoded JSON bytes.

Extends the standard json.dumps with support for additional types
commonly used in the SDK, such as `datetime`, `pydantic.BaseModel`, etc.
"""
return json.dumps(
obj,
cls=_CustomEncoder,
# Uses the same defaults as httpx's JSON serialization
ensure_ascii=False,
separators=(",", ":"),
allow_nan=False,
).encode()


class _CustomEncoder(json.JSONEncoder):
@override
def default(self, o: Any) -> Any:
if isinstance(o, datetime):
return o.isoformat()
if isinstance(o, pydantic.BaseModel):
return model_dump(o, exclude_unset=True, mode="json", by_alias=True)
return super().default(o)
2 changes: 1 addition & 1 deletion src/gcore/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

__title__ = "gcore"
__version__ = "0.30.0" # x-release-please-version
__version__ = "0.31.0" # x-release-please-version
24 changes: 12 additions & 12 deletions src/gcore/pagination.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@
"AsyncPageStreamingAI",
"SyncPageStreaming",
"AsyncPageStreaming",
"SyncOffsetPageCdn",
"AsyncOffsetPageCdn",
"OffsetPageCdnLogsMeta",
"SyncOffsetPageCdnLogs",
"AsyncOffsetPageCdnLogs",
"SyncOffsetPageCDN",
"AsyncOffsetPageCDN",
"OffsetPageCDNLogsMeta",
"SyncOffsetPageCDNLogs",
"AsyncOffsetPageCDNLogs",
]

_BaseModelT = TypeVar("_BaseModelT", bound=BaseModel)
Expand Down Expand Up @@ -364,7 +364,7 @@ def build(cls: Type[_BaseModelT], *, response: Response, data: object) -> _BaseM
)


class SyncOffsetPageCdn(BaseSyncPage[_T], BasePage[_T], Generic[_T]):
class SyncOffsetPageCDN(BaseSyncPage[_T], BasePage[_T], Generic[_T]):
items: List[_T]

@override
Expand Down Expand Up @@ -395,7 +395,7 @@ def build(cls: Type[_BaseModelT], *, response: Response, data: object) -> _BaseM
)


class AsyncOffsetPageCdn(BaseAsyncPage[_T], BasePage[_T], Generic[_T]):
class AsyncOffsetPageCDN(BaseAsyncPage[_T], BasePage[_T], Generic[_T]):
items: List[_T]

@override
Expand Down Expand Up @@ -426,13 +426,13 @@ def build(cls: Type[_BaseModelT], *, response: Response, data: object) -> _BaseM
)


class OffsetPageCdnLogsMeta(BaseModel):
class OffsetPageCDNLogsMeta(BaseModel):
count: Optional[int] = None


class SyncOffsetPageCdnLogs(BaseSyncPage[_T], BasePage[_T], Generic[_T]):
class SyncOffsetPageCDNLogs(BaseSyncPage[_T], BasePage[_T], Generic[_T]):
data: List[_T]
meta: Optional[OffsetPageCdnLogsMeta] = None
meta: Optional[OffsetPageCDNLogsMeta] = None

@override
def _get_page_items(self) -> List[_T]:
Expand Down Expand Up @@ -463,9 +463,9 @@ def next_page_info(self) -> Optional[PageInfo]:
return None


class AsyncOffsetPageCdnLogs(BaseAsyncPage[_T], BasePage[_T], Generic[_T]):
class AsyncOffsetPageCDNLogs(BaseAsyncPage[_T], BasePage[_T], Generic[_T]):
data: List[_T]
meta: Optional[OffsetPageCdnLogsMeta] = None
meta: Optional[OffsetPageCDNLogsMeta] = None

@override
def _get_page_items(self) -> List[_T]:
Expand Down
24 changes: 12 additions & 12 deletions src/gcore/resources/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

from .cdn import (
CdnResource,
AsyncCdnResource,
CdnResourceWithRawResponse,
AsyncCdnResourceWithRawResponse,
CdnResourceWithStreamingResponse,
AsyncCdnResourceWithStreamingResponse,
CDNResource,
AsyncCDNResource,
CDNResourceWithRawResponse,
AsyncCDNResourceWithRawResponse,
CDNResourceWithStreamingResponse,
AsyncCDNResourceWithStreamingResponse,
)
from .dns import (
DNSResource,
Expand Down Expand Up @@ -122,10 +122,10 @@
"AsyncStorageResourceWithRawResponse",
"StorageResourceWithStreamingResponse",
"AsyncStorageResourceWithStreamingResponse",
"CdnResource",
"AsyncCdnResource",
"CdnResourceWithRawResponse",
"AsyncCdnResourceWithRawResponse",
"CdnResourceWithStreamingResponse",
"AsyncCdnResourceWithStreamingResponse",
"CDNResource",
"AsyncCDNResource",
"CDNResourceWithRawResponse",
"AsyncCDNResourceWithRawResponse",
"CDNResourceWithStreamingResponse",
"AsyncCDNResourceWithStreamingResponse",
]
Loading
Loading