From 926c0ddfcef420ba47eca7b399ea43462a18371a Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 22 Oct 2025 08:49:18 +0000
Subject: [PATCH 01/27] feat(api): aggregated API specs update
---
.stats.yml | 4 +-
api.md | 4 +-
src/gcore/resources/cdn/ip_ranges.py | 102 +++++++++++++++-
src/gcore/resources/cdn/statistics.py | 114 +++++++++---------
src/gcore/resources/cloud/quotas/requests.py | 8 --
src/gcore/types/cdn/__init__.py | 2 +
.../types/cdn/ip_range_list_ips_params.py | 19 +++
src/gcore/types/cdn/ip_range_list_params.py | 19 +++
src/gcore/types/cdn/resource_usage_stats.py | 31 ++---
...tistic_get_logs_usage_aggregated_params.py | 5 +-
.../statistic_get_logs_usage_series_params.py | 17 +--
...ic_get_resource_usage_aggregated_params.py | 31 ++---
...tistic_get_resource_usage_series_params.py | 7 +-
...stic_get_shield_usage_aggregated_params.py | 7 +-
...tatistic_get_shield_usage_series_params.py | 3 +
.../cloud/quotas/request_create_params.py | 3 -
src/gcore/types/cloud/security_group.py | 9 +-
tests/api_resources/cdn/test_ip_ranges.py | 32 +++++
.../cloud/quotas/test_requests.py | 2 -
19 files changed, 286 insertions(+), 133 deletions(-)
create mode 100644 src/gcore/types/cdn/ip_range_list_ips_params.py
create mode 100644 src/gcore/types/cdn/ip_range_list_params.py
diff --git a/.stats.yml b/.stats.yml
index fd2d5539..c8537dbe 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 609
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-56132999d4ac773438df4415a4bb56c8cf7f067c3c340d80424bf968074f66dc.yml
-openapi_spec_hash: c33cea043ddbfe20778e0774313fa7e6
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-593c5e99888d61f0b89a96221b71679316ae326fe0bf7468d93a3f4d73d06e8c.yml
+openapi_spec_hash: cfd6560b017a4ff1d003e335b739f2f3
config_hash: bb4a27712c30f7a2b52e1f3b31766f24
diff --git a/api.md b/api.md
index 01ab7916..8904e330 100644
--- a/api.md
+++ b/api.md
@@ -2383,5 +2383,5 @@ from gcore.types.cdn import PublicIPList, PublicNetworkList
Methods:
-- client.cdn.ip_ranges.list() -> PublicNetworkList
-- client.cdn.ip_ranges.list_ips() -> PublicIPList
+- client.cdn.ip_ranges.list(\*\*params) -> PublicNetworkList
+- client.cdn.ip_ranges.list_ips(\*\*params) -> PublicIPList
diff --git a/src/gcore/resources/cdn/ip_ranges.py b/src/gcore/resources/cdn/ip_ranges.py
index 606e9b83..ee39f4a9 100644
--- a/src/gcore/resources/cdn/ip_ranges.py
+++ b/src/gcore/resources/cdn/ip_ranges.py
@@ -2,9 +2,12 @@
from __future__ import annotations
+from typing_extensions import Literal
+
import httpx
-from ..._types import Body, Query, Headers, NotGiven, not_given
+from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ..._utils import is_given, maybe_transform, strip_not_given, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
@@ -13,6 +16,7 @@
async_to_raw_response_wrapper,
async_to_streamed_response_wrapper,
)
+from ...types.cdn import ip_range_list_params, ip_range_list_ips_params
from ..._base_client import make_request_options
from ...types.cdn.public_ip_list import PublicIPList
from ...types.cdn.public_network_list import PublicNetworkList
@@ -43,6 +47,8 @@ def with_streaming_response(self) -> IPRangesResourceWithStreamingResponse:
def list(
self,
*,
+ format: Literal["json", "plain"] | Omit = omit,
+ accept: Literal["application/json", "text/plain"] | Omit = omit,
# 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,
@@ -58,11 +64,31 @@ def list(
relevance. We recommend using a script for automatically update IP ACL.
This request does not require authorization.
+
+ Args:
+ format: Optional format override. When set, this takes precedence over the `Accept`
+ header.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
"""
+ extra_headers = {
+ **strip_not_given({"Accept": str(accept) if is_given(accept) else not_given}),
+ **(extra_headers or {}),
+ }
return self._get(
"/cdn/public-net-list",
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform({"format": format}, ip_range_list_params.IPRangeListParams),
),
cast_to=PublicNetworkList,
)
@@ -70,6 +96,8 @@ def list(
def list_ips(
self,
*,
+ format: Literal["json", "plain"] | Omit = omit,
+ accept: Literal["application/json", "text/plain"] | Omit = omit,
# 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,
@@ -86,11 +114,31 @@ def list_ips(
relevance. We recommend using a script to automatically update IP ACL.
This request does not require authorization.
+
+ Args:
+ format: Optional format override. When set, this takes precedence over the `Accept`
+ header.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
"""
+ extra_headers = {
+ **strip_not_given({"Accept": str(accept) if is_given(accept) else not_given}),
+ **(extra_headers or {}),
+ }
return self._get(
"/cdn/public-ip-list",
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform({"format": format}, ip_range_list_ips_params.IPRangeListIPsParams),
),
cast_to=PublicIPList,
)
@@ -119,6 +167,8 @@ def with_streaming_response(self) -> AsyncIPRangesResourceWithStreamingResponse:
async def list(
self,
*,
+ format: Literal["json", "plain"] | Omit = omit,
+ accept: Literal["application/json", "text/plain"] | Omit = omit,
# 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,
@@ -134,11 +184,31 @@ async def list(
relevance. We recommend using a script for automatically update IP ACL.
This request does not require authorization.
+
+ Args:
+ format: Optional format override. When set, this takes precedence over the `Accept`
+ header.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
"""
+ extra_headers = {
+ **strip_not_given({"Accept": str(accept) if is_given(accept) else not_given}),
+ **(extra_headers or {}),
+ }
return await self._get(
"/cdn/public-net-list",
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform({"format": format}, ip_range_list_params.IPRangeListParams),
),
cast_to=PublicNetworkList,
)
@@ -146,6 +216,8 @@ async def list(
async def list_ips(
self,
*,
+ format: Literal["json", "plain"] | Omit = omit,
+ accept: Literal["application/json", "text/plain"] | Omit = omit,
# 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,
@@ -162,11 +234,31 @@ async def list_ips(
relevance. We recommend using a script to automatically update IP ACL.
This request does not require authorization.
+
+ Args:
+ format: Optional format override. When set, this takes precedence over the `Accept`
+ header.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
"""
+ extra_headers = {
+ **strip_not_given({"Accept": str(accept) if is_given(accept) else not_given}),
+ **(extra_headers or {}),
+ }
return await self._get(
"/cdn/public-ip-list",
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform({"format": format}, ip_range_list_ips_params.IPRangeListIPsParams),
),
cast_to=PublicIPList,
)
diff --git a/src/gcore/resources/cdn/statistics.py b/src/gcore/resources/cdn/statistics.py
index 14f2fa8c..0e6a32a6 100644
--- a/src/gcore/resources/cdn/statistics.py
+++ b/src/gcore/resources/cdn/statistics.py
@@ -77,7 +77,7 @@ def get_logs_usage_aggregated(
to: End of the requested time period (ISO 8601/RFC 3339 format, UTC.)
- flat: The waу parameters are arranged in the response.
+ flat: The way the parameters are arranged in the response.
Possible values:
@@ -96,6 +96,9 @@ def get_logs_usage_aggregated(
- &resource=1&resource=2
+ If CDN resource ID is not specified, data related to all CDN resources is
+ returned.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -146,22 +149,17 @@ def get_logs_usage_series(
Args:
from_: Beginning of the requested time period (ISO 8601/RFC 3339 format, UTC.)
- Example:
-
- - &from=2020-01-01T00:00:00.000
-
to: End of the requested time period (ISO 8601/RFC 3339 format, UTC.)
- Example:
-
- - &from=2020-01-01T00:00:00.000
-
resource: CDN resources IDs by that statistics data is grouped.
To request multiple values, use:
- &resource=1&resource=2
+ If CDN resource ID is not specified, data related to all CDN resources is
+ returned.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -218,11 +216,6 @@ def get_resource_usage_aggregated(
Args:
from_: Beginning of the requested time period (ISO 8601/RFC 3339 format, UTC.)
- Examples:
-
- - &from=2018-11-01T00:00:00.000
- - &from=2018-11-01
-
metrics: Types of statistics data.
Possible values:
@@ -279,15 +272,8 @@ def get_resource_usage_aggregated(
to: End of the requested time period (ISO 8601/RFC 3339 format, UTC.)
- Examples:
-
- - &to=2018-11-01T00:00:00.000
- - &to=2018-11-01
-
- countries: Names of countries for which data is displayed.
-
- English short name from [ISO 3166 standard][1] without the definite article
- "the" should be used.
+ countries: Names of countries for which data should be displayed. English short name from
+ [ISO 3166 standard][1] without the definite article ("the") should be used.
[1]: https://www.iso.org/obp/ui/#search/code/
@@ -295,7 +281,7 @@ def get_resource_usage_aggregated(
- &countries=france&countries=denmark
- flat: The waу the parameters are arranged in the response.
+ flat: The way the parameters are arranged in the response.
Possible values:
@@ -309,7 +295,9 @@ def get_resource_usage_aggregated(
- **resource** – Data is grouped by CDN resources IDs.
- **region** – Data is grouped by regions of CDN edge servers.
- **country** – Data is grouped by countries of CDN edge servers.
- - **vhost** – Data is grouped by resources CNAME.
+ - **vhost** – Data is grouped by resources CNAMEs.
+ - **`client_country`** - Data is grouped by countries, based on end-users'
+ location.
To request multiple values, use:
@@ -329,7 +317,7 @@ def get_resource_usage_aggregated(
- **africa** - Africa
- **sa** - South America
- resource: CDN resources IDs by which statistics data is grouped.
+ resource: CDN resources IDs by that statistics data is grouped.
To request multiple values, use:
@@ -472,6 +460,8 @@ def get_resource_usage_series(
- **region** – Data is grouped by regions of CDN edge servers.
- **country** – Data is grouped by countries of CDN edge servers.
- **vhost** – Data is grouped by resources CNAMEs.
+ - **`client_country`** - Data is grouped by countries, based on end-users'
+ location.
To request multiple values, use:
@@ -491,12 +481,15 @@ def get_resource_usage_series(
- **africa** - Africa
- **sa** - South America
- resource: CDN resource IDs.
+ resource: CDN resources IDs by that statistics data is grouped.
To request multiple values, use:
- &resource=1&resource=2
+ If CDN resource ID is not specified, data related to all CDN resources is
+ returned.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -555,7 +548,7 @@ def get_shield_usage_aggregated(
to: End of the requested time period (ISO 8601/RFC 3339 format, UTC.)
- flat: The waу parameters are arranged in the response.
+ flat: The way the parameters are arranged in the response.
Possible values:
@@ -566,7 +559,7 @@ def get_shield_usage_aggregated(
Possible value:
- - **resource** - Data is grouped by CDN resource.
+ - **resource** - Data is grouped by CDN resources.
resource: CDN resources IDs by that statistics data is grouped.
@@ -574,6 +567,9 @@ def get_shield_usage_aggregated(
- &resource=1&resource=2
+ If CDN resource ID is not specified, data related to all CDN resources is
+ returned.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -632,6 +628,9 @@ def get_shield_usage_series(
- &resource=1&resource=2
+ If CDN resource ID is not specified, data related to all CDN resources is
+ returned.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -705,7 +704,7 @@ async def get_logs_usage_aggregated(
to: End of the requested time period (ISO 8601/RFC 3339 format, UTC.)
- flat: The waу parameters are arranged in the response.
+ flat: The way the parameters are arranged in the response.
Possible values:
@@ -724,6 +723,9 @@ async def get_logs_usage_aggregated(
- &resource=1&resource=2
+ If CDN resource ID is not specified, data related to all CDN resources is
+ returned.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -774,22 +776,17 @@ async def get_logs_usage_series(
Args:
from_: Beginning of the requested time period (ISO 8601/RFC 3339 format, UTC.)
- Example:
-
- - &from=2020-01-01T00:00:00.000
-
to: End of the requested time period (ISO 8601/RFC 3339 format, UTC.)
- Example:
-
- - &from=2020-01-01T00:00:00.000
-
resource: CDN resources IDs by that statistics data is grouped.
To request multiple values, use:
- &resource=1&resource=2
+ If CDN resource ID is not specified, data related to all CDN resources is
+ returned.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -846,11 +843,6 @@ async def get_resource_usage_aggregated(
Args:
from_: Beginning of the requested time period (ISO 8601/RFC 3339 format, UTC.)
- Examples:
-
- - &from=2018-11-01T00:00:00.000
- - &from=2018-11-01
-
metrics: Types of statistics data.
Possible values:
@@ -907,15 +899,8 @@ async def get_resource_usage_aggregated(
to: End of the requested time period (ISO 8601/RFC 3339 format, UTC.)
- Examples:
-
- - &to=2018-11-01T00:00:00.000
- - &to=2018-11-01
-
- countries: Names of countries for which data is displayed.
-
- English short name from [ISO 3166 standard][1] without the definite article
- "the" should be used.
+ countries: Names of countries for which data should be displayed. English short name from
+ [ISO 3166 standard][1] without the definite article ("the") should be used.
[1]: https://www.iso.org/obp/ui/#search/code/
@@ -923,7 +908,7 @@ async def get_resource_usage_aggregated(
- &countries=france&countries=denmark
- flat: The waу the parameters are arranged in the response.
+ flat: The way the parameters are arranged in the response.
Possible values:
@@ -937,7 +922,9 @@ async def get_resource_usage_aggregated(
- **resource** – Data is grouped by CDN resources IDs.
- **region** – Data is grouped by regions of CDN edge servers.
- **country** – Data is grouped by countries of CDN edge servers.
- - **vhost** – Data is grouped by resources CNAME.
+ - **vhost** – Data is grouped by resources CNAMEs.
+ - **`client_country`** - Data is grouped by countries, based on end-users'
+ location.
To request multiple values, use:
@@ -957,7 +944,7 @@ async def get_resource_usage_aggregated(
- **africa** - Africa
- **sa** - South America
- resource: CDN resources IDs by which statistics data is grouped.
+ resource: CDN resources IDs by that statistics data is grouped.
To request multiple values, use:
@@ -1100,6 +1087,8 @@ async def get_resource_usage_series(
- **region** – Data is grouped by regions of CDN edge servers.
- **country** – Data is grouped by countries of CDN edge servers.
- **vhost** – Data is grouped by resources CNAMEs.
+ - **`client_country`** - Data is grouped by countries, based on end-users'
+ location.
To request multiple values, use:
@@ -1119,12 +1108,15 @@ async def get_resource_usage_series(
- **africa** - Africa
- **sa** - South America
- resource: CDN resource IDs.
+ resource: CDN resources IDs by that statistics data is grouped.
To request multiple values, use:
- &resource=1&resource=2
+ If CDN resource ID is not specified, data related to all CDN resources is
+ returned.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1183,7 +1175,7 @@ async def get_shield_usage_aggregated(
to: End of the requested time period (ISO 8601/RFC 3339 format, UTC.)
- flat: The waу parameters are arranged in the response.
+ flat: The way the parameters are arranged in the response.
Possible values:
@@ -1194,7 +1186,7 @@ async def get_shield_usage_aggregated(
Possible value:
- - **resource** - Data is grouped by CDN resource.
+ - **resource** - Data is grouped by CDN resources.
resource: CDN resources IDs by that statistics data is grouped.
@@ -1202,6 +1194,9 @@ async def get_shield_usage_aggregated(
- &resource=1&resource=2
+ If CDN resource ID is not specified, data related to all CDN resources is
+ returned.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1260,6 +1255,9 @@ async def get_shield_usage_series(
- &resource=1&resource=2
+ If CDN resource ID is not specified, data related to all CDN resources is
+ returned.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
diff --git a/src/gcore/resources/cloud/quotas/requests.py b/src/gcore/resources/cloud/quotas/requests.py
index 6857110a..5d778e27 100644
--- a/src/gcore/resources/cloud/quotas/requests.py
+++ b/src/gcore/resources/cloud/quotas/requests.py
@@ -51,7 +51,6 @@ def create(
*,
description: str,
requested_limits: request_create_params.RequestedLimits,
- client_id: int | Omit = omit,
# 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,
@@ -67,8 +66,6 @@ def create(
requested_limits: Limits you want to increase.
- client_id: Client ID that requests the limit increase.
-
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -84,7 +81,6 @@ def create(
{
"description": description,
"requested_limits": requested_limits,
- "client_id": client_id,
},
request_create_params.RequestCreateParams,
),
@@ -239,7 +235,6 @@ async def create(
*,
description: str,
requested_limits: request_create_params.RequestedLimits,
- client_id: int | Omit = omit,
# 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,
@@ -255,8 +250,6 @@ async def create(
requested_limits: Limits you want to increase.
- client_id: Client ID that requests the limit increase.
-
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -272,7 +265,6 @@ async def create(
{
"description": description,
"requested_limits": requested_limits,
- "client_id": client_id,
},
request_create_params.RequestCreateParams,
),
diff --git a/src/gcore/types/cdn/__init__.py b/src/gcore/types/cdn/__init__.py
index ebb15cf3..8cd6fefc 100644
--- a/src/gcore/types/cdn/__init__.py
+++ b/src/gcore/types/cdn/__init__.py
@@ -30,6 +30,7 @@
from .cdn_audit_log_entry import CdnAuditLogEntry as CdnAuditLogEntry
from .log_download_params import LogDownloadParams as LogDownloadParams
from .public_network_list import PublicNetworkList as PublicNetworkList
+from .ip_range_list_params import IPRangeListParams as IPRangeListParams
from .resource_list_params import ResourceListParams as ResourceListParams
from .resource_usage_stats import ResourceUsageStats as ResourceUsageStats
from .shield_list_response import ShieldListResponse as ShieldListResponse
@@ -42,6 +43,7 @@
from .certificate_list_params import CertificateListParams as CertificateListParams
from .resource_replace_params import ResourceReplaceParams as ResourceReplaceParams
from .shield_aggregated_stats import ShieldAggregatedStats as ShieldAggregatedStats
+from .ip_range_list_ips_params import IPRangeListIPsParams as IPRangeListIPsParams
from .logs_uploader_validation import LogsUploaderValidation as LogsUploaderValidation
from .origin_group_list_params import OriginGroupListParams as OriginGroupListParams
from .resource_prefetch_params import ResourcePrefetchParams as ResourcePrefetchParams
diff --git a/src/gcore/types/cdn/ip_range_list_ips_params.py b/src/gcore/types/cdn/ip_range_list_ips_params.py
new file mode 100644
index 00000000..f10f642c
--- /dev/null
+++ b/src/gcore/types/cdn/ip_range_list_ips_params.py
@@ -0,0 +1,19 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, Annotated, TypedDict
+
+from ..._utils import PropertyInfo
+
+__all__ = ["IPRangeListIPsParams"]
+
+
+class IPRangeListIPsParams(TypedDict, total=False):
+ format: Literal["json", "plain"]
+ """
+ Optional format override. When set, this takes precedence over the `Accept`
+ header.
+ """
+
+ accept: Annotated[Literal["application/json", "text/plain"], PropertyInfo(alias="Accept")]
diff --git a/src/gcore/types/cdn/ip_range_list_params.py b/src/gcore/types/cdn/ip_range_list_params.py
new file mode 100644
index 00000000..2de60645
--- /dev/null
+++ b/src/gcore/types/cdn/ip_range_list_params.py
@@ -0,0 +1,19 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, Annotated, TypedDict
+
+from ..._utils import PropertyInfo
+
+__all__ = ["IPRangeListParams"]
+
+
+class IPRangeListParams(TypedDict, total=False):
+ format: Literal["json", "plain"]
+ """
+ Optional format override. When set, this takes precedence over the `Accept`
+ header.
+ """
+
+ accept: Annotated[Literal["application/json", "text/plain"], PropertyInfo(alias="Accept")]
diff --git a/src/gcore/types/cdn/resource_usage_stats.py b/src/gcore/types/cdn/resource_usage_stats.py
index 7a6f6255..93e1fea7 100644
--- a/src/gcore/types/cdn/resource_usage_stats.py
+++ b/src/gcore/types/cdn/resource_usage_stats.py
@@ -28,7 +28,7 @@ class ResourceUsageStats(BaseModel):
Possible values:
- **`upstream_bytes`** – Traffic in bytes from an origin server to CDN servers
- or to origin shielding, if used.
+ or to origin shielding when used.
- **`sent_bytes`** – Traffic in bytes from CDN servers to clients.
- **`shield_bytes`** – Traffic in bytes from origin shielding to CDN servers.
- **`backblaze_bytes`** - Traffic in bytes from Backblaze origin.
@@ -45,39 +45,40 @@ class ResourceUsageStats(BaseModel):
- **`response_types`** – Statistics by content type. It returns a number of
responses for content with different MIME types.
- **`cache_hit_traffic_ratio`** – Formula: 1 - `upstream_bytes` / `sent_bytes`.
- We deduct the non-cached traffic from the total traffic value.
- - **`cache_hit_requests_ratio`** – Share of sending cached content. Formula:
- `responses_hit` / requests.
- - **`shield_traffic_ratio`** – Origin shielding efficiency: how much more
- traffic is sent from the origin shielding than from the origin. Formula:
- (`shield_bytes` - `upstream_bytes`) / `shield_bytes`.
+ We deduct the non-cached traffic from the total traffic amount.
+ - **`cache_hit_requests_ratio`** – Formula: `responses_hit` / requests. The
+ share of sending cached content.
+ - **`shield_traffic_ratio`** – Formula: (`shield_bytes` - `upstream_bytes`) /
+ `shield_bytes`. The efficiency of the Origin Shielding: how much more traffic
+ is sent from the Origin Shielding than from the origin.
- **`image_processed`** - Number of images transformed on the Image optimization
service.
- **`request_time`** - Time elapsed between the first bytes of a request were
processed and logging after the last bytes were sent to a user.
- **`upstream_response_time`** - Number of milliseconds it took to receive a
response from an origin. If upstream `response_time_` contains several
- indications for one request (when there is more than one origin,) we summarize
- them. When aggregating several queries, the average is calculated.
+ indications for one request (in case of more than 1 origin), we summarize
+ them. In case of aggregating several queries, the average of this amount is
+ calculated.
Metrics **`upstream_response_time`** and **`request_time`** should be requested
separately from other metrics
"""
region: Optional[object] = None
- """Locations (regions) by which the data is grouped.
+ """Regions for which data is displayed.
Possible values:
+ - **na** – North America
+ - **eu** – Europe
+ - **cis** – Commonwealth of Independent States
- **asia** – Asia
- **au** – Australia
- - **cis** – CIS (Commonwealth of Independent States)
- - **eu** – Europe
- **latam** – Latin America
- **me** – Middle East
- - **na** – North America
- - **africa** – Africa
- - **sa** – South America
+ - **africa** - Africa
+ - **sa** - South America
"""
resource: Optional[object] = None
diff --git a/src/gcore/types/cdn/statistic_get_logs_usage_aggregated_params.py b/src/gcore/types/cdn/statistic_get_logs_usage_aggregated_params.py
index a1a50799..e5dff95c 100644
--- a/src/gcore/types/cdn/statistic_get_logs_usage_aggregated_params.py
+++ b/src/gcore/types/cdn/statistic_get_logs_usage_aggregated_params.py
@@ -17,7 +17,7 @@ class StatisticGetLogsUsageAggregatedParams(TypedDict, total=False):
"""End of the requested time period (ISO 8601/RFC 3339 format, UTC.)"""
flat: bool
- """The waу parameters are arranged in the response.
+ """The way the parameters are arranged in the response.
Possible values:
@@ -39,4 +39,7 @@ class StatisticGetLogsUsageAggregatedParams(TypedDict, total=False):
To request multiple values, use:
- &resource=1&resource=2
+
+ If CDN resource ID is not specified, data related to all CDN resources is
+ returned.
"""
diff --git a/src/gcore/types/cdn/statistic_get_logs_usage_series_params.py b/src/gcore/types/cdn/statistic_get_logs_usage_series_params.py
index 634f818e..400835af 100644
--- a/src/gcore/types/cdn/statistic_get_logs_usage_series_params.py
+++ b/src/gcore/types/cdn/statistic_get_logs_usage_series_params.py
@@ -11,20 +11,10 @@
class StatisticGetLogsUsageSeriesParams(TypedDict, total=False):
from_: Required[Annotated[str, PropertyInfo(alias="from")]]
- """Beginning of the requested time period (ISO 8601/RFC 3339 format, UTC.)
-
- Example:
-
- - &from=2020-01-01T00:00:00.000
- """
+ """Beginning of the requested time period (ISO 8601/RFC 3339 format, UTC.)"""
to: Required[str]
- """End of the requested time period (ISO 8601/RFC 3339 format, UTC.)
-
- Example:
-
- - &from=2020-01-01T00:00:00.000
- """
+ """End of the requested time period (ISO 8601/RFC 3339 format, UTC.)"""
resource: int
"""CDN resources IDs by that statistics data is grouped.
@@ -32,4 +22,7 @@ class StatisticGetLogsUsageSeriesParams(TypedDict, total=False):
To request multiple values, use:
- &resource=1&resource=2
+
+ If CDN resource ID is not specified, data related to all CDN resources is
+ returned.
"""
diff --git a/src/gcore/types/cdn/statistic_get_resource_usage_aggregated_params.py b/src/gcore/types/cdn/statistic_get_resource_usage_aggregated_params.py
index 9518ebe1..ccf15dac 100644
--- a/src/gcore/types/cdn/statistic_get_resource_usage_aggregated_params.py
+++ b/src/gcore/types/cdn/statistic_get_resource_usage_aggregated_params.py
@@ -11,13 +11,7 @@
class StatisticGetResourceUsageAggregatedParams(TypedDict, total=False):
from_: Required[Annotated[str, PropertyInfo(alias="from")]]
- """Beginning of the requested time period (ISO 8601/RFC 3339 format, UTC.)
-
- Examples:
-
- - &from=2018-11-01T00:00:00.000
- - &from=2018-11-01
- """
+ """Beginning of the requested time period (ISO 8601/RFC 3339 format, UTC.)"""
metrics: Required[str]
"""Types of statistics data.
@@ -78,19 +72,12 @@ class StatisticGetResourceUsageAggregatedParams(TypedDict, total=False):
"""
to: Required[str]
- """End of the requested time period (ISO 8601/RFC 3339 format, UTC.)
-
- Examples:
-
- - &to=2018-11-01T00:00:00.000
- - &to=2018-11-01
- """
+ """End of the requested time period (ISO 8601/RFC 3339 format, UTC.)"""
countries: str
- """Names of countries for which data is displayed.
-
- English short name from [ISO 3166 standard][1] without the definite article
- "the" should be used.
+ """
+ Names of countries for which data should be displayed. English short name from
+ [ISO 3166 standard][1] without the definite article ("the") should be used.
[1]: https://www.iso.org/obp/ui/#search/code/
@@ -100,7 +87,7 @@ class StatisticGetResourceUsageAggregatedParams(TypedDict, total=False):
"""
flat: bool
- """The waу the parameters are arranged in the response.
+ """The way the parameters are arranged in the response.
Possible values:
@@ -116,7 +103,9 @@ class StatisticGetResourceUsageAggregatedParams(TypedDict, total=False):
- **resource** – Data is grouped by CDN resources IDs.
- **region** – Data is grouped by regions of CDN edge servers.
- **country** – Data is grouped by countries of CDN edge servers.
- - **vhost** – Data is grouped by resources CNAME.
+ - **vhost** – Data is grouped by resources CNAMEs.
+ - **`client_country`** - Data is grouped by countries, based on end-users'
+ location.
To request multiple values, use:
@@ -140,7 +129,7 @@ class StatisticGetResourceUsageAggregatedParams(TypedDict, total=False):
"""
resource: int
- """CDN resources IDs by which statistics data is grouped.
+ """CDN resources IDs by that statistics data is grouped.
To request multiple values, use:
diff --git a/src/gcore/types/cdn/statistic_get_resource_usage_series_params.py b/src/gcore/types/cdn/statistic_get_resource_usage_series_params.py
index e830094f..27b963f5 100644
--- a/src/gcore/types/cdn/statistic_get_resource_usage_series_params.py
+++ b/src/gcore/types/cdn/statistic_get_resource_usage_series_params.py
@@ -100,6 +100,8 @@ class StatisticGetResourceUsageSeriesParams(TypedDict, total=False):
- **region** – Data is grouped by regions of CDN edge servers.
- **country** – Data is grouped by countries of CDN edge servers.
- **vhost** – Data is grouped by resources CNAMEs.
+ - **`client_country`** - Data is grouped by countries, based on end-users'
+ location.
To request multiple values, use:
@@ -123,9 +125,12 @@ class StatisticGetResourceUsageSeriesParams(TypedDict, total=False):
"""
resource: int
- """CDN resource IDs.
+ """CDN resources IDs by that statistics data is grouped.
To request multiple values, use:
- &resource=1&resource=2
+
+ If CDN resource ID is not specified, data related to all CDN resources is
+ returned.
"""
diff --git a/src/gcore/types/cdn/statistic_get_shield_usage_aggregated_params.py b/src/gcore/types/cdn/statistic_get_shield_usage_aggregated_params.py
index eff1d4f0..f40579b7 100644
--- a/src/gcore/types/cdn/statistic_get_shield_usage_aggregated_params.py
+++ b/src/gcore/types/cdn/statistic_get_shield_usage_aggregated_params.py
@@ -17,7 +17,7 @@ class StatisticGetShieldUsageAggregatedParams(TypedDict, total=False):
"""End of the requested time period (ISO 8601/RFC 3339 format, UTC.)"""
flat: bool
- """The waу parameters are arranged in the response.
+ """The way the parameters are arranged in the response.
Possible values:
@@ -30,7 +30,7 @@ class StatisticGetShieldUsageAggregatedParams(TypedDict, total=False):
Possible value:
- - **resource** - Data is grouped by CDN resource.
+ - **resource** - Data is grouped by CDN resources.
"""
resource: int
@@ -39,4 +39,7 @@ class StatisticGetShieldUsageAggregatedParams(TypedDict, total=False):
To request multiple values, use:
- &resource=1&resource=2
+
+ If CDN resource ID is not specified, data related to all CDN resources is
+ returned.
"""
diff --git a/src/gcore/types/cdn/statistic_get_shield_usage_series_params.py b/src/gcore/types/cdn/statistic_get_shield_usage_series_params.py
index 2b0e1a38..3ba5ad5a 100644
--- a/src/gcore/types/cdn/statistic_get_shield_usage_series_params.py
+++ b/src/gcore/types/cdn/statistic_get_shield_usage_series_params.py
@@ -22,4 +22,7 @@ class StatisticGetShieldUsageSeriesParams(TypedDict, total=False):
To request multiple values, use:
- &resource=1&resource=2
+
+ If CDN resource ID is not specified, data related to all CDN resources is
+ returned.
"""
diff --git a/src/gcore/types/cloud/quotas/request_create_params.py b/src/gcore/types/cloud/quotas/request_create_params.py
index 282e29ad..8732cde2 100644
--- a/src/gcore/types/cloud/quotas/request_create_params.py
+++ b/src/gcore/types/cloud/quotas/request_create_params.py
@@ -15,9 +15,6 @@ class RequestCreateParams(TypedDict, total=False):
requested_limits: Required[RequestedLimits]
"""Limits you want to increase."""
- client_id: int
- """Client ID that requests the limit increase."""
-
class RequestedLimitsGlobalLimits(TypedDict, total=False):
inference_cpu_millicore_count_limit: int
diff --git a/src/gcore/types/cloud/security_group.py b/src/gcore/types/cloud/security_group.py
index 7407daad..412b43d5 100644
--- a/src/gcore/types/cloud/security_group.py
+++ b/src/gcore/types/cloud/security_group.py
@@ -33,7 +33,14 @@ class SecurityGroup(BaseModel):
"""The number of revisions"""
tags_v2: List[Tag]
- """Tags for a security group"""
+ """List of key-value tags associated with the resource.
+
+ A tag is a key-value pair that can be associated with a resource, enabling
+ efficient filtering and grouping for better organization and management. Some
+ tags are read-only and cannot be modified by the user. Tags are also integrated
+ with cost reports, allowing cost data to be filtered based on tag keys or
+ values.
+ """
updated_at: datetime
"""Datetime when the security group was last updated"""
diff --git a/tests/api_resources/cdn/test_ip_ranges.py b/tests/api_resources/cdn/test_ip_ranges.py
index c9bbdb5e..b4967cd6 100644
--- a/tests/api_resources/cdn/test_ip_ranges.py
+++ b/tests/api_resources/cdn/test_ip_ranges.py
@@ -22,6 +22,14 @@ def test_method_list(self, client: Gcore) -> None:
ip_range = client.cdn.ip_ranges.list()
assert_matches_type(PublicNetworkList, ip_range, path=["response"])
+ @parametrize
+ def test_method_list_with_all_params(self, client: Gcore) -> None:
+ ip_range = client.cdn.ip_ranges.list(
+ format="json",
+ accept="application/json",
+ )
+ assert_matches_type(PublicNetworkList, ip_range, path=["response"])
+
@parametrize
def test_raw_response_list(self, client: Gcore) -> None:
response = client.cdn.ip_ranges.with_raw_response.list()
@@ -47,6 +55,14 @@ def test_method_list_ips(self, client: Gcore) -> None:
ip_range = client.cdn.ip_ranges.list_ips()
assert_matches_type(PublicIPList, ip_range, path=["response"])
+ @parametrize
+ def test_method_list_ips_with_all_params(self, client: Gcore) -> None:
+ ip_range = client.cdn.ip_ranges.list_ips(
+ format="json",
+ accept="application/json",
+ )
+ assert_matches_type(PublicIPList, ip_range, path=["response"])
+
@parametrize
def test_raw_response_list_ips(self, client: Gcore) -> None:
response = client.cdn.ip_ranges.with_raw_response.list_ips()
@@ -78,6 +94,14 @@ async def test_method_list(self, async_client: AsyncGcore) -> None:
ip_range = await async_client.cdn.ip_ranges.list()
assert_matches_type(PublicNetworkList, ip_range, path=["response"])
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> None:
+ ip_range = await async_client.cdn.ip_ranges.list(
+ format="json",
+ accept="application/json",
+ )
+ assert_matches_type(PublicNetworkList, ip_range, path=["response"])
+
@parametrize
async def test_raw_response_list(self, async_client: AsyncGcore) -> None:
response = await async_client.cdn.ip_ranges.with_raw_response.list()
@@ -103,6 +127,14 @@ async def test_method_list_ips(self, async_client: AsyncGcore) -> None:
ip_range = await async_client.cdn.ip_ranges.list_ips()
assert_matches_type(PublicIPList, ip_range, path=["response"])
+ @parametrize
+ async def test_method_list_ips_with_all_params(self, async_client: AsyncGcore) -> None:
+ ip_range = await async_client.cdn.ip_ranges.list_ips(
+ format="json",
+ accept="application/json",
+ )
+ assert_matches_type(PublicIPList, ip_range, path=["response"])
+
@parametrize
async def test_raw_response_list_ips(self, async_client: AsyncGcore) -> None:
response = await async_client.cdn.ip_ranges.with_raw_response.list_ips()
diff --git a/tests/api_resources/cloud/quotas/test_requests.py b/tests/api_resources/cloud/quotas/test_requests.py
index 9b2b7487..3c7152a1 100644
--- a/tests/api_resources/cloud/quotas/test_requests.py
+++ b/tests/api_resources/cloud/quotas/test_requests.py
@@ -97,7 +97,6 @@ def test_method_create_with_all_params(self, client: Gcore) -> None:
}
],
},
- client_id=1,
)
assert request is None
@@ -308,7 +307,6 @@ async def test_method_create_with_all_params(self, async_client: AsyncGcore) ->
}
],
},
- client_id=1,
)
assert request is None
From 434bf068d53bb1cf34329710f484b6873ed457a0 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 22 Oct 2025 09:44:53 +0000
Subject: [PATCH 02/27] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index c8537dbe..e310623d 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 609
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-593c5e99888d61f0b89a96221b71679316ae326fe0bf7468d93a3f4d73d06e8c.yml
-openapi_spec_hash: cfd6560b017a4ff1d003e335b739f2f3
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-f1aa5e69e579d8ef50ab8dbc55b74e312029a61a8764dd5eb6b71d186f31ffc4.yml
+openapi_spec_hash: 79d6c39952e4e8ef5a10705031cc88af
config_hash: bb4a27712c30f7a2b52e1f3b31766f24
From 203e4ba94f655ae11fae8ed32611f6291f2acaf1 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 22 Oct 2025 13:41:14 +0000
Subject: [PATCH 03/27] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index e310623d..20191264 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 609
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-f1aa5e69e579d8ef50ab8dbc55b74e312029a61a8764dd5eb6b71d186f31ffc4.yml
-openapi_spec_hash: 79d6c39952e4e8ef5a10705031cc88af
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-7f43b28f5f3787d90ad3097b603d78732c31602963a0706e9d3faab773ffe35a.yml
+openapi_spec_hash: d3684a66988042fe56ddad6fea6a0373
config_hash: bb4a27712c30f7a2b52e1f3b31766f24
From 4dc12a7f67f12022e019ff0305697d4e91dbef51 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 22 Oct 2025 15:12:26 +0000
Subject: [PATCH 04/27] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 20191264..4e936b75 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 609
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-7f43b28f5f3787d90ad3097b603d78732c31602963a0706e9d3faab773ffe35a.yml
-openapi_spec_hash: d3684a66988042fe56ddad6fea6a0373
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-926c452d13564ca1a0c7a5f6d4596d9ae2f0b62087bfe0f3229eae1e76cb9a86.yml
+openapi_spec_hash: a887cd2beb7fe136a63a14ad3508462b
config_hash: bb4a27712c30f7a2b52e1f3b31766f24
From a281b357bb9f765e5a12d1beedd1eb703d71b13f Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 23 Oct 2025 07:22:39 +0000
Subject: [PATCH 05/27] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 4e936b75..dab5821b 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 609
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-926c452d13564ca1a0c7a5f6d4596d9ae2f0b62087bfe0f3229eae1e76cb9a86.yml
-openapi_spec_hash: a887cd2beb7fe136a63a14ad3508462b
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-f7fe3d141383d9367eea75565a3dae94897e44354066b110db09dacf0f581187.yml
+openapi_spec_hash: f710af685b8aa4d0f7962a77fd13ee40
config_hash: bb4a27712c30f7a2b52e1f3b31766f24
From 05ac34fc31ea3bff2a5db5f0cce753c8d0fa2ba2 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 24 Oct 2025 07:50:27 +0000
Subject: [PATCH 06/27] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index dab5821b..de0ab459 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 609
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-f7fe3d141383d9367eea75565a3dae94897e44354066b110db09dacf0f581187.yml
-openapi_spec_hash: f710af685b8aa4d0f7962a77fd13ee40
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-99fc33842c158346e3b39e07fc0cef0151a5fe60c003494d60d73e3e1221d083.yml
+openapi_spec_hash: 0a9e2bf938e4490d06959e14b65f3ab0
config_hash: bb4a27712c30f7a2b52e1f3b31766f24
From 25247c75001ac77c3f1c25da38ec57cd394ec5e6 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 24 Oct 2025 08:22:47 +0000
Subject: [PATCH 07/27] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index de0ab459..78cae3bd 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 609
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-99fc33842c158346e3b39e07fc0cef0151a5fe60c003494d60d73e3e1221d083.yml
-openapi_spec_hash: 0a9e2bf938e4490d06959e14b65f3ab0
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-286a65430a65eb4a40437fca2268857a509498373c2d8def0557e6dbd873dd41.yml
+openapi_spec_hash: 25cb371f8eacd4951b1f7f8451201e83
config_hash: bb4a27712c30f7a2b52e1f3b31766f24
From d8886ce4abeadd3d260c3f533e72b778d521482c Mon Sep 17 00:00:00 2001
From: Danil Krox
Date: Fri, 24 Oct 2025 15:30:26 +0200
Subject: [PATCH 08/27] chore(cloud): add *_and_poll() to *WithRawResponse and
*WithStreaming
---
.../resources/cloud/baremetal/servers.py | 24 ++++++++
.../gpu_baremetal_clusters.py | 36 +++++++++++
.../cloud/gpu_baremetal_clusters/images.py | 24 ++++++++
.../cloud/gpu_baremetal_clusters/servers.py | 12 ++++
.../inference/deployments/deployments.py | 36 +++++++++++
src/gcore/resources/cloud/instances/images.py | 36 +++++++++++
.../resources/cloud/instances/instances.py | 60 +++++++++++++++++++
.../load_balancers/l7_policies/l7_policies.py | 36 +++++++++++
.../cloud/load_balancers/l7_policies/rules.py | 36 +++++++++++
.../cloud/load_balancers/listeners.py | 36 +++++++++++
.../cloud/load_balancers/load_balancers.py | 48 +++++++++++++++
.../cloud/load_balancers/pools/pools.py | 36 +++++++++++
src/gcore/resources/cloud/secrets.py | 12 ++++
13 files changed, 432 insertions(+)
diff --git a/src/gcore/resources/cloud/baremetal/servers.py b/src/gcore/resources/cloud/baremetal/servers.py
index 88ca7fcc..39be2ae6 100644
--- a/src/gcore/resources/cloud/baremetal/servers.py
+++ b/src/gcore/resources/cloud/baremetal/servers.py
@@ -1022,6 +1022,12 @@ def __init__(self, servers: ServersResource) -> None:
self.rebuild = to_raw_response_wrapper(
servers.rebuild,
)
+ self.create_and_poll = to_raw_response_wrapper(
+ servers.create_and_poll,
+ )
+ self.rebuild_and_poll = to_raw_response_wrapper(
+ servers.rebuild_and_poll,
+ )
class AsyncServersResourceWithRawResponse:
@@ -1037,6 +1043,12 @@ def __init__(self, servers: AsyncServersResource) -> None:
self.rebuild = async_to_raw_response_wrapper(
servers.rebuild,
)
+ self.create_and_poll = async_to_raw_response_wrapper(
+ servers.create_and_poll,
+ )
+ self.rebuild_and_poll = async_to_raw_response_wrapper(
+ servers.rebuild_and_poll,
+ )
class ServersResourceWithStreamingResponse:
@@ -1052,6 +1064,12 @@ def __init__(self, servers: ServersResource) -> None:
self.rebuild = to_streamed_response_wrapper(
servers.rebuild,
)
+ self.create_and_poll = to_streamed_response_wrapper(
+ servers.create_and_poll,
+ )
+ self.rebuild_and_poll = to_streamed_response_wrapper(
+ servers.rebuild_and_poll,
+ )
class AsyncServersResourceWithStreamingResponse:
@@ -1067,3 +1085,9 @@ def __init__(self, servers: AsyncServersResource) -> None:
self.rebuild = async_to_streamed_response_wrapper(
servers.rebuild,
)
+ self.create_and_poll = async_to_streamed_response_wrapper(
+ servers.create_and_poll,
+ )
+ self.rebuild_and_poll = async_to_streamed_response_wrapper(
+ servers.rebuild_and_poll,
+ )
diff --git a/src/gcore/resources/cloud/gpu_baremetal_clusters/gpu_baremetal_clusters.py b/src/gcore/resources/cloud/gpu_baremetal_clusters/gpu_baremetal_clusters.py
index 932484d9..2847eea2 100644
--- a/src/gcore/resources/cloud/gpu_baremetal_clusters/gpu_baremetal_clusters.py
+++ b/src/gcore/resources/cloud/gpu_baremetal_clusters/gpu_baremetal_clusters.py
@@ -1536,6 +1536,15 @@ def __init__(self, gpu_baremetal_clusters: GPUBaremetalClustersResource) -> None
self.resize = to_raw_response_wrapper(
gpu_baremetal_clusters.resize,
)
+ self.create_and_poll = to_raw_response_wrapper(
+ gpu_baremetal_clusters.create_and_poll,
+ )
+ self.rebuild_and_poll = to_raw_response_wrapper(
+ gpu_baremetal_clusters.rebuild_and_poll,
+ )
+ self.resize_and_poll = to_raw_response_wrapper(
+ gpu_baremetal_clusters.resize_and_poll,
+ )
@cached_property
def interfaces(self) -> InterfacesResourceWithRawResponse:
@@ -1585,6 +1594,15 @@ def __init__(self, gpu_baremetal_clusters: AsyncGPUBaremetalClustersResource) ->
self.resize = async_to_raw_response_wrapper(
gpu_baremetal_clusters.resize,
)
+ self.create_and_poll = async_to_raw_response_wrapper(
+ gpu_baremetal_clusters.create_and_poll,
+ )
+ self.rebuild_and_poll = async_to_raw_response_wrapper(
+ gpu_baremetal_clusters.rebuild_and_poll,
+ )
+ self.resize_and_poll = async_to_raw_response_wrapper(
+ gpu_baremetal_clusters.resize_and_poll,
+ )
@cached_property
def interfaces(self) -> AsyncInterfacesResourceWithRawResponse:
@@ -1634,6 +1652,15 @@ def __init__(self, gpu_baremetal_clusters: GPUBaremetalClustersResource) -> None
self.resize = to_streamed_response_wrapper(
gpu_baremetal_clusters.resize,
)
+ self.create_and_poll = to_streamed_response_wrapper(
+ gpu_baremetal_clusters.create_and_poll,
+ )
+ self.rebuild_and_poll = to_streamed_response_wrapper(
+ gpu_baremetal_clusters.rebuild_and_poll,
+ )
+ self.resize_and_poll = to_streamed_response_wrapper(
+ gpu_baremetal_clusters.resize_and_poll,
+ )
@cached_property
def interfaces(self) -> InterfacesResourceWithStreamingResponse:
@@ -1683,6 +1710,15 @@ def __init__(self, gpu_baremetal_clusters: AsyncGPUBaremetalClustersResource) ->
self.resize = async_to_streamed_response_wrapper(
gpu_baremetal_clusters.resize,
)
+ self.create_and_poll = async_to_streamed_response_wrapper(
+ gpu_baremetal_clusters.create_and_poll,
+ )
+ self.rebuild_and_poll = async_to_streamed_response_wrapper(
+ gpu_baremetal_clusters.rebuild_and_poll,
+ )
+ self.resize_and_poll = async_to_streamed_response_wrapper(
+ gpu_baremetal_clusters.resize_and_poll,
+ )
@cached_property
def interfaces(self) -> AsyncInterfacesResourceWithStreamingResponse:
diff --git a/src/gcore/resources/cloud/gpu_baremetal_clusters/images.py b/src/gcore/resources/cloud/gpu_baremetal_clusters/images.py
index fe8c6f81..036a98d9 100644
--- a/src/gcore/resources/cloud/gpu_baremetal_clusters/images.py
+++ b/src/gcore/resources/cloud/gpu_baremetal_clusters/images.py
@@ -736,6 +736,12 @@ def __init__(self, images: ImagesResource) -> None:
self.upload = to_raw_response_wrapper(
images.upload,
)
+ self.delete_and_poll = to_raw_response_wrapper(
+ images.delete_and_poll,
+ )
+ self.upload_and_poll = to_raw_response_wrapper(
+ images.upload_and_poll,
+ )
class AsyncImagesResourceWithRawResponse:
@@ -754,6 +760,12 @@ def __init__(self, images: AsyncImagesResource) -> None:
self.upload = async_to_raw_response_wrapper(
images.upload,
)
+ self.delete_and_poll = async_to_raw_response_wrapper(
+ images.delete_and_poll,
+ )
+ self.upload_and_poll = async_to_raw_response_wrapper(
+ images.upload_and_poll,
+ )
class ImagesResourceWithStreamingResponse:
@@ -772,6 +784,12 @@ def __init__(self, images: ImagesResource) -> None:
self.upload = to_streamed_response_wrapper(
images.upload,
)
+ self.delete_and_poll = to_streamed_response_wrapper(
+ images.delete_and_poll,
+ )
+ self.upload_and_poll = to_streamed_response_wrapper(
+ images.upload_and_poll,
+ )
class AsyncImagesResourceWithStreamingResponse:
@@ -790,3 +808,9 @@ def __init__(self, images: AsyncImagesResource) -> None:
self.upload = async_to_streamed_response_wrapper(
images.upload,
)
+ self.delete_and_poll = async_to_streamed_response_wrapper(
+ images.delete_and_poll,
+ )
+ self.upload_and_poll = async_to_streamed_response_wrapper(
+ images.upload_and_poll,
+ )
diff --git a/src/gcore/resources/cloud/gpu_baremetal_clusters/servers.py b/src/gcore/resources/cloud/gpu_baremetal_clusters/servers.py
index f2771dff..0394a1b1 100644
--- a/src/gcore/resources/cloud/gpu_baremetal_clusters/servers.py
+++ b/src/gcore/resources/cloud/gpu_baremetal_clusters/servers.py
@@ -1355,6 +1355,9 @@ def __init__(self, servers: ServersResource) -> None:
self.reboot = to_raw_response_wrapper(
servers.reboot,
)
+ self.delete_and_poll = to_raw_response_wrapper(
+ servers.delete_and_poll,
+ )
class AsyncServersResourceWithRawResponse:
@@ -1382,6 +1385,9 @@ def __init__(self, servers: AsyncServersResource) -> None:
self.reboot = async_to_raw_response_wrapper(
servers.reboot,
)
+ self.delete_and_poll = async_to_raw_response_wrapper(
+ servers.delete_and_poll,
+ )
class ServersResourceWithStreamingResponse:
@@ -1409,6 +1415,9 @@ def __init__(self, servers: ServersResource) -> None:
self.reboot = to_streamed_response_wrapper(
servers.reboot,
)
+ self.delete_and_poll = to_streamed_response_wrapper(
+ servers.delete_and_poll,
+ )
class AsyncServersResourceWithStreamingResponse:
@@ -1436,3 +1445,6 @@ def __init__(self, servers: AsyncServersResource) -> None:
self.reboot = async_to_streamed_response_wrapper(
servers.reboot,
)
+ self.delete_and_poll = async_to_streamed_response_wrapper(
+ servers.delete_and_poll,
+ )
diff --git a/src/gcore/resources/cloud/inference/deployments/deployments.py b/src/gcore/resources/cloud/inference/deployments/deployments.py
index bc7b8132..cecda529 100644
--- a/src/gcore/resources/cloud/inference/deployments/deployments.py
+++ b/src/gcore/resources/cloud/inference/deployments/deployments.py
@@ -1463,6 +1463,15 @@ def __init__(self, deployments: DeploymentsResource) -> None:
self.stop = to_raw_response_wrapper(
deployments.stop,
)
+ self.create_and_poll = to_raw_response_wrapper(
+ deployments.create_and_poll,
+ )
+ self.update_and_poll = to_raw_response_wrapper(
+ deployments.update_and_poll,
+ )
+ self.delete_and_poll = to_raw_response_wrapper(
+ deployments.delete_and_poll,
+ )
@cached_property
def logs(self) -> LogsResourceWithRawResponse:
@@ -1499,6 +1508,15 @@ def __init__(self, deployments: AsyncDeploymentsResource) -> None:
self.stop = async_to_raw_response_wrapper(
deployments.stop,
)
+ self.create_and_poll = async_to_raw_response_wrapper(
+ deployments.create_and_poll,
+ )
+ self.update_and_poll = async_to_raw_response_wrapper(
+ deployments.update_and_poll,
+ )
+ self.delete_and_poll = async_to_raw_response_wrapper(
+ deployments.delete_and_poll,
+ )
@cached_property
def logs(self) -> AsyncLogsResourceWithRawResponse:
@@ -1535,6 +1553,15 @@ def __init__(self, deployments: DeploymentsResource) -> None:
self.stop = to_streamed_response_wrapper(
deployments.stop,
)
+ self.create_and_poll = to_streamed_response_wrapper(
+ deployments.create_and_poll,
+ )
+ self.update_and_poll = to_streamed_response_wrapper(
+ deployments.update_and_poll,
+ )
+ self.delete_and_poll = to_streamed_response_wrapper(
+ deployments.delete_and_poll,
+ )
@cached_property
def logs(self) -> LogsResourceWithStreamingResponse:
@@ -1571,6 +1598,15 @@ def __init__(self, deployments: AsyncDeploymentsResource) -> None:
self.stop = async_to_streamed_response_wrapper(
deployments.stop,
)
+ self.create_and_poll = async_to_streamed_response_wrapper(
+ deployments.create_and_poll,
+ )
+ self.update_and_poll = async_to_streamed_response_wrapper(
+ deployments.update_and_poll,
+ )
+ self.delete_and_poll = async_to_streamed_response_wrapper(
+ deployments.delete_and_poll,
+ )
@cached_property
def logs(self) -> AsyncLogsResourceWithStreamingResponse:
diff --git a/src/gcore/resources/cloud/instances/images.py b/src/gcore/resources/cloud/instances/images.py
index 0932052b..cb32712a 100644
--- a/src/gcore/resources/cloud/instances/images.py
+++ b/src/gcore/resources/cloud/instances/images.py
@@ -1251,6 +1251,15 @@ def __init__(self, images: ImagesResource) -> None:
self.upload = to_raw_response_wrapper(
images.upload,
)
+ self.delete_and_poll = to_raw_response_wrapper(
+ images.delete_and_poll,
+ )
+ self.create_from_volume_and_poll = to_raw_response_wrapper(
+ images.create_from_volume_and_poll,
+ )
+ self.upload_and_poll = to_raw_response_wrapper(
+ images.upload_and_poll,
+ )
class AsyncImagesResourceWithRawResponse:
@@ -1275,6 +1284,15 @@ def __init__(self, images: AsyncImagesResource) -> None:
self.upload = async_to_raw_response_wrapper(
images.upload,
)
+ self.delete_and_poll = async_to_raw_response_wrapper(
+ images.delete_and_poll,
+ )
+ self.create_from_volume_and_poll = async_to_raw_response_wrapper(
+ images.create_from_volume_and_poll,
+ )
+ self.upload_and_poll = async_to_raw_response_wrapper(
+ images.upload_and_poll,
+ )
class ImagesResourceWithStreamingResponse:
@@ -1299,6 +1317,15 @@ def __init__(self, images: ImagesResource) -> None:
self.upload = to_streamed_response_wrapper(
images.upload,
)
+ self.delete_and_poll = to_streamed_response_wrapper(
+ images.delete_and_poll,
+ )
+ self.create_from_volume_and_poll = to_streamed_response_wrapper(
+ images.create_from_volume_and_poll,
+ )
+ self.upload_and_poll = to_streamed_response_wrapper(
+ images.upload_and_poll,
+ )
class AsyncImagesResourceWithStreamingResponse:
@@ -1323,3 +1350,12 @@ def __init__(self, images: AsyncImagesResource) -> None:
self.upload = async_to_streamed_response_wrapper(
images.upload,
)
+ self.delete_and_poll = async_to_streamed_response_wrapper(
+ images.delete_and_poll,
+ )
+ self.create_from_volume_and_poll = async_to_streamed_response_wrapper(
+ images.create_from_volume_and_poll,
+ )
+ self.upload_and_poll = async_to_streamed_response_wrapper(
+ images.upload_and_poll,
+ )
diff --git a/src/gcore/resources/cloud/instances/instances.py b/src/gcore/resources/cloud/instances/instances.py
index 170ad2d9..f26959d7 100644
--- a/src/gcore/resources/cloud/instances/instances.py
+++ b/src/gcore/resources/cloud/instances/instances.py
@@ -2958,6 +2958,21 @@ def __init__(self, instances: InstancesResource) -> None:
self.unassign_security_group = to_raw_response_wrapper(
instances.unassign_security_group,
)
+ self.create_and_poll = to_raw_response_wrapper(
+ instances.create_and_poll,
+ )
+ self.delete_and_poll = to_raw_response_wrapper(
+ instances.delete_and_poll,
+ )
+ self.add_to_placement_group_and_poll = to_raw_response_wrapper(
+ instances.add_to_placement_group_and_poll,
+ )
+ self.remove_from_placement_group_and_poll = to_raw_response_wrapper(
+ instances.remove_from_placement_group_and_poll,
+ )
+ self.resize_and_poll = to_raw_response_wrapper(
+ instances.resize_and_poll,
+ )
@cached_property
def flavors(self) -> FlavorsResourceWithRawResponse:
@@ -3025,6 +3040,21 @@ def __init__(self, instances: AsyncInstancesResource) -> None:
self.unassign_security_group = async_to_raw_response_wrapper(
instances.unassign_security_group,
)
+ self.create_and_poll = async_to_raw_response_wrapper(
+ instances.create_and_poll,
+ )
+ self.delete_and_poll = async_to_raw_response_wrapper(
+ instances.delete_and_poll,
+ )
+ self.add_to_placement_group_and_poll = async_to_raw_response_wrapper(
+ instances.add_to_placement_group_and_poll,
+ )
+ self.remove_from_placement_group_and_poll = async_to_raw_response_wrapper(
+ instances.remove_from_placement_group_and_poll,
+ )
+ self.resize_and_poll = async_to_raw_response_wrapper(
+ instances.resize_and_poll,
+ )
@cached_property
def flavors(self) -> AsyncFlavorsResourceWithRawResponse:
@@ -3092,6 +3122,21 @@ def __init__(self, instances: InstancesResource) -> None:
self.unassign_security_group = to_streamed_response_wrapper(
instances.unassign_security_group,
)
+ self.create_and_poll = to_streamed_response_wrapper(
+ instances.create_and_poll,
+ )
+ self.delete_and_poll = to_streamed_response_wrapper(
+ instances.delete_and_poll,
+ )
+ self.add_to_placement_group_and_poll = to_streamed_response_wrapper(
+ instances.add_to_placement_group_and_poll,
+ )
+ self.remove_from_placement_group_and_poll = to_streamed_response_wrapper(
+ instances.remove_from_placement_group_and_poll,
+ )
+ self.resize_and_poll = to_streamed_response_wrapper(
+ instances.resize_and_poll,
+ )
@cached_property
def flavors(self) -> FlavorsResourceWithStreamingResponse:
@@ -3159,6 +3204,21 @@ def __init__(self, instances: AsyncInstancesResource) -> None:
self.unassign_security_group = async_to_streamed_response_wrapper(
instances.unassign_security_group,
)
+ self.create_and_poll = async_to_streamed_response_wrapper(
+ instances.create_and_poll,
+ )
+ self.delete_and_poll = async_to_streamed_response_wrapper(
+ instances.delete_and_poll,
+ )
+ self.add_to_placement_group_and_poll = async_to_streamed_response_wrapper(
+ instances.add_to_placement_group_and_poll,
+ )
+ self.remove_from_placement_group_and_poll = async_to_streamed_response_wrapper(
+ instances.remove_from_placement_group_and_poll,
+ )
+ self.resize_and_poll = async_to_streamed_response_wrapper(
+ instances.resize_and_poll,
+ )
@cached_property
def flavors(self) -> AsyncFlavorsResourceWithStreamingResponse:
diff --git a/src/gcore/resources/cloud/load_balancers/l7_policies/l7_policies.py b/src/gcore/resources/cloud/load_balancers/l7_policies/l7_policies.py
index 79c839a3..f4149fd3 100644
--- a/src/gcore/resources/cloud/load_balancers/l7_policies/l7_policies.py
+++ b/src/gcore/resources/cloud/load_balancers/l7_policies/l7_policies.py
@@ -958,6 +958,15 @@ def __init__(self, l7_policies: L7PoliciesResource) -> None:
self.replace = to_raw_response_wrapper(
l7_policies.replace,
)
+ self.create_and_poll = to_raw_response_wrapper(
+ l7_policies.create_and_poll,
+ )
+ self.delete_and_poll = to_raw_response_wrapper(
+ l7_policies.delete_and_poll,
+ )
+ self.replace_and_poll = to_raw_response_wrapper(
+ l7_policies.replace_and_poll,
+ )
@cached_property
def rules(self) -> RulesResourceWithRawResponse:
@@ -983,6 +992,15 @@ def __init__(self, l7_policies: AsyncL7PoliciesResource) -> None:
self.replace = async_to_raw_response_wrapper(
l7_policies.replace,
)
+ self.create_and_poll = async_to_raw_response_wrapper(
+ l7_policies.create_and_poll,
+ )
+ self.delete_and_poll = async_to_raw_response_wrapper(
+ l7_policies.delete_and_poll,
+ )
+ self.replace_and_poll = async_to_raw_response_wrapper(
+ l7_policies.replace_and_poll,
+ )
@cached_property
def rules(self) -> AsyncRulesResourceWithRawResponse:
@@ -1008,6 +1026,15 @@ def __init__(self, l7_policies: L7PoliciesResource) -> None:
self.replace = to_streamed_response_wrapper(
l7_policies.replace,
)
+ self.create_and_poll = to_streamed_response_wrapper(
+ l7_policies.create_and_poll,
+ )
+ self.delete_and_poll = to_streamed_response_wrapper(
+ l7_policies.delete_and_poll,
+ )
+ self.replace_and_poll = to_streamed_response_wrapper(
+ l7_policies.replace_and_poll,
+ )
@cached_property
def rules(self) -> RulesResourceWithStreamingResponse:
@@ -1033,6 +1060,15 @@ def __init__(self, l7_policies: AsyncL7PoliciesResource) -> None:
self.replace = async_to_streamed_response_wrapper(
l7_policies.replace,
)
+ self.create_and_poll = async_to_streamed_response_wrapper(
+ l7_policies.create_and_poll,
+ )
+ self.delete_and_poll = async_to_streamed_response_wrapper(
+ l7_policies.delete_and_poll,
+ )
+ self.replace_and_poll = async_to_streamed_response_wrapper(
+ l7_policies.replace_and_poll,
+ )
@cached_property
def rules(self) -> AsyncRulesResourceWithStreamingResponse:
diff --git a/src/gcore/resources/cloud/load_balancers/l7_policies/rules.py b/src/gcore/resources/cloud/load_balancers/l7_policies/rules.py
index c6a33549..844068db 100644
--- a/src/gcore/resources/cloud/load_balancers/l7_policies/rules.py
+++ b/src/gcore/resources/cloud/load_balancers/l7_policies/rules.py
@@ -994,6 +994,15 @@ def __init__(self, rules: RulesResource) -> None:
self.replace = to_raw_response_wrapper(
rules.replace,
)
+ self.create_and_poll = to_raw_response_wrapper(
+ rules.create_and_poll,
+ )
+ self.delete_and_poll = to_raw_response_wrapper(
+ rules.delete_and_poll,
+ )
+ self.replace_and_poll = to_raw_response_wrapper(
+ rules.replace_and_poll,
+ )
class AsyncRulesResourceWithRawResponse:
@@ -1015,6 +1024,15 @@ def __init__(self, rules: AsyncRulesResource) -> None:
self.replace = async_to_raw_response_wrapper(
rules.replace,
)
+ self.create_and_poll = async_to_raw_response_wrapper(
+ rules.create_and_poll,
+ )
+ self.delete_and_poll = async_to_raw_response_wrapper(
+ rules.delete_and_poll,
+ )
+ self.replace_and_poll = async_to_raw_response_wrapper(
+ rules.replace_and_poll,
+ )
class RulesResourceWithStreamingResponse:
@@ -1036,6 +1054,15 @@ def __init__(self, rules: RulesResource) -> None:
self.replace = to_streamed_response_wrapper(
rules.replace,
)
+ self.create_and_poll = to_streamed_response_wrapper(
+ rules.create_and_poll,
+ )
+ self.delete_and_poll = to_streamed_response_wrapper(
+ rules.delete_and_poll,
+ )
+ self.replace_and_poll = to_streamed_response_wrapper(
+ rules.replace_and_poll,
+ )
class AsyncRulesResourceWithStreamingResponse:
@@ -1057,3 +1084,12 @@ def __init__(self, rules: AsyncRulesResource) -> None:
self.replace = async_to_streamed_response_wrapper(
rules.replace,
)
+ self.create_and_poll = async_to_streamed_response_wrapper(
+ rules.create_and_poll,
+ )
+ self.delete_and_poll = async_to_streamed_response_wrapper(
+ rules.delete_and_poll,
+ )
+ self.replace_and_poll = async_to_streamed_response_wrapper(
+ rules.replace_and_poll,
+ )
diff --git a/src/gcore/resources/cloud/load_balancers/listeners.py b/src/gcore/resources/cloud/load_balancers/listeners.py
index 0a831988..da0a38a1 100644
--- a/src/gcore/resources/cloud/load_balancers/listeners.py
+++ b/src/gcore/resources/cloud/load_balancers/listeners.py
@@ -1109,6 +1109,15 @@ def __init__(self, listeners: ListenersResource) -> None:
self.get = to_raw_response_wrapper(
listeners.get,
)
+ self.create_and_poll = to_raw_response_wrapper(
+ listeners.create_and_poll,
+ )
+ self.delete_and_poll = to_raw_response_wrapper(
+ listeners.delete_and_poll,
+ )
+ self.update_and_poll = to_raw_response_wrapper(
+ listeners.update_and_poll,
+ )
class AsyncListenersResourceWithRawResponse:
@@ -1130,6 +1139,15 @@ def __init__(self, listeners: AsyncListenersResource) -> None:
self.get = async_to_raw_response_wrapper(
listeners.get,
)
+ self.create_and_poll = async_to_raw_response_wrapper(
+ listeners.create_and_poll,
+ )
+ self.delete_and_poll = async_to_raw_response_wrapper(
+ listeners.delete_and_poll,
+ )
+ self.update_and_poll = async_to_raw_response_wrapper(
+ listeners.update_and_poll,
+ )
class ListenersResourceWithStreamingResponse:
@@ -1151,6 +1169,15 @@ def __init__(self, listeners: ListenersResource) -> None:
self.get = to_streamed_response_wrapper(
listeners.get,
)
+ self.create_and_poll = to_streamed_response_wrapper(
+ listeners.create_and_poll,
+ )
+ self.delete_and_poll = to_streamed_response_wrapper(
+ listeners.delete_and_poll,
+ )
+ self.update_and_poll = to_streamed_response_wrapper(
+ listeners.update_and_poll,
+ )
class AsyncListenersResourceWithStreamingResponse:
@@ -1172,3 +1199,12 @@ def __init__(self, listeners: AsyncListenersResource) -> None:
self.get = async_to_streamed_response_wrapper(
listeners.get,
)
+ self.create_and_poll = async_to_streamed_response_wrapper(
+ listeners.create_and_poll,
+ )
+ self.delete_and_poll = async_to_streamed_response_wrapper(
+ listeners.delete_and_poll,
+ )
+ self.update_and_poll = async_to_streamed_response_wrapper(
+ listeners.update_and_poll,
+ )
diff --git a/src/gcore/resources/cloud/load_balancers/load_balancers.py b/src/gcore/resources/cloud/load_balancers/load_balancers.py
index 905aef54..3a9dcf02 100644
--- a/src/gcore/resources/cloud/load_balancers/load_balancers.py
+++ b/src/gcore/resources/cloud/load_balancers/load_balancers.py
@@ -1498,6 +1498,18 @@ def __init__(self, load_balancers: LoadBalancersResource) -> None:
self.resize = to_raw_response_wrapper(
load_balancers.resize,
)
+ self.create_and_poll = to_raw_response_wrapper(
+ load_balancers.create_and_poll,
+ )
+ self.delete_and_poll = to_raw_response_wrapper(
+ load_balancers.delete_and_poll,
+ )
+ self.failover_and_poll = to_raw_response_wrapper(
+ load_balancers.failover_and_poll,
+ )
+ self.resize_and_poll = to_raw_response_wrapper(
+ load_balancers.resize_and_poll,
+ )
@cached_property
def l7_policies(self) -> L7PoliciesResourceWithRawResponse:
@@ -1549,6 +1561,18 @@ def __init__(self, load_balancers: AsyncLoadBalancersResource) -> None:
self.resize = async_to_raw_response_wrapper(
load_balancers.resize,
)
+ self.create_and_poll = async_to_raw_response_wrapper(
+ load_balancers.create_and_poll,
+ )
+ self.delete_and_poll = async_to_raw_response_wrapper(
+ load_balancers.delete_and_poll,
+ )
+ self.failover_and_poll = async_to_raw_response_wrapper(
+ load_balancers.failover_and_poll,
+ )
+ self.resize_and_poll = async_to_raw_response_wrapper(
+ load_balancers.resize_and_poll,
+ )
@cached_property
def l7_policies(self) -> AsyncL7PoliciesResourceWithRawResponse:
@@ -1600,6 +1624,18 @@ def __init__(self, load_balancers: LoadBalancersResource) -> None:
self.resize = to_streamed_response_wrapper(
load_balancers.resize,
)
+ self.create_and_poll = to_streamed_response_wrapper(
+ load_balancers.create_and_poll,
+ )
+ self.delete_and_poll = to_streamed_response_wrapper(
+ load_balancers.delete_and_poll,
+ )
+ self.failover_and_poll = to_streamed_response_wrapper(
+ load_balancers.failover_and_poll,
+ )
+ self.resize_and_poll = to_streamed_response_wrapper(
+ load_balancers.resize_and_poll,
+ )
@cached_property
def l7_policies(self) -> L7PoliciesResourceWithStreamingResponse:
@@ -1651,6 +1687,18 @@ def __init__(self, load_balancers: AsyncLoadBalancersResource) -> None:
self.resize = async_to_streamed_response_wrapper(
load_balancers.resize,
)
+ self.create_and_poll = async_to_streamed_response_wrapper(
+ load_balancers.create_and_poll,
+ )
+ self.delete_and_poll = async_to_streamed_response_wrapper(
+ load_balancers.delete_and_poll,
+ )
+ self.failover_and_poll = async_to_streamed_response_wrapper(
+ load_balancers.failover_and_poll,
+ )
+ self.resize_and_poll = async_to_streamed_response_wrapper(
+ load_balancers.resize_and_poll,
+ )
@cached_property
def l7_policies(self) -> AsyncL7PoliciesResourceWithStreamingResponse:
diff --git a/src/gcore/resources/cloud/load_balancers/pools/pools.py b/src/gcore/resources/cloud/load_balancers/pools/pools.py
index 3d61764f..b258a0f1 100644
--- a/src/gcore/resources/cloud/load_balancers/pools/pools.py
+++ b/src/gcore/resources/cloud/load_balancers/pools/pools.py
@@ -1197,6 +1197,15 @@ def __init__(self, pools: PoolsResource) -> None:
self.get = to_raw_response_wrapper(
pools.get,
)
+ self.create_and_poll = to_raw_response_wrapper(
+ pools.create_and_poll,
+ )
+ self.delete_and_poll = to_raw_response_wrapper(
+ pools.delete_and_poll,
+ )
+ self.update_and_poll = to_raw_response_wrapper(
+ pools.update_and_poll,
+ )
@cached_property
def health_monitors(self) -> HealthMonitorsResourceWithRawResponse:
@@ -1226,6 +1235,15 @@ def __init__(self, pools: AsyncPoolsResource) -> None:
self.get = async_to_raw_response_wrapper(
pools.get,
)
+ self.create_and_poll = async_to_raw_response_wrapper(
+ pools.create_and_poll,
+ )
+ self.delete_and_poll = async_to_raw_response_wrapper(
+ pools.delete_and_poll,
+ )
+ self.update_and_poll = async_to_raw_response_wrapper(
+ pools.update_and_poll,
+ )
@cached_property
def health_monitors(self) -> AsyncHealthMonitorsResourceWithRawResponse:
@@ -1255,6 +1273,15 @@ def __init__(self, pools: PoolsResource) -> None:
self.get = to_streamed_response_wrapper(
pools.get,
)
+ self.create_and_poll = to_streamed_response_wrapper(
+ pools.create_and_poll,
+ )
+ self.delete_and_poll = to_streamed_response_wrapper(
+ pools.delete_and_poll,
+ )
+ self.update_and_poll = to_streamed_response_wrapper(
+ pools.update_and_poll,
+ )
@cached_property
def health_monitors(self) -> HealthMonitorsResourceWithStreamingResponse:
@@ -1284,6 +1311,15 @@ def __init__(self, pools: AsyncPoolsResource) -> None:
self.get = async_to_streamed_response_wrapper(
pools.get,
)
+ self.create_and_poll = async_to_streamed_response_wrapper(
+ pools.create_and_poll,
+ )
+ self.delete_and_poll = async_to_streamed_response_wrapper(
+ pools.delete_and_poll,
+ )
+ self.update_and_poll = async_to_streamed_response_wrapper(
+ pools.update_and_poll,
+ )
@cached_property
def health_monitors(self) -> AsyncHealthMonitorsResourceWithStreamingResponse:
diff --git a/src/gcore/resources/cloud/secrets.py b/src/gcore/resources/cloud/secrets.py
index 9a6fed1d..0e506c6d 100644
--- a/src/gcore/resources/cloud/secrets.py
+++ b/src/gcore/resources/cloud/secrets.py
@@ -580,6 +580,9 @@ def __init__(self, secrets: SecretsResource) -> None:
self.upload_tls_certificate = to_raw_response_wrapper(
secrets.upload_tls_certificate,
)
+ self.upload_tls_certificate_and_poll = to_raw_response_wrapper(
+ secrets.upload_tls_certificate_and_poll,
+ )
class AsyncSecretsResourceWithRawResponse:
@@ -598,6 +601,9 @@ def __init__(self, secrets: AsyncSecretsResource) -> None:
self.upload_tls_certificate = async_to_raw_response_wrapper(
secrets.upload_tls_certificate,
)
+ self.upload_tls_certificate_and_poll = async_to_raw_response_wrapper(
+ secrets.upload_tls_certificate_and_poll,
+ )
class SecretsResourceWithStreamingResponse:
@@ -616,6 +622,9 @@ def __init__(self, secrets: SecretsResource) -> None:
self.upload_tls_certificate = to_streamed_response_wrapper(
secrets.upload_tls_certificate,
)
+ self.upload_tls_certificate_and_poll = to_streamed_response_wrapper(
+ secrets.upload_tls_certificate_and_poll,
+ )
class AsyncSecretsResourceWithStreamingResponse:
@@ -634,3 +643,6 @@ def __init__(self, secrets: AsyncSecretsResource) -> None:
self.upload_tls_certificate = async_to_streamed_response_wrapper(
secrets.upload_tls_certificate,
)
+ self.upload_tls_certificate_and_poll = async_to_streamed_response_wrapper(
+ secrets.upload_tls_certificate_and_poll,
+ )
From 18614cb786fd3ea9020cee18c2a23c4c81f116f3 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 27 Oct 2025 08:13:41 +0000
Subject: [PATCH 09/27] feat(api): aggregated API specs update
---
.stats.yml | 4 ++--
tests/api_resources/cdn/test_resources.py | 8 ++++----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 78cae3bd..60b9cef8 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 609
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-286a65430a65eb4a40437fca2268857a509498373c2d8def0557e6dbd873dd41.yml
-openapi_spec_hash: 25cb371f8eacd4951b1f7f8451201e83
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-3f6cc1eae983d7512f2a83d113890737b5af78501b08d3b87d1c6a8e888671c7.yml
+openapi_spec_hash: 41d631be71afa942d320dc4f57f2b919
config_hash: bb4a27712c30f7a2b52e1f3b31766f24
diff --git a/tests/api_resources/cdn/test_resources.py b/tests/api_resources/cdn/test_resources.py
index aecf0ca9..debacd03 100644
--- a/tests/api_resources/cdn/test_resources.py
+++ b/tests/api_resources/cdn/test_resources.py
@@ -886,7 +886,7 @@ def test_method_purge_overload_1(self, client: Gcore) -> None:
def test_method_purge_with_all_params_overload_1(self, client: Gcore) -> None:
resource = client.cdn.resources.purge(
resource_id=0,
- urls=["string"],
+ urls=["/some-url.jpg", "/img/example.jpg"],
)
assert resource is None
@@ -925,7 +925,7 @@ def test_method_purge_overload_2(self, client: Gcore) -> None:
def test_method_purge_with_all_params_overload_2(self, client: Gcore) -> None:
resource = client.cdn.resources.purge(
resource_id=0,
- paths=["string"],
+ paths=["/images/*", "/videos/*"],
)
assert resource is None
@@ -2202,7 +2202,7 @@ async def test_method_purge_overload_1(self, async_client: AsyncGcore) -> None:
async def test_method_purge_with_all_params_overload_1(self, async_client: AsyncGcore) -> None:
resource = await async_client.cdn.resources.purge(
resource_id=0,
- urls=["string"],
+ urls=["/some-url.jpg", "/img/example.jpg"],
)
assert resource is None
@@ -2241,7 +2241,7 @@ async def test_method_purge_overload_2(self, async_client: AsyncGcore) -> None:
async def test_method_purge_with_all_params_overload_2(self, async_client: AsyncGcore) -> None:
resource = await async_client.cdn.resources.purge(
resource_id=0,
- paths=["string"],
+ paths=["/images/*", "/videos/*"],
)
assert resource is None
From da1429d0a0a3dba3079b816c930b44853e5946d4 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 27 Oct 2025 12:15:28 +0000
Subject: [PATCH 10/27] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 60b9cef8..8927182b 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 609
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-3f6cc1eae983d7512f2a83d113890737b5af78501b08d3b87d1c6a8e888671c7.yml
-openapi_spec_hash: 41d631be71afa942d320dc4f57f2b919
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-40612ca61459a98a98276b2788ba9fcdb457df1ecbbaa3556a3a379ce4de8272.yml
+openapi_spec_hash: 619b199ac27e1919bc7d9996455fd96b
config_hash: bb4a27712c30f7a2b52e1f3b31766f24
From 4e629534e07db80d93c46e5ccc5e3d2ba48d9eb4 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 27 Oct 2025 14:10:49 +0000
Subject: [PATCH 11/27] feat(api): aggregated API specs update
---
.stats.yml | 4 ++--
src/gcore/types/cdn/cdn_resource.py | 10 ++++++++--
src/gcore/types/cdn/resource_create_params.py | 10 ++++++++--
src/gcore/types/cdn/resource_replace_params.py | 10 ++++++++--
src/gcore/types/cdn/resource_update_params.py | 10 ++++++++--
src/gcore/types/cdn/resources/cdn_resource_rule.py | 10 ++++++++--
src/gcore/types/cdn/resources/rule_create_params.py | 10 ++++++++--
src/gcore/types/cdn/resources/rule_replace_params.py | 10 ++++++++--
src/gcore/types/cdn/resources/rule_update_params.py | 10 ++++++++--
src/gcore/types/cdn/rule_template.py | 10 ++++++++--
src/gcore/types/cdn/rule_template_create_params.py | 10 ++++++++--
src/gcore/types/cdn/rule_template_replace_params.py | 10 ++++++++--
src/gcore/types/cdn/rule_template_update_params.py | 10 ++++++++--
13 files changed, 98 insertions(+), 26 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 8927182b..c7e76cf1 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 609
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-40612ca61459a98a98276b2788ba9fcdb457df1ecbbaa3556a3a379ce4de8272.yml
-openapi_spec_hash: 619b199ac27e1919bc7d9996455fd96b
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-9a8804253e6b10b100fd87d24631d4b6e3fb018fa6e57bb9a7404af7cae5c132.yml
+openapi_spec_hash: 1fd683372fd558a27e495fb2d2aa7141
config_hash: bb4a27712c30f7a2b52e1f3b31766f24
diff --git a/src/gcore/types/cdn/cdn_resource.py b/src/gcore/types/cdn/cdn_resource.py
index dd05e44f..007d4be8 100644
--- a/src/gcore/types/cdn/cdn_resource.py
+++ b/src/gcore/types/cdn/cdn_resource.py
@@ -759,7 +759,10 @@ class OptionsProxyConnectTimeout(BaseModel):
"""
value: str
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 5s**.
+ """
class OptionsProxyReadTimeout(BaseModel):
@@ -773,7 +776,10 @@ class OptionsProxyReadTimeout(BaseModel):
"""
value: str
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 30s**.
+ """
class OptionsQueryParamsBlacklist(BaseModel):
diff --git a/src/gcore/types/cdn/resource_create_params.py b/src/gcore/types/cdn/resource_create_params.py
index f31367c0..ce9dad10 100644
--- a/src/gcore/types/cdn/resource_create_params.py
+++ b/src/gcore/types/cdn/resource_create_params.py
@@ -882,7 +882,10 @@ class OptionsProxyConnectTimeout(TypedDict, total=False):
"""
value: Required[str]
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 5s**.
+ """
class OptionsProxyReadTimeout(TypedDict, total=False):
@@ -896,7 +899,10 @@ class OptionsProxyReadTimeout(TypedDict, total=False):
"""
value: Required[str]
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 30s**.
+ """
class OptionsQueryParamsBlacklist(TypedDict, total=False):
diff --git a/src/gcore/types/cdn/resource_replace_params.py b/src/gcore/types/cdn/resource_replace_params.py
index 717114a4..58e21ac4 100644
--- a/src/gcore/types/cdn/resource_replace_params.py
+++ b/src/gcore/types/cdn/resource_replace_params.py
@@ -860,7 +860,10 @@ class OptionsProxyConnectTimeout(TypedDict, total=False):
"""
value: Required[str]
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 5s**.
+ """
class OptionsProxyReadTimeout(TypedDict, total=False):
@@ -874,7 +877,10 @@ class OptionsProxyReadTimeout(TypedDict, total=False):
"""
value: Required[str]
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 30s**.
+ """
class OptionsQueryParamsBlacklist(TypedDict, total=False):
diff --git a/src/gcore/types/cdn/resource_update_params.py b/src/gcore/types/cdn/resource_update_params.py
index d980ad8c..a382bda2 100644
--- a/src/gcore/types/cdn/resource_update_params.py
+++ b/src/gcore/types/cdn/resource_update_params.py
@@ -851,7 +851,10 @@ class OptionsProxyConnectTimeout(TypedDict, total=False):
"""
value: Required[str]
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 5s**.
+ """
class OptionsProxyReadTimeout(TypedDict, total=False):
@@ -865,7 +868,10 @@ class OptionsProxyReadTimeout(TypedDict, total=False):
"""
value: Required[str]
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 30s**.
+ """
class OptionsQueryParamsBlacklist(TypedDict, total=False):
diff --git a/src/gcore/types/cdn/resources/cdn_resource_rule.py b/src/gcore/types/cdn/resources/cdn_resource_rule.py
index 28dc2ebf..8f66f00c 100644
--- a/src/gcore/types/cdn/resources/cdn_resource_rule.py
+++ b/src/gcore/types/cdn/resources/cdn_resource_rule.py
@@ -736,7 +736,10 @@ class OptionsProxyConnectTimeout(BaseModel):
"""
value: str
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 5s**.
+ """
class OptionsProxyReadTimeout(BaseModel):
@@ -750,7 +753,10 @@ class OptionsProxyReadTimeout(BaseModel):
"""
value: str
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 30s**.
+ """
class OptionsQueryParamsBlacklist(BaseModel):
diff --git a/src/gcore/types/cdn/resources/rule_create_params.py b/src/gcore/types/cdn/resources/rule_create_params.py
index 6c8ab837..4d80f7c6 100644
--- a/src/gcore/types/cdn/resources/rule_create_params.py
+++ b/src/gcore/types/cdn/resources/rule_create_params.py
@@ -812,7 +812,10 @@ class OptionsProxyConnectTimeout(TypedDict, total=False):
"""
value: Required[str]
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 5s**.
+ """
class OptionsProxyReadTimeout(TypedDict, total=False):
@@ -826,7 +829,10 @@ class OptionsProxyReadTimeout(TypedDict, total=False):
"""
value: Required[str]
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 30s**.
+ """
class OptionsQueryParamsBlacklist(TypedDict, total=False):
diff --git a/src/gcore/types/cdn/resources/rule_replace_params.py b/src/gcore/types/cdn/resources/rule_replace_params.py
index 6eb3eddc..c6bf65cc 100644
--- a/src/gcore/types/cdn/resources/rule_replace_params.py
+++ b/src/gcore/types/cdn/resources/rule_replace_params.py
@@ -814,7 +814,10 @@ class OptionsProxyConnectTimeout(TypedDict, total=False):
"""
value: Required[str]
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 5s**.
+ """
class OptionsProxyReadTimeout(TypedDict, total=False):
@@ -828,7 +831,10 @@ class OptionsProxyReadTimeout(TypedDict, total=False):
"""
value: Required[str]
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 30s**.
+ """
class OptionsQueryParamsBlacklist(TypedDict, total=False):
diff --git a/src/gcore/types/cdn/resources/rule_update_params.py b/src/gcore/types/cdn/resources/rule_update_params.py
index 154c4cef..e04e0c93 100644
--- a/src/gcore/types/cdn/resources/rule_update_params.py
+++ b/src/gcore/types/cdn/resources/rule_update_params.py
@@ -814,7 +814,10 @@ class OptionsProxyConnectTimeout(TypedDict, total=False):
"""
value: Required[str]
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 5s**.
+ """
class OptionsProxyReadTimeout(TypedDict, total=False):
@@ -828,7 +831,10 @@ class OptionsProxyReadTimeout(TypedDict, total=False):
"""
value: Required[str]
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 30s**.
+ """
class OptionsQueryParamsBlacklist(TypedDict, total=False):
diff --git a/src/gcore/types/cdn/rule_template.py b/src/gcore/types/cdn/rule_template.py
index 6d73d4f4..1d7b8693 100644
--- a/src/gcore/types/cdn/rule_template.py
+++ b/src/gcore/types/cdn/rule_template.py
@@ -736,7 +736,10 @@ class OptionsProxyConnectTimeout(BaseModel):
"""
value: str
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 5s**.
+ """
class OptionsProxyReadTimeout(BaseModel):
@@ -750,7 +753,10 @@ class OptionsProxyReadTimeout(BaseModel):
"""
value: str
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 30s**.
+ """
class OptionsQueryParamsBlacklist(BaseModel):
diff --git a/src/gcore/types/cdn/rule_template_create_params.py b/src/gcore/types/cdn/rule_template_create_params.py
index a0e9ea73..30d52eba 100644
--- a/src/gcore/types/cdn/rule_template_create_params.py
+++ b/src/gcore/types/cdn/rule_template_create_params.py
@@ -796,7 +796,10 @@ class OptionsProxyConnectTimeout(TypedDict, total=False):
"""
value: Required[str]
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 5s**.
+ """
class OptionsProxyReadTimeout(TypedDict, total=False):
@@ -810,7 +813,10 @@ class OptionsProxyReadTimeout(TypedDict, total=False):
"""
value: Required[str]
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 30s**.
+ """
class OptionsQueryParamsBlacklist(TypedDict, total=False):
diff --git a/src/gcore/types/cdn/rule_template_replace_params.py b/src/gcore/types/cdn/rule_template_replace_params.py
index 683bd306..ccb47c56 100644
--- a/src/gcore/types/cdn/rule_template_replace_params.py
+++ b/src/gcore/types/cdn/rule_template_replace_params.py
@@ -796,7 +796,10 @@ class OptionsProxyConnectTimeout(TypedDict, total=False):
"""
value: Required[str]
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 5s**.
+ """
class OptionsProxyReadTimeout(TypedDict, total=False):
@@ -810,7 +813,10 @@ class OptionsProxyReadTimeout(TypedDict, total=False):
"""
value: Required[str]
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 30s**.
+ """
class OptionsQueryParamsBlacklist(TypedDict, total=False):
diff --git a/src/gcore/types/cdn/rule_template_update_params.py b/src/gcore/types/cdn/rule_template_update_params.py
index c1e77142..2be5eb7e 100644
--- a/src/gcore/types/cdn/rule_template_update_params.py
+++ b/src/gcore/types/cdn/rule_template_update_params.py
@@ -796,7 +796,10 @@ class OptionsProxyConnectTimeout(TypedDict, total=False):
"""
value: Required[str]
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 5s**.
+ """
class OptionsProxyReadTimeout(TypedDict, total=False):
@@ -810,7 +813,10 @@ class OptionsProxyReadTimeout(TypedDict, total=False):
"""
value: Required[str]
- """Timeout value in seconds."""
+ """Timeout value in seconds.
+
+ Supported range: **1s - 30s**.
+ """
class OptionsQueryParamsBlacklist(TypedDict, total=False):
From 94f0e4695389f59df18aeda5ef4eaebcb95d90ed Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 28 Oct 2025 10:11:42 +0000
Subject: [PATCH 12/27] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index c7e76cf1..c6f718d3 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 609
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-9a8804253e6b10b100fd87d24631d4b6e3fb018fa6e57bb9a7404af7cae5c132.yml
-openapi_spec_hash: 1fd683372fd558a27e495fb2d2aa7141
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-7a2f7e9dd81da1b84b614443585eb99dca6581b155f778de2af43cf9e02ff144.yml
+openapi_spec_hash: 236bdc057e30d676bc46e7d4f22cbee7
config_hash: bb4a27712c30f7a2b52e1f3b31766f24
From af54c886222ea41e6ef57d8683fbb64e2b688a15 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 28 Oct 2025 12:15:36 +0000
Subject: [PATCH 13/27] feat(api): aggregated API specs update
---
.stats.yml | 4 +--
api.md | 2 +-
.../cloud/load_balancers/listeners.py | 35 +++++++++++++++----
.../cloud/load_balancer_create_params.py | 5 ++-
.../types/cloud/load_balancers/__init__.py | 1 +
.../load_balancers/listener_create_params.py | 5 ++-
.../load_balancers/listener_delete_params.py | 18 ++++++++++
.../load_balancers/listener_update_params.py | 5 ++-
.../cloud/load_balancers/test_listeners.py | 20 +++++++++++
9 files changed, 83 insertions(+), 12 deletions(-)
create mode 100644 src/gcore/types/cloud/load_balancers/listener_delete_params.py
diff --git a/.stats.yml b/.stats.yml
index c6f718d3..035cadcd 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 609
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-7a2f7e9dd81da1b84b614443585eb99dca6581b155f778de2af43cf9e02ff144.yml
-openapi_spec_hash: 236bdc057e30d676bc46e7d4f22cbee7
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-7bb076221b6b8c4e465291804fa37dfec95dc815c0670753eec9e02420aef8eb.yml
+openapi_spec_hash: 5c56fa55767a46498c083e3fa940c227
config_hash: bb4a27712c30f7a2b52e1f3b31766f24
diff --git a/api.md b/api.md
index 8904e330..6ff46915 100644
--- a/api.md
+++ b/api.md
@@ -250,7 +250,7 @@ Methods:
- client.cloud.load_balancers.listeners.create(\*, project_id, region_id, \*\*params) -> TaskIDList
- client.cloud.load_balancers.listeners.update(listener_id, \*, project_id, region_id, \*\*params) -> TaskIDList
- client.cloud.load_balancers.listeners.list(\*, project_id, region_id, \*\*params) -> LoadBalancerListenerList
-- client.cloud.load_balancers.listeners.delete(listener_id, \*, project_id, region_id) -> TaskIDList
+- client.cloud.load_balancers.listeners.delete(listener_id, \*, project_id, region_id, \*\*params) -> TaskIDList
- client.cloud.load_balancers.listeners.get(listener_id, \*, project_id, region_id, \*\*params) -> LoadBalancerListenerDetail
### Pools
diff --git a/src/gcore/resources/cloud/load_balancers/listeners.py b/src/gcore/resources/cloud/load_balancers/listeners.py
index da0a38a1..1e8c89e0 100644
--- a/src/gcore/resources/cloud/load_balancers/listeners.py
+++ b/src/gcore/resources/cloud/load_balancers/listeners.py
@@ -23,6 +23,7 @@
listener_get_params,
listener_list_params,
listener_create_params,
+ listener_delete_params,
listener_update_params,
)
from ....types.cloud.lb_listener_protocol import LbListenerProtocol
@@ -95,7 +96,8 @@ def create(
allowed_cidrs: Network CIDRs from which service will be accessible
- connection_limit: Limit of the simultaneous connections
+ connection_limit: Limit of the simultaneous connections. If -1 is provided, it is translated to
+ the default value 100000.
insert_x_forwarded: Add headers X-Forwarded-For, X-Forwarded-Port, X-Forwarded-Proto to requests.
Only used with HTTP or `TERMINATED_HTTPS` protocols.
@@ -186,7 +188,8 @@ def update(
allowed_cidrs: Network CIDRs from which service will be accessible
- connection_limit: Limit of simultaneous connections
+ connection_limit: Limit of simultaneous connections. If -1 is provided, it is translated to the
+ default value 100000.
name: Load balancer listener name
@@ -302,6 +305,7 @@ def delete(
*,
project_id: int | None = None,
region_id: int | None = None,
+ delete_default_pool: bool | Omit = omit,
# 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,
@@ -319,6 +323,8 @@ def delete(
listener_id: Listener ID
+ delete_default_pool: Delete default pool attached directly to the listener.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -336,7 +342,13 @@ def delete(
return self._delete(
f"/cloud/v1/lblisteners/{project_id}/{region_id}/{listener_id}",
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {"delete_default_pool": delete_default_pool}, listener_delete_params.ListenerDeleteParams
+ ),
),
cast_to=TaskIDList,
)
@@ -624,7 +636,8 @@ async def create(
allowed_cidrs: Network CIDRs from which service will be accessible
- connection_limit: Limit of the simultaneous connections
+ connection_limit: Limit of the simultaneous connections. If -1 is provided, it is translated to
+ the default value 100000.
insert_x_forwarded: Add headers X-Forwarded-For, X-Forwarded-Port, X-Forwarded-Proto to requests.
Only used with HTTP or `TERMINATED_HTTPS` protocols.
@@ -715,7 +728,8 @@ async def update(
allowed_cidrs: Network CIDRs from which service will be accessible
- connection_limit: Limit of simultaneous connections
+ connection_limit: Limit of simultaneous connections. If -1 is provided, it is translated to the
+ default value 100000.
name: Load balancer listener name
@@ -831,6 +845,7 @@ async def delete(
*,
project_id: int | None = None,
region_id: int | None = None,
+ delete_default_pool: bool | Omit = omit,
# 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,
@@ -848,6 +863,8 @@ async def delete(
listener_id: Listener ID
+ delete_default_pool: Delete default pool attached directly to the listener.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -865,7 +882,13 @@ async def delete(
return await self._delete(
f"/cloud/v1/lblisteners/{project_id}/{region_id}/{listener_id}",
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {"delete_default_pool": delete_default_pool}, listener_delete_params.ListenerDeleteParams
+ ),
),
cast_to=TaskIDList,
)
diff --git a/src/gcore/types/cloud/load_balancer_create_params.py b/src/gcore/types/cloud/load_balancer_create_params.py
index a41fd6e4..0ab6f5ce 100644
--- a/src/gcore/types/cloud/load_balancer_create_params.py
+++ b/src/gcore/types/cloud/load_balancer_create_params.py
@@ -318,7 +318,10 @@ class Listener(TypedDict, total=False):
"""Network CIDRs from which service will be accessible"""
connection_limit: int
- """Limit of the simultaneous connections"""
+ """Limit of the simultaneous connections.
+
+ If -1 is provided, it is translated to the default value 100000.
+ """
insert_x_forwarded: bool
"""Add headers X-Forwarded-For, X-Forwarded-Port, X-Forwarded-Proto to requests.
diff --git a/src/gcore/types/cloud/load_balancers/__init__.py b/src/gcore/types/cloud/load_balancers/__init__.py
index 433f966c..c68b77c9 100644
--- a/src/gcore/types/cloud/load_balancers/__init__.py
+++ b/src/gcore/types/cloud/load_balancers/__init__.py
@@ -10,6 +10,7 @@
from .listener_get_params import ListenerGetParams as ListenerGetParams
from .listener_list_params import ListenerListParams as ListenerListParams
from .listener_create_params import ListenerCreateParams as ListenerCreateParams
+from .listener_delete_params import ListenerDeleteParams as ListenerDeleteParams
from .listener_update_params import ListenerUpdateParams as ListenerUpdateParams
from .l7_policy_create_params import L7PolicyCreateParams as L7PolicyCreateParams
from .l7_policy_replace_params import L7PolicyReplaceParams as L7PolicyReplaceParams
diff --git a/src/gcore/types/cloud/load_balancers/listener_create_params.py b/src/gcore/types/cloud/load_balancers/listener_create_params.py
index c5b6f5e6..9850d348 100644
--- a/src/gcore/types/cloud/load_balancers/listener_create_params.py
+++ b/src/gcore/types/cloud/load_balancers/listener_create_params.py
@@ -34,7 +34,10 @@ class ListenerCreateParams(TypedDict, total=False):
"""Network CIDRs from which service will be accessible"""
connection_limit: int
- """Limit of the simultaneous connections"""
+ """Limit of the simultaneous connections.
+
+ If -1 is provided, it is translated to the default value 100000.
+ """
insert_x_forwarded: bool
"""Add headers X-Forwarded-For, X-Forwarded-Port, X-Forwarded-Proto to requests.
diff --git a/src/gcore/types/cloud/load_balancers/listener_delete_params.py b/src/gcore/types/cloud/load_balancers/listener_delete_params.py
new file mode 100644
index 00000000..7d0e31a4
--- /dev/null
+++ b/src/gcore/types/cloud/load_balancers/listener_delete_params.py
@@ -0,0 +1,18 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+__all__ = ["ListenerDeleteParams"]
+
+
+class ListenerDeleteParams(TypedDict, total=False):
+ project_id: int
+ """Project ID"""
+
+ region_id: int
+ """Region ID"""
+
+ delete_default_pool: bool
+ """Delete default pool attached directly to the listener."""
diff --git a/src/gcore/types/cloud/load_balancers/listener_update_params.py b/src/gcore/types/cloud/load_balancers/listener_update_params.py
index 492c990d..42fa7e38 100644
--- a/src/gcore/types/cloud/load_balancers/listener_update_params.py
+++ b/src/gcore/types/cloud/load_balancers/listener_update_params.py
@@ -21,7 +21,10 @@ class ListenerUpdateParams(TypedDict, total=False):
"""Network CIDRs from which service will be accessible"""
connection_limit: int
- """Limit of simultaneous connections"""
+ """Limit of simultaneous connections.
+
+ If -1 is provided, it is translated to the default value 100000.
+ """
name: str
"""Load balancer listener name"""
diff --git a/tests/api_resources/cloud/load_balancers/test_listeners.py b/tests/api_resources/cloud/load_balancers/test_listeners.py
index b7228ea5..628a84f8 100644
--- a/tests/api_resources/cloud/load_balancers/test_listeners.py
+++ b/tests/api_resources/cloud/load_balancers/test_listeners.py
@@ -211,6 +211,16 @@ def test_method_delete(self, client: Gcore) -> None:
)
assert_matches_type(TaskIDList, listener, path=["response"])
+ @parametrize
+ def test_method_delete_with_all_params(self, client: Gcore) -> None:
+ listener = client.cloud.load_balancers.listeners.delete(
+ listener_id="00000000-0000-4000-8000-000000000000",
+ project_id=1,
+ region_id=1,
+ delete_default_pool=False,
+ )
+ assert_matches_type(TaskIDList, listener, path=["response"])
+
@parametrize
def test_raw_response_delete(self, client: Gcore) -> None:
response = client.cloud.load_balancers.listeners.with_raw_response.delete(
@@ -504,6 +514,16 @@ async def test_method_delete(self, async_client: AsyncGcore) -> None:
)
assert_matches_type(TaskIDList, listener, path=["response"])
+ @parametrize
+ async def test_method_delete_with_all_params(self, async_client: AsyncGcore) -> None:
+ listener = await async_client.cloud.load_balancers.listeners.delete(
+ listener_id="00000000-0000-4000-8000-000000000000",
+ project_id=1,
+ region_id=1,
+ delete_default_pool=False,
+ )
+ assert_matches_type(TaskIDList, listener, path=["response"])
+
@parametrize
async def test_raw_response_delete(self, async_client: AsyncGcore) -> None:
response = await async_client.cloud.load_balancers.listeners.with_raw_response.delete(
From a25394192b45e4da62fbf94ead1f9774598052b3 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 29 Oct 2025 09:46:24 +0000
Subject: [PATCH 14/27] codegen metadata
---
.stats.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.stats.yml b/.stats.yml
index 035cadcd..e33bba97 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 609
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-7bb076221b6b8c4e465291804fa37dfec95dc815c0670753eec9e02420aef8eb.yml
openapi_spec_hash: 5c56fa55767a46498c083e3fa940c227
-config_hash: bb4a27712c30f7a2b52e1f3b31766f24
+config_hash: 25b1dd444559d26e51bf85892358c0bc
From cd7152cd959a9984e5c60edb41d16fa2db342012 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 29 Oct 2025 10:43:04 +0000
Subject: [PATCH 15/27] fix(client): close streams without requiring full
consumption
---
src/gcore/_streaming.py | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/src/gcore/_streaming.py b/src/gcore/_streaming.py
index bf3046cf..16c106ae 100644
--- a/src/gcore/_streaming.py
+++ b/src/gcore/_streaming.py
@@ -57,9 +57,8 @@ def __stream__(self) -> Iterator[_T]:
for sse in iterator:
yield process_data(data=sse.json(), cast_to=cast_to, response=response)
- # Ensure the entire stream is consumed
- for _sse in iterator:
- ...
+ # As we might not fully consume the response stream, we need to close it explicitly
+ response.close()
def __enter__(self) -> Self:
return self
@@ -121,9 +120,8 @@ async def __stream__(self) -> AsyncIterator[_T]:
async for sse in iterator:
yield process_data(data=sse.json(), cast_to=cast_to, response=response)
- # Ensure the entire stream is consumed
- async for _sse in iterator:
- ...
+ # As we might not fully consume the response stream, we need to close it explicitly
+ await response.aclose()
async def __aenter__(self) -> Self:
return self
From 3ef8586481df9533a0627310458bb72b9b458d2f Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 29 Oct 2025 12:15:35 +0000
Subject: [PATCH 16/27] feat(api): aggregated API specs update
---
.stats.yml | 4 ++--
src/gcore/types/cloud/gpu_baremetal_cluster.py | 14 +++++++++++++-
.../cloud/gpu_baremetal_cluster_create_params.py | 12 ++++++++++++
.../cloud/test_gpu_baremetal_clusters.py | 12 ++++++++++++
4 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index e33bba97..f535120f 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 609
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-7bb076221b6b8c4e465291804fa37dfec95dc815c0670753eec9e02420aef8eb.yml
-openapi_spec_hash: 5c56fa55767a46498c083e3fa940c227
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-848b764e60807c1c1aedd39ebdbadd2ee63dcc6ae3910179cdfff3ef80429563.yml
+openapi_spec_hash: 04d6bac6704e464b0fa52af0cd0e18a2
config_hash: 25b1dd444559d26e51bf85892358c0bc
diff --git a/src/gcore/types/cloud/gpu_baremetal_cluster.py b/src/gcore/types/cloud/gpu_baremetal_cluster.py
index aa310a9b..373678bf 100644
--- a/src/gcore/types/cloud/gpu_baremetal_cluster.py
+++ b/src/gcore/types/cloud/gpu_baremetal_cluster.py
@@ -11,6 +11,7 @@
__all__ = [
"GPUBaremetalCluster",
"ServersSettings",
+ "ServersSettingsFileShare",
"ServersSettingsInterface",
"ServersSettingsInterfaceExternalInterfaceOutputSerializer",
"ServersSettingsInterfaceSubnetInterfaceOutputSerializer",
@@ -21,6 +22,14 @@
]
+class ServersSettingsFileShare(BaseModel):
+ id: str
+ """Unique identifier of the file share in UUID format."""
+
+ mount_path: str
+ """Absolute mount path inside the system where the file share will be mounted."""
+
+
class ServersSettingsInterfaceExternalInterfaceOutputSerializer(BaseModel):
ip_family: Literal["dual", "ipv4", "ipv6"]
"""Which subnets should be selected: IPv4, IPv6, or use dual stack."""
@@ -90,6 +99,9 @@ class ServersSettingsSecurityGroup(BaseModel):
class ServersSettings(BaseModel):
+ file_shares: List[ServersSettingsFileShare]
+ """List of file shares mounted across the cluster."""
+
interfaces: List[ServersSettingsInterface]
security_groups: List[ServersSettingsSecurityGroup]
@@ -99,7 +111,7 @@ class ServersSettings(BaseModel):
"""SSH key name"""
user_data: Optional[str] = None
- """Optional custom user data (Base64-encoded) Mutually exclusive with 'password'."""
+ """Optional custom user data"""
class GPUBaremetalCluster(BaseModel):
diff --git a/src/gcore/types/cloud/gpu_baremetal_cluster_create_params.py b/src/gcore/types/cloud/gpu_baremetal_cluster_create_params.py
index 2dd61b2c..7bdf8a8a 100644
--- a/src/gcore/types/cloud/gpu_baremetal_cluster_create_params.py
+++ b/src/gcore/types/cloud/gpu_baremetal_cluster_create_params.py
@@ -15,6 +15,7 @@
"ServersSettingsInterfaceAnySubnetInterfaceInputSerializer",
"ServersSettingsInterfaceAnySubnetInterfaceInputSerializerFloatingIP",
"ServersSettingsCredentials",
+ "ServersSettingsFileShare",
"ServersSettingsSecurityGroup",
]
@@ -127,6 +128,14 @@ class ServersSettingsCredentials(TypedDict, total=False):
"""The 'username' and 'password' fields create a new user on the system"""
+class ServersSettingsFileShare(TypedDict, total=False):
+ id: Required[str]
+ """Unique identifier of the file share in UUID format."""
+
+ mount_path: Required[str]
+ """Absolute mount path inside the system where the file share will be mounted."""
+
+
class ServersSettingsSecurityGroup(TypedDict, total=False):
id: Required[str]
"""Resource ID"""
@@ -139,6 +148,9 @@ class ServersSettings(TypedDict, total=False):
credentials: ServersSettingsCredentials
"""Optional server access credentials"""
+ file_shares: Iterable[ServersSettingsFileShare]
+ """List of file shares to be mounted across the cluster."""
+
security_groups: Iterable[ServersSettingsSecurityGroup]
"""List of security groups UUIDs"""
diff --git a/tests/api_resources/cloud/test_gpu_baremetal_clusters.py b/tests/api_resources/cloud/test_gpu_baremetal_clusters.py
index 9fc01cc9..90aa7127 100644
--- a/tests/api_resources/cloud/test_gpu_baremetal_clusters.py
+++ b/tests/api_resources/cloud/test_gpu_baremetal_clusters.py
@@ -57,6 +57,12 @@ def test_method_create_with_all_params(self, client: Gcore) -> None:
"ssh_key_name": "my-ssh-key",
"username": "admin",
},
+ "file_shares": [
+ {
+ "id": "a3f2d1b8-45e6-4f8a-bb5d-19dbf2cd7e9a",
+ "mount_path": "/mnt/vast",
+ }
+ ],
"security_groups": [{"id": "b4849ffa-89f2-45a1-951f-0ae5b7809d98"}],
"user_data": "eyJ0ZXN0IjogImRhdGEifQ==",
},
@@ -549,6 +555,12 @@ async def test_method_create_with_all_params(self, async_client: AsyncGcore) ->
"ssh_key_name": "my-ssh-key",
"username": "admin",
},
+ "file_shares": [
+ {
+ "id": "a3f2d1b8-45e6-4f8a-bb5d-19dbf2cd7e9a",
+ "mount_path": "/mnt/vast",
+ }
+ ],
"security_groups": [{"id": "b4849ffa-89f2-45a1-951f-0ae5b7809d98"}],
"user_data": "eyJ0ZXN0IjogImRhdGEifQ==",
},
From 67e4c77936fca0b2192b931ec71003dd62383c81 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 30 Oct 2025 11:03:32 +0000
Subject: [PATCH 17/27] chore(internal/tests): avoid race condition with
implicit client cleanup
---
tests/test_client.py | 398 +++++++++++++++++++++++--------------------
1 file changed, 212 insertions(+), 186 deletions(-)
diff --git a/tests/test_client.py b/tests/test_client.py
index 1ef62fe4..5e4cd0ed 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -59,51 +59,49 @@ def _get_open_connections(client: Gcore | AsyncGcore) -> int:
class TestGcore:
- client = Gcore(base_url=base_url, api_key=api_key, _strict_response_validation=True)
-
@pytest.mark.respx(base_url=base_url)
- def test_raw_response(self, respx_mock: MockRouter) -> None:
+ def test_raw_response(self, respx_mock: MockRouter, client: Gcore) -> None:
respx_mock.post("/foo").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- response = self.client.post("/foo", cast_to=httpx.Response)
+ response = client.post("/foo", cast_to=httpx.Response)
assert response.status_code == 200
assert isinstance(response, httpx.Response)
assert response.json() == {"foo": "bar"}
@pytest.mark.respx(base_url=base_url)
- def test_raw_response_for_binary(self, respx_mock: MockRouter) -> None:
+ def test_raw_response_for_binary(self, respx_mock: MockRouter, client: Gcore) -> None:
respx_mock.post("/foo").mock(
return_value=httpx.Response(200, headers={"Content-Type": "application/binary"}, content='{"foo": "bar"}')
)
- response = self.client.post("/foo", cast_to=httpx.Response)
+ response = client.post("/foo", cast_to=httpx.Response)
assert response.status_code == 200
assert isinstance(response, httpx.Response)
assert response.json() == {"foo": "bar"}
- def test_copy(self) -> None:
- copied = self.client.copy()
- assert id(copied) != id(self.client)
+ def test_copy(self, client: Gcore) -> None:
+ copied = client.copy()
+ assert id(copied) != id(client)
- copied = self.client.copy(api_key="another My API Key")
+ copied = client.copy(api_key="another My API Key")
assert copied.api_key == "another My API Key"
- assert self.client.api_key == "My API Key"
+ assert client.api_key == "My API Key"
- def test_copy_default_options(self) -> None:
+ def test_copy_default_options(self, client: Gcore) -> None:
# options that have a default are overridden correctly
- copied = self.client.copy(max_retries=7)
+ copied = client.copy(max_retries=7)
assert copied.max_retries == 7
- assert self.client.max_retries == 2
+ assert client.max_retries == 2
copied2 = copied.copy(max_retries=6)
assert copied2.max_retries == 6
assert copied.max_retries == 7
# timeout
- assert isinstance(self.client.timeout, httpx.Timeout)
- copied = self.client.copy(timeout=None)
+ assert isinstance(client.timeout, httpx.Timeout)
+ copied = client.copy(timeout=None)
assert copied.timeout is None
- assert isinstance(self.client.timeout, httpx.Timeout)
+ assert isinstance(client.timeout, httpx.Timeout)
def test_copy_default_headers(self) -> None:
client = Gcore(
@@ -138,6 +136,7 @@ def test_copy_default_headers(self) -> None:
match="`default_headers` and `set_default_headers` arguments are mutually exclusive",
):
client.copy(set_default_headers={}, default_headers={"X-Foo": "Bar"})
+ client.close()
def test_copy_default_query(self) -> None:
client = Gcore(
@@ -175,13 +174,15 @@ def test_copy_default_query(self) -> None:
):
client.copy(set_default_query={}, default_query={"foo": "Bar"})
- def test_copy_signature(self) -> None:
+ client.close()
+
+ def test_copy_signature(self, client: Gcore) -> None:
# ensure the same parameters that can be passed to the client are defined in the `.copy()` method
init_signature = inspect.signature(
# mypy doesn't like that we access the `__init__` property.
- self.client.__init__, # type: ignore[misc]
+ client.__init__, # type: ignore[misc]
)
- copy_signature = inspect.signature(self.client.copy)
+ copy_signature = inspect.signature(client.copy)
exclude_params = {"transport", "proxies", "_strict_response_validation"}
for name in init_signature.parameters.keys():
@@ -192,12 +193,12 @@ def test_copy_signature(self) -> None:
assert copy_param is not None, f"copy() signature is missing the {name} param"
@pytest.mark.skipif(sys.version_info >= (3, 10), reason="fails because of a memory leak that started from 3.12")
- def test_copy_build_request(self) -> None:
+ def test_copy_build_request(self, client: Gcore) -> None:
options = FinalRequestOptions(method="get", url="/foo")
def build_request(options: FinalRequestOptions) -> None:
- client = self.client.copy()
- client._build_request(options)
+ client_copy = client.copy()
+ client_copy._build_request(options)
# ensure that the machinery is warmed up before tracing starts.
build_request(options)
@@ -254,14 +255,12 @@ def add_leak(leaks: list[tracemalloc.StatisticDiff], diff: tracemalloc.Statistic
print(frame)
raise AssertionError()
- def test_request_timeout(self) -> None:
- request = self.client._build_request(FinalRequestOptions(method="get", url="/foo"))
+ def test_request_timeout(self, client: Gcore) -> None:
+ request = client._build_request(FinalRequestOptions(method="get", url="/foo"))
timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore
assert timeout == DEFAULT_TIMEOUT
- request = self.client._build_request(
- FinalRequestOptions(method="get", url="/foo", timeout=httpx.Timeout(100.0))
- )
+ request = client._build_request(FinalRequestOptions(method="get", url="/foo", timeout=httpx.Timeout(100.0)))
timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore
assert timeout == httpx.Timeout(100.0)
@@ -272,6 +271,8 @@ def test_client_timeout_option(self) -> None:
timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore
assert timeout == httpx.Timeout(0)
+ client.close()
+
def test_http_client_timeout_option(self) -> None:
# custom timeout given to the httpx client should be used
with httpx.Client(timeout=None) as http_client:
@@ -283,6 +284,8 @@ def test_http_client_timeout_option(self) -> None:
timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore
assert timeout == httpx.Timeout(None)
+ client.close()
+
# no timeout given to the httpx client should not use the httpx default
with httpx.Client() as http_client:
client = Gcore(
@@ -293,6 +296,8 @@ def test_http_client_timeout_option(self) -> None:
timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore
assert timeout == DEFAULT_TIMEOUT
+ client.close()
+
# explicitly passing the default timeout currently results in it being ignored
with httpx.Client(timeout=HTTPX_DEFAULT_TIMEOUT) as http_client:
client = Gcore(
@@ -303,6 +308,8 @@ def test_http_client_timeout_option(self) -> None:
timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore
assert timeout == DEFAULT_TIMEOUT # our default
+ client.close()
+
async def test_invalid_http_client(self) -> None:
with pytest.raises(TypeError, match="Invalid `http_client` arg"):
async with httpx.AsyncClient() as http_client:
@@ -314,14 +321,14 @@ async def test_invalid_http_client(self) -> None:
)
def test_default_headers_option(self) -> None:
- client = Gcore(
+ test_client = Gcore(
base_url=base_url, api_key=api_key, _strict_response_validation=True, default_headers={"X-Foo": "bar"}
)
- request = client._build_request(FinalRequestOptions(method="get", url="/foo"))
+ request = test_client._build_request(FinalRequestOptions(method="get", url="/foo"))
assert request.headers.get("x-foo") == "bar"
assert request.headers.get("x-stainless-lang") == "python"
- client2 = Gcore(
+ test_client2 = Gcore(
base_url=base_url,
api_key=api_key,
_strict_response_validation=True,
@@ -330,10 +337,13 @@ def test_default_headers_option(self) -> None:
"X-Stainless-Lang": "my-overriding-header",
},
)
- request = client2._build_request(FinalRequestOptions(method="get", url="/foo"))
+ request = test_client2._build_request(FinalRequestOptions(method="get", url="/foo"))
assert request.headers.get("x-foo") == "stainless"
assert request.headers.get("x-stainless-lang") == "my-overriding-header"
+ test_client.close()
+ test_client2.close()
+
def test_validate_headers(self) -> None:
client = Gcore(base_url=base_url, api_key=api_key, _strict_response_validation=True)
request = client._build_request(FinalRequestOptions(method="get", url="/foo"))
@@ -362,30 +372,28 @@ def test_default_query_option(self) -> None:
url = httpx.URL(request.url)
assert dict(url.params) == {"foo": "baz", "query_param": "overridden"}
- def test_cloud_project_id_client_params(self) -> None:
- client = Gcore(base_url=base_url, api_key=api_key, _strict_response_validation=True)
+ client.close()
- with client as c2:
- with pytest.raises(ValueError, match="Missing cloud_project_id argument;"):
- c2.cloud.projects.update(name="New Project")
+ def test_cloud_project_id_client_params(self, client: Gcore) -> None:
+ # Test with base client (no custom params)
+ with pytest.raises(ValueError, match="Missing cloud_project_id argument;"):
+ client.cloud.projects.update(name="New Project")
client = Gcore(base_url=base_url, api_key=api_key, _strict_response_validation=True, cloud_project_id=0)
with client as c2:
c2.cloud.projects.update(name="New Project")
- def test_cloud_region_id_client_params(self) -> None:
- client = Gcore(base_url=base_url, api_key=api_key, _strict_response_validation=True)
-
- with client as c2:
- with pytest.raises(ValueError, match="Missing cloud_region_id argument;"):
- c2.cloud.regions.get()
+ def test_cloud_region_id_client_params(self, client: Gcore) -> None:
+ # Test with base client (no custom params)
+ with pytest.raises(ValueError, match="Missing cloud_region_id argument;"):
+ client.cloud.regions.get()
client = Gcore(base_url=base_url, api_key=api_key, _strict_response_validation=True, cloud_region_id=0)
with client as c2:
c2.cloud.regions.get()
- def test_request_extra_json(self) -> None:
- request = self.client._build_request(
+ def test_request_extra_json(self, client: Gcore) -> None:
+ request = client._build_request(
FinalRequestOptions(
method="post",
url="/foo",
@@ -396,7 +404,7 @@ def test_request_extra_json(self) -> None:
data = json.loads(request.content.decode("utf-8"))
assert data == {"foo": "bar", "baz": False}
- request = self.client._build_request(
+ request = client._build_request(
FinalRequestOptions(
method="post",
url="/foo",
@@ -407,7 +415,7 @@ def test_request_extra_json(self) -> None:
assert data == {"baz": False}
# `extra_json` takes priority over `json_data` when keys clash
- request = self.client._build_request(
+ request = client._build_request(
FinalRequestOptions(
method="post",
url="/foo",
@@ -418,8 +426,8 @@ def test_request_extra_json(self) -> None:
data = json.loads(request.content.decode("utf-8"))
assert data == {"foo": "bar", "baz": None}
- def test_request_extra_headers(self) -> None:
- request = self.client._build_request(
+ def test_request_extra_headers(self, client: Gcore) -> None:
+ request = client._build_request(
FinalRequestOptions(
method="post",
url="/foo",
@@ -429,7 +437,7 @@ def test_request_extra_headers(self) -> None:
assert request.headers.get("X-Foo") == "Foo"
# `extra_headers` takes priority over `default_headers` when keys clash
- request = self.client.with_options(default_headers={"X-Bar": "true"})._build_request(
+ request = client.with_options(default_headers={"X-Bar": "true"})._build_request(
FinalRequestOptions(
method="post",
url="/foo",
@@ -440,8 +448,8 @@ def test_request_extra_headers(self) -> None:
)
assert request.headers.get("X-Bar") == "false"
- def test_request_extra_query(self) -> None:
- request = self.client._build_request(
+ def test_request_extra_query(self, client: Gcore) -> None:
+ request = client._build_request(
FinalRequestOptions(
method="post",
url="/foo",
@@ -454,7 +462,7 @@ def test_request_extra_query(self) -> None:
assert params == {"my_query_param": "Foo"}
# if both `query` and `extra_query` are given, they are merged
- request = self.client._build_request(
+ request = client._build_request(
FinalRequestOptions(
method="post",
url="/foo",
@@ -468,7 +476,7 @@ def test_request_extra_query(self) -> None:
assert params == {"bar": "1", "foo": "2"}
# `extra_query` takes priority over `query` when keys clash
- request = self.client._build_request(
+ request = client._build_request(
FinalRequestOptions(
method="post",
url="/foo",
@@ -511,7 +519,7 @@ def test_multipart_repeating_array(self, client: Gcore) -> None:
]
@pytest.mark.respx(base_url=base_url)
- def test_basic_union_response(self, respx_mock: MockRouter) -> None:
+ def test_basic_union_response(self, respx_mock: MockRouter, client: Gcore) -> None:
class Model1(BaseModel):
name: str
@@ -520,12 +528,12 @@ class Model2(BaseModel):
respx_mock.get("/foo").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- response = self.client.get("/foo", cast_to=cast(Any, Union[Model1, Model2]))
+ response = client.get("/foo", cast_to=cast(Any, Union[Model1, Model2]))
assert isinstance(response, Model2)
assert response.foo == "bar"
@pytest.mark.respx(base_url=base_url)
- def test_union_response_different_types(self, respx_mock: MockRouter) -> None:
+ def test_union_response_different_types(self, respx_mock: MockRouter, client: Gcore) -> None:
"""Union of objects with the same field name using a different type"""
class Model1(BaseModel):
@@ -536,18 +544,18 @@ class Model2(BaseModel):
respx_mock.get("/foo").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- response = self.client.get("/foo", cast_to=cast(Any, Union[Model1, Model2]))
+ response = client.get("/foo", cast_to=cast(Any, Union[Model1, Model2]))
assert isinstance(response, Model2)
assert response.foo == "bar"
respx_mock.get("/foo").mock(return_value=httpx.Response(200, json={"foo": 1}))
- response = self.client.get("/foo", cast_to=cast(Any, Union[Model1, Model2]))
+ response = client.get("/foo", cast_to=cast(Any, Union[Model1, Model2]))
assert isinstance(response, Model1)
assert response.foo == 1
@pytest.mark.respx(base_url=base_url)
- def test_non_application_json_content_type_for_json_data(self, respx_mock: MockRouter) -> None:
+ def test_non_application_json_content_type_for_json_data(self, respx_mock: MockRouter, client: Gcore) -> None:
"""
Response that sets Content-Type to something other than application/json but returns json data
"""
@@ -563,7 +571,7 @@ class Model(BaseModel):
)
)
- response = self.client.get("/foo", cast_to=Model)
+ response = client.get("/foo", cast_to=Model)
assert isinstance(response, Model)
assert response.foo == 2
@@ -575,6 +583,8 @@ def test_base_url_setter(self) -> None:
assert client.base_url == "https://example.com/from_setter/"
+ client.close()
+
def test_base_url_env(self) -> None:
with update_env(GCORE_BASE_URL="http://localhost:5000/from/env"):
client = Gcore(api_key=api_key, _strict_response_validation=True)
@@ -602,6 +612,7 @@ def test_base_url_trailing_slash(self, client: Gcore) -> None:
),
)
assert request.url == "http://localhost:5000/custom/path/foo"
+ client.close()
@pytest.mark.parametrize(
"client",
@@ -625,6 +636,7 @@ def test_base_url_no_trailing_slash(self, client: Gcore) -> None:
),
)
assert request.url == "http://localhost:5000/custom/path/foo"
+ client.close()
@pytest.mark.parametrize(
"client",
@@ -648,35 +660,36 @@ def test_absolute_request_url(self, client: Gcore) -> None:
),
)
assert request.url == "https://myapi.com/foo"
+ client.close()
def test_copied_client_does_not_close_http(self) -> None:
- client = Gcore(base_url=base_url, api_key=api_key, _strict_response_validation=True)
- assert not client.is_closed()
+ test_client = Gcore(base_url=base_url, api_key=api_key, _strict_response_validation=True)
+ assert not test_client.is_closed()
- copied = client.copy()
- assert copied is not client
+ copied = test_client.copy()
+ assert copied is not test_client
del copied
- assert not client.is_closed()
+ assert not test_client.is_closed()
def test_client_context_manager(self) -> None:
- client = Gcore(base_url=base_url, api_key=api_key, _strict_response_validation=True)
- with client as c2:
- assert c2 is client
+ test_client = Gcore(base_url=base_url, api_key=api_key, _strict_response_validation=True)
+ with test_client as c2:
+ assert c2 is test_client
assert not c2.is_closed()
- assert not client.is_closed()
- assert client.is_closed()
+ assert not test_client.is_closed()
+ assert test_client.is_closed()
@pytest.mark.respx(base_url=base_url)
- def test_client_response_validation_error(self, respx_mock: MockRouter) -> None:
+ def test_client_response_validation_error(self, respx_mock: MockRouter, client: Gcore) -> None:
class Model(BaseModel):
foo: str
respx_mock.get("/foo").mock(return_value=httpx.Response(200, json={"foo": {"invalid": True}}))
with pytest.raises(APIResponseValidationError) as exc:
- self.client.get("/foo", cast_to=Model)
+ client.get("/foo", cast_to=Model)
assert isinstance(exc.value.__cause__, ValidationError)
@@ -696,11 +709,14 @@ class Model(BaseModel):
with pytest.raises(APIResponseValidationError):
strict_client.get("/foo", cast_to=Model)
- client = Gcore(base_url=base_url, api_key=api_key, _strict_response_validation=False)
+ non_strict_client = Gcore(base_url=base_url, api_key=api_key, _strict_response_validation=False)
- response = client.get("/foo", cast_to=Model)
+ response = non_strict_client.get("/foo", cast_to=Model)
assert isinstance(response, str) # type: ignore[unreachable]
+ strict_client.close()
+ non_strict_client.close()
+
@pytest.mark.parametrize(
"remaining_retries,retry_after,timeout",
[
@@ -723,9 +739,9 @@ class Model(BaseModel):
],
)
@mock.patch("time.time", mock.MagicMock(return_value=1696004797))
- def test_parse_retry_after_header(self, remaining_retries: int, retry_after: str, timeout: float) -> None:
- client = Gcore(base_url=base_url, api_key=api_key, _strict_response_validation=True)
-
+ def test_parse_retry_after_header(
+ self, remaining_retries: int, retry_after: str, timeout: float, client: Gcore
+ ) -> None:
headers = httpx.Headers({"retry-after": retry_after})
options = FinalRequestOptions(method="get", url="/foo", max_retries=3)
calculated = client._calculate_retry_timeout(remaining_retries, options, headers)
@@ -739,7 +755,7 @@ def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter, clien
with pytest.raises(APITimeoutError):
client.cloud.projects.with_streaming_response.create(name="New Project").__enter__()
- assert _get_open_connections(self.client) == 0
+ assert _get_open_connections(client) == 0
@mock.patch("gcore._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
@@ -748,7 +764,7 @@ def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter, client
with pytest.raises(APIStatusError):
client.cloud.projects.with_streaming_response.create(name="New Project").__enter__()
- assert _get_open_connections(self.client) == 0
+ assert _get_open_connections(client) == 0
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
@mock.patch("gcore._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@@ -852,83 +868,77 @@ def test_default_client_creation(self) -> None:
)
@pytest.mark.respx(base_url=base_url)
- def test_follow_redirects(self, respx_mock: MockRouter) -> None:
+ def test_follow_redirects(self, respx_mock: MockRouter, client: Gcore) -> None:
# Test that the default follow_redirects=True allows following redirects
respx_mock.post("/redirect").mock(
return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"})
)
respx_mock.get("/redirected").mock(return_value=httpx.Response(200, json={"status": "ok"}))
- response = self.client.post("/redirect", body={"key": "value"}, cast_to=httpx.Response)
+ response = client.post("/redirect", body={"key": "value"}, cast_to=httpx.Response)
assert response.status_code == 200
assert response.json() == {"status": "ok"}
@pytest.mark.respx(base_url=base_url)
- def test_follow_redirects_disabled(self, respx_mock: MockRouter) -> None:
+ def test_follow_redirects_disabled(self, respx_mock: MockRouter, client: Gcore) -> None:
# Test that follow_redirects=False prevents following redirects
respx_mock.post("/redirect").mock(
return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"})
)
with pytest.raises(APIStatusError) as exc_info:
- self.client.post(
- "/redirect", body={"key": "value"}, options={"follow_redirects": False}, cast_to=httpx.Response
- )
+ client.post("/redirect", body={"key": "value"}, options={"follow_redirects": False}, cast_to=httpx.Response)
assert exc_info.value.response.status_code == 302
assert exc_info.value.response.headers["Location"] == f"{base_url}/redirected"
class TestAsyncGcore:
- client = AsyncGcore(base_url=base_url, api_key=api_key, _strict_response_validation=True)
-
@pytest.mark.respx(base_url=base_url)
- @pytest.mark.asyncio
- async def test_raw_response(self, respx_mock: MockRouter) -> None:
+ async def test_raw_response(self, respx_mock: MockRouter, async_client: AsyncGcore) -> None:
respx_mock.post("/foo").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- response = await self.client.post("/foo", cast_to=httpx.Response)
+ response = await async_client.post("/foo", cast_to=httpx.Response)
assert response.status_code == 200
assert isinstance(response, httpx.Response)
assert response.json() == {"foo": "bar"}
@pytest.mark.respx(base_url=base_url)
- @pytest.mark.asyncio
- async def test_raw_response_for_binary(self, respx_mock: MockRouter) -> None:
+ async def test_raw_response_for_binary(self, respx_mock: MockRouter, async_client: AsyncGcore) -> None:
respx_mock.post("/foo").mock(
return_value=httpx.Response(200, headers={"Content-Type": "application/binary"}, content='{"foo": "bar"}')
)
- response = await self.client.post("/foo", cast_to=httpx.Response)
+ response = await async_client.post("/foo", cast_to=httpx.Response)
assert response.status_code == 200
assert isinstance(response, httpx.Response)
assert response.json() == {"foo": "bar"}
- def test_copy(self) -> None:
- copied = self.client.copy()
- assert id(copied) != id(self.client)
+ def test_copy(self, async_client: AsyncGcore) -> None:
+ copied = async_client.copy()
+ assert id(copied) != id(async_client)
- copied = self.client.copy(api_key="another My API Key")
+ copied = async_client.copy(api_key="another My API Key")
assert copied.api_key == "another My API Key"
- assert self.client.api_key == "My API Key"
+ assert async_client.api_key == "My API Key"
- def test_copy_default_options(self) -> None:
+ def test_copy_default_options(self, async_client: AsyncGcore) -> None:
# options that have a default are overridden correctly
- copied = self.client.copy(max_retries=7)
+ copied = async_client.copy(max_retries=7)
assert copied.max_retries == 7
- assert self.client.max_retries == 2
+ assert async_client.max_retries == 2
copied2 = copied.copy(max_retries=6)
assert copied2.max_retries == 6
assert copied.max_retries == 7
# timeout
- assert isinstance(self.client.timeout, httpx.Timeout)
- copied = self.client.copy(timeout=None)
+ assert isinstance(async_client.timeout, httpx.Timeout)
+ copied = async_client.copy(timeout=None)
assert copied.timeout is None
- assert isinstance(self.client.timeout, httpx.Timeout)
+ assert isinstance(async_client.timeout, httpx.Timeout)
- def test_copy_default_headers(self) -> None:
+ async def test_copy_default_headers(self) -> None:
client = AsyncGcore(
base_url=base_url, api_key=api_key, _strict_response_validation=True, default_headers={"X-Foo": "bar"}
)
@@ -961,8 +971,9 @@ def test_copy_default_headers(self) -> None:
match="`default_headers` and `set_default_headers` arguments are mutually exclusive",
):
client.copy(set_default_headers={}, default_headers={"X-Foo": "Bar"})
+ await client.close()
- def test_copy_default_query(self) -> None:
+ async def test_copy_default_query(self) -> None:
client = AsyncGcore(
base_url=base_url, api_key=api_key, _strict_response_validation=True, default_query={"foo": "bar"}
)
@@ -998,13 +1009,15 @@ def test_copy_default_query(self) -> None:
):
client.copy(set_default_query={}, default_query={"foo": "Bar"})
- def test_copy_signature(self) -> None:
+ await client.close()
+
+ def test_copy_signature(self, async_client: AsyncGcore) -> None:
# ensure the same parameters that can be passed to the client are defined in the `.copy()` method
init_signature = inspect.signature(
# mypy doesn't like that we access the `__init__` property.
- self.client.__init__, # type: ignore[misc]
+ async_client.__init__, # type: ignore[misc]
)
- copy_signature = inspect.signature(self.client.copy)
+ copy_signature = inspect.signature(async_client.copy)
exclude_params = {"transport", "proxies", "_strict_response_validation"}
for name in init_signature.parameters.keys():
@@ -1015,12 +1028,12 @@ def test_copy_signature(self) -> None:
assert copy_param is not None, f"copy() signature is missing the {name} param"
@pytest.mark.skipif(sys.version_info >= (3, 10), reason="fails because of a memory leak that started from 3.12")
- def test_copy_build_request(self) -> None:
+ def test_copy_build_request(self, async_client: AsyncGcore) -> None:
options = FinalRequestOptions(method="get", url="/foo")
def build_request(options: FinalRequestOptions) -> None:
- client = self.client.copy()
- client._build_request(options)
+ client_copy = async_client.copy()
+ client_copy._build_request(options)
# ensure that the machinery is warmed up before tracing starts.
build_request(options)
@@ -1077,12 +1090,12 @@ def add_leak(leaks: list[tracemalloc.StatisticDiff], diff: tracemalloc.Statistic
print(frame)
raise AssertionError()
- async def test_request_timeout(self) -> None:
- request = self.client._build_request(FinalRequestOptions(method="get", url="/foo"))
+ async def test_request_timeout(self, async_client: AsyncGcore) -> None:
+ request = async_client._build_request(FinalRequestOptions(method="get", url="/foo"))
timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore
assert timeout == DEFAULT_TIMEOUT
- request = self.client._build_request(
+ request = async_client._build_request(
FinalRequestOptions(method="get", url="/foo", timeout=httpx.Timeout(100.0))
)
timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore
@@ -1097,6 +1110,8 @@ async def test_client_timeout_option(self) -> None:
timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore
assert timeout == httpx.Timeout(0)
+ await client.close()
+
async def test_http_client_timeout_option(self) -> None:
# custom timeout given to the httpx client should be used
async with httpx.AsyncClient(timeout=None) as http_client:
@@ -1108,6 +1123,8 @@ async def test_http_client_timeout_option(self) -> None:
timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore
assert timeout == httpx.Timeout(None)
+ await client.close()
+
# no timeout given to the httpx client should not use the httpx default
async with httpx.AsyncClient() as http_client:
client = AsyncGcore(
@@ -1118,6 +1135,8 @@ async def test_http_client_timeout_option(self) -> None:
timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore
assert timeout == DEFAULT_TIMEOUT
+ await client.close()
+
# explicitly passing the default timeout currently results in it being ignored
async with httpx.AsyncClient(timeout=HTTPX_DEFAULT_TIMEOUT) as http_client:
client = AsyncGcore(
@@ -1128,6 +1147,8 @@ async def test_http_client_timeout_option(self) -> None:
timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore
assert timeout == DEFAULT_TIMEOUT # our default
+ await client.close()
+
def test_invalid_http_client(self) -> None:
with pytest.raises(TypeError, match="Invalid `http_client` arg"):
with httpx.Client() as http_client:
@@ -1138,15 +1159,15 @@ def test_invalid_http_client(self) -> None:
http_client=cast(Any, http_client),
)
- def test_default_headers_option(self) -> None:
- client = AsyncGcore(
+ async def test_default_headers_option(self) -> None:
+ test_client = AsyncGcore(
base_url=base_url, api_key=api_key, _strict_response_validation=True, default_headers={"X-Foo": "bar"}
)
- request = client._build_request(FinalRequestOptions(method="get", url="/foo"))
+ request = test_client._build_request(FinalRequestOptions(method="get", url="/foo"))
assert request.headers.get("x-foo") == "bar"
assert request.headers.get("x-stainless-lang") == "python"
- client2 = AsyncGcore(
+ test_client2 = AsyncGcore(
base_url=base_url,
api_key=api_key,
_strict_response_validation=True,
@@ -1155,10 +1176,13 @@ def test_default_headers_option(self) -> None:
"X-Stainless-Lang": "my-overriding-header",
},
)
- request = client2._build_request(FinalRequestOptions(method="get", url="/foo"))
+ request = test_client2._build_request(FinalRequestOptions(method="get", url="/foo"))
assert request.headers.get("x-foo") == "stainless"
assert request.headers.get("x-stainless-lang") == "my-overriding-header"
+ await test_client.close()
+ await test_client2.close()
+
def test_validate_headers(self) -> None:
client = AsyncGcore(base_url=base_url, api_key=api_key, _strict_response_validation=True)
request = client._build_request(FinalRequestOptions(method="get", url="/foo"))
@@ -1169,7 +1193,7 @@ def test_validate_headers(self) -> None:
client2 = AsyncGcore(base_url=base_url, api_key=None, _strict_response_validation=True)
_ = client2
- def test_default_query_option(self) -> None:
+ async def test_default_query_option(self) -> None:
client = AsyncGcore(
base_url=base_url, api_key=api_key, _strict_response_validation=True, default_query={"query_param": "bar"}
)
@@ -1187,30 +1211,28 @@ def test_default_query_option(self) -> None:
url = httpx.URL(request.url)
assert dict(url.params) == {"foo": "baz", "query_param": "overridden"}
- async def test_cloud_project_id_client_params(self) -> None:
- client = AsyncGcore(base_url=base_url, api_key=api_key, _strict_response_validation=True)
+ await client.close()
- async with client as c2:
- with pytest.raises(ValueError, match="Missing cloud_project_id argument;"):
- await c2.cloud.projects.update(name="New Project")
+ async def test_cloud_project_id_client_params(self, async_client: AsyncGcore) -> None:
+ # Test with base client (no custom params)
+ with pytest.raises(ValueError, match="Missing cloud_project_id argument;"):
+ await async_client.cloud.projects.update(name="New Project")
client = AsyncGcore(base_url=base_url, api_key=api_key, _strict_response_validation=True, cloud_project_id=0)
async with client as c2:
await c2.cloud.projects.update(name="New Project")
- async def test_cloud_region_id_client_params(self) -> None:
- client = AsyncGcore(base_url=base_url, api_key=api_key, _strict_response_validation=True)
-
- async with client as c2:
- with pytest.raises(ValueError, match="Missing cloud_region_id argument;"):
- await c2.cloud.regions.get()
+ async def test_cloud_region_id_client_params(self, async_client: AsyncGcore) -> None:
+ # Test with base client (no custom params)
+ with pytest.raises(ValueError, match="Missing cloud_region_id argument;"):
+ await async_client.cloud.regions.get()
client = AsyncGcore(base_url=base_url, api_key=api_key, _strict_response_validation=True, cloud_region_id=0)
async with client as c2:
await c2.cloud.regions.get()
- def test_request_extra_json(self) -> None:
- request = self.client._build_request(
+ def test_request_extra_json(self, client: Gcore) -> None:
+ request = client._build_request(
FinalRequestOptions(
method="post",
url="/foo",
@@ -1221,7 +1243,7 @@ def test_request_extra_json(self) -> None:
data = json.loads(request.content.decode("utf-8"))
assert data == {"foo": "bar", "baz": False}
- request = self.client._build_request(
+ request = client._build_request(
FinalRequestOptions(
method="post",
url="/foo",
@@ -1232,7 +1254,7 @@ def test_request_extra_json(self) -> None:
assert data == {"baz": False}
# `extra_json` takes priority over `json_data` when keys clash
- request = self.client._build_request(
+ request = client._build_request(
FinalRequestOptions(
method="post",
url="/foo",
@@ -1243,8 +1265,8 @@ def test_request_extra_json(self) -> None:
data = json.loads(request.content.decode("utf-8"))
assert data == {"foo": "bar", "baz": None}
- def test_request_extra_headers(self) -> None:
- request = self.client._build_request(
+ def test_request_extra_headers(self, client: Gcore) -> None:
+ request = client._build_request(
FinalRequestOptions(
method="post",
url="/foo",
@@ -1254,7 +1276,7 @@ def test_request_extra_headers(self) -> None:
assert request.headers.get("X-Foo") == "Foo"
# `extra_headers` takes priority over `default_headers` when keys clash
- request = self.client.with_options(default_headers={"X-Bar": "true"})._build_request(
+ request = client.with_options(default_headers={"X-Bar": "true"})._build_request(
FinalRequestOptions(
method="post",
url="/foo",
@@ -1265,8 +1287,8 @@ def test_request_extra_headers(self) -> None:
)
assert request.headers.get("X-Bar") == "false"
- def test_request_extra_query(self) -> None:
- request = self.client._build_request(
+ def test_request_extra_query(self, client: Gcore) -> None:
+ request = client._build_request(
FinalRequestOptions(
method="post",
url="/foo",
@@ -1279,7 +1301,7 @@ def test_request_extra_query(self) -> None:
assert params == {"my_query_param": "Foo"}
# if both `query` and `extra_query` are given, they are merged
- request = self.client._build_request(
+ request = client._build_request(
FinalRequestOptions(
method="post",
url="/foo",
@@ -1293,7 +1315,7 @@ def test_request_extra_query(self) -> None:
assert params == {"bar": "1", "foo": "2"}
# `extra_query` takes priority over `query` when keys clash
- request = self.client._build_request(
+ request = client._build_request(
FinalRequestOptions(
method="post",
url="/foo",
@@ -1336,7 +1358,7 @@ def test_multipart_repeating_array(self, async_client: AsyncGcore) -> None:
]
@pytest.mark.respx(base_url=base_url)
- async def test_basic_union_response(self, respx_mock: MockRouter) -> None:
+ async def test_basic_union_response(self, respx_mock: MockRouter, async_client: AsyncGcore) -> None:
class Model1(BaseModel):
name: str
@@ -1345,12 +1367,12 @@ class Model2(BaseModel):
respx_mock.get("/foo").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- response = await self.client.get("/foo", cast_to=cast(Any, Union[Model1, Model2]))
+ response = await async_client.get("/foo", cast_to=cast(Any, Union[Model1, Model2]))
assert isinstance(response, Model2)
assert response.foo == "bar"
@pytest.mark.respx(base_url=base_url)
- async def test_union_response_different_types(self, respx_mock: MockRouter) -> None:
+ async def test_union_response_different_types(self, respx_mock: MockRouter, async_client: AsyncGcore) -> None:
"""Union of objects with the same field name using a different type"""
class Model1(BaseModel):
@@ -1361,18 +1383,20 @@ class Model2(BaseModel):
respx_mock.get("/foo").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- response = await self.client.get("/foo", cast_to=cast(Any, Union[Model1, Model2]))
+ response = await async_client.get("/foo", cast_to=cast(Any, Union[Model1, Model2]))
assert isinstance(response, Model2)
assert response.foo == "bar"
respx_mock.get("/foo").mock(return_value=httpx.Response(200, json={"foo": 1}))
- response = await self.client.get("/foo", cast_to=cast(Any, Union[Model1, Model2]))
+ response = await async_client.get("/foo", cast_to=cast(Any, Union[Model1, Model2]))
assert isinstance(response, Model1)
assert response.foo == 1
@pytest.mark.respx(base_url=base_url)
- async def test_non_application_json_content_type_for_json_data(self, respx_mock: MockRouter) -> None:
+ async def test_non_application_json_content_type_for_json_data(
+ self, respx_mock: MockRouter, async_client: AsyncGcore
+ ) -> None:
"""
Response that sets Content-Type to something other than application/json but returns json data
"""
@@ -1388,11 +1412,11 @@ class Model(BaseModel):
)
)
- response = await self.client.get("/foo", cast_to=Model)
+ response = await async_client.get("/foo", cast_to=Model)
assert isinstance(response, Model)
assert response.foo == 2
- def test_base_url_setter(self) -> None:
+ async def test_base_url_setter(self) -> None:
client = AsyncGcore(base_url="https://example.com/from_init", api_key=api_key, _strict_response_validation=True)
assert client.base_url == "https://example.com/from_init/"
@@ -1400,7 +1424,9 @@ def test_base_url_setter(self) -> None:
assert client.base_url == "https://example.com/from_setter/"
- def test_base_url_env(self) -> None:
+ await client.close()
+
+ async def test_base_url_env(self) -> None:
with update_env(GCORE_BASE_URL="http://localhost:5000/from/env"):
client = AsyncGcore(api_key=api_key, _strict_response_validation=True)
assert client.base_url == "http://localhost:5000/from/env/"
@@ -1420,7 +1446,7 @@ def test_base_url_env(self) -> None:
],
ids=["standard", "custom http client"],
)
- def test_base_url_trailing_slash(self, client: AsyncGcore) -> None:
+ async def test_base_url_trailing_slash(self, client: AsyncGcore) -> None:
request = client._build_request(
FinalRequestOptions(
method="post",
@@ -1429,6 +1455,7 @@ def test_base_url_trailing_slash(self, client: AsyncGcore) -> None:
),
)
assert request.url == "http://localhost:5000/custom/path/foo"
+ await client.close()
@pytest.mark.parametrize(
"client",
@@ -1445,7 +1472,7 @@ def test_base_url_trailing_slash(self, client: AsyncGcore) -> None:
],
ids=["standard", "custom http client"],
)
- def test_base_url_no_trailing_slash(self, client: AsyncGcore) -> None:
+ async def test_base_url_no_trailing_slash(self, client: AsyncGcore) -> None:
request = client._build_request(
FinalRequestOptions(
method="post",
@@ -1454,6 +1481,7 @@ def test_base_url_no_trailing_slash(self, client: AsyncGcore) -> None:
),
)
assert request.url == "http://localhost:5000/custom/path/foo"
+ await client.close()
@pytest.mark.parametrize(
"client",
@@ -1470,7 +1498,7 @@ def test_base_url_no_trailing_slash(self, client: AsyncGcore) -> None:
],
ids=["standard", "custom http client"],
)
- def test_absolute_request_url(self, client: AsyncGcore) -> None:
+ async def test_absolute_request_url(self, client: AsyncGcore) -> None:
request = client._build_request(
FinalRequestOptions(
method="post",
@@ -1479,37 +1507,37 @@ def test_absolute_request_url(self, client: AsyncGcore) -> None:
),
)
assert request.url == "https://myapi.com/foo"
+ await client.close()
async def test_copied_client_does_not_close_http(self) -> None:
- client = AsyncGcore(base_url=base_url, api_key=api_key, _strict_response_validation=True)
- assert not client.is_closed()
+ test_client = AsyncGcore(base_url=base_url, api_key=api_key, _strict_response_validation=True)
+ assert not test_client.is_closed()
- copied = client.copy()
- assert copied is not client
+ copied = test_client.copy()
+ assert copied is not test_client
del copied
await asyncio.sleep(0.2)
- assert not client.is_closed()
+ assert not test_client.is_closed()
async def test_client_context_manager(self) -> None:
- client = AsyncGcore(base_url=base_url, api_key=api_key, _strict_response_validation=True)
- async with client as c2:
- assert c2 is client
+ test_client = AsyncGcore(base_url=base_url, api_key=api_key, _strict_response_validation=True)
+ async with test_client as c2:
+ assert c2 is test_client
assert not c2.is_closed()
- assert not client.is_closed()
- assert client.is_closed()
+ assert not test_client.is_closed()
+ assert test_client.is_closed()
@pytest.mark.respx(base_url=base_url)
- @pytest.mark.asyncio
- async def test_client_response_validation_error(self, respx_mock: MockRouter) -> None:
+ async def test_client_response_validation_error(self, respx_mock: MockRouter, async_client: AsyncGcore) -> None:
class Model(BaseModel):
foo: str
respx_mock.get("/foo").mock(return_value=httpx.Response(200, json={"foo": {"invalid": True}}))
with pytest.raises(APIResponseValidationError) as exc:
- await self.client.get("/foo", cast_to=Model)
+ await async_client.get("/foo", cast_to=Model)
assert isinstance(exc.value.__cause__, ValidationError)
@@ -1520,7 +1548,6 @@ async def test_client_max_retries_validation(self) -> None:
)
@pytest.mark.respx(base_url=base_url)
- @pytest.mark.asyncio
async def test_received_text_for_expected_json(self, respx_mock: MockRouter) -> None:
class Model(BaseModel):
name: str
@@ -1532,11 +1559,14 @@ class Model(BaseModel):
with pytest.raises(APIResponseValidationError):
await strict_client.get("/foo", cast_to=Model)
- client = AsyncGcore(base_url=base_url, api_key=api_key, _strict_response_validation=False)
+ non_strict_client = AsyncGcore(base_url=base_url, api_key=api_key, _strict_response_validation=False)
- response = await client.get("/foo", cast_to=Model)
+ response = await non_strict_client.get("/foo", cast_to=Model)
assert isinstance(response, str) # type: ignore[unreachable]
+ await strict_client.close()
+ await non_strict_client.close()
+
@pytest.mark.parametrize(
"remaining_retries,retry_after,timeout",
[
@@ -1559,13 +1589,12 @@ class Model(BaseModel):
],
)
@mock.patch("time.time", mock.MagicMock(return_value=1696004797))
- @pytest.mark.asyncio
- async def test_parse_retry_after_header(self, remaining_retries: int, retry_after: str, timeout: float) -> None:
- client = AsyncGcore(base_url=base_url, api_key=api_key, _strict_response_validation=True)
-
+ async def test_parse_retry_after_header(
+ self, remaining_retries: int, retry_after: str, timeout: float, async_client: AsyncGcore
+ ) -> None:
headers = httpx.Headers({"retry-after": retry_after})
options = FinalRequestOptions(method="get", url="/foo", max_retries=3)
- calculated = client._calculate_retry_timeout(remaining_retries, options, headers)
+ calculated = async_client._calculate_retry_timeout(remaining_retries, options, headers)
assert calculated == pytest.approx(timeout, 0.5 * 0.875) # pyright: ignore[reportUnknownMemberType]
@mock.patch("gcore._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@@ -1576,7 +1605,7 @@ async def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter,
with pytest.raises(APITimeoutError):
await async_client.cloud.projects.with_streaming_response.create(name="New Project").__aenter__()
- assert _get_open_connections(self.client) == 0
+ assert _get_open_connections(async_client) == 0
@mock.patch("gcore._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
@@ -1585,12 +1614,11 @@ async def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter,
with pytest.raises(APIStatusError):
await async_client.cloud.projects.with_streaming_response.create(name="New Project").__aenter__()
- assert _get_open_connections(self.client) == 0
+ assert _get_open_connections(async_client) == 0
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
@mock.patch("gcore._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
- @pytest.mark.asyncio
@pytest.mark.parametrize("failure_mode", ["status", "exception"])
async def test_retries_taken(
self,
@@ -1622,7 +1650,6 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
@mock.patch("gcore._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
- @pytest.mark.asyncio
async def test_omit_retry_count_header(
self, async_client: AsyncGcore, failures_before_success: int, respx_mock: MockRouter
) -> None:
@@ -1648,7 +1675,6 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
@mock.patch("gcore._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
- @pytest.mark.asyncio
async def test_overwrite_retry_count_header(
self, async_client: AsyncGcore, failures_before_success: int, respx_mock: MockRouter
) -> None:
@@ -1698,26 +1724,26 @@ async def test_default_client_creation(self) -> None:
)
@pytest.mark.respx(base_url=base_url)
- async def test_follow_redirects(self, respx_mock: MockRouter) -> None:
+ async def test_follow_redirects(self, respx_mock: MockRouter, async_client: AsyncGcore) -> None:
# Test that the default follow_redirects=True allows following redirects
respx_mock.post("/redirect").mock(
return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"})
)
respx_mock.get("/redirected").mock(return_value=httpx.Response(200, json={"status": "ok"}))
- response = await self.client.post("/redirect", body={"key": "value"}, cast_to=httpx.Response)
+ response = await async_client.post("/redirect", body={"key": "value"}, cast_to=httpx.Response)
assert response.status_code == 200
assert response.json() == {"status": "ok"}
@pytest.mark.respx(base_url=base_url)
- async def test_follow_redirects_disabled(self, respx_mock: MockRouter) -> None:
+ async def test_follow_redirects_disabled(self, respx_mock: MockRouter, async_client: AsyncGcore) -> None:
# Test that follow_redirects=False prevents following redirects
respx_mock.post("/redirect").mock(
return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"})
)
with pytest.raises(APIStatusError) as exc_info:
- await self.client.post(
+ await async_client.post(
"/redirect", body={"key": "value"}, options={"follow_redirects": False}, cast_to=httpx.Response
)
From 62b23ee2f8f81f4f2159cee48dc6133463bbf526 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 30 Oct 2025 14:25:37 +0000
Subject: [PATCH 18/27] codegen metadata
---
.stats.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.stats.yml b/.stats.yml
index f535120f..4f5a18fa 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 609
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-848b764e60807c1c1aedd39ebdbadd2ee63dcc6ae3910179cdfff3ef80429563.yml
openapi_spec_hash: 04d6bac6704e464b0fa52af0cd0e18a2
-config_hash: 25b1dd444559d26e51bf85892358c0bc
+config_hash: 4758209f53bb13d06f55e4cf6c952b6d
From 9f6d1a715b8a64fc4973d80f5d511ecaf878837e Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 30 Oct 2025 16:12:06 +0000
Subject: [PATCH 19/27] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 4f5a18fa..c4fe28d4 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 609
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-848b764e60807c1c1aedd39ebdbadd2ee63dcc6ae3910179cdfff3ef80429563.yml
-openapi_spec_hash: 04d6bac6704e464b0fa52af0cd0e18a2
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-0346b042bad7a80c3a1d4281080d8196a2e7fe31d16555fa09a969c17135802d.yml
+openapi_spec_hash: 89f372e20779803f35c14b4189960972
config_hash: 4758209f53bb13d06f55e4cf6c952b6d
From 01c746977c89d813e54b97c87513960a5cba42c3 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 3 Nov 2025 10:12:06 +0000
Subject: [PATCH 20/27] feat(api): aggregated API specs update
---
.stats.yml | 6 +-
api.md | 42 +-
src/gcore/_client.py | 9 -
src/gcore/resources/__init__.py | 14 -
src/gcore/resources/security/__init__.py | 75 --
src/gcore/resources/security/bgp_announces.py | 308 --------
src/gcore/resources/security/events.py | 234 -------
.../resources/security/profile_templates.py | 143 ----
src/gcore/resources/security/profiles.py | 661 ------------------
src/gcore/resources/security/security.py | 198 ------
src/gcore/types/security/__init__.py | 15 -
.../security/bgp_announce_list_params.py | 18 -
.../security/bgp_announce_list_response.py | 10 -
.../security/bgp_announce_toggle_params.py | 16 -
src/gcore/types/security/client_announce.py | 15 -
src/gcore/types/security/client_profile.py | 56 --
.../types/security/client_profile_template.py | 43 --
src/gcore/types/security/client_view.py | 29 -
src/gcore/types/security/event_list_params.py | 38 -
.../types/security/profile_create_params.py | 24 -
.../types/security/profile_list_params.py | 17 -
.../types/security/profile_list_response.py | 10 -
.../types/security/profile_recreate_params.py | 24 -
.../types/security/profile_replace_params.py | 24 -
.../profile_template_list_response.py | 10 -
tests/api_resources/security/__init__.py | 1 -
.../security/test_bgp_announces.py | 180 -----
tests/api_resources/security/test_events.py | 102 ---
.../security/test_profile_templates.py | 74 --
tests/api_resources/security/test_profiles.py | 537 --------------
30 files changed, 5 insertions(+), 2928 deletions(-)
delete mode 100644 src/gcore/resources/security/__init__.py
delete mode 100644 src/gcore/resources/security/bgp_announces.py
delete mode 100644 src/gcore/resources/security/events.py
delete mode 100644 src/gcore/resources/security/profile_templates.py
delete mode 100644 src/gcore/resources/security/profiles.py
delete mode 100644 src/gcore/resources/security/security.py
delete mode 100644 src/gcore/types/security/bgp_announce_list_params.py
delete mode 100644 src/gcore/types/security/bgp_announce_list_response.py
delete mode 100644 src/gcore/types/security/bgp_announce_toggle_params.py
delete mode 100644 src/gcore/types/security/client_announce.py
delete mode 100644 src/gcore/types/security/client_profile.py
delete mode 100644 src/gcore/types/security/client_profile_template.py
delete mode 100644 src/gcore/types/security/client_view.py
delete mode 100644 src/gcore/types/security/event_list_params.py
delete mode 100644 src/gcore/types/security/profile_create_params.py
delete mode 100644 src/gcore/types/security/profile_list_params.py
delete mode 100644 src/gcore/types/security/profile_list_response.py
delete mode 100644 src/gcore/types/security/profile_recreate_params.py
delete mode 100644 src/gcore/types/security/profile_replace_params.py
delete mode 100644 src/gcore/types/security/profile_template_list_response.py
delete mode 100644 tests/api_resources/security/__init__.py
delete mode 100644 tests/api_resources/security/test_bgp_announces.py
delete mode 100644 tests/api_resources/security/test_events.py
delete mode 100644 tests/api_resources/security/test_profile_templates.py
delete mode 100644 tests/api_resources/security/test_profiles.py
diff --git a/.stats.yml b/.stats.yml
index c4fe28d4..d0525a7d 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 609
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-0346b042bad7a80c3a1d4281080d8196a2e7fe31d16555fa09a969c17135802d.yml
-openapi_spec_hash: 89f372e20779803f35c14b4189960972
+configured_endpoints: 599
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-963021ac0cb8a12826d7e00d317340e71748a27c18553422a76d882d2e8ad389.yml
+openapi_spec_hash: 0c1ea27cd584bf0d47fed367663053b2
config_hash: 4758209f53bb13d06f55e4cf6c952b6d
diff --git a/api.md b/api.md
index 6ff46915..2fe398c1 100644
--- a/api.md
+++ b/api.md
@@ -1789,60 +1789,22 @@ Methods:
# Security
-## Events
-
-Types:
-
-```python
-from gcore.types.security import ClientView
-```
-
-Methods:
-
-- client.security.events.list(\*\*params) -> SyncOffsetPage[ClientView]
-
-## BgpAnnounces
-
-Types:
-
-```python
-from gcore.types.security import ClientAnnounce, BgpAnnounceListResponse
-```
-
-Methods:
-
-- client.security.bgp_announces.list(\*\*params) -> BgpAnnounceListResponse
-- client.security.bgp_announces.toggle(\*\*params) -> object
-
## ProfileTemplates
Types:
```python
-from gcore.types.security import ClientProfileTemplate, ProfileTemplateListResponse
+from gcore.types.security import ClientProfileTemplate
```
-Methods:
-
-- client.security.profile_templates.list() -> ProfileTemplateListResponse
-
## Profiles
Types:
```python
-from gcore.types.security import ClientProfile, ProfileListResponse
+from gcore.types.security import ClientProfile
```
-Methods:
-
-- client.security.profiles.create(\*\*params) -> ClientProfile
-- client.security.profiles.list(\*\*params) -> ProfileListResponse
-- client.security.profiles.delete(id) -> None
-- client.security.profiles.get(id) -> ClientProfile
-- client.security.profiles.recreate(id, \*\*params) -> ClientProfile
-- client.security.profiles.replace(id, \*\*params) -> ClientProfile
-
# DNS
Types:
diff --git a/src/gcore/_client.py b/src/gcore/_client.py
index d900f571..df7f4886 100644
--- a/src/gcore/_client.py
+++ b/src/gcore/_client.py
@@ -35,7 +35,6 @@
from .resources.cloud import cloud
from .resources.storage import storage
from .resources.fastedge import fastedge
-from .resources.security import security
from .resources.streaming import streaming
__all__ = ["Timeout", "Transport", "ProxiesTypes", "RequestOptions", "Gcore", "AsyncGcore", "Client", "AsyncClient"]
@@ -47,7 +46,6 @@ class Gcore(SyncAPIClient):
iam: iam.IamResource
fastedge: fastedge.FastedgeResource
streaming: streaming.StreamingResource
- security: security.SecurityResource
dns: dns.DNSResource
storage: storage.StorageResource
cdn: cdn.CdnResource
@@ -140,7 +138,6 @@ def __init__(
self.iam = iam.IamResource(self)
self.fastedge = fastedge.FastedgeResource(self)
self.streaming = streaming.StreamingResource(self)
- self.security = security.SecurityResource(self)
self.dns = dns.DNSResource(self)
self.storage = storage.StorageResource(self)
self.cdn = cdn.CdnResource(self)
@@ -284,7 +281,6 @@ class AsyncGcore(AsyncAPIClient):
iam: iam.AsyncIamResource
fastedge: fastedge.AsyncFastedgeResource
streaming: streaming.AsyncStreamingResource
- security: security.AsyncSecurityResource
dns: dns.AsyncDNSResource
storage: storage.AsyncStorageResource
cdn: cdn.AsyncCdnResource
@@ -377,7 +373,6 @@ def __init__(
self.iam = iam.AsyncIamResource(self)
self.fastedge = fastedge.AsyncFastedgeResource(self)
self.streaming = streaming.AsyncStreamingResource(self)
- self.security = security.AsyncSecurityResource(self)
self.dns = dns.AsyncDNSResource(self)
self.storage = storage.AsyncStorageResource(self)
self.cdn = cdn.AsyncCdnResource(self)
@@ -522,7 +517,6 @@ def __init__(self, client: Gcore) -> None:
self.iam = iam.IamResourceWithRawResponse(client.iam)
self.fastedge = fastedge.FastedgeResourceWithRawResponse(client.fastedge)
self.streaming = streaming.StreamingResourceWithRawResponse(client.streaming)
- self.security = security.SecurityResourceWithRawResponse(client.security)
self.dns = dns.DNSResourceWithRawResponse(client.dns)
self.storage = storage.StorageResourceWithRawResponse(client.storage)
self.cdn = cdn.CdnResourceWithRawResponse(client.cdn)
@@ -535,7 +529,6 @@ def __init__(self, client: AsyncGcore) -> None:
self.iam = iam.AsyncIamResourceWithRawResponse(client.iam)
self.fastedge = fastedge.AsyncFastedgeResourceWithRawResponse(client.fastedge)
self.streaming = streaming.AsyncStreamingResourceWithRawResponse(client.streaming)
- self.security = security.AsyncSecurityResourceWithRawResponse(client.security)
self.dns = dns.AsyncDNSResourceWithRawResponse(client.dns)
self.storage = storage.AsyncStorageResourceWithRawResponse(client.storage)
self.cdn = cdn.AsyncCdnResourceWithRawResponse(client.cdn)
@@ -548,7 +541,6 @@ def __init__(self, client: Gcore) -> None:
self.iam = iam.IamResourceWithStreamingResponse(client.iam)
self.fastedge = fastedge.FastedgeResourceWithStreamingResponse(client.fastedge)
self.streaming = streaming.StreamingResourceWithStreamingResponse(client.streaming)
- self.security = security.SecurityResourceWithStreamingResponse(client.security)
self.dns = dns.DNSResourceWithStreamingResponse(client.dns)
self.storage = storage.StorageResourceWithStreamingResponse(client.storage)
self.cdn = cdn.CdnResourceWithStreamingResponse(client.cdn)
@@ -561,7 +553,6 @@ def __init__(self, client: AsyncGcore) -> None:
self.iam = iam.AsyncIamResourceWithStreamingResponse(client.iam)
self.fastedge = fastedge.AsyncFastedgeResourceWithStreamingResponse(client.fastedge)
self.streaming = streaming.AsyncStreamingResourceWithStreamingResponse(client.streaming)
- self.security = security.AsyncSecurityResourceWithStreamingResponse(client.security)
self.dns = dns.AsyncDNSResourceWithStreamingResponse(client.dns)
self.storage = storage.AsyncStorageResourceWithStreamingResponse(client.storage)
self.cdn = cdn.AsyncCdnResourceWithStreamingResponse(client.cdn)
diff --git a/src/gcore/resources/__init__.py b/src/gcore/resources/__init__.py
index c8aaa6a7..d7b63884 100644
--- a/src/gcore/resources/__init__.py
+++ b/src/gcore/resources/__init__.py
@@ -56,14 +56,6 @@
FastedgeResourceWithStreamingResponse,
AsyncFastedgeResourceWithStreamingResponse,
)
-from .security import (
- SecurityResource,
- AsyncSecurityResource,
- SecurityResourceWithRawResponse,
- AsyncSecurityResourceWithRawResponse,
- SecurityResourceWithStreamingResponse,
- AsyncSecurityResourceWithStreamingResponse,
-)
from .streaming import (
StreamingResource,
AsyncStreamingResource,
@@ -104,12 +96,6 @@
"AsyncStreamingResourceWithRawResponse",
"StreamingResourceWithStreamingResponse",
"AsyncStreamingResourceWithStreamingResponse",
- "SecurityResource",
- "AsyncSecurityResource",
- "SecurityResourceWithRawResponse",
- "AsyncSecurityResourceWithRawResponse",
- "SecurityResourceWithStreamingResponse",
- "AsyncSecurityResourceWithStreamingResponse",
"DNSResource",
"AsyncDNSResource",
"DNSResourceWithRawResponse",
diff --git a/src/gcore/resources/security/__init__.py b/src/gcore/resources/security/__init__.py
deleted file mode 100644
index a1a7a5ea..00000000
--- a/src/gcore/resources/security/__init__.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from .events import (
- EventsResource,
- AsyncEventsResource,
- EventsResourceWithRawResponse,
- AsyncEventsResourceWithRawResponse,
- EventsResourceWithStreamingResponse,
- AsyncEventsResourceWithStreamingResponse,
-)
-from .profiles import (
- ProfilesResource,
- AsyncProfilesResource,
- ProfilesResourceWithRawResponse,
- AsyncProfilesResourceWithRawResponse,
- ProfilesResourceWithStreamingResponse,
- AsyncProfilesResourceWithStreamingResponse,
-)
-from .security import (
- SecurityResource,
- AsyncSecurityResource,
- SecurityResourceWithRawResponse,
- AsyncSecurityResourceWithRawResponse,
- SecurityResourceWithStreamingResponse,
- AsyncSecurityResourceWithStreamingResponse,
-)
-from .bgp_announces import (
- BgpAnnouncesResource,
- AsyncBgpAnnouncesResource,
- BgpAnnouncesResourceWithRawResponse,
- AsyncBgpAnnouncesResourceWithRawResponse,
- BgpAnnouncesResourceWithStreamingResponse,
- AsyncBgpAnnouncesResourceWithStreamingResponse,
-)
-from .profile_templates import (
- ProfileTemplatesResource,
- AsyncProfileTemplatesResource,
- ProfileTemplatesResourceWithRawResponse,
- AsyncProfileTemplatesResourceWithRawResponse,
- ProfileTemplatesResourceWithStreamingResponse,
- AsyncProfileTemplatesResourceWithStreamingResponse,
-)
-
-__all__ = [
- "EventsResource",
- "AsyncEventsResource",
- "EventsResourceWithRawResponse",
- "AsyncEventsResourceWithRawResponse",
- "EventsResourceWithStreamingResponse",
- "AsyncEventsResourceWithStreamingResponse",
- "BgpAnnouncesResource",
- "AsyncBgpAnnouncesResource",
- "BgpAnnouncesResourceWithRawResponse",
- "AsyncBgpAnnouncesResourceWithRawResponse",
- "BgpAnnouncesResourceWithStreamingResponse",
- "AsyncBgpAnnouncesResourceWithStreamingResponse",
- "ProfileTemplatesResource",
- "AsyncProfileTemplatesResource",
- "ProfileTemplatesResourceWithRawResponse",
- "AsyncProfileTemplatesResourceWithRawResponse",
- "ProfileTemplatesResourceWithStreamingResponse",
- "AsyncProfileTemplatesResourceWithStreamingResponse",
- "ProfilesResource",
- "AsyncProfilesResource",
- "ProfilesResourceWithRawResponse",
- "AsyncProfilesResourceWithRawResponse",
- "ProfilesResourceWithStreamingResponse",
- "AsyncProfilesResourceWithStreamingResponse",
- "SecurityResource",
- "AsyncSecurityResource",
- "SecurityResourceWithRawResponse",
- "AsyncSecurityResourceWithRawResponse",
- "SecurityResourceWithStreamingResponse",
- "AsyncSecurityResourceWithStreamingResponse",
-]
diff --git a/src/gcore/resources/security/bgp_announces.py b/src/gcore/resources/security/bgp_announces.py
deleted file mode 100644
index 26b3bc96..00000000
--- a/src/gcore/resources/security/bgp_announces.py
+++ /dev/null
@@ -1,308 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Optional
-from typing_extensions import Literal
-
-import httpx
-
-from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
-from ..._compat import cached_property
-from ..._resource import SyncAPIResource, AsyncAPIResource
-from ..._response import (
- to_raw_response_wrapper,
- to_streamed_response_wrapper,
- async_to_raw_response_wrapper,
- async_to_streamed_response_wrapper,
-)
-from ..._base_client import make_request_options
-from ...types.security import bgp_announce_list_params, bgp_announce_toggle_params
-from ...types.security.bgp_announce_list_response import BgpAnnounceListResponse
-
-__all__ = ["BgpAnnouncesResource", "AsyncBgpAnnouncesResource"]
-
-
-class BgpAnnouncesResource(SyncAPIResource):
- @cached_property
- def with_raw_response(self) -> BgpAnnouncesResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
- """
- return BgpAnnouncesResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> BgpAnnouncesResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
- """
- return BgpAnnouncesResourceWithStreamingResponse(self)
-
- def list(
- self,
- *,
- announced: Optional[bool] | Omit = omit,
- client_id: Optional[int] | Omit = omit,
- origin: Optional[Literal["STATIC", "DYNAMIC"]] | Omit = omit,
- site: Optional[str] | Omit = omit,
- # 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,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> BgpAnnounceListResponse:
- """Get BGP announces filtered by parameters.
-
- Shows announces in active profiles,
- meaning that to get a non-empty response, the client must have at least one
- active profile.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return self._get(
- "/security/sifter/v2/protected_addresses/announces",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "announced": announced,
- "client_id": client_id,
- "origin": origin,
- "site": site,
- },
- bgp_announce_list_params.BgpAnnounceListParams,
- ),
- ),
- cast_to=BgpAnnounceListResponse,
- )
-
- def toggle(
- self,
- *,
- announce: str,
- enabled: bool,
- client_id: Optional[int] | Omit = omit,
- # 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,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> object:
- """Change BGP announces (it can be enabled or disabled, but not created or
- updated).
-
- Can be applied to already existing announces in active profiles,
- meaning that the client must have at least one active profile.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return self._post(
- "/security/sifter/v2/protected_addresses/announces",
- body=maybe_transform(
- {
- "announce": announce,
- "enabled": enabled,
- },
- bgp_announce_toggle_params.BgpAnnounceToggleParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform({"client_id": client_id}, bgp_announce_toggle_params.BgpAnnounceToggleParams),
- ),
- cast_to=object,
- )
-
-
-class AsyncBgpAnnouncesResource(AsyncAPIResource):
- @cached_property
- def with_raw_response(self) -> AsyncBgpAnnouncesResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
- """
- return AsyncBgpAnnouncesResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncBgpAnnouncesResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
- """
- return AsyncBgpAnnouncesResourceWithStreamingResponse(self)
-
- async def list(
- self,
- *,
- announced: Optional[bool] | Omit = omit,
- client_id: Optional[int] | Omit = omit,
- origin: Optional[Literal["STATIC", "DYNAMIC"]] | Omit = omit,
- site: Optional[str] | Omit = omit,
- # 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,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> BgpAnnounceListResponse:
- """Get BGP announces filtered by parameters.
-
- Shows announces in active profiles,
- meaning that to get a non-empty response, the client must have at least one
- active profile.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return await self._get(
- "/security/sifter/v2/protected_addresses/announces",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {
- "announced": announced,
- "client_id": client_id,
- "origin": origin,
- "site": site,
- },
- bgp_announce_list_params.BgpAnnounceListParams,
- ),
- ),
- cast_to=BgpAnnounceListResponse,
- )
-
- async def toggle(
- self,
- *,
- announce: str,
- enabled: bool,
- client_id: Optional[int] | Omit = omit,
- # 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,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> object:
- """Change BGP announces (it can be enabled or disabled, but not created or
- updated).
-
- Can be applied to already existing announces in active profiles,
- meaning that the client must have at least one active profile.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return await self._post(
- "/security/sifter/v2/protected_addresses/announces",
- body=await async_maybe_transform(
- {
- "announce": announce,
- "enabled": enabled,
- },
- bgp_announce_toggle_params.BgpAnnounceToggleParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {"client_id": client_id}, bgp_announce_toggle_params.BgpAnnounceToggleParams
- ),
- ),
- cast_to=object,
- )
-
-
-class BgpAnnouncesResourceWithRawResponse:
- def __init__(self, bgp_announces: BgpAnnouncesResource) -> None:
- self._bgp_announces = bgp_announces
-
- self.list = to_raw_response_wrapper(
- bgp_announces.list,
- )
- self.toggle = to_raw_response_wrapper(
- bgp_announces.toggle,
- )
-
-
-class AsyncBgpAnnouncesResourceWithRawResponse:
- def __init__(self, bgp_announces: AsyncBgpAnnouncesResource) -> None:
- self._bgp_announces = bgp_announces
-
- self.list = async_to_raw_response_wrapper(
- bgp_announces.list,
- )
- self.toggle = async_to_raw_response_wrapper(
- bgp_announces.toggle,
- )
-
-
-class BgpAnnouncesResourceWithStreamingResponse:
- def __init__(self, bgp_announces: BgpAnnouncesResource) -> None:
- self._bgp_announces = bgp_announces
-
- self.list = to_streamed_response_wrapper(
- bgp_announces.list,
- )
- self.toggle = to_streamed_response_wrapper(
- bgp_announces.toggle,
- )
-
-
-class AsyncBgpAnnouncesResourceWithStreamingResponse:
- def __init__(self, bgp_announces: AsyncBgpAnnouncesResource) -> None:
- self._bgp_announces = bgp_announces
-
- self.list = async_to_streamed_response_wrapper(
- bgp_announces.list,
- )
- self.toggle = async_to_streamed_response_wrapper(
- bgp_announces.toggle,
- )
diff --git a/src/gcore/resources/security/events.py b/src/gcore/resources/security/events.py
deleted file mode 100644
index e0699398..00000000
--- a/src/gcore/resources/security/events.py
+++ /dev/null
@@ -1,234 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Union, Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-import httpx
-
-from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform
-from ..._compat import cached_property
-from ..._resource import SyncAPIResource, AsyncAPIResource
-from ..._response import (
- to_raw_response_wrapper,
- to_streamed_response_wrapper,
- async_to_raw_response_wrapper,
- async_to_streamed_response_wrapper,
-)
-from ...pagination import SyncOffsetPage, AsyncOffsetPage
-from ..._base_client import AsyncPaginator, make_request_options
-from ...types.security import event_list_params
-from ...types.security.client_view import ClientView
-
-__all__ = ["EventsResource", "AsyncEventsResource"]
-
-
-class EventsResource(SyncAPIResource):
- @cached_property
- def with_raw_response(self) -> EventsResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
- """
- return EventsResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> EventsResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
- """
- return EventsResourceWithStreamingResponse(self)
-
- def list(
- self,
- *,
- alert_type: Optional[Literal["ddos_alert", "rtbh_alert"]] | Omit = omit,
- date_from: Union[Union[str, datetime], str] | Omit = omit,
- date_to: Union[Union[str, datetime], str] | Omit = omit,
- limit: int | Omit = omit,
- offset: int | Omit = omit,
- ordering: Literal[
- "attack_start_time",
- "-attack_start_time",
- "attack_power_bps",
- "-attack_power_bps",
- "attack_power_pps",
- "-attack_power_pps",
- "number_of_ip_involved_in_attack",
- "-number_of_ip_involved_in_attack",
- "alert_type",
- "-alert_type",
- ]
- | Omit = omit,
- targeted_ip_addresses: Optional[str] | Omit = omit,
- # 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,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> SyncOffsetPage[ClientView]:
- """
- Event Logs Clients View
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return self._get_api_list(
- "/security/notifier/v1/event_logs",
- page=SyncOffsetPage[ClientView],
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "alert_type": alert_type,
- "date_from": date_from,
- "date_to": date_to,
- "limit": limit,
- "offset": offset,
- "ordering": ordering,
- "targeted_ip_addresses": targeted_ip_addresses,
- },
- event_list_params.EventListParams,
- ),
- ),
- model=ClientView,
- )
-
-
-class AsyncEventsResource(AsyncAPIResource):
- @cached_property
- def with_raw_response(self) -> AsyncEventsResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
- """
- return AsyncEventsResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncEventsResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
- """
- return AsyncEventsResourceWithStreamingResponse(self)
-
- def list(
- self,
- *,
- alert_type: Optional[Literal["ddos_alert", "rtbh_alert"]] | Omit = omit,
- date_from: Union[Union[str, datetime], str] | Omit = omit,
- date_to: Union[Union[str, datetime], str] | Omit = omit,
- limit: int | Omit = omit,
- offset: int | Omit = omit,
- ordering: Literal[
- "attack_start_time",
- "-attack_start_time",
- "attack_power_bps",
- "-attack_power_bps",
- "attack_power_pps",
- "-attack_power_pps",
- "number_of_ip_involved_in_attack",
- "-number_of_ip_involved_in_attack",
- "alert_type",
- "-alert_type",
- ]
- | Omit = omit,
- targeted_ip_addresses: Optional[str] | Omit = omit,
- # 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,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AsyncPaginator[ClientView, AsyncOffsetPage[ClientView]]:
- """
- Event Logs Clients View
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return self._get_api_list(
- "/security/notifier/v1/event_logs",
- page=AsyncOffsetPage[ClientView],
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "alert_type": alert_type,
- "date_from": date_from,
- "date_to": date_to,
- "limit": limit,
- "offset": offset,
- "ordering": ordering,
- "targeted_ip_addresses": targeted_ip_addresses,
- },
- event_list_params.EventListParams,
- ),
- ),
- model=ClientView,
- )
-
-
-class EventsResourceWithRawResponse:
- def __init__(self, events: EventsResource) -> None:
- self._events = events
-
- self.list = to_raw_response_wrapper(
- events.list,
- )
-
-
-class AsyncEventsResourceWithRawResponse:
- def __init__(self, events: AsyncEventsResource) -> None:
- self._events = events
-
- self.list = async_to_raw_response_wrapper(
- events.list,
- )
-
-
-class EventsResourceWithStreamingResponse:
- def __init__(self, events: EventsResource) -> None:
- self._events = events
-
- self.list = to_streamed_response_wrapper(
- events.list,
- )
-
-
-class AsyncEventsResourceWithStreamingResponse:
- def __init__(self, events: AsyncEventsResource) -> None:
- self._events = events
-
- self.list = async_to_streamed_response_wrapper(
- events.list,
- )
diff --git a/src/gcore/resources/security/profile_templates.py b/src/gcore/resources/security/profile_templates.py
deleted file mode 100644
index 307f3c0d..00000000
--- a/src/gcore/resources/security/profile_templates.py
+++ /dev/null
@@ -1,143 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import httpx
-
-from ..._types import Body, Query, Headers, NotGiven, not_given
-from ..._compat import cached_property
-from ..._resource import SyncAPIResource, AsyncAPIResource
-from ..._response import (
- to_raw_response_wrapper,
- to_streamed_response_wrapper,
- async_to_raw_response_wrapper,
- async_to_streamed_response_wrapper,
-)
-from ..._base_client import make_request_options
-from ...types.security.profile_template_list_response import ProfileTemplateListResponse
-
-__all__ = ["ProfileTemplatesResource", "AsyncProfileTemplatesResource"]
-
-
-class ProfileTemplatesResource(SyncAPIResource):
- @cached_property
- def with_raw_response(self) -> ProfileTemplatesResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
- """
- return ProfileTemplatesResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> ProfileTemplatesResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
- """
- return ProfileTemplatesResourceWithStreamingResponse(self)
-
- def list(
- self,
- *,
- # 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,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ProfileTemplateListResponse:
- """Get list of profile templates.
-
- Profile template is used as a template to create
- profile. Client receives only common and created for him profile templates.
- """
- return self._get(
- "/security/iaas/profile-templates",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ProfileTemplateListResponse,
- )
-
-
-class AsyncProfileTemplatesResource(AsyncAPIResource):
- @cached_property
- def with_raw_response(self) -> AsyncProfileTemplatesResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
- """
- return AsyncProfileTemplatesResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncProfileTemplatesResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
- """
- return AsyncProfileTemplatesResourceWithStreamingResponse(self)
-
- async def list(
- self,
- *,
- # 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,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ProfileTemplateListResponse:
- """Get list of profile templates.
-
- Profile template is used as a template to create
- profile. Client receives only common and created for him profile templates.
- """
- return await self._get(
- "/security/iaas/profile-templates",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ProfileTemplateListResponse,
- )
-
-
-class ProfileTemplatesResourceWithRawResponse:
- def __init__(self, profile_templates: ProfileTemplatesResource) -> None:
- self._profile_templates = profile_templates
-
- self.list = to_raw_response_wrapper(
- profile_templates.list,
- )
-
-
-class AsyncProfileTemplatesResourceWithRawResponse:
- def __init__(self, profile_templates: AsyncProfileTemplatesResource) -> None:
- self._profile_templates = profile_templates
-
- self.list = async_to_raw_response_wrapper(
- profile_templates.list,
- )
-
-
-class ProfileTemplatesResourceWithStreamingResponse:
- def __init__(self, profile_templates: ProfileTemplatesResource) -> None:
- self._profile_templates = profile_templates
-
- self.list = to_streamed_response_wrapper(
- profile_templates.list,
- )
-
-
-class AsyncProfileTemplatesResourceWithStreamingResponse:
- def __init__(self, profile_templates: AsyncProfileTemplatesResource) -> None:
- self._profile_templates = profile_templates
-
- self.list = async_to_streamed_response_wrapper(
- profile_templates.list,
- )
diff --git a/src/gcore/resources/security/profiles.py b/src/gcore/resources/security/profiles.py
deleted file mode 100644
index 2ddf3257..00000000
--- a/src/gcore/resources/security/profiles.py
+++ /dev/null
@@ -1,661 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Iterable, Optional
-
-import httpx
-
-from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
-from ..._compat import cached_property
-from ..._resource import SyncAPIResource, AsyncAPIResource
-from ..._response import (
- to_raw_response_wrapper,
- to_streamed_response_wrapper,
- async_to_raw_response_wrapper,
- async_to_streamed_response_wrapper,
-)
-from ..._base_client import make_request_options
-from ...types.security import (
- profile_list_params,
- profile_create_params,
- profile_replace_params,
- profile_recreate_params,
-)
-from ...types.security.client_profile import ClientProfile
-from ...types.security.profile_list_response import ProfileListResponse
-
-__all__ = ["ProfilesResource", "AsyncProfilesResource"]
-
-
-class ProfilesResource(SyncAPIResource):
- @cached_property
- def with_raw_response(self) -> ProfilesResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
- """
- return ProfilesResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> ProfilesResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
- """
- return ProfilesResourceWithStreamingResponse(self)
-
- def create(
- self,
- *,
- fields: Iterable[profile_create_params.Field],
- profile_template: int,
- site: str,
- ip_address: Optional[str] | Omit = omit,
- # 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,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ClientProfile:
- """Create protection profile.
-
- Protection is enabled at the same time as profile is
- created
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return self._post(
- "/security/iaas/v2/profiles",
- body=maybe_transform(
- {
- "fields": fields,
- "profile_template": profile_template,
- "site": site,
- "ip_address": ip_address,
- },
- profile_create_params.ProfileCreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ClientProfile,
- )
-
- def list(
- self,
- *,
- exclude_empty_address: bool | Omit = omit,
- include_deleted: bool | Omit = omit,
- ip_address: str | Omit = omit,
- site: str | Omit = omit,
- # 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,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ProfileListResponse:
- """Get list of protection profiles.
-
- Client receives only profiles created by him
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return self._get(
- "/security/iaas/v2/profiles",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "exclude_empty_address": exclude_empty_address,
- "include_deleted": include_deleted,
- "ip_address": ip_address,
- "site": site,
- },
- profile_list_params.ProfileListParams,
- ),
- ),
- cast_to=ProfileListResponse,
- )
-
- def delete(
- self,
- id: int,
- *,
- # 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,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """Delete protection profile.
-
- Protection is disabled at the same time as profile is
- deleted
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return self._delete(
- f"/security/iaas/v2/profiles/{id}",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- def get(
- self,
- id: int,
- *,
- # 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,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ClientProfile:
- """
- Get profile by id
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return self._get(
- f"/security/iaas/v2/profiles/{id}",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ClientProfile,
- )
-
- def recreate(
- self,
- id: int,
- *,
- fields: Iterable[profile_recreate_params.Field],
- profile_template: int,
- ip_address: Optional[str] | Omit = omit,
- site: str | Omit = omit,
- # 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,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ClientProfile:
- """
- Recreate profile with another profile template (for other cases use detail API)
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return self._put(
- f"/security/iaas/v2/profiles/{id}/recreate",
- body=maybe_transform(
- {
- "fields": fields,
- "profile_template": profile_template,
- "ip_address": ip_address,
- "site": site,
- },
- profile_recreate_params.ProfileRecreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ClientProfile,
- )
-
- def replace(
- self,
- id: int,
- *,
- fields: Iterable[profile_replace_params.Field],
- profile_template: int,
- ip_address: Optional[str] | Omit = omit,
- site: str | Omit = omit,
- # 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,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ClientProfile:
- """Update profile.
-
- Protection policies are updated at the same time as profile
- updated
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return self._put(
- f"/security/iaas/v2/profiles/{id}",
- body=maybe_transform(
- {
- "fields": fields,
- "profile_template": profile_template,
- "ip_address": ip_address,
- "site": site,
- },
- profile_replace_params.ProfileReplaceParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ClientProfile,
- )
-
-
-class AsyncProfilesResource(AsyncAPIResource):
- @cached_property
- def with_raw_response(self) -> AsyncProfilesResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
- """
- return AsyncProfilesResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncProfilesResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
- """
- return AsyncProfilesResourceWithStreamingResponse(self)
-
- async def create(
- self,
- *,
- fields: Iterable[profile_create_params.Field],
- profile_template: int,
- site: str,
- ip_address: Optional[str] | Omit = omit,
- # 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,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ClientProfile:
- """Create protection profile.
-
- Protection is enabled at the same time as profile is
- created
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return await self._post(
- "/security/iaas/v2/profiles",
- body=await async_maybe_transform(
- {
- "fields": fields,
- "profile_template": profile_template,
- "site": site,
- "ip_address": ip_address,
- },
- profile_create_params.ProfileCreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ClientProfile,
- )
-
- async def list(
- self,
- *,
- exclude_empty_address: bool | Omit = omit,
- include_deleted: bool | Omit = omit,
- ip_address: str | Omit = omit,
- site: str | Omit = omit,
- # 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,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ProfileListResponse:
- """Get list of protection profiles.
-
- Client receives only profiles created by him
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return await self._get(
- "/security/iaas/v2/profiles",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {
- "exclude_empty_address": exclude_empty_address,
- "include_deleted": include_deleted,
- "ip_address": ip_address,
- "site": site,
- },
- profile_list_params.ProfileListParams,
- ),
- ),
- cast_to=ProfileListResponse,
- )
-
- async def delete(
- self,
- id: int,
- *,
- # 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,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """Delete protection profile.
-
- Protection is disabled at the same time as profile is
- deleted
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return await self._delete(
- f"/security/iaas/v2/profiles/{id}",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- async def get(
- self,
- id: int,
- *,
- # 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,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ClientProfile:
- """
- Get profile by id
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return await self._get(
- f"/security/iaas/v2/profiles/{id}",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ClientProfile,
- )
-
- async def recreate(
- self,
- id: int,
- *,
- fields: Iterable[profile_recreate_params.Field],
- profile_template: int,
- ip_address: Optional[str] | Omit = omit,
- site: str | Omit = omit,
- # 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,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ClientProfile:
- """
- Recreate profile with another profile template (for other cases use detail API)
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return await self._put(
- f"/security/iaas/v2/profiles/{id}/recreate",
- body=await async_maybe_transform(
- {
- "fields": fields,
- "profile_template": profile_template,
- "ip_address": ip_address,
- "site": site,
- },
- profile_recreate_params.ProfileRecreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ClientProfile,
- )
-
- async def replace(
- self,
- id: int,
- *,
- fields: Iterable[profile_replace_params.Field],
- profile_template: int,
- ip_address: Optional[str] | Omit = omit,
- site: str | Omit = omit,
- # 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,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ClientProfile:
- """Update profile.
-
- Protection policies are updated at the same time as profile
- updated
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return await self._put(
- f"/security/iaas/v2/profiles/{id}",
- body=await async_maybe_transform(
- {
- "fields": fields,
- "profile_template": profile_template,
- "ip_address": ip_address,
- "site": site,
- },
- profile_replace_params.ProfileReplaceParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ClientProfile,
- )
-
-
-class ProfilesResourceWithRawResponse:
- def __init__(self, profiles: ProfilesResource) -> None:
- self._profiles = profiles
-
- self.create = to_raw_response_wrapper(
- profiles.create,
- )
- self.list = to_raw_response_wrapper(
- profiles.list,
- )
- self.delete = to_raw_response_wrapper(
- profiles.delete,
- )
- self.get = to_raw_response_wrapper(
- profiles.get,
- )
- self.recreate = to_raw_response_wrapper(
- profiles.recreate,
- )
- self.replace = to_raw_response_wrapper(
- profiles.replace,
- )
-
-
-class AsyncProfilesResourceWithRawResponse:
- def __init__(self, profiles: AsyncProfilesResource) -> None:
- self._profiles = profiles
-
- self.create = async_to_raw_response_wrapper(
- profiles.create,
- )
- self.list = async_to_raw_response_wrapper(
- profiles.list,
- )
- self.delete = async_to_raw_response_wrapper(
- profiles.delete,
- )
- self.get = async_to_raw_response_wrapper(
- profiles.get,
- )
- self.recreate = async_to_raw_response_wrapper(
- profiles.recreate,
- )
- self.replace = async_to_raw_response_wrapper(
- profiles.replace,
- )
-
-
-class ProfilesResourceWithStreamingResponse:
- def __init__(self, profiles: ProfilesResource) -> None:
- self._profiles = profiles
-
- self.create = to_streamed_response_wrapper(
- profiles.create,
- )
- self.list = to_streamed_response_wrapper(
- profiles.list,
- )
- self.delete = to_streamed_response_wrapper(
- profiles.delete,
- )
- self.get = to_streamed_response_wrapper(
- profiles.get,
- )
- self.recreate = to_streamed_response_wrapper(
- profiles.recreate,
- )
- self.replace = to_streamed_response_wrapper(
- profiles.replace,
- )
-
-
-class AsyncProfilesResourceWithStreamingResponse:
- def __init__(self, profiles: AsyncProfilesResource) -> None:
- self._profiles = profiles
-
- self.create = async_to_streamed_response_wrapper(
- profiles.create,
- )
- self.list = async_to_streamed_response_wrapper(
- profiles.list,
- )
- self.delete = async_to_streamed_response_wrapper(
- profiles.delete,
- )
- self.get = async_to_streamed_response_wrapper(
- profiles.get,
- )
- self.recreate = async_to_streamed_response_wrapper(
- profiles.recreate,
- )
- self.replace = async_to_streamed_response_wrapper(
- profiles.replace,
- )
diff --git a/src/gcore/resources/security/security.py b/src/gcore/resources/security/security.py
deleted file mode 100644
index 2d0d9c11..00000000
--- a/src/gcore/resources/security/security.py
+++ /dev/null
@@ -1,198 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from .events import (
- EventsResource,
- AsyncEventsResource,
- EventsResourceWithRawResponse,
- AsyncEventsResourceWithRawResponse,
- EventsResourceWithStreamingResponse,
- AsyncEventsResourceWithStreamingResponse,
-)
-from .profiles import (
- ProfilesResource,
- AsyncProfilesResource,
- ProfilesResourceWithRawResponse,
- AsyncProfilesResourceWithRawResponse,
- ProfilesResourceWithStreamingResponse,
- AsyncProfilesResourceWithStreamingResponse,
-)
-from ..._compat import cached_property
-from ..._resource import SyncAPIResource, AsyncAPIResource
-from .bgp_announces import (
- BgpAnnouncesResource,
- AsyncBgpAnnouncesResource,
- BgpAnnouncesResourceWithRawResponse,
- AsyncBgpAnnouncesResourceWithRawResponse,
- BgpAnnouncesResourceWithStreamingResponse,
- AsyncBgpAnnouncesResourceWithStreamingResponse,
-)
-from .profile_templates import (
- ProfileTemplatesResource,
- AsyncProfileTemplatesResource,
- ProfileTemplatesResourceWithRawResponse,
- AsyncProfileTemplatesResourceWithRawResponse,
- ProfileTemplatesResourceWithStreamingResponse,
- AsyncProfileTemplatesResourceWithStreamingResponse,
-)
-
-__all__ = ["SecurityResource", "AsyncSecurityResource"]
-
-
-class SecurityResource(SyncAPIResource):
- @cached_property
- def events(self) -> EventsResource:
- return EventsResource(self._client)
-
- @cached_property
- def bgp_announces(self) -> BgpAnnouncesResource:
- return BgpAnnouncesResource(self._client)
-
- @cached_property
- def profile_templates(self) -> ProfileTemplatesResource:
- return ProfileTemplatesResource(self._client)
-
- @cached_property
- def profiles(self) -> ProfilesResource:
- return ProfilesResource(self._client)
-
- @cached_property
- def with_raw_response(self) -> SecurityResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
- """
- return SecurityResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> SecurityResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
- """
- return SecurityResourceWithStreamingResponse(self)
-
-
-class AsyncSecurityResource(AsyncAPIResource):
- @cached_property
- def events(self) -> AsyncEventsResource:
- return AsyncEventsResource(self._client)
-
- @cached_property
- def bgp_announces(self) -> AsyncBgpAnnouncesResource:
- return AsyncBgpAnnouncesResource(self._client)
-
- @cached_property
- def profile_templates(self) -> AsyncProfileTemplatesResource:
- return AsyncProfileTemplatesResource(self._client)
-
- @cached_property
- def profiles(self) -> AsyncProfilesResource:
- return AsyncProfilesResource(self._client)
-
- @cached_property
- def with_raw_response(self) -> AsyncSecurityResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
- """
- return AsyncSecurityResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncSecurityResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
- """
- return AsyncSecurityResourceWithStreamingResponse(self)
-
-
-class SecurityResourceWithRawResponse:
- def __init__(self, security: SecurityResource) -> None:
- self._security = security
-
- @cached_property
- def events(self) -> EventsResourceWithRawResponse:
- return EventsResourceWithRawResponse(self._security.events)
-
- @cached_property
- def bgp_announces(self) -> BgpAnnouncesResourceWithRawResponse:
- return BgpAnnouncesResourceWithRawResponse(self._security.bgp_announces)
-
- @cached_property
- def profile_templates(self) -> ProfileTemplatesResourceWithRawResponse:
- return ProfileTemplatesResourceWithRawResponse(self._security.profile_templates)
-
- @cached_property
- def profiles(self) -> ProfilesResourceWithRawResponse:
- return ProfilesResourceWithRawResponse(self._security.profiles)
-
-
-class AsyncSecurityResourceWithRawResponse:
- def __init__(self, security: AsyncSecurityResource) -> None:
- self._security = security
-
- @cached_property
- def events(self) -> AsyncEventsResourceWithRawResponse:
- return AsyncEventsResourceWithRawResponse(self._security.events)
-
- @cached_property
- def bgp_announces(self) -> AsyncBgpAnnouncesResourceWithRawResponse:
- return AsyncBgpAnnouncesResourceWithRawResponse(self._security.bgp_announces)
-
- @cached_property
- def profile_templates(self) -> AsyncProfileTemplatesResourceWithRawResponse:
- return AsyncProfileTemplatesResourceWithRawResponse(self._security.profile_templates)
-
- @cached_property
- def profiles(self) -> AsyncProfilesResourceWithRawResponse:
- return AsyncProfilesResourceWithRawResponse(self._security.profiles)
-
-
-class SecurityResourceWithStreamingResponse:
- def __init__(self, security: SecurityResource) -> None:
- self._security = security
-
- @cached_property
- def events(self) -> EventsResourceWithStreamingResponse:
- return EventsResourceWithStreamingResponse(self._security.events)
-
- @cached_property
- def bgp_announces(self) -> BgpAnnouncesResourceWithStreamingResponse:
- return BgpAnnouncesResourceWithStreamingResponse(self._security.bgp_announces)
-
- @cached_property
- def profile_templates(self) -> ProfileTemplatesResourceWithStreamingResponse:
- return ProfileTemplatesResourceWithStreamingResponse(self._security.profile_templates)
-
- @cached_property
- def profiles(self) -> ProfilesResourceWithStreamingResponse:
- return ProfilesResourceWithStreamingResponse(self._security.profiles)
-
-
-class AsyncSecurityResourceWithStreamingResponse:
- def __init__(self, security: AsyncSecurityResource) -> None:
- self._security = security
-
- @cached_property
- def events(self) -> AsyncEventsResourceWithStreamingResponse:
- return AsyncEventsResourceWithStreamingResponse(self._security.events)
-
- @cached_property
- def bgp_announces(self) -> AsyncBgpAnnouncesResourceWithStreamingResponse:
- return AsyncBgpAnnouncesResourceWithStreamingResponse(self._security.bgp_announces)
-
- @cached_property
- def profile_templates(self) -> AsyncProfileTemplatesResourceWithStreamingResponse:
- return AsyncProfileTemplatesResourceWithStreamingResponse(self._security.profile_templates)
-
- @cached_property
- def profiles(self) -> AsyncProfilesResourceWithStreamingResponse:
- return AsyncProfilesResourceWithStreamingResponse(self._security.profiles)
diff --git a/src/gcore/types/security/__init__.py b/src/gcore/types/security/__init__.py
index 4994ea70..f8ee8b14 100644
--- a/src/gcore/types/security/__init__.py
+++ b/src/gcore/types/security/__init__.py
@@ -1,18 +1,3 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from __future__ import annotations
-
-from .client_view import ClientView as ClientView
-from .client_profile import ClientProfile as ClientProfile
-from .client_announce import ClientAnnounce as ClientAnnounce
-from .event_list_params import EventListParams as EventListParams
-from .profile_list_params import ProfileListParams as ProfileListParams
-from .profile_create_params import ProfileCreateParams as ProfileCreateParams
-from .profile_list_response import ProfileListResponse as ProfileListResponse
-from .profile_replace_params import ProfileReplaceParams as ProfileReplaceParams
-from .client_profile_template import ClientProfileTemplate as ClientProfileTemplate
-from .profile_recreate_params import ProfileRecreateParams as ProfileRecreateParams
-from .bgp_announce_list_params import BgpAnnounceListParams as BgpAnnounceListParams
-from .bgp_announce_list_response import BgpAnnounceListResponse as BgpAnnounceListResponse
-from .bgp_announce_toggle_params import BgpAnnounceToggleParams as BgpAnnounceToggleParams
-from .profile_template_list_response import ProfileTemplateListResponse as ProfileTemplateListResponse
diff --git a/src/gcore/types/security/bgp_announce_list_params.py b/src/gcore/types/security/bgp_announce_list_params.py
deleted file mode 100644
index 390464fe..00000000
--- a/src/gcore/types/security/bgp_announce_list_params.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Optional
-from typing_extensions import Literal, TypedDict
-
-__all__ = ["BgpAnnounceListParams"]
-
-
-class BgpAnnounceListParams(TypedDict, total=False):
- announced: Optional[bool]
-
- client_id: Optional[int]
-
- origin: Optional[Literal["STATIC", "DYNAMIC"]]
-
- site: Optional[str]
diff --git a/src/gcore/types/security/bgp_announce_list_response.py b/src/gcore/types/security/bgp_announce_list_response.py
deleted file mode 100644
index 6981ba90..00000000
--- a/src/gcore/types/security/bgp_announce_list_response.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List
-from typing_extensions import TypeAlias
-
-from .client_announce import ClientAnnounce
-
-__all__ = ["BgpAnnounceListResponse"]
-
-BgpAnnounceListResponse: TypeAlias = List[ClientAnnounce]
diff --git a/src/gcore/types/security/bgp_announce_toggle_params.py b/src/gcore/types/security/bgp_announce_toggle_params.py
deleted file mode 100644
index 4c5dd1b6..00000000
--- a/src/gcore/types/security/bgp_announce_toggle_params.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Optional
-from typing_extensions import Required, TypedDict
-
-__all__ = ["BgpAnnounceToggleParams"]
-
-
-class BgpAnnounceToggleParams(TypedDict, total=False):
- announce: Required[str]
-
- enabled: Required[bool]
-
- client_id: Optional[int]
diff --git a/src/gcore/types/security/client_announce.py b/src/gcore/types/security/client_announce.py
deleted file mode 100644
index ef276615..00000000
--- a/src/gcore/types/security/client_announce.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List
-
-from ..._models import BaseModel
-
-__all__ = ["ClientAnnounce"]
-
-
-class ClientAnnounce(BaseModel):
- announced: List[str]
-
- client_id: int
-
- not_announced: List[str]
diff --git a/src/gcore/types/security/client_profile.py b/src/gcore/types/security/client_profile.py
deleted file mode 100644
index e02111b5..00000000
--- a/src/gcore/types/security/client_profile.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Dict, List, Optional
-
-from ..._models import BaseModel
-from .client_profile_template import ClientProfileTemplate
-
-__all__ = ["ClientProfile", "Field", "Options"]
-
-
-class Field(BaseModel):
- id: int
-
- base_field: int
-
- default: str
-
- description: str
-
- field_type: str
-
- name: str
-
- required: bool
-
- validation_schema: Dict[str, object]
-
- field_value: Optional[object] = None
-
-
-class Options(BaseModel):
- active: bool
-
- bgp: bool
-
- price: str
-
-
-class ClientProfile(BaseModel):
- id: int
-
- fields: List[Field]
-
- options: Options
-
- plan: str
-
- profile_template: ClientProfileTemplate
-
- protocols: List[Dict[str, object]]
-
- site: str
-
- status: Dict[str, object]
-
- ip_address: Optional[str] = None
diff --git a/src/gcore/types/security/client_profile_template.py b/src/gcore/types/security/client_profile_template.py
deleted file mode 100644
index 4ea63e14..00000000
--- a/src/gcore/types/security/client_profile_template.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Dict, List, Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from ..._models import BaseModel
-
-__all__ = ["ClientProfileTemplate", "Field"]
-
-
-class Field(BaseModel):
- id: int
-
- name: str
-
- default: Optional[str] = None
-
- description: Optional[str] = None
-
- field_type: Optional[Literal["int", "bool", "str"]] = None
-
- required: Optional[bool] = None
-
- validation_schema: Optional[Dict[str, object]] = None
-
-
-class ClientProfileTemplate(BaseModel):
- id: int
-
- created: datetime
-
- fields: List[Field]
-
- name: str
-
- version: str
-
- base_template: Optional[int] = None
-
- description: Optional[str] = None
-
- template_sifter: Optional[str] = None
diff --git a/src/gcore/types/security/client_view.py b/src/gcore/types/security/client_view.py
deleted file mode 100644
index 802060ab..00000000
--- a/src/gcore/types/security/client_view.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from ..._models import BaseModel
-
-__all__ = ["ClientView"]
-
-
-class ClientView(BaseModel):
- id: str
-
- alert_type: Optional[Literal["ddos_alert", "rtbh_alert"]] = None
-
- attack_power_bps: Optional[float] = None
-
- attack_power_pps: Optional[float] = None
-
- attack_start_time: Optional[datetime] = None
-
- client_id: Optional[int] = None
-
- notification_type: Optional[str] = None
-
- number_of_ip_involved_in_attack: Optional[int] = None
-
- targeted_ip_addresses: Optional[str] = None
diff --git a/src/gcore/types/security/event_list_params.py b/src/gcore/types/security/event_list_params.py
deleted file mode 100644
index 0bd703c3..00000000
--- a/src/gcore/types/security/event_list_params.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Union, Optional
-from datetime import datetime
-from typing_extensions import Literal, Annotated, TypedDict
-
-from ..._utils import PropertyInfo
-
-__all__ = ["EventListParams"]
-
-
-class EventListParams(TypedDict, total=False):
- alert_type: Optional[Literal["ddos_alert", "rtbh_alert"]]
-
- date_from: Annotated[Union[Union[str, datetime], str], PropertyInfo(format="iso8601")]
-
- date_to: Annotated[Union[Union[str, datetime], str], PropertyInfo(format="iso8601")]
-
- limit: int
-
- offset: int
-
- ordering: Literal[
- "attack_start_time",
- "-attack_start_time",
- "attack_power_bps",
- "-attack_power_bps",
- "attack_power_pps",
- "-attack_power_pps",
- "number_of_ip_involved_in_attack",
- "-number_of_ip_involved_in_attack",
- "alert_type",
- "-alert_type",
- ]
-
- targeted_ip_addresses: Optional[str]
diff --git a/src/gcore/types/security/profile_create_params.py b/src/gcore/types/security/profile_create_params.py
deleted file mode 100644
index ad7b982c..00000000
--- a/src/gcore/types/security/profile_create_params.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Iterable, Optional
-from typing_extensions import Required, TypedDict
-
-__all__ = ["ProfileCreateParams", "Field"]
-
-
-class ProfileCreateParams(TypedDict, total=False):
- fields: Required[Iterable[Field]]
-
- profile_template: Required[int]
-
- site: Required[str]
-
- ip_address: Optional[str]
-
-
-class Field(TypedDict, total=False):
- base_field: Required[int]
-
- field_value: object
diff --git a/src/gcore/types/security/profile_list_params.py b/src/gcore/types/security/profile_list_params.py
deleted file mode 100644
index e54f232f..00000000
--- a/src/gcore/types/security/profile_list_params.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import TypedDict
-
-__all__ = ["ProfileListParams"]
-
-
-class ProfileListParams(TypedDict, total=False):
- exclude_empty_address: bool
-
- include_deleted: bool
-
- ip_address: str
-
- site: str
diff --git a/src/gcore/types/security/profile_list_response.py b/src/gcore/types/security/profile_list_response.py
deleted file mode 100644
index 816021c8..00000000
--- a/src/gcore/types/security/profile_list_response.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List
-from typing_extensions import TypeAlias
-
-from .client_profile import ClientProfile
-
-__all__ = ["ProfileListResponse"]
-
-ProfileListResponse: TypeAlias = List[ClientProfile]
diff --git a/src/gcore/types/security/profile_recreate_params.py b/src/gcore/types/security/profile_recreate_params.py
deleted file mode 100644
index e1dd3d10..00000000
--- a/src/gcore/types/security/profile_recreate_params.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Iterable, Optional
-from typing_extensions import Required, TypedDict
-
-__all__ = ["ProfileRecreateParams", "Field"]
-
-
-class ProfileRecreateParams(TypedDict, total=False):
- fields: Required[Iterable[Field]]
-
- profile_template: Required[int]
-
- ip_address: Optional[str]
-
- site: str
-
-
-class Field(TypedDict, total=False):
- base_field: Required[int]
-
- field_value: object
diff --git a/src/gcore/types/security/profile_replace_params.py b/src/gcore/types/security/profile_replace_params.py
deleted file mode 100644
index 9684dffd..00000000
--- a/src/gcore/types/security/profile_replace_params.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Iterable, Optional
-from typing_extensions import Required, TypedDict
-
-__all__ = ["ProfileReplaceParams", "Field"]
-
-
-class ProfileReplaceParams(TypedDict, total=False):
- fields: Required[Iterable[Field]]
-
- profile_template: Required[int]
-
- ip_address: Optional[str]
-
- site: str
-
-
-class Field(TypedDict, total=False):
- base_field: Required[int]
-
- field_value: object
diff --git a/src/gcore/types/security/profile_template_list_response.py b/src/gcore/types/security/profile_template_list_response.py
deleted file mode 100644
index 2264e970..00000000
--- a/src/gcore/types/security/profile_template_list_response.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List
-from typing_extensions import TypeAlias
-
-from .client_profile_template import ClientProfileTemplate
-
-__all__ = ["ProfileTemplateListResponse"]
-
-ProfileTemplateListResponse: TypeAlias = List[ClientProfileTemplate]
diff --git a/tests/api_resources/security/__init__.py b/tests/api_resources/security/__init__.py
deleted file mode 100644
index fd8019a9..00000000
--- a/tests/api_resources/security/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/security/test_bgp_announces.py b/tests/api_resources/security/test_bgp_announces.py
deleted file mode 100644
index c1115976..00000000
--- a/tests/api_resources/security/test_bgp_announces.py
+++ /dev/null
@@ -1,180 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import pytest
-
-from gcore import Gcore, AsyncGcore
-from tests.utils import assert_matches_type
-from gcore.types.security import BgpAnnounceListResponse
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestBgpAnnounces:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- def test_method_list(self, client: Gcore) -> None:
- bgp_announce = client.security.bgp_announces.list()
- assert_matches_type(BgpAnnounceListResponse, bgp_announce, path=["response"])
-
- @parametrize
- def test_method_list_with_all_params(self, client: Gcore) -> None:
- bgp_announce = client.security.bgp_announces.list(
- announced=True,
- client_id=0,
- origin="STATIC",
- site="x",
- )
- assert_matches_type(BgpAnnounceListResponse, bgp_announce, path=["response"])
-
- @parametrize
- def test_raw_response_list(self, client: Gcore) -> None:
- response = client.security.bgp_announces.with_raw_response.list()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- bgp_announce = response.parse()
- assert_matches_type(BgpAnnounceListResponse, bgp_announce, path=["response"])
-
- @parametrize
- def test_streaming_response_list(self, client: Gcore) -> None:
- with client.security.bgp_announces.with_streaming_response.list() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- bgp_announce = response.parse()
- assert_matches_type(BgpAnnounceListResponse, bgp_announce, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_method_toggle(self, client: Gcore) -> None:
- bgp_announce = client.security.bgp_announces.toggle(
- announce="192.9.9.1/32",
- enabled=True,
- )
- assert_matches_type(object, bgp_announce, path=["response"])
-
- @parametrize
- def test_method_toggle_with_all_params(self, client: Gcore) -> None:
- bgp_announce = client.security.bgp_announces.toggle(
- announce="192.9.9.1/32",
- enabled=True,
- client_id=0,
- )
- assert_matches_type(object, bgp_announce, path=["response"])
-
- @parametrize
- def test_raw_response_toggle(self, client: Gcore) -> None:
- response = client.security.bgp_announces.with_raw_response.toggle(
- announce="192.9.9.1/32",
- enabled=True,
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- bgp_announce = response.parse()
- assert_matches_type(object, bgp_announce, path=["response"])
-
- @parametrize
- def test_streaming_response_toggle(self, client: Gcore) -> None:
- with client.security.bgp_announces.with_streaming_response.toggle(
- announce="192.9.9.1/32",
- enabled=True,
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- bgp_announce = response.parse()
- assert_matches_type(object, bgp_announce, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
-
-class TestAsyncBgpAnnounces:
- parametrize = pytest.mark.parametrize(
- "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
- )
-
- @parametrize
- async def test_method_list(self, async_client: AsyncGcore) -> None:
- bgp_announce = await async_client.security.bgp_announces.list()
- assert_matches_type(BgpAnnounceListResponse, bgp_announce, path=["response"])
-
- @parametrize
- async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> None:
- bgp_announce = await async_client.security.bgp_announces.list(
- announced=True,
- client_id=0,
- origin="STATIC",
- site="x",
- )
- assert_matches_type(BgpAnnounceListResponse, bgp_announce, path=["response"])
-
- @parametrize
- async def test_raw_response_list(self, async_client: AsyncGcore) -> None:
- response = await async_client.security.bgp_announces.with_raw_response.list()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- bgp_announce = await response.parse()
- assert_matches_type(BgpAnnounceListResponse, bgp_announce, path=["response"])
-
- @parametrize
- async def test_streaming_response_list(self, async_client: AsyncGcore) -> None:
- async with async_client.security.bgp_announces.with_streaming_response.list() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- bgp_announce = await response.parse()
- assert_matches_type(BgpAnnounceListResponse, bgp_announce, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_method_toggle(self, async_client: AsyncGcore) -> None:
- bgp_announce = await async_client.security.bgp_announces.toggle(
- announce="192.9.9.1/32",
- enabled=True,
- )
- assert_matches_type(object, bgp_announce, path=["response"])
-
- @parametrize
- async def test_method_toggle_with_all_params(self, async_client: AsyncGcore) -> None:
- bgp_announce = await async_client.security.bgp_announces.toggle(
- announce="192.9.9.1/32",
- enabled=True,
- client_id=0,
- )
- assert_matches_type(object, bgp_announce, path=["response"])
-
- @parametrize
- async def test_raw_response_toggle(self, async_client: AsyncGcore) -> None:
- response = await async_client.security.bgp_announces.with_raw_response.toggle(
- announce="192.9.9.1/32",
- enabled=True,
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- bgp_announce = await response.parse()
- assert_matches_type(object, bgp_announce, path=["response"])
-
- @parametrize
- async def test_streaming_response_toggle(self, async_client: AsyncGcore) -> None:
- async with async_client.security.bgp_announces.with_streaming_response.toggle(
- announce="192.9.9.1/32",
- enabled=True,
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- bgp_announce = await response.parse()
- assert_matches_type(object, bgp_announce, path=["response"])
-
- assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/security/test_events.py b/tests/api_resources/security/test_events.py
deleted file mode 100644
index 650de2cf..00000000
--- a/tests/api_resources/security/test_events.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import pytest
-
-from gcore import Gcore, AsyncGcore
-from tests.utils import assert_matches_type
-from gcore._utils import parse_datetime
-from gcore.pagination import SyncOffsetPage, AsyncOffsetPage
-from gcore.types.security import ClientView
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestEvents:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- def test_method_list(self, client: Gcore) -> None:
- event = client.security.events.list()
- assert_matches_type(SyncOffsetPage[ClientView], event, path=["response"])
-
- @parametrize
- def test_method_list_with_all_params(self, client: Gcore) -> None:
- event = client.security.events.list(
- alert_type="ddos_alert",
- date_from=parse_datetime("2019-12-27T18:11:19.117Z"),
- date_to=parse_datetime("2019-12-27T18:11:19.117Z"),
- limit=1,
- offset=0,
- ordering="attack_start_time",
- targeted_ip_addresses="targeted_ip_addresses",
- )
- assert_matches_type(SyncOffsetPage[ClientView], event, path=["response"])
-
- @parametrize
- def test_raw_response_list(self, client: Gcore) -> None:
- response = client.security.events.with_raw_response.list()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- event = response.parse()
- assert_matches_type(SyncOffsetPage[ClientView], event, path=["response"])
-
- @parametrize
- def test_streaming_response_list(self, client: Gcore) -> None:
- with client.security.events.with_streaming_response.list() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- event = response.parse()
- assert_matches_type(SyncOffsetPage[ClientView], event, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
-
-class TestAsyncEvents:
- parametrize = pytest.mark.parametrize(
- "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
- )
-
- @parametrize
- async def test_method_list(self, async_client: AsyncGcore) -> None:
- event = await async_client.security.events.list()
- assert_matches_type(AsyncOffsetPage[ClientView], event, path=["response"])
-
- @parametrize
- async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> None:
- event = await async_client.security.events.list(
- alert_type="ddos_alert",
- date_from=parse_datetime("2019-12-27T18:11:19.117Z"),
- date_to=parse_datetime("2019-12-27T18:11:19.117Z"),
- limit=1,
- offset=0,
- ordering="attack_start_time",
- targeted_ip_addresses="targeted_ip_addresses",
- )
- assert_matches_type(AsyncOffsetPage[ClientView], event, path=["response"])
-
- @parametrize
- async def test_raw_response_list(self, async_client: AsyncGcore) -> None:
- response = await async_client.security.events.with_raw_response.list()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- event = await response.parse()
- assert_matches_type(AsyncOffsetPage[ClientView], event, path=["response"])
-
- @parametrize
- async def test_streaming_response_list(self, async_client: AsyncGcore) -> None:
- async with async_client.security.events.with_streaming_response.list() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- event = await response.parse()
- assert_matches_type(AsyncOffsetPage[ClientView], event, path=["response"])
-
- assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/security/test_profile_templates.py b/tests/api_resources/security/test_profile_templates.py
deleted file mode 100644
index 7df4918f..00000000
--- a/tests/api_resources/security/test_profile_templates.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import pytest
-
-from gcore import Gcore, AsyncGcore
-from tests.utils import assert_matches_type
-from gcore.types.security import ProfileTemplateListResponse
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestProfileTemplates:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- def test_method_list(self, client: Gcore) -> None:
- profile_template = client.security.profile_templates.list()
- assert_matches_type(ProfileTemplateListResponse, profile_template, path=["response"])
-
- @parametrize
- def test_raw_response_list(self, client: Gcore) -> None:
- response = client.security.profile_templates.with_raw_response.list()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- profile_template = response.parse()
- assert_matches_type(ProfileTemplateListResponse, profile_template, path=["response"])
-
- @parametrize
- def test_streaming_response_list(self, client: Gcore) -> None:
- with client.security.profile_templates.with_streaming_response.list() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- profile_template = response.parse()
- assert_matches_type(ProfileTemplateListResponse, profile_template, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
-
-class TestAsyncProfileTemplates:
- parametrize = pytest.mark.parametrize(
- "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
- )
-
- @parametrize
- async def test_method_list(self, async_client: AsyncGcore) -> None:
- profile_template = await async_client.security.profile_templates.list()
- assert_matches_type(ProfileTemplateListResponse, profile_template, path=["response"])
-
- @parametrize
- async def test_raw_response_list(self, async_client: AsyncGcore) -> None:
- response = await async_client.security.profile_templates.with_raw_response.list()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- profile_template = await response.parse()
- assert_matches_type(ProfileTemplateListResponse, profile_template, path=["response"])
-
- @parametrize
- async def test_streaming_response_list(self, async_client: AsyncGcore) -> None:
- async with async_client.security.profile_templates.with_streaming_response.list() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- profile_template = await response.parse()
- assert_matches_type(ProfileTemplateListResponse, profile_template, path=["response"])
-
- assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/security/test_profiles.py b/tests/api_resources/security/test_profiles.py
deleted file mode 100644
index c79499ab..00000000
--- a/tests/api_resources/security/test_profiles.py
+++ /dev/null
@@ -1,537 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import pytest
-
-from gcore import Gcore, AsyncGcore
-from tests.utils import assert_matches_type
-from gcore.types.security import (
- ClientProfile,
- ProfileListResponse,
-)
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestProfiles:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- def test_method_create(self, client: Gcore) -> None:
- profile = client.security.profiles.create(
- fields=[{"base_field": 1}],
- profile_template=1,
- site="GNC",
- )
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- @parametrize
- def test_method_create_with_all_params(self, client: Gcore) -> None:
- profile = client.security.profiles.create(
- fields=[
- {
- "base_field": 1,
- "field_value": {},
- }
- ],
- profile_template=1,
- site="GNC",
- ip_address="123.43.2.10",
- )
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- @parametrize
- def test_raw_response_create(self, client: Gcore) -> None:
- response = client.security.profiles.with_raw_response.create(
- fields=[{"base_field": 1}],
- profile_template=1,
- site="GNC",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- profile = response.parse()
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- @parametrize
- def test_streaming_response_create(self, client: Gcore) -> None:
- with client.security.profiles.with_streaming_response.create(
- fields=[{"base_field": 1}],
- profile_template=1,
- site="GNC",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- profile = response.parse()
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_method_list(self, client: Gcore) -> None:
- profile = client.security.profiles.list()
- assert_matches_type(ProfileListResponse, profile, path=["response"])
-
- @parametrize
- def test_method_list_with_all_params(self, client: Gcore) -> None:
- profile = client.security.profiles.list(
- exclude_empty_address=True,
- include_deleted=True,
- ip_address="ip_address",
- site="site",
- )
- assert_matches_type(ProfileListResponse, profile, path=["response"])
-
- @parametrize
- def test_raw_response_list(self, client: Gcore) -> None:
- response = client.security.profiles.with_raw_response.list()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- profile = response.parse()
- assert_matches_type(ProfileListResponse, profile, path=["response"])
-
- @parametrize
- def test_streaming_response_list(self, client: Gcore) -> None:
- with client.security.profiles.with_streaming_response.list() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- profile = response.parse()
- assert_matches_type(ProfileListResponse, profile, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_method_delete(self, client: Gcore) -> None:
- profile = client.security.profiles.delete(
- 0,
- )
- assert profile is None
-
- @parametrize
- def test_raw_response_delete(self, client: Gcore) -> None:
- response = client.security.profiles.with_raw_response.delete(
- 0,
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- profile = response.parse()
- assert profile is None
-
- @parametrize
- def test_streaming_response_delete(self, client: Gcore) -> None:
- with client.security.profiles.with_streaming_response.delete(
- 0,
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- profile = response.parse()
- assert profile is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_method_get(self, client: Gcore) -> None:
- profile = client.security.profiles.get(
- 0,
- )
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- @parametrize
- def test_raw_response_get(self, client: Gcore) -> None:
- response = client.security.profiles.with_raw_response.get(
- 0,
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- profile = response.parse()
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- @parametrize
- def test_streaming_response_get(self, client: Gcore) -> None:
- with client.security.profiles.with_streaming_response.get(
- 0,
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- profile = response.parse()
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_method_recreate(self, client: Gcore) -> None:
- profile = client.security.profiles.recreate(
- id=0,
- fields=[{"base_field": 1}],
- profile_template=1,
- )
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- @parametrize
- def test_method_recreate_with_all_params(self, client: Gcore) -> None:
- profile = client.security.profiles.recreate(
- id=0,
- fields=[
- {
- "base_field": 1,
- "field_value": {},
- }
- ],
- profile_template=1,
- ip_address="ip_address",
- site="ED",
- )
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- @parametrize
- def test_raw_response_recreate(self, client: Gcore) -> None:
- response = client.security.profiles.with_raw_response.recreate(
- id=0,
- fields=[{"base_field": 1}],
- profile_template=1,
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- profile = response.parse()
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- @parametrize
- def test_streaming_response_recreate(self, client: Gcore) -> None:
- with client.security.profiles.with_streaming_response.recreate(
- id=0,
- fields=[{"base_field": 1}],
- profile_template=1,
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- profile = response.parse()
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_method_replace(self, client: Gcore) -> None:
- profile = client.security.profiles.replace(
- id=0,
- fields=[{"base_field": 1}],
- profile_template=1,
- )
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- @parametrize
- def test_method_replace_with_all_params(self, client: Gcore) -> None:
- profile = client.security.profiles.replace(
- id=0,
- fields=[
- {
- "base_field": 1,
- "field_value": {},
- }
- ],
- profile_template=1,
- ip_address="ip_address",
- site="ED",
- )
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- @parametrize
- def test_raw_response_replace(self, client: Gcore) -> None:
- response = client.security.profiles.with_raw_response.replace(
- id=0,
- fields=[{"base_field": 1}],
- profile_template=1,
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- profile = response.parse()
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- @parametrize
- def test_streaming_response_replace(self, client: Gcore) -> None:
- with client.security.profiles.with_streaming_response.replace(
- id=0,
- fields=[{"base_field": 1}],
- profile_template=1,
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- profile = response.parse()
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
-
-class TestAsyncProfiles:
- parametrize = pytest.mark.parametrize(
- "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
- )
-
- @parametrize
- async def test_method_create(self, async_client: AsyncGcore) -> None:
- profile = await async_client.security.profiles.create(
- fields=[{"base_field": 1}],
- profile_template=1,
- site="GNC",
- )
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- @parametrize
- async def test_method_create_with_all_params(self, async_client: AsyncGcore) -> None:
- profile = await async_client.security.profiles.create(
- fields=[
- {
- "base_field": 1,
- "field_value": {},
- }
- ],
- profile_template=1,
- site="GNC",
- ip_address="123.43.2.10",
- )
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- @parametrize
- async def test_raw_response_create(self, async_client: AsyncGcore) -> None:
- response = await async_client.security.profiles.with_raw_response.create(
- fields=[{"base_field": 1}],
- profile_template=1,
- site="GNC",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- profile = await response.parse()
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- @parametrize
- async def test_streaming_response_create(self, async_client: AsyncGcore) -> None:
- async with async_client.security.profiles.with_streaming_response.create(
- fields=[{"base_field": 1}],
- profile_template=1,
- site="GNC",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- profile = await response.parse()
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_method_list(self, async_client: AsyncGcore) -> None:
- profile = await async_client.security.profiles.list()
- assert_matches_type(ProfileListResponse, profile, path=["response"])
-
- @parametrize
- async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> None:
- profile = await async_client.security.profiles.list(
- exclude_empty_address=True,
- include_deleted=True,
- ip_address="ip_address",
- site="site",
- )
- assert_matches_type(ProfileListResponse, profile, path=["response"])
-
- @parametrize
- async def test_raw_response_list(self, async_client: AsyncGcore) -> None:
- response = await async_client.security.profiles.with_raw_response.list()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- profile = await response.parse()
- assert_matches_type(ProfileListResponse, profile, path=["response"])
-
- @parametrize
- async def test_streaming_response_list(self, async_client: AsyncGcore) -> None:
- async with async_client.security.profiles.with_streaming_response.list() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- profile = await response.parse()
- assert_matches_type(ProfileListResponse, profile, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_method_delete(self, async_client: AsyncGcore) -> None:
- profile = await async_client.security.profiles.delete(
- 0,
- )
- assert profile is None
-
- @parametrize
- async def test_raw_response_delete(self, async_client: AsyncGcore) -> None:
- response = await async_client.security.profiles.with_raw_response.delete(
- 0,
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- profile = await response.parse()
- assert profile is None
-
- @parametrize
- async def test_streaming_response_delete(self, async_client: AsyncGcore) -> None:
- async with async_client.security.profiles.with_streaming_response.delete(
- 0,
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- profile = await response.parse()
- assert profile is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_method_get(self, async_client: AsyncGcore) -> None:
- profile = await async_client.security.profiles.get(
- 0,
- )
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- @parametrize
- async def test_raw_response_get(self, async_client: AsyncGcore) -> None:
- response = await async_client.security.profiles.with_raw_response.get(
- 0,
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- profile = await response.parse()
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- @parametrize
- async def test_streaming_response_get(self, async_client: AsyncGcore) -> None:
- async with async_client.security.profiles.with_streaming_response.get(
- 0,
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- profile = await response.parse()
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_method_recreate(self, async_client: AsyncGcore) -> None:
- profile = await async_client.security.profiles.recreate(
- id=0,
- fields=[{"base_field": 1}],
- profile_template=1,
- )
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- @parametrize
- async def test_method_recreate_with_all_params(self, async_client: AsyncGcore) -> None:
- profile = await async_client.security.profiles.recreate(
- id=0,
- fields=[
- {
- "base_field": 1,
- "field_value": {},
- }
- ],
- profile_template=1,
- ip_address="ip_address",
- site="ED",
- )
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- @parametrize
- async def test_raw_response_recreate(self, async_client: AsyncGcore) -> None:
- response = await async_client.security.profiles.with_raw_response.recreate(
- id=0,
- fields=[{"base_field": 1}],
- profile_template=1,
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- profile = await response.parse()
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- @parametrize
- async def test_streaming_response_recreate(self, async_client: AsyncGcore) -> None:
- async with async_client.security.profiles.with_streaming_response.recreate(
- id=0,
- fields=[{"base_field": 1}],
- profile_template=1,
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- profile = await response.parse()
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_method_replace(self, async_client: AsyncGcore) -> None:
- profile = await async_client.security.profiles.replace(
- id=0,
- fields=[{"base_field": 1}],
- profile_template=1,
- )
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- @parametrize
- async def test_method_replace_with_all_params(self, async_client: AsyncGcore) -> None:
- profile = await async_client.security.profiles.replace(
- id=0,
- fields=[
- {
- "base_field": 1,
- "field_value": {},
- }
- ],
- profile_template=1,
- ip_address="ip_address",
- site="ED",
- )
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- @parametrize
- async def test_raw_response_replace(self, async_client: AsyncGcore) -> None:
- response = await async_client.security.profiles.with_raw_response.replace(
- id=0,
- fields=[{"base_field": 1}],
- profile_template=1,
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- profile = await response.parse()
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- @parametrize
- async def test_streaming_response_replace(self, async_client: AsyncGcore) -> None:
- async with async_client.security.profiles.with_streaming_response.replace(
- id=0,
- fields=[{"base_field": 1}],
- profile_template=1,
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- profile = await response.parse()
- assert_matches_type(ClientProfile, profile, path=["response"])
-
- assert cast(Any, response.is_closed) is True
From 9bf8a18f42a2122f43d9084ff3287e4d1aa7dd95 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 3 Nov 2025 16:11:06 +0000
Subject: [PATCH 21/27] chore(internal): grammar fix (it's -> its)
---
src/gcore/_utils/_utils.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/gcore/_utils/_utils.py b/src/gcore/_utils/_utils.py
index 50d59269..eec7f4a1 100644
--- a/src/gcore/_utils/_utils.py
+++ b/src/gcore/_utils/_utils.py
@@ -133,7 +133,7 @@ def is_given(obj: _T | NotGiven | Omit) -> TypeGuard[_T]:
# Type safe methods for narrowing types with TypeVars.
# The default narrowing for isinstance(obj, dict) is dict[unknown, unknown],
# however this cause Pyright to rightfully report errors. As we know we don't
-# care about the contained types we can safely use `object` in it's place.
+# care about the contained types we can safely use `object` in its place.
#
# There are two separate functions defined, `is_*` and `is_*_t` for different use cases.
# `is_*` is for when you're dealing with an unknown input
From 7e17f98624fecfb8d1ad5a53a001dcd20ca15214 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 4 Nov 2025 07:34:13 +0000
Subject: [PATCH 22/27] feat(api): aggregated API specs update
---
.stats.yml | 4 ++--
.../resources/cloud/load_balancers/pools/pools.py | 4 ++--
src/gcore/types/cloud/k8s/k8s_cluster_kubeconfig.py | 12 ++++++++++++
src/gcore/types/cloud/load_balancer_create_params.py | 2 +-
.../types/cloud/load_balancers/pool_create_params.py | 2 +-
5 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index d0525a7d..505403dc 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 599
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-963021ac0cb8a12826d7e00d317340e71748a27c18553422a76d882d2e8ad389.yml
-openapi_spec_hash: 0c1ea27cd584bf0d47fed367663053b2
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-54e13cd82113c74d43e82dc26f72f31cc1c7dcbdba376c44513a707a954ad778.yml
+openapi_spec_hash: 044a6432c14ebaa2c163ad90733d10a8
config_hash: 4758209f53bb13d06f55e4cf6c952b6d
diff --git a/src/gcore/resources/cloud/load_balancers/pools/pools.py b/src/gcore/resources/cloud/load_balancers/pools/pools.py
index b258a0f1..3dd5314b 100644
--- a/src/gcore/resources/cloud/load_balancers/pools/pools.py
+++ b/src/gcore/resources/cloud/load_balancers/pools/pools.py
@@ -85,7 +85,7 @@ def create(
healthmonitor: Optional[pool_create_params.Healthmonitor] | Omit = omit,
listener_id: Optional[str] | Omit = omit,
load_balancer_id: Optional[str] | Omit = omit,
- members: Optional[Iterable[pool_create_params.Member]] | Omit = omit,
+ members: Iterable[pool_create_params.Member] | Omit = omit,
secret_id: Optional[str] | Omit = omit,
session_persistence: Optional[pool_create_params.SessionPersistence] | Omit = omit,
timeout_client_data: Optional[int] | Omit = omit,
@@ -652,7 +652,7 @@ async def create(
healthmonitor: Optional[pool_create_params.Healthmonitor] | Omit = omit,
listener_id: Optional[str] | Omit = omit,
load_balancer_id: Optional[str] | Omit = omit,
- members: Optional[Iterable[pool_create_params.Member]] | Omit = omit,
+ members: Iterable[pool_create_params.Member] | Omit = omit,
secret_id: Optional[str] | Omit = omit,
session_persistence: Optional[pool_create_params.SessionPersistence] | Omit = omit,
timeout_client_data: Optional[int] | Omit = omit,
diff --git a/src/gcore/types/cloud/k8s/k8s_cluster_kubeconfig.py b/src/gcore/types/cloud/k8s/k8s_cluster_kubeconfig.py
index 38aaabe4..c7f7426e 100644
--- a/src/gcore/types/cloud/k8s/k8s_cluster_kubeconfig.py
+++ b/src/gcore/types/cloud/k8s/k8s_cluster_kubeconfig.py
@@ -9,9 +9,21 @@
class K8sClusterKubeconfig(BaseModel):
+ client_certificate: str
+ """String in base64 format. Cluster client certificate"""
+
+ client_key: str
+ """String in base64 format. Cluster client key"""
+
+ cluster_ca_certificate: str
+ """String in base64 format. Cluster ca certificate"""
+
config: str
"""Cluster kubeconfig"""
+ host: str
+ """Cluster host"""
+
created_at: Optional[datetime] = None
"""Kubeconfig creation date"""
diff --git a/src/gcore/types/cloud/load_balancer_create_params.py b/src/gcore/types/cloud/load_balancer_create_params.py
index 0ab6f5ce..28429738 100644
--- a/src/gcore/types/cloud/load_balancer_create_params.py
+++ b/src/gcore/types/cloud/load_balancer_create_params.py
@@ -277,7 +277,7 @@ class ListenerPool(TypedDict, total=False):
load_balancer_id: Optional[str]
"""Loadbalancer ID"""
- members: Optional[Iterable[ListenerPoolMember]]
+ members: Iterable[ListenerPoolMember]
"""Pool members"""
secret_id: Optional[str]
diff --git a/src/gcore/types/cloud/load_balancers/pool_create_params.py b/src/gcore/types/cloud/load_balancers/pool_create_params.py
index 492e9640..c8e503a5 100644
--- a/src/gcore/types/cloud/load_balancers/pool_create_params.py
+++ b/src/gcore/types/cloud/load_balancers/pool_create_params.py
@@ -45,7 +45,7 @@ class PoolCreateParams(TypedDict, total=False):
load_balancer_id: Optional[str]
"""Loadbalancer ID"""
- members: Optional[Iterable[Member]]
+ members: Iterable[Member]
"""Pool members"""
secret_id: Optional[str]
From e008291499f90553d12deffbcef5c4a9b6752f61 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 4 Nov 2025 10:11:50 +0000
Subject: [PATCH 23/27] feat(api): aggregated API specs update
---
.stats.yml | 4 +--
README.md | 16 ++++-----
src/gcore/resources/cloud/projects.py | 28 +++------------
.../types/cloud/project_create_params.py | 6 ----
tests/api_resources/cloud/test_projects.py | 36 +++++++++----------
tests/test_client.py | 28 +++++++--------
6 files changed, 44 insertions(+), 74 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 505403dc..373cf5e0 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 599
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-54e13cd82113c74d43e82dc26f72f31cc1c7dcbdba376c44513a707a954ad778.yml
-openapi_spec_hash: 044a6432c14ebaa2c163ad90733d10a8
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-62590a431788ed5841ef8a0e86fdf0d666ef18819a2a1c784a573b03fb314f60.yml
+openapi_spec_hash: cf5994f5522f209e3c2e3290bc7b418a
config_hash: 4758209f53bb13d06f55e4cf6c952b6d
diff --git a/README.md b/README.md
index 33b1e15e..bcba1e06 100644
--- a/README.md
+++ b/README.md
@@ -34,7 +34,7 @@ client = Gcore(
)
project = client.cloud.projects.create(
- name="New Project",
+ name="my-project",
)
print(project.id)
```
@@ -60,7 +60,7 @@ client = AsyncGcore(
async def main() -> None:
project = await client.cloud.projects.create(
- name="New Project",
+ name="my-project",
)
print(project.id)
@@ -95,7 +95,7 @@ async def main() -> None:
http_client=DefaultAioHttpClient(),
) as client:
project = await client.cloud.projects.create(
- name="New Project",
+ name="my-project",
)
print(project.id)
@@ -236,7 +236,7 @@ client = Gcore()
try:
client.cloud.projects.create(
- name="New Project",
+ name="my-project",
)
except gcore.APIConnectionError as e:
print("The server could not be reached")
@@ -280,7 +280,7 @@ client = Gcore(
# Or, configure per-request:
client.with_options(max_retries=5).cloud.projects.create(
- name="New Project",
+ name="my-project",
)
```
@@ -305,7 +305,7 @@ client = Gcore(
# Override per-request:
client.with_options(timeout=5.0).cloud.projects.create(
- name="New Project",
+ name="my-project",
)
```
@@ -348,7 +348,7 @@ from gcore import Gcore
client = Gcore()
response = client.cloud.projects.with_raw_response.create(
- name="New Project",
+ name="my-project",
)
print(response.headers.get('X-My-Header'))
@@ -368,7 +368,7 @@ To stream the response body, use `.with_streaming_response` instead, which requi
```python
with client.cloud.projects.with_streaming_response.create(
- name="New Project",
+ name="my-project",
) as response:
print(response.headers.get("X-My-Header"))
diff --git a/src/gcore/resources/cloud/projects.py b/src/gcore/resources/cloud/projects.py
index 2e5ae929..ad5381ec 100644
--- a/src/gcore/resources/cloud/projects.py
+++ b/src/gcore/resources/cloud/projects.py
@@ -50,9 +50,7 @@ def create(
self,
*,
name: str,
- client_id: Optional[int] | Omit = omit,
description: Optional[str] | Omit = omit,
- state: Optional[str] | Omit = omit,
# 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,
@@ -68,12 +66,8 @@ def create(
Args:
name: Unique project name for a client. Each client always has one "default" project.
- client_id: ID associated with the client.
-
description: Description of the project.
- state: State of the project.
-
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -87,9 +81,7 @@ def create(
body=maybe_transform(
{
"name": name,
- "client_id": client_id,
"description": description,
- "state": state,
},
project_create_params.ProjectCreateParams,
),
@@ -112,10 +104,8 @@ def update(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> Project:
- """Update project name and description.
-
- Project management must be enabled to
- perform this operation.
+ """
+ Update project name and description.
Args:
name: Name of the entity, following a specific format.
@@ -306,9 +296,7 @@ async def create(
self,
*,
name: str,
- client_id: Optional[int] | Omit = omit,
description: Optional[str] | Omit = omit,
- state: Optional[str] | Omit = omit,
# 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,
@@ -324,12 +312,8 @@ async def create(
Args:
name: Unique project name for a client. Each client always has one "default" project.
- client_id: ID associated with the client.
-
description: Description of the project.
- state: State of the project.
-
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -343,9 +327,7 @@ async def create(
body=await async_maybe_transform(
{
"name": name,
- "client_id": client_id,
"description": description,
- "state": state,
},
project_create_params.ProjectCreateParams,
),
@@ -368,10 +350,8 @@ async def update(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> Project:
- """Update project name and description.
-
- Project management must be enabled to
- perform this operation.
+ """
+ Update project name and description.
Args:
name: Name of the entity, following a specific format.
diff --git a/src/gcore/types/cloud/project_create_params.py b/src/gcore/types/cloud/project_create_params.py
index 9a9255be..86a3ff86 100644
--- a/src/gcore/types/cloud/project_create_params.py
+++ b/src/gcore/types/cloud/project_create_params.py
@@ -12,11 +12,5 @@ class ProjectCreateParams(TypedDict, total=False):
name: Required[str]
"""Unique project name for a client. Each client always has one "default" project."""
- client_id: Optional[int]
- """ID associated with the client."""
-
description: Optional[str]
"""Description of the project."""
-
- state: Optional[str]
- """State of the project."""
diff --git a/tests/api_resources/cloud/test_projects.py b/tests/api_resources/cloud/test_projects.py
index 33942a79..2a620652 100644
--- a/tests/api_resources/cloud/test_projects.py
+++ b/tests/api_resources/cloud/test_projects.py
@@ -21,24 +21,22 @@ class TestProjects:
@parametrize
def test_method_create(self, client: Gcore) -> None:
project = client.cloud.projects.create(
- name="New Project",
+ name="my-project",
)
assert_matches_type(Project, project, path=["response"])
@parametrize
def test_method_create_with_all_params(self, client: Gcore) -> None:
project = client.cloud.projects.create(
- name="New Project",
- client_id=3,
+ name="my-project",
description="Project description",
- state="ACTIVE",
)
assert_matches_type(Project, project, path=["response"])
@parametrize
def test_raw_response_create(self, client: Gcore) -> None:
response = client.cloud.projects.with_raw_response.create(
- name="New Project",
+ name="my-project",
)
assert response.is_closed is True
@@ -49,7 +47,7 @@ def test_raw_response_create(self, client: Gcore) -> None:
@parametrize
def test_streaming_response_create(self, client: Gcore) -> None:
with client.cloud.projects.with_streaming_response.create(
- name="New Project",
+ name="my-project",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -63,7 +61,7 @@ def test_streaming_response_create(self, client: Gcore) -> None:
def test_method_update(self, client: Gcore) -> None:
project = client.cloud.projects.update(
project_id=0,
- name="New Project",
+ name="my-project",
)
assert_matches_type(Project, project, path=["response"])
@@ -71,7 +69,7 @@ def test_method_update(self, client: Gcore) -> None:
def test_method_update_with_all_params(self, client: Gcore) -> None:
project = client.cloud.projects.update(
project_id=0,
- name="New Project",
+ name="my-project",
description="Project description",
)
assert_matches_type(Project, project, path=["response"])
@@ -80,7 +78,7 @@ def test_method_update_with_all_params(self, client: Gcore) -> None:
def test_raw_response_update(self, client: Gcore) -> None:
response = client.cloud.projects.with_raw_response.update(
project_id=0,
- name="New Project",
+ name="my-project",
)
assert response.is_closed is True
@@ -92,7 +90,7 @@ def test_raw_response_update(self, client: Gcore) -> None:
def test_streaming_response_update(self, client: Gcore) -> None:
with client.cloud.projects.with_streaming_response.update(
project_id=0,
- name="New Project",
+ name="my-project",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -210,24 +208,22 @@ class TestAsyncProjects:
@parametrize
async def test_method_create(self, async_client: AsyncGcore) -> None:
project = await async_client.cloud.projects.create(
- name="New Project",
+ name="my-project",
)
assert_matches_type(Project, project, path=["response"])
@parametrize
async def test_method_create_with_all_params(self, async_client: AsyncGcore) -> None:
project = await async_client.cloud.projects.create(
- name="New Project",
- client_id=3,
+ name="my-project",
description="Project description",
- state="ACTIVE",
)
assert_matches_type(Project, project, path=["response"])
@parametrize
async def test_raw_response_create(self, async_client: AsyncGcore) -> None:
response = await async_client.cloud.projects.with_raw_response.create(
- name="New Project",
+ name="my-project",
)
assert response.is_closed is True
@@ -238,7 +234,7 @@ async def test_raw_response_create(self, async_client: AsyncGcore) -> None:
@parametrize
async def test_streaming_response_create(self, async_client: AsyncGcore) -> None:
async with async_client.cloud.projects.with_streaming_response.create(
- name="New Project",
+ name="my-project",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -252,7 +248,7 @@ async def test_streaming_response_create(self, async_client: AsyncGcore) -> None
async def test_method_update(self, async_client: AsyncGcore) -> None:
project = await async_client.cloud.projects.update(
project_id=0,
- name="New Project",
+ name="my-project",
)
assert_matches_type(Project, project, path=["response"])
@@ -260,7 +256,7 @@ async def test_method_update(self, async_client: AsyncGcore) -> None:
async def test_method_update_with_all_params(self, async_client: AsyncGcore) -> None:
project = await async_client.cloud.projects.update(
project_id=0,
- name="New Project",
+ name="my-project",
description="Project description",
)
assert_matches_type(Project, project, path=["response"])
@@ -269,7 +265,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncGcore) ->
async def test_raw_response_update(self, async_client: AsyncGcore) -> None:
response = await async_client.cloud.projects.with_raw_response.update(
project_id=0,
- name="New Project",
+ name="my-project",
)
assert response.is_closed is True
@@ -281,7 +277,7 @@ async def test_raw_response_update(self, async_client: AsyncGcore) -> None:
async def test_streaming_response_update(self, async_client: AsyncGcore) -> None:
async with async_client.cloud.projects.with_streaming_response.update(
project_id=0,
- name="New Project",
+ name="my-project",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
diff --git a/tests/test_client.py b/tests/test_client.py
index 5e4cd0ed..8f4855f7 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -377,11 +377,11 @@ def test_default_query_option(self) -> None:
def test_cloud_project_id_client_params(self, client: Gcore) -> None:
# Test with base client (no custom params)
with pytest.raises(ValueError, match="Missing cloud_project_id argument;"):
- client.cloud.projects.update(name="New Project")
+ client.cloud.projects.update(name="my-project")
client = Gcore(base_url=base_url, api_key=api_key, _strict_response_validation=True, cloud_project_id=0)
with client as c2:
- c2.cloud.projects.update(name="New Project")
+ c2.cloud.projects.update(name="my-project")
def test_cloud_region_id_client_params(self, client: Gcore) -> None:
# Test with base client (no custom params)
@@ -753,7 +753,7 @@ def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter, clien
respx_mock.post("/cloud/v1/projects").mock(side_effect=httpx.TimeoutException("Test timeout error"))
with pytest.raises(APITimeoutError):
- client.cloud.projects.with_streaming_response.create(name="New Project").__enter__()
+ client.cloud.projects.with_streaming_response.create(name="my-project").__enter__()
assert _get_open_connections(client) == 0
@@ -763,7 +763,7 @@ def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter, client
respx_mock.post("/cloud/v1/projects").mock(return_value=httpx.Response(500))
with pytest.raises(APIStatusError):
- client.cloud.projects.with_streaming_response.create(name="New Project").__enter__()
+ client.cloud.projects.with_streaming_response.create(name="my-project").__enter__()
assert _get_open_connections(client) == 0
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
@@ -792,7 +792,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
respx_mock.post("/cloud/v1/projects").mock(side_effect=retry_handler)
- response = client.cloud.projects.with_raw_response.create(name="New Project")
+ response = client.cloud.projects.with_raw_response.create(name="my-project")
assert response.retries_taken == failures_before_success
assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success
@@ -815,7 +815,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
respx_mock.post("/cloud/v1/projects").mock(side_effect=retry_handler)
response = client.cloud.projects.with_raw_response.create(
- name="New Project", extra_headers={"x-stainless-retry-count": Omit()}
+ name="my-project", extra_headers={"x-stainless-retry-count": Omit()}
)
assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0
@@ -840,7 +840,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
respx_mock.post("/cloud/v1/projects").mock(side_effect=retry_handler)
response = client.cloud.projects.with_raw_response.create(
- name="New Project", extra_headers={"x-stainless-retry-count": "42"}
+ name="my-project", extra_headers={"x-stainless-retry-count": "42"}
)
assert response.http_request.headers.get("x-stainless-retry-count") == "42"
@@ -1216,11 +1216,11 @@ async def test_default_query_option(self) -> None:
async def test_cloud_project_id_client_params(self, async_client: AsyncGcore) -> None:
# Test with base client (no custom params)
with pytest.raises(ValueError, match="Missing cloud_project_id argument;"):
- await async_client.cloud.projects.update(name="New Project")
+ await async_client.cloud.projects.update(name="my-project")
client = AsyncGcore(base_url=base_url, api_key=api_key, _strict_response_validation=True, cloud_project_id=0)
async with client as c2:
- await c2.cloud.projects.update(name="New Project")
+ await c2.cloud.projects.update(name="my-project")
async def test_cloud_region_id_client_params(self, async_client: AsyncGcore) -> None:
# Test with base client (no custom params)
@@ -1603,7 +1603,7 @@ async def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter,
respx_mock.post("/cloud/v1/projects").mock(side_effect=httpx.TimeoutException("Test timeout error"))
with pytest.raises(APITimeoutError):
- await async_client.cloud.projects.with_streaming_response.create(name="New Project").__aenter__()
+ await async_client.cloud.projects.with_streaming_response.create(name="my-project").__aenter__()
assert _get_open_connections(async_client) == 0
@@ -1613,7 +1613,7 @@ async def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter,
respx_mock.post("/cloud/v1/projects").mock(return_value=httpx.Response(500))
with pytest.raises(APIStatusError):
- await async_client.cloud.projects.with_streaming_response.create(name="New Project").__aenter__()
+ await async_client.cloud.projects.with_streaming_response.create(name="my-project").__aenter__()
assert _get_open_connections(async_client) == 0
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
@@ -1642,7 +1642,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
respx_mock.post("/cloud/v1/projects").mock(side_effect=retry_handler)
- response = await client.cloud.projects.with_raw_response.create(name="New Project")
+ response = await client.cloud.projects.with_raw_response.create(name="my-project")
assert response.retries_taken == failures_before_success
assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success
@@ -1667,7 +1667,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
respx_mock.post("/cloud/v1/projects").mock(side_effect=retry_handler)
response = await client.cloud.projects.with_raw_response.create(
- name="New Project", extra_headers={"x-stainless-retry-count": Omit()}
+ name="my-project", extra_headers={"x-stainless-retry-count": Omit()}
)
assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0
@@ -1692,7 +1692,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
respx_mock.post("/cloud/v1/projects").mock(side_effect=retry_handler)
response = await client.cloud.projects.with_raw_response.create(
- name="New Project", extra_headers={"x-stainless-retry-count": "42"}
+ name="my-project", extra_headers={"x-stainless-retry-count": "42"}
)
assert response.http_request.headers.get("x-stainless-retry-count") == "42"
From c69f622f4d085d5c93978edbf4deb2ecbe4279d6 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 4 Nov 2025 13:57:16 +0000
Subject: [PATCH 24/27] feat(api): aggregated API specs update
---
.stats.yml | 6 +-
api.md | 42 +-
src/gcore/_client.py | 9 +
src/gcore/resources/__init__.py | 14 +
src/gcore/resources/security/__init__.py | 75 ++
src/gcore/resources/security/bgp_announces.py | 308 ++++++++
src/gcore/resources/security/events.py | 234 +++++++
.../resources/security/profile_templates.py | 143 ++++
src/gcore/resources/security/profiles.py | 661 ++++++++++++++++++
src/gcore/resources/security/security.py | 198 ++++++
src/gcore/types/security/__init__.py | 15 +
.../security/bgp_announce_list_params.py | 18 +
.../security/bgp_announce_list_response.py | 10 +
.../security/bgp_announce_toggle_params.py | 16 +
src/gcore/types/security/client_announce.py | 15 +
src/gcore/types/security/client_profile.py | 56 ++
.../types/security/client_profile_template.py | 43 ++
src/gcore/types/security/client_view.py | 29 +
src/gcore/types/security/event_list_params.py | 38 +
.../types/security/profile_create_params.py | 24 +
.../types/security/profile_list_params.py | 17 +
.../types/security/profile_list_response.py | 10 +
.../types/security/profile_recreate_params.py | 24 +
.../types/security/profile_replace_params.py | 24 +
.../profile_template_list_response.py | 10 +
tests/api_resources/security/__init__.py | 1 +
.../security/test_bgp_announces.py | 180 +++++
tests/api_resources/security/test_events.py | 102 +++
.../security/test_profile_templates.py | 74 ++
tests/api_resources/security/test_profiles.py | 537 ++++++++++++++
30 files changed, 2928 insertions(+), 5 deletions(-)
create mode 100644 src/gcore/resources/security/__init__.py
create mode 100644 src/gcore/resources/security/bgp_announces.py
create mode 100644 src/gcore/resources/security/events.py
create mode 100644 src/gcore/resources/security/profile_templates.py
create mode 100644 src/gcore/resources/security/profiles.py
create mode 100644 src/gcore/resources/security/security.py
create mode 100644 src/gcore/types/security/bgp_announce_list_params.py
create mode 100644 src/gcore/types/security/bgp_announce_list_response.py
create mode 100644 src/gcore/types/security/bgp_announce_toggle_params.py
create mode 100644 src/gcore/types/security/client_announce.py
create mode 100644 src/gcore/types/security/client_profile.py
create mode 100644 src/gcore/types/security/client_profile_template.py
create mode 100644 src/gcore/types/security/client_view.py
create mode 100644 src/gcore/types/security/event_list_params.py
create mode 100644 src/gcore/types/security/profile_create_params.py
create mode 100644 src/gcore/types/security/profile_list_params.py
create mode 100644 src/gcore/types/security/profile_list_response.py
create mode 100644 src/gcore/types/security/profile_recreate_params.py
create mode 100644 src/gcore/types/security/profile_replace_params.py
create mode 100644 src/gcore/types/security/profile_template_list_response.py
create mode 100644 tests/api_resources/security/__init__.py
create mode 100644 tests/api_resources/security/test_bgp_announces.py
create mode 100644 tests/api_resources/security/test_events.py
create mode 100644 tests/api_resources/security/test_profile_templates.py
create mode 100644 tests/api_resources/security/test_profiles.py
diff --git a/.stats.yml b/.stats.yml
index 373cf5e0..72bd8302 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 599
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-62590a431788ed5841ef8a0e86fdf0d666ef18819a2a1c784a573b03fb314f60.yml
-openapi_spec_hash: cf5994f5522f209e3c2e3290bc7b418a
+configured_endpoints: 609
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-1089f2c131ebee7df82e158c4210c07f019b47549d84fe6ea7f022117c83a008.yml
+openapi_spec_hash: 9758acbadc1ee1bc0d826d4657e1ad4a
config_hash: 4758209f53bb13d06f55e4cf6c952b6d
diff --git a/api.md b/api.md
index 2fe398c1..6ff46915 100644
--- a/api.md
+++ b/api.md
@@ -1789,22 +1789,60 @@ Methods:
# Security
+## Events
+
+Types:
+
+```python
+from gcore.types.security import ClientView
+```
+
+Methods:
+
+- client.security.events.list(\*\*params) -> SyncOffsetPage[ClientView]
+
+## BgpAnnounces
+
+Types:
+
+```python
+from gcore.types.security import ClientAnnounce, BgpAnnounceListResponse
+```
+
+Methods:
+
+- client.security.bgp_announces.list(\*\*params) -> BgpAnnounceListResponse
+- client.security.bgp_announces.toggle(\*\*params) -> object
+
## ProfileTemplates
Types:
```python
-from gcore.types.security import ClientProfileTemplate
+from gcore.types.security import ClientProfileTemplate, ProfileTemplateListResponse
```
+Methods:
+
+- client.security.profile_templates.list() -> ProfileTemplateListResponse
+
## Profiles
Types:
```python
-from gcore.types.security import ClientProfile
+from gcore.types.security import ClientProfile, ProfileListResponse
```
+Methods:
+
+- client.security.profiles.create(\*\*params) -> ClientProfile
+- client.security.profiles.list(\*\*params) -> ProfileListResponse
+- client.security.profiles.delete(id) -> None
+- client.security.profiles.get(id) -> ClientProfile
+- client.security.profiles.recreate(id, \*\*params) -> ClientProfile
+- client.security.profiles.replace(id, \*\*params) -> ClientProfile
+
# DNS
Types:
diff --git a/src/gcore/_client.py b/src/gcore/_client.py
index df7f4886..d900f571 100644
--- a/src/gcore/_client.py
+++ b/src/gcore/_client.py
@@ -35,6 +35,7 @@
from .resources.cloud import cloud
from .resources.storage import storage
from .resources.fastedge import fastedge
+from .resources.security import security
from .resources.streaming import streaming
__all__ = ["Timeout", "Transport", "ProxiesTypes", "RequestOptions", "Gcore", "AsyncGcore", "Client", "AsyncClient"]
@@ -46,6 +47,7 @@ class Gcore(SyncAPIClient):
iam: iam.IamResource
fastedge: fastedge.FastedgeResource
streaming: streaming.StreamingResource
+ security: security.SecurityResource
dns: dns.DNSResource
storage: storage.StorageResource
cdn: cdn.CdnResource
@@ -138,6 +140,7 @@ def __init__(
self.iam = iam.IamResource(self)
self.fastedge = fastedge.FastedgeResource(self)
self.streaming = streaming.StreamingResource(self)
+ self.security = security.SecurityResource(self)
self.dns = dns.DNSResource(self)
self.storage = storage.StorageResource(self)
self.cdn = cdn.CdnResource(self)
@@ -281,6 +284,7 @@ class AsyncGcore(AsyncAPIClient):
iam: iam.AsyncIamResource
fastedge: fastedge.AsyncFastedgeResource
streaming: streaming.AsyncStreamingResource
+ security: security.AsyncSecurityResource
dns: dns.AsyncDNSResource
storage: storage.AsyncStorageResource
cdn: cdn.AsyncCdnResource
@@ -373,6 +377,7 @@ def __init__(
self.iam = iam.AsyncIamResource(self)
self.fastedge = fastedge.AsyncFastedgeResource(self)
self.streaming = streaming.AsyncStreamingResource(self)
+ self.security = security.AsyncSecurityResource(self)
self.dns = dns.AsyncDNSResource(self)
self.storage = storage.AsyncStorageResource(self)
self.cdn = cdn.AsyncCdnResource(self)
@@ -517,6 +522,7 @@ def __init__(self, client: Gcore) -> None:
self.iam = iam.IamResourceWithRawResponse(client.iam)
self.fastedge = fastedge.FastedgeResourceWithRawResponse(client.fastedge)
self.streaming = streaming.StreamingResourceWithRawResponse(client.streaming)
+ self.security = security.SecurityResourceWithRawResponse(client.security)
self.dns = dns.DNSResourceWithRawResponse(client.dns)
self.storage = storage.StorageResourceWithRawResponse(client.storage)
self.cdn = cdn.CdnResourceWithRawResponse(client.cdn)
@@ -529,6 +535,7 @@ def __init__(self, client: AsyncGcore) -> None:
self.iam = iam.AsyncIamResourceWithRawResponse(client.iam)
self.fastedge = fastedge.AsyncFastedgeResourceWithRawResponse(client.fastedge)
self.streaming = streaming.AsyncStreamingResourceWithRawResponse(client.streaming)
+ self.security = security.AsyncSecurityResourceWithRawResponse(client.security)
self.dns = dns.AsyncDNSResourceWithRawResponse(client.dns)
self.storage = storage.AsyncStorageResourceWithRawResponse(client.storage)
self.cdn = cdn.AsyncCdnResourceWithRawResponse(client.cdn)
@@ -541,6 +548,7 @@ def __init__(self, client: Gcore) -> None:
self.iam = iam.IamResourceWithStreamingResponse(client.iam)
self.fastedge = fastedge.FastedgeResourceWithStreamingResponse(client.fastedge)
self.streaming = streaming.StreamingResourceWithStreamingResponse(client.streaming)
+ self.security = security.SecurityResourceWithStreamingResponse(client.security)
self.dns = dns.DNSResourceWithStreamingResponse(client.dns)
self.storage = storage.StorageResourceWithStreamingResponse(client.storage)
self.cdn = cdn.CdnResourceWithStreamingResponse(client.cdn)
@@ -553,6 +561,7 @@ def __init__(self, client: AsyncGcore) -> None:
self.iam = iam.AsyncIamResourceWithStreamingResponse(client.iam)
self.fastedge = fastedge.AsyncFastedgeResourceWithStreamingResponse(client.fastedge)
self.streaming = streaming.AsyncStreamingResourceWithStreamingResponse(client.streaming)
+ self.security = security.AsyncSecurityResourceWithStreamingResponse(client.security)
self.dns = dns.AsyncDNSResourceWithStreamingResponse(client.dns)
self.storage = storage.AsyncStorageResourceWithStreamingResponse(client.storage)
self.cdn = cdn.AsyncCdnResourceWithStreamingResponse(client.cdn)
diff --git a/src/gcore/resources/__init__.py b/src/gcore/resources/__init__.py
index d7b63884..c8aaa6a7 100644
--- a/src/gcore/resources/__init__.py
+++ b/src/gcore/resources/__init__.py
@@ -56,6 +56,14 @@
FastedgeResourceWithStreamingResponse,
AsyncFastedgeResourceWithStreamingResponse,
)
+from .security import (
+ SecurityResource,
+ AsyncSecurityResource,
+ SecurityResourceWithRawResponse,
+ AsyncSecurityResourceWithRawResponse,
+ SecurityResourceWithStreamingResponse,
+ AsyncSecurityResourceWithStreamingResponse,
+)
from .streaming import (
StreamingResource,
AsyncStreamingResource,
@@ -96,6 +104,12 @@
"AsyncStreamingResourceWithRawResponse",
"StreamingResourceWithStreamingResponse",
"AsyncStreamingResourceWithStreamingResponse",
+ "SecurityResource",
+ "AsyncSecurityResource",
+ "SecurityResourceWithRawResponse",
+ "AsyncSecurityResourceWithRawResponse",
+ "SecurityResourceWithStreamingResponse",
+ "AsyncSecurityResourceWithStreamingResponse",
"DNSResource",
"AsyncDNSResource",
"DNSResourceWithRawResponse",
diff --git a/src/gcore/resources/security/__init__.py b/src/gcore/resources/security/__init__.py
new file mode 100644
index 00000000..a1a7a5ea
--- /dev/null
+++ b/src/gcore/resources/security/__init__.py
@@ -0,0 +1,75 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .events import (
+ EventsResource,
+ AsyncEventsResource,
+ EventsResourceWithRawResponse,
+ AsyncEventsResourceWithRawResponse,
+ EventsResourceWithStreamingResponse,
+ AsyncEventsResourceWithStreamingResponse,
+)
+from .profiles import (
+ ProfilesResource,
+ AsyncProfilesResource,
+ ProfilesResourceWithRawResponse,
+ AsyncProfilesResourceWithRawResponse,
+ ProfilesResourceWithStreamingResponse,
+ AsyncProfilesResourceWithStreamingResponse,
+)
+from .security import (
+ SecurityResource,
+ AsyncSecurityResource,
+ SecurityResourceWithRawResponse,
+ AsyncSecurityResourceWithRawResponse,
+ SecurityResourceWithStreamingResponse,
+ AsyncSecurityResourceWithStreamingResponse,
+)
+from .bgp_announces import (
+ BgpAnnouncesResource,
+ AsyncBgpAnnouncesResource,
+ BgpAnnouncesResourceWithRawResponse,
+ AsyncBgpAnnouncesResourceWithRawResponse,
+ BgpAnnouncesResourceWithStreamingResponse,
+ AsyncBgpAnnouncesResourceWithStreamingResponse,
+)
+from .profile_templates import (
+ ProfileTemplatesResource,
+ AsyncProfileTemplatesResource,
+ ProfileTemplatesResourceWithRawResponse,
+ AsyncProfileTemplatesResourceWithRawResponse,
+ ProfileTemplatesResourceWithStreamingResponse,
+ AsyncProfileTemplatesResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "EventsResource",
+ "AsyncEventsResource",
+ "EventsResourceWithRawResponse",
+ "AsyncEventsResourceWithRawResponse",
+ "EventsResourceWithStreamingResponse",
+ "AsyncEventsResourceWithStreamingResponse",
+ "BgpAnnouncesResource",
+ "AsyncBgpAnnouncesResource",
+ "BgpAnnouncesResourceWithRawResponse",
+ "AsyncBgpAnnouncesResourceWithRawResponse",
+ "BgpAnnouncesResourceWithStreamingResponse",
+ "AsyncBgpAnnouncesResourceWithStreamingResponse",
+ "ProfileTemplatesResource",
+ "AsyncProfileTemplatesResource",
+ "ProfileTemplatesResourceWithRawResponse",
+ "AsyncProfileTemplatesResourceWithRawResponse",
+ "ProfileTemplatesResourceWithStreamingResponse",
+ "AsyncProfileTemplatesResourceWithStreamingResponse",
+ "ProfilesResource",
+ "AsyncProfilesResource",
+ "ProfilesResourceWithRawResponse",
+ "AsyncProfilesResourceWithRawResponse",
+ "ProfilesResourceWithStreamingResponse",
+ "AsyncProfilesResourceWithStreamingResponse",
+ "SecurityResource",
+ "AsyncSecurityResource",
+ "SecurityResourceWithRawResponse",
+ "AsyncSecurityResourceWithRawResponse",
+ "SecurityResourceWithStreamingResponse",
+ "AsyncSecurityResourceWithStreamingResponse",
+]
diff --git a/src/gcore/resources/security/bgp_announces.py b/src/gcore/resources/security/bgp_announces.py
new file mode 100644
index 00000000..26b3bc96
--- /dev/null
+++ b/src/gcore/resources/security/bgp_announces.py
@@ -0,0 +1,308 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+from typing_extensions import Literal
+
+import httpx
+
+from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ..._utils import maybe_transform, async_maybe_transform
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from ..._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ..._base_client import make_request_options
+from ...types.security import bgp_announce_list_params, bgp_announce_toggle_params
+from ...types.security.bgp_announce_list_response import BgpAnnounceListResponse
+
+__all__ = ["BgpAnnouncesResource", "AsyncBgpAnnouncesResource"]
+
+
+class BgpAnnouncesResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> BgpAnnouncesResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
+ """
+ return BgpAnnouncesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> BgpAnnouncesResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
+ """
+ return BgpAnnouncesResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ *,
+ announced: Optional[bool] | Omit = omit,
+ client_id: Optional[int] | Omit = omit,
+ origin: Optional[Literal["STATIC", "DYNAMIC"]] | Omit = omit,
+ site: Optional[str] | Omit = omit,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> BgpAnnounceListResponse:
+ """Get BGP announces filtered by parameters.
+
+ Shows announces in active profiles,
+ meaning that to get a non-empty response, the client must have at least one
+ active profile.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._get(
+ "/security/sifter/v2/protected_addresses/announces",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "announced": announced,
+ "client_id": client_id,
+ "origin": origin,
+ "site": site,
+ },
+ bgp_announce_list_params.BgpAnnounceListParams,
+ ),
+ ),
+ cast_to=BgpAnnounceListResponse,
+ )
+
+ def toggle(
+ self,
+ *,
+ announce: str,
+ enabled: bool,
+ client_id: Optional[int] | Omit = omit,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> object:
+ """Change BGP announces (it can be enabled or disabled, but not created or
+ updated).
+
+ Can be applied to already existing announces in active profiles,
+ meaning that the client must have at least one active profile.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._post(
+ "/security/sifter/v2/protected_addresses/announces",
+ body=maybe_transform(
+ {
+ "announce": announce,
+ "enabled": enabled,
+ },
+ bgp_announce_toggle_params.BgpAnnounceToggleParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform({"client_id": client_id}, bgp_announce_toggle_params.BgpAnnounceToggleParams),
+ ),
+ cast_to=object,
+ )
+
+
+class AsyncBgpAnnouncesResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncBgpAnnouncesResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncBgpAnnouncesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncBgpAnnouncesResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
+ """
+ return AsyncBgpAnnouncesResourceWithStreamingResponse(self)
+
+ async def list(
+ self,
+ *,
+ announced: Optional[bool] | Omit = omit,
+ client_id: Optional[int] | Omit = omit,
+ origin: Optional[Literal["STATIC", "DYNAMIC"]] | Omit = omit,
+ site: Optional[str] | Omit = omit,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> BgpAnnounceListResponse:
+ """Get BGP announces filtered by parameters.
+
+ Shows announces in active profiles,
+ meaning that to get a non-empty response, the client must have at least one
+ active profile.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._get(
+ "/security/sifter/v2/protected_addresses/announces",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "announced": announced,
+ "client_id": client_id,
+ "origin": origin,
+ "site": site,
+ },
+ bgp_announce_list_params.BgpAnnounceListParams,
+ ),
+ ),
+ cast_to=BgpAnnounceListResponse,
+ )
+
+ async def toggle(
+ self,
+ *,
+ announce: str,
+ enabled: bool,
+ client_id: Optional[int] | Omit = omit,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> object:
+ """Change BGP announces (it can be enabled or disabled, but not created or
+ updated).
+
+ Can be applied to already existing announces in active profiles,
+ meaning that the client must have at least one active profile.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._post(
+ "/security/sifter/v2/protected_addresses/announces",
+ body=await async_maybe_transform(
+ {
+ "announce": announce,
+ "enabled": enabled,
+ },
+ bgp_announce_toggle_params.BgpAnnounceToggleParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {"client_id": client_id}, bgp_announce_toggle_params.BgpAnnounceToggleParams
+ ),
+ ),
+ cast_to=object,
+ )
+
+
+class BgpAnnouncesResourceWithRawResponse:
+ def __init__(self, bgp_announces: BgpAnnouncesResource) -> None:
+ self._bgp_announces = bgp_announces
+
+ self.list = to_raw_response_wrapper(
+ bgp_announces.list,
+ )
+ self.toggle = to_raw_response_wrapper(
+ bgp_announces.toggle,
+ )
+
+
+class AsyncBgpAnnouncesResourceWithRawResponse:
+ def __init__(self, bgp_announces: AsyncBgpAnnouncesResource) -> None:
+ self._bgp_announces = bgp_announces
+
+ self.list = async_to_raw_response_wrapper(
+ bgp_announces.list,
+ )
+ self.toggle = async_to_raw_response_wrapper(
+ bgp_announces.toggle,
+ )
+
+
+class BgpAnnouncesResourceWithStreamingResponse:
+ def __init__(self, bgp_announces: BgpAnnouncesResource) -> None:
+ self._bgp_announces = bgp_announces
+
+ self.list = to_streamed_response_wrapper(
+ bgp_announces.list,
+ )
+ self.toggle = to_streamed_response_wrapper(
+ bgp_announces.toggle,
+ )
+
+
+class AsyncBgpAnnouncesResourceWithStreamingResponse:
+ def __init__(self, bgp_announces: AsyncBgpAnnouncesResource) -> None:
+ self._bgp_announces = bgp_announces
+
+ self.list = async_to_streamed_response_wrapper(
+ bgp_announces.list,
+ )
+ self.toggle = async_to_streamed_response_wrapper(
+ bgp_announces.toggle,
+ )
diff --git a/src/gcore/resources/security/events.py b/src/gcore/resources/security/events.py
new file mode 100644
index 00000000..e0699398
--- /dev/null
+++ b/src/gcore/resources/security/events.py
@@ -0,0 +1,234 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+import httpx
+
+from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ..._utils import maybe_transform
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from ..._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ...pagination import SyncOffsetPage, AsyncOffsetPage
+from ..._base_client import AsyncPaginator, make_request_options
+from ...types.security import event_list_params
+from ...types.security.client_view import ClientView
+
+__all__ = ["EventsResource", "AsyncEventsResource"]
+
+
+class EventsResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> EventsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
+ """
+ return EventsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> EventsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
+ """
+ return EventsResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ *,
+ alert_type: Optional[Literal["ddos_alert", "rtbh_alert"]] | Omit = omit,
+ date_from: Union[Union[str, datetime], str] | Omit = omit,
+ date_to: Union[Union[str, datetime], str] | Omit = omit,
+ limit: int | Omit = omit,
+ offset: int | Omit = omit,
+ ordering: Literal[
+ "attack_start_time",
+ "-attack_start_time",
+ "attack_power_bps",
+ "-attack_power_bps",
+ "attack_power_pps",
+ "-attack_power_pps",
+ "number_of_ip_involved_in_attack",
+ "-number_of_ip_involved_in_attack",
+ "alert_type",
+ "-alert_type",
+ ]
+ | Omit = omit,
+ targeted_ip_addresses: Optional[str] | Omit = omit,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> SyncOffsetPage[ClientView]:
+ """
+ Event Logs Clients View
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._get_api_list(
+ "/security/notifier/v1/event_logs",
+ page=SyncOffsetPage[ClientView],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "alert_type": alert_type,
+ "date_from": date_from,
+ "date_to": date_to,
+ "limit": limit,
+ "offset": offset,
+ "ordering": ordering,
+ "targeted_ip_addresses": targeted_ip_addresses,
+ },
+ event_list_params.EventListParams,
+ ),
+ ),
+ model=ClientView,
+ )
+
+
+class AsyncEventsResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncEventsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncEventsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncEventsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
+ """
+ return AsyncEventsResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ *,
+ alert_type: Optional[Literal["ddos_alert", "rtbh_alert"]] | Omit = omit,
+ date_from: Union[Union[str, datetime], str] | Omit = omit,
+ date_to: Union[Union[str, datetime], str] | Omit = omit,
+ limit: int | Omit = omit,
+ offset: int | Omit = omit,
+ ordering: Literal[
+ "attack_start_time",
+ "-attack_start_time",
+ "attack_power_bps",
+ "-attack_power_bps",
+ "attack_power_pps",
+ "-attack_power_pps",
+ "number_of_ip_involved_in_attack",
+ "-number_of_ip_involved_in_attack",
+ "alert_type",
+ "-alert_type",
+ ]
+ | Omit = omit,
+ targeted_ip_addresses: Optional[str] | Omit = omit,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> AsyncPaginator[ClientView, AsyncOffsetPage[ClientView]]:
+ """
+ Event Logs Clients View
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._get_api_list(
+ "/security/notifier/v1/event_logs",
+ page=AsyncOffsetPage[ClientView],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "alert_type": alert_type,
+ "date_from": date_from,
+ "date_to": date_to,
+ "limit": limit,
+ "offset": offset,
+ "ordering": ordering,
+ "targeted_ip_addresses": targeted_ip_addresses,
+ },
+ event_list_params.EventListParams,
+ ),
+ ),
+ model=ClientView,
+ )
+
+
+class EventsResourceWithRawResponse:
+ def __init__(self, events: EventsResource) -> None:
+ self._events = events
+
+ self.list = to_raw_response_wrapper(
+ events.list,
+ )
+
+
+class AsyncEventsResourceWithRawResponse:
+ def __init__(self, events: AsyncEventsResource) -> None:
+ self._events = events
+
+ self.list = async_to_raw_response_wrapper(
+ events.list,
+ )
+
+
+class EventsResourceWithStreamingResponse:
+ def __init__(self, events: EventsResource) -> None:
+ self._events = events
+
+ self.list = to_streamed_response_wrapper(
+ events.list,
+ )
+
+
+class AsyncEventsResourceWithStreamingResponse:
+ def __init__(self, events: AsyncEventsResource) -> None:
+ self._events = events
+
+ self.list = async_to_streamed_response_wrapper(
+ events.list,
+ )
diff --git a/src/gcore/resources/security/profile_templates.py b/src/gcore/resources/security/profile_templates.py
new file mode 100644
index 00000000..307f3c0d
--- /dev/null
+++ b/src/gcore/resources/security/profile_templates.py
@@ -0,0 +1,143 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from ..._types import Body, Query, Headers, NotGiven, not_given
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from ..._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ..._base_client import make_request_options
+from ...types.security.profile_template_list_response import ProfileTemplateListResponse
+
+__all__ = ["ProfileTemplatesResource", "AsyncProfileTemplatesResource"]
+
+
+class ProfileTemplatesResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> ProfileTemplatesResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
+ """
+ return ProfileTemplatesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> ProfileTemplatesResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
+ """
+ return ProfileTemplatesResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ *,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ProfileTemplateListResponse:
+ """Get list of profile templates.
+
+ Profile template is used as a template to create
+ profile. Client receives only common and created for him profile templates.
+ """
+ return self._get(
+ "/security/iaas/profile-templates",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ProfileTemplateListResponse,
+ )
+
+
+class AsyncProfileTemplatesResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncProfileTemplatesResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncProfileTemplatesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncProfileTemplatesResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
+ """
+ return AsyncProfileTemplatesResourceWithStreamingResponse(self)
+
+ async def list(
+ self,
+ *,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ProfileTemplateListResponse:
+ """Get list of profile templates.
+
+ Profile template is used as a template to create
+ profile. Client receives only common and created for him profile templates.
+ """
+ return await self._get(
+ "/security/iaas/profile-templates",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ProfileTemplateListResponse,
+ )
+
+
+class ProfileTemplatesResourceWithRawResponse:
+ def __init__(self, profile_templates: ProfileTemplatesResource) -> None:
+ self._profile_templates = profile_templates
+
+ self.list = to_raw_response_wrapper(
+ profile_templates.list,
+ )
+
+
+class AsyncProfileTemplatesResourceWithRawResponse:
+ def __init__(self, profile_templates: AsyncProfileTemplatesResource) -> None:
+ self._profile_templates = profile_templates
+
+ self.list = async_to_raw_response_wrapper(
+ profile_templates.list,
+ )
+
+
+class ProfileTemplatesResourceWithStreamingResponse:
+ def __init__(self, profile_templates: ProfileTemplatesResource) -> None:
+ self._profile_templates = profile_templates
+
+ self.list = to_streamed_response_wrapper(
+ profile_templates.list,
+ )
+
+
+class AsyncProfileTemplatesResourceWithStreamingResponse:
+ def __init__(self, profile_templates: AsyncProfileTemplatesResource) -> None:
+ self._profile_templates = profile_templates
+
+ self.list = async_to_streamed_response_wrapper(
+ profile_templates.list,
+ )
diff --git a/src/gcore/resources/security/profiles.py b/src/gcore/resources/security/profiles.py
new file mode 100644
index 00000000..2ddf3257
--- /dev/null
+++ b/src/gcore/resources/security/profiles.py
@@ -0,0 +1,661 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable, Optional
+
+import httpx
+
+from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
+from ..._utils import maybe_transform, async_maybe_transform
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from ..._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ..._base_client import make_request_options
+from ...types.security import (
+ profile_list_params,
+ profile_create_params,
+ profile_replace_params,
+ profile_recreate_params,
+)
+from ...types.security.client_profile import ClientProfile
+from ...types.security.profile_list_response import ProfileListResponse
+
+__all__ = ["ProfilesResource", "AsyncProfilesResource"]
+
+
+class ProfilesResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> ProfilesResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
+ """
+ return ProfilesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> ProfilesResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
+ """
+ return ProfilesResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ fields: Iterable[profile_create_params.Field],
+ profile_template: int,
+ site: str,
+ ip_address: Optional[str] | Omit = omit,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ClientProfile:
+ """Create protection profile.
+
+ Protection is enabled at the same time as profile is
+ created
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._post(
+ "/security/iaas/v2/profiles",
+ body=maybe_transform(
+ {
+ "fields": fields,
+ "profile_template": profile_template,
+ "site": site,
+ "ip_address": ip_address,
+ },
+ profile_create_params.ProfileCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ClientProfile,
+ )
+
+ def list(
+ self,
+ *,
+ exclude_empty_address: bool | Omit = omit,
+ include_deleted: bool | Omit = omit,
+ ip_address: str | Omit = omit,
+ site: str | Omit = omit,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ProfileListResponse:
+ """Get list of protection profiles.
+
+ Client receives only profiles created by him
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._get(
+ "/security/iaas/v2/profiles",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "exclude_empty_address": exclude_empty_address,
+ "include_deleted": include_deleted,
+ "ip_address": ip_address,
+ "site": site,
+ },
+ profile_list_params.ProfileListParams,
+ ),
+ ),
+ cast_to=ProfileListResponse,
+ )
+
+ def delete(
+ self,
+ id: int,
+ *,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> None:
+ """Delete protection profile.
+
+ Protection is disabled at the same time as profile is
+ deleted
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._delete(
+ f"/security/iaas/v2/profiles/{id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
+ def get(
+ self,
+ id: int,
+ *,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ClientProfile:
+ """
+ Get profile by id
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._get(
+ f"/security/iaas/v2/profiles/{id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ClientProfile,
+ )
+
+ def recreate(
+ self,
+ id: int,
+ *,
+ fields: Iterable[profile_recreate_params.Field],
+ profile_template: int,
+ ip_address: Optional[str] | Omit = omit,
+ site: str | Omit = omit,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ClientProfile:
+ """
+ Recreate profile with another profile template (for other cases use detail API)
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._put(
+ f"/security/iaas/v2/profiles/{id}/recreate",
+ body=maybe_transform(
+ {
+ "fields": fields,
+ "profile_template": profile_template,
+ "ip_address": ip_address,
+ "site": site,
+ },
+ profile_recreate_params.ProfileRecreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ClientProfile,
+ )
+
+ def replace(
+ self,
+ id: int,
+ *,
+ fields: Iterable[profile_replace_params.Field],
+ profile_template: int,
+ ip_address: Optional[str] | Omit = omit,
+ site: str | Omit = omit,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ClientProfile:
+ """Update profile.
+
+ Protection policies are updated at the same time as profile
+ updated
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._put(
+ f"/security/iaas/v2/profiles/{id}",
+ body=maybe_transform(
+ {
+ "fields": fields,
+ "profile_template": profile_template,
+ "ip_address": ip_address,
+ "site": site,
+ },
+ profile_replace_params.ProfileReplaceParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ClientProfile,
+ )
+
+
+class AsyncProfilesResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncProfilesResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncProfilesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncProfilesResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
+ """
+ return AsyncProfilesResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ *,
+ fields: Iterable[profile_create_params.Field],
+ profile_template: int,
+ site: str,
+ ip_address: Optional[str] | Omit = omit,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ClientProfile:
+ """Create protection profile.
+
+ Protection is enabled at the same time as profile is
+ created
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._post(
+ "/security/iaas/v2/profiles",
+ body=await async_maybe_transform(
+ {
+ "fields": fields,
+ "profile_template": profile_template,
+ "site": site,
+ "ip_address": ip_address,
+ },
+ profile_create_params.ProfileCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ClientProfile,
+ )
+
+ async def list(
+ self,
+ *,
+ exclude_empty_address: bool | Omit = omit,
+ include_deleted: bool | Omit = omit,
+ ip_address: str | Omit = omit,
+ site: str | Omit = omit,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ProfileListResponse:
+ """Get list of protection profiles.
+
+ Client receives only profiles created by him
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._get(
+ "/security/iaas/v2/profiles",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "exclude_empty_address": exclude_empty_address,
+ "include_deleted": include_deleted,
+ "ip_address": ip_address,
+ "site": site,
+ },
+ profile_list_params.ProfileListParams,
+ ),
+ ),
+ cast_to=ProfileListResponse,
+ )
+
+ async def delete(
+ self,
+ id: int,
+ *,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> None:
+ """Delete protection profile.
+
+ Protection is disabled at the same time as profile is
+ deleted
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._delete(
+ f"/security/iaas/v2/profiles/{id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
+ async def get(
+ self,
+ id: int,
+ *,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ClientProfile:
+ """
+ Get profile by id
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._get(
+ f"/security/iaas/v2/profiles/{id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ClientProfile,
+ )
+
+ async def recreate(
+ self,
+ id: int,
+ *,
+ fields: Iterable[profile_recreate_params.Field],
+ profile_template: int,
+ ip_address: Optional[str] | Omit = omit,
+ site: str | Omit = omit,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ClientProfile:
+ """
+ Recreate profile with another profile template (for other cases use detail API)
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._put(
+ f"/security/iaas/v2/profiles/{id}/recreate",
+ body=await async_maybe_transform(
+ {
+ "fields": fields,
+ "profile_template": profile_template,
+ "ip_address": ip_address,
+ "site": site,
+ },
+ profile_recreate_params.ProfileRecreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ClientProfile,
+ )
+
+ async def replace(
+ self,
+ id: int,
+ *,
+ fields: Iterable[profile_replace_params.Field],
+ profile_template: int,
+ ip_address: Optional[str] | Omit = omit,
+ site: str | Omit = omit,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ClientProfile:
+ """Update profile.
+
+ Protection policies are updated at the same time as profile
+ updated
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._put(
+ f"/security/iaas/v2/profiles/{id}",
+ body=await async_maybe_transform(
+ {
+ "fields": fields,
+ "profile_template": profile_template,
+ "ip_address": ip_address,
+ "site": site,
+ },
+ profile_replace_params.ProfileReplaceParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ClientProfile,
+ )
+
+
+class ProfilesResourceWithRawResponse:
+ def __init__(self, profiles: ProfilesResource) -> None:
+ self._profiles = profiles
+
+ self.create = to_raw_response_wrapper(
+ profiles.create,
+ )
+ self.list = to_raw_response_wrapper(
+ profiles.list,
+ )
+ self.delete = to_raw_response_wrapper(
+ profiles.delete,
+ )
+ self.get = to_raw_response_wrapper(
+ profiles.get,
+ )
+ self.recreate = to_raw_response_wrapper(
+ profiles.recreate,
+ )
+ self.replace = to_raw_response_wrapper(
+ profiles.replace,
+ )
+
+
+class AsyncProfilesResourceWithRawResponse:
+ def __init__(self, profiles: AsyncProfilesResource) -> None:
+ self._profiles = profiles
+
+ self.create = async_to_raw_response_wrapper(
+ profiles.create,
+ )
+ self.list = async_to_raw_response_wrapper(
+ profiles.list,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ profiles.delete,
+ )
+ self.get = async_to_raw_response_wrapper(
+ profiles.get,
+ )
+ self.recreate = async_to_raw_response_wrapper(
+ profiles.recreate,
+ )
+ self.replace = async_to_raw_response_wrapper(
+ profiles.replace,
+ )
+
+
+class ProfilesResourceWithStreamingResponse:
+ def __init__(self, profiles: ProfilesResource) -> None:
+ self._profiles = profiles
+
+ self.create = to_streamed_response_wrapper(
+ profiles.create,
+ )
+ self.list = to_streamed_response_wrapper(
+ profiles.list,
+ )
+ self.delete = to_streamed_response_wrapper(
+ profiles.delete,
+ )
+ self.get = to_streamed_response_wrapper(
+ profiles.get,
+ )
+ self.recreate = to_streamed_response_wrapper(
+ profiles.recreate,
+ )
+ self.replace = to_streamed_response_wrapper(
+ profiles.replace,
+ )
+
+
+class AsyncProfilesResourceWithStreamingResponse:
+ def __init__(self, profiles: AsyncProfilesResource) -> None:
+ self._profiles = profiles
+
+ self.create = async_to_streamed_response_wrapper(
+ profiles.create,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ profiles.list,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ profiles.delete,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ profiles.get,
+ )
+ self.recreate = async_to_streamed_response_wrapper(
+ profiles.recreate,
+ )
+ self.replace = async_to_streamed_response_wrapper(
+ profiles.replace,
+ )
diff --git a/src/gcore/resources/security/security.py b/src/gcore/resources/security/security.py
new file mode 100644
index 00000000..2d0d9c11
--- /dev/null
+++ b/src/gcore/resources/security/security.py
@@ -0,0 +1,198 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .events import (
+ EventsResource,
+ AsyncEventsResource,
+ EventsResourceWithRawResponse,
+ AsyncEventsResourceWithRawResponse,
+ EventsResourceWithStreamingResponse,
+ AsyncEventsResourceWithStreamingResponse,
+)
+from .profiles import (
+ ProfilesResource,
+ AsyncProfilesResource,
+ ProfilesResourceWithRawResponse,
+ AsyncProfilesResourceWithRawResponse,
+ ProfilesResourceWithStreamingResponse,
+ AsyncProfilesResourceWithStreamingResponse,
+)
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from .bgp_announces import (
+ BgpAnnouncesResource,
+ AsyncBgpAnnouncesResource,
+ BgpAnnouncesResourceWithRawResponse,
+ AsyncBgpAnnouncesResourceWithRawResponse,
+ BgpAnnouncesResourceWithStreamingResponse,
+ AsyncBgpAnnouncesResourceWithStreamingResponse,
+)
+from .profile_templates import (
+ ProfileTemplatesResource,
+ AsyncProfileTemplatesResource,
+ ProfileTemplatesResourceWithRawResponse,
+ AsyncProfileTemplatesResourceWithRawResponse,
+ ProfileTemplatesResourceWithStreamingResponse,
+ AsyncProfileTemplatesResourceWithStreamingResponse,
+)
+
+__all__ = ["SecurityResource", "AsyncSecurityResource"]
+
+
+class SecurityResource(SyncAPIResource):
+ @cached_property
+ def events(self) -> EventsResource:
+ return EventsResource(self._client)
+
+ @cached_property
+ def bgp_announces(self) -> BgpAnnouncesResource:
+ return BgpAnnouncesResource(self._client)
+
+ @cached_property
+ def profile_templates(self) -> ProfileTemplatesResource:
+ return ProfileTemplatesResource(self._client)
+
+ @cached_property
+ def profiles(self) -> ProfilesResource:
+ return ProfilesResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> SecurityResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
+ """
+ return SecurityResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> SecurityResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
+ """
+ return SecurityResourceWithStreamingResponse(self)
+
+
+class AsyncSecurityResource(AsyncAPIResource):
+ @cached_property
+ def events(self) -> AsyncEventsResource:
+ return AsyncEventsResource(self._client)
+
+ @cached_property
+ def bgp_announces(self) -> AsyncBgpAnnouncesResource:
+ return AsyncBgpAnnouncesResource(self._client)
+
+ @cached_property
+ def profile_templates(self) -> AsyncProfileTemplatesResource:
+ return AsyncProfileTemplatesResource(self._client)
+
+ @cached_property
+ def profiles(self) -> AsyncProfilesResource:
+ return AsyncProfilesResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncSecurityResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncSecurityResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncSecurityResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
+ """
+ return AsyncSecurityResourceWithStreamingResponse(self)
+
+
+class SecurityResourceWithRawResponse:
+ def __init__(self, security: SecurityResource) -> None:
+ self._security = security
+
+ @cached_property
+ def events(self) -> EventsResourceWithRawResponse:
+ return EventsResourceWithRawResponse(self._security.events)
+
+ @cached_property
+ def bgp_announces(self) -> BgpAnnouncesResourceWithRawResponse:
+ return BgpAnnouncesResourceWithRawResponse(self._security.bgp_announces)
+
+ @cached_property
+ def profile_templates(self) -> ProfileTemplatesResourceWithRawResponse:
+ return ProfileTemplatesResourceWithRawResponse(self._security.profile_templates)
+
+ @cached_property
+ def profiles(self) -> ProfilesResourceWithRawResponse:
+ return ProfilesResourceWithRawResponse(self._security.profiles)
+
+
+class AsyncSecurityResourceWithRawResponse:
+ def __init__(self, security: AsyncSecurityResource) -> None:
+ self._security = security
+
+ @cached_property
+ def events(self) -> AsyncEventsResourceWithRawResponse:
+ return AsyncEventsResourceWithRawResponse(self._security.events)
+
+ @cached_property
+ def bgp_announces(self) -> AsyncBgpAnnouncesResourceWithRawResponse:
+ return AsyncBgpAnnouncesResourceWithRawResponse(self._security.bgp_announces)
+
+ @cached_property
+ def profile_templates(self) -> AsyncProfileTemplatesResourceWithRawResponse:
+ return AsyncProfileTemplatesResourceWithRawResponse(self._security.profile_templates)
+
+ @cached_property
+ def profiles(self) -> AsyncProfilesResourceWithRawResponse:
+ return AsyncProfilesResourceWithRawResponse(self._security.profiles)
+
+
+class SecurityResourceWithStreamingResponse:
+ def __init__(self, security: SecurityResource) -> None:
+ self._security = security
+
+ @cached_property
+ def events(self) -> EventsResourceWithStreamingResponse:
+ return EventsResourceWithStreamingResponse(self._security.events)
+
+ @cached_property
+ def bgp_announces(self) -> BgpAnnouncesResourceWithStreamingResponse:
+ return BgpAnnouncesResourceWithStreamingResponse(self._security.bgp_announces)
+
+ @cached_property
+ def profile_templates(self) -> ProfileTemplatesResourceWithStreamingResponse:
+ return ProfileTemplatesResourceWithStreamingResponse(self._security.profile_templates)
+
+ @cached_property
+ def profiles(self) -> ProfilesResourceWithStreamingResponse:
+ return ProfilesResourceWithStreamingResponse(self._security.profiles)
+
+
+class AsyncSecurityResourceWithStreamingResponse:
+ def __init__(self, security: AsyncSecurityResource) -> None:
+ self._security = security
+
+ @cached_property
+ def events(self) -> AsyncEventsResourceWithStreamingResponse:
+ return AsyncEventsResourceWithStreamingResponse(self._security.events)
+
+ @cached_property
+ def bgp_announces(self) -> AsyncBgpAnnouncesResourceWithStreamingResponse:
+ return AsyncBgpAnnouncesResourceWithStreamingResponse(self._security.bgp_announces)
+
+ @cached_property
+ def profile_templates(self) -> AsyncProfileTemplatesResourceWithStreamingResponse:
+ return AsyncProfileTemplatesResourceWithStreamingResponse(self._security.profile_templates)
+
+ @cached_property
+ def profiles(self) -> AsyncProfilesResourceWithStreamingResponse:
+ return AsyncProfilesResourceWithStreamingResponse(self._security.profiles)
diff --git a/src/gcore/types/security/__init__.py b/src/gcore/types/security/__init__.py
index f8ee8b14..4994ea70 100644
--- a/src/gcore/types/security/__init__.py
+++ b/src/gcore/types/security/__init__.py
@@ -1,3 +1,18 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from __future__ import annotations
+
+from .client_view import ClientView as ClientView
+from .client_profile import ClientProfile as ClientProfile
+from .client_announce import ClientAnnounce as ClientAnnounce
+from .event_list_params import EventListParams as EventListParams
+from .profile_list_params import ProfileListParams as ProfileListParams
+from .profile_create_params import ProfileCreateParams as ProfileCreateParams
+from .profile_list_response import ProfileListResponse as ProfileListResponse
+from .profile_replace_params import ProfileReplaceParams as ProfileReplaceParams
+from .client_profile_template import ClientProfileTemplate as ClientProfileTemplate
+from .profile_recreate_params import ProfileRecreateParams as ProfileRecreateParams
+from .bgp_announce_list_params import BgpAnnounceListParams as BgpAnnounceListParams
+from .bgp_announce_list_response import BgpAnnounceListResponse as BgpAnnounceListResponse
+from .bgp_announce_toggle_params import BgpAnnounceToggleParams as BgpAnnounceToggleParams
+from .profile_template_list_response import ProfileTemplateListResponse as ProfileTemplateListResponse
diff --git a/src/gcore/types/security/bgp_announce_list_params.py b/src/gcore/types/security/bgp_announce_list_params.py
new file mode 100644
index 00000000..390464fe
--- /dev/null
+++ b/src/gcore/types/security/bgp_announce_list_params.py
@@ -0,0 +1,18 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+from typing_extensions import Literal, TypedDict
+
+__all__ = ["BgpAnnounceListParams"]
+
+
+class BgpAnnounceListParams(TypedDict, total=False):
+ announced: Optional[bool]
+
+ client_id: Optional[int]
+
+ origin: Optional[Literal["STATIC", "DYNAMIC"]]
+
+ site: Optional[str]
diff --git a/src/gcore/types/security/bgp_announce_list_response.py b/src/gcore/types/security/bgp_announce_list_response.py
new file mode 100644
index 00000000..6981ba90
--- /dev/null
+++ b/src/gcore/types/security/bgp_announce_list_response.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+from typing_extensions import TypeAlias
+
+from .client_announce import ClientAnnounce
+
+__all__ = ["BgpAnnounceListResponse"]
+
+BgpAnnounceListResponse: TypeAlias = List[ClientAnnounce]
diff --git a/src/gcore/types/security/bgp_announce_toggle_params.py b/src/gcore/types/security/bgp_announce_toggle_params.py
new file mode 100644
index 00000000..4c5dd1b6
--- /dev/null
+++ b/src/gcore/types/security/bgp_announce_toggle_params.py
@@ -0,0 +1,16 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+from typing_extensions import Required, TypedDict
+
+__all__ = ["BgpAnnounceToggleParams"]
+
+
+class BgpAnnounceToggleParams(TypedDict, total=False):
+ announce: Required[str]
+
+ enabled: Required[bool]
+
+ client_id: Optional[int]
diff --git a/src/gcore/types/security/client_announce.py b/src/gcore/types/security/client_announce.py
new file mode 100644
index 00000000..ef276615
--- /dev/null
+++ b/src/gcore/types/security/client_announce.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+
+from ..._models import BaseModel
+
+__all__ = ["ClientAnnounce"]
+
+
+class ClientAnnounce(BaseModel):
+ announced: List[str]
+
+ client_id: int
+
+ not_announced: List[str]
diff --git a/src/gcore/types/security/client_profile.py b/src/gcore/types/security/client_profile.py
new file mode 100644
index 00000000..e02111b5
--- /dev/null
+++ b/src/gcore/types/security/client_profile.py
@@ -0,0 +1,56 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, List, Optional
+
+from ..._models import BaseModel
+from .client_profile_template import ClientProfileTemplate
+
+__all__ = ["ClientProfile", "Field", "Options"]
+
+
+class Field(BaseModel):
+ id: int
+
+ base_field: int
+
+ default: str
+
+ description: str
+
+ field_type: str
+
+ name: str
+
+ required: bool
+
+ validation_schema: Dict[str, object]
+
+ field_value: Optional[object] = None
+
+
+class Options(BaseModel):
+ active: bool
+
+ bgp: bool
+
+ price: str
+
+
+class ClientProfile(BaseModel):
+ id: int
+
+ fields: List[Field]
+
+ options: Options
+
+ plan: str
+
+ profile_template: ClientProfileTemplate
+
+ protocols: List[Dict[str, object]]
+
+ site: str
+
+ status: Dict[str, object]
+
+ ip_address: Optional[str] = None
diff --git a/src/gcore/types/security/client_profile_template.py b/src/gcore/types/security/client_profile_template.py
new file mode 100644
index 00000000..4ea63e14
--- /dev/null
+++ b/src/gcore/types/security/client_profile_template.py
@@ -0,0 +1,43 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["ClientProfileTemplate", "Field"]
+
+
+class Field(BaseModel):
+ id: int
+
+ name: str
+
+ default: Optional[str] = None
+
+ description: Optional[str] = None
+
+ field_type: Optional[Literal["int", "bool", "str"]] = None
+
+ required: Optional[bool] = None
+
+ validation_schema: Optional[Dict[str, object]] = None
+
+
+class ClientProfileTemplate(BaseModel):
+ id: int
+
+ created: datetime
+
+ fields: List[Field]
+
+ name: str
+
+ version: str
+
+ base_template: Optional[int] = None
+
+ description: Optional[str] = None
+
+ template_sifter: Optional[str] = None
diff --git a/src/gcore/types/security/client_view.py b/src/gcore/types/security/client_view.py
new file mode 100644
index 00000000..802060ab
--- /dev/null
+++ b/src/gcore/types/security/client_view.py
@@ -0,0 +1,29 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["ClientView"]
+
+
+class ClientView(BaseModel):
+ id: str
+
+ alert_type: Optional[Literal["ddos_alert", "rtbh_alert"]] = None
+
+ attack_power_bps: Optional[float] = None
+
+ attack_power_pps: Optional[float] = None
+
+ attack_start_time: Optional[datetime] = None
+
+ client_id: Optional[int] = None
+
+ notification_type: Optional[str] = None
+
+ number_of_ip_involved_in_attack: Optional[int] = None
+
+ targeted_ip_addresses: Optional[str] = None
diff --git a/src/gcore/types/security/event_list_params.py b/src/gcore/types/security/event_list_params.py
new file mode 100644
index 00000000..0bd703c3
--- /dev/null
+++ b/src/gcore/types/security/event_list_params.py
@@ -0,0 +1,38 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union, Optional
+from datetime import datetime
+from typing_extensions import Literal, Annotated, TypedDict
+
+from ..._utils import PropertyInfo
+
+__all__ = ["EventListParams"]
+
+
+class EventListParams(TypedDict, total=False):
+ alert_type: Optional[Literal["ddos_alert", "rtbh_alert"]]
+
+ date_from: Annotated[Union[Union[str, datetime], str], PropertyInfo(format="iso8601")]
+
+ date_to: Annotated[Union[Union[str, datetime], str], PropertyInfo(format="iso8601")]
+
+ limit: int
+
+ offset: int
+
+ ordering: Literal[
+ "attack_start_time",
+ "-attack_start_time",
+ "attack_power_bps",
+ "-attack_power_bps",
+ "attack_power_pps",
+ "-attack_power_pps",
+ "number_of_ip_involved_in_attack",
+ "-number_of_ip_involved_in_attack",
+ "alert_type",
+ "-alert_type",
+ ]
+
+ targeted_ip_addresses: Optional[str]
diff --git a/src/gcore/types/security/profile_create_params.py b/src/gcore/types/security/profile_create_params.py
new file mode 100644
index 00000000..ad7b982c
--- /dev/null
+++ b/src/gcore/types/security/profile_create_params.py
@@ -0,0 +1,24 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable, Optional
+from typing_extensions import Required, TypedDict
+
+__all__ = ["ProfileCreateParams", "Field"]
+
+
+class ProfileCreateParams(TypedDict, total=False):
+ fields: Required[Iterable[Field]]
+
+ profile_template: Required[int]
+
+ site: Required[str]
+
+ ip_address: Optional[str]
+
+
+class Field(TypedDict, total=False):
+ base_field: Required[int]
+
+ field_value: object
diff --git a/src/gcore/types/security/profile_list_params.py b/src/gcore/types/security/profile_list_params.py
new file mode 100644
index 00000000..e54f232f
--- /dev/null
+++ b/src/gcore/types/security/profile_list_params.py
@@ -0,0 +1,17 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+__all__ = ["ProfileListParams"]
+
+
+class ProfileListParams(TypedDict, total=False):
+ exclude_empty_address: bool
+
+ include_deleted: bool
+
+ ip_address: str
+
+ site: str
diff --git a/src/gcore/types/security/profile_list_response.py b/src/gcore/types/security/profile_list_response.py
new file mode 100644
index 00000000..816021c8
--- /dev/null
+++ b/src/gcore/types/security/profile_list_response.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+from typing_extensions import TypeAlias
+
+from .client_profile import ClientProfile
+
+__all__ = ["ProfileListResponse"]
+
+ProfileListResponse: TypeAlias = List[ClientProfile]
diff --git a/src/gcore/types/security/profile_recreate_params.py b/src/gcore/types/security/profile_recreate_params.py
new file mode 100644
index 00000000..e1dd3d10
--- /dev/null
+++ b/src/gcore/types/security/profile_recreate_params.py
@@ -0,0 +1,24 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable, Optional
+from typing_extensions import Required, TypedDict
+
+__all__ = ["ProfileRecreateParams", "Field"]
+
+
+class ProfileRecreateParams(TypedDict, total=False):
+ fields: Required[Iterable[Field]]
+
+ profile_template: Required[int]
+
+ ip_address: Optional[str]
+
+ site: str
+
+
+class Field(TypedDict, total=False):
+ base_field: Required[int]
+
+ field_value: object
diff --git a/src/gcore/types/security/profile_replace_params.py b/src/gcore/types/security/profile_replace_params.py
new file mode 100644
index 00000000..9684dffd
--- /dev/null
+++ b/src/gcore/types/security/profile_replace_params.py
@@ -0,0 +1,24 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable, Optional
+from typing_extensions import Required, TypedDict
+
+__all__ = ["ProfileReplaceParams", "Field"]
+
+
+class ProfileReplaceParams(TypedDict, total=False):
+ fields: Required[Iterable[Field]]
+
+ profile_template: Required[int]
+
+ ip_address: Optional[str]
+
+ site: str
+
+
+class Field(TypedDict, total=False):
+ base_field: Required[int]
+
+ field_value: object
diff --git a/src/gcore/types/security/profile_template_list_response.py b/src/gcore/types/security/profile_template_list_response.py
new file mode 100644
index 00000000..2264e970
--- /dev/null
+++ b/src/gcore/types/security/profile_template_list_response.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+from typing_extensions import TypeAlias
+
+from .client_profile_template import ClientProfileTemplate
+
+__all__ = ["ProfileTemplateListResponse"]
+
+ProfileTemplateListResponse: TypeAlias = List[ClientProfileTemplate]
diff --git a/tests/api_resources/security/__init__.py b/tests/api_resources/security/__init__.py
new file mode 100644
index 00000000..fd8019a9
--- /dev/null
+++ b/tests/api_resources/security/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/security/test_bgp_announces.py b/tests/api_resources/security/test_bgp_announces.py
new file mode 100644
index 00000000..c1115976
--- /dev/null
+++ b/tests/api_resources/security/test_bgp_announces.py
@@ -0,0 +1,180 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from gcore import Gcore, AsyncGcore
+from tests.utils import assert_matches_type
+from gcore.types.security import BgpAnnounceListResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestBgpAnnounces:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_list(self, client: Gcore) -> None:
+ bgp_announce = client.security.bgp_announces.list()
+ assert_matches_type(BgpAnnounceListResponse, bgp_announce, path=["response"])
+
+ @parametrize
+ def test_method_list_with_all_params(self, client: Gcore) -> None:
+ bgp_announce = client.security.bgp_announces.list(
+ announced=True,
+ client_id=0,
+ origin="STATIC",
+ site="x",
+ )
+ assert_matches_type(BgpAnnounceListResponse, bgp_announce, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Gcore) -> None:
+ response = client.security.bgp_announces.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ bgp_announce = response.parse()
+ assert_matches_type(BgpAnnounceListResponse, bgp_announce, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Gcore) -> None:
+ with client.security.bgp_announces.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ bgp_announce = response.parse()
+ assert_matches_type(BgpAnnounceListResponse, bgp_announce, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_toggle(self, client: Gcore) -> None:
+ bgp_announce = client.security.bgp_announces.toggle(
+ announce="192.9.9.1/32",
+ enabled=True,
+ )
+ assert_matches_type(object, bgp_announce, path=["response"])
+
+ @parametrize
+ def test_method_toggle_with_all_params(self, client: Gcore) -> None:
+ bgp_announce = client.security.bgp_announces.toggle(
+ announce="192.9.9.1/32",
+ enabled=True,
+ client_id=0,
+ )
+ assert_matches_type(object, bgp_announce, path=["response"])
+
+ @parametrize
+ def test_raw_response_toggle(self, client: Gcore) -> None:
+ response = client.security.bgp_announces.with_raw_response.toggle(
+ announce="192.9.9.1/32",
+ enabled=True,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ bgp_announce = response.parse()
+ assert_matches_type(object, bgp_announce, path=["response"])
+
+ @parametrize
+ def test_streaming_response_toggle(self, client: Gcore) -> None:
+ with client.security.bgp_announces.with_streaming_response.toggle(
+ announce="192.9.9.1/32",
+ enabled=True,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ bgp_announce = response.parse()
+ assert_matches_type(object, bgp_announce, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncBgpAnnounces:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncGcore) -> None:
+ bgp_announce = await async_client.security.bgp_announces.list()
+ assert_matches_type(BgpAnnounceListResponse, bgp_announce, path=["response"])
+
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> None:
+ bgp_announce = await async_client.security.bgp_announces.list(
+ announced=True,
+ client_id=0,
+ origin="STATIC",
+ site="x",
+ )
+ assert_matches_type(BgpAnnounceListResponse, bgp_announce, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncGcore) -> None:
+ response = await async_client.security.bgp_announces.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ bgp_announce = await response.parse()
+ assert_matches_type(BgpAnnounceListResponse, bgp_announce, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncGcore) -> None:
+ async with async_client.security.bgp_announces.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ bgp_announce = await response.parse()
+ assert_matches_type(BgpAnnounceListResponse, bgp_announce, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_toggle(self, async_client: AsyncGcore) -> None:
+ bgp_announce = await async_client.security.bgp_announces.toggle(
+ announce="192.9.9.1/32",
+ enabled=True,
+ )
+ assert_matches_type(object, bgp_announce, path=["response"])
+
+ @parametrize
+ async def test_method_toggle_with_all_params(self, async_client: AsyncGcore) -> None:
+ bgp_announce = await async_client.security.bgp_announces.toggle(
+ announce="192.9.9.1/32",
+ enabled=True,
+ client_id=0,
+ )
+ assert_matches_type(object, bgp_announce, path=["response"])
+
+ @parametrize
+ async def test_raw_response_toggle(self, async_client: AsyncGcore) -> None:
+ response = await async_client.security.bgp_announces.with_raw_response.toggle(
+ announce="192.9.9.1/32",
+ enabled=True,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ bgp_announce = await response.parse()
+ assert_matches_type(object, bgp_announce, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_toggle(self, async_client: AsyncGcore) -> None:
+ async with async_client.security.bgp_announces.with_streaming_response.toggle(
+ announce="192.9.9.1/32",
+ enabled=True,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ bgp_announce = await response.parse()
+ assert_matches_type(object, bgp_announce, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/security/test_events.py b/tests/api_resources/security/test_events.py
new file mode 100644
index 00000000..650de2cf
--- /dev/null
+++ b/tests/api_resources/security/test_events.py
@@ -0,0 +1,102 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from gcore import Gcore, AsyncGcore
+from tests.utils import assert_matches_type
+from gcore._utils import parse_datetime
+from gcore.pagination import SyncOffsetPage, AsyncOffsetPage
+from gcore.types.security import ClientView
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestEvents:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_list(self, client: Gcore) -> None:
+ event = client.security.events.list()
+ assert_matches_type(SyncOffsetPage[ClientView], event, path=["response"])
+
+ @parametrize
+ def test_method_list_with_all_params(self, client: Gcore) -> None:
+ event = client.security.events.list(
+ alert_type="ddos_alert",
+ date_from=parse_datetime("2019-12-27T18:11:19.117Z"),
+ date_to=parse_datetime("2019-12-27T18:11:19.117Z"),
+ limit=1,
+ offset=0,
+ ordering="attack_start_time",
+ targeted_ip_addresses="targeted_ip_addresses",
+ )
+ assert_matches_type(SyncOffsetPage[ClientView], event, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Gcore) -> None:
+ response = client.security.events.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ event = response.parse()
+ assert_matches_type(SyncOffsetPage[ClientView], event, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Gcore) -> None:
+ with client.security.events.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ event = response.parse()
+ assert_matches_type(SyncOffsetPage[ClientView], event, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncEvents:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncGcore) -> None:
+ event = await async_client.security.events.list()
+ assert_matches_type(AsyncOffsetPage[ClientView], event, path=["response"])
+
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> None:
+ event = await async_client.security.events.list(
+ alert_type="ddos_alert",
+ date_from=parse_datetime("2019-12-27T18:11:19.117Z"),
+ date_to=parse_datetime("2019-12-27T18:11:19.117Z"),
+ limit=1,
+ offset=0,
+ ordering="attack_start_time",
+ targeted_ip_addresses="targeted_ip_addresses",
+ )
+ assert_matches_type(AsyncOffsetPage[ClientView], event, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncGcore) -> None:
+ response = await async_client.security.events.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ event = await response.parse()
+ assert_matches_type(AsyncOffsetPage[ClientView], event, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncGcore) -> None:
+ async with async_client.security.events.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ event = await response.parse()
+ assert_matches_type(AsyncOffsetPage[ClientView], event, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/security/test_profile_templates.py b/tests/api_resources/security/test_profile_templates.py
new file mode 100644
index 00000000..7df4918f
--- /dev/null
+++ b/tests/api_resources/security/test_profile_templates.py
@@ -0,0 +1,74 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from gcore import Gcore, AsyncGcore
+from tests.utils import assert_matches_type
+from gcore.types.security import ProfileTemplateListResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestProfileTemplates:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_list(self, client: Gcore) -> None:
+ profile_template = client.security.profile_templates.list()
+ assert_matches_type(ProfileTemplateListResponse, profile_template, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Gcore) -> None:
+ response = client.security.profile_templates.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ profile_template = response.parse()
+ assert_matches_type(ProfileTemplateListResponse, profile_template, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Gcore) -> None:
+ with client.security.profile_templates.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ profile_template = response.parse()
+ assert_matches_type(ProfileTemplateListResponse, profile_template, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncProfileTemplates:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncGcore) -> None:
+ profile_template = await async_client.security.profile_templates.list()
+ assert_matches_type(ProfileTemplateListResponse, profile_template, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncGcore) -> None:
+ response = await async_client.security.profile_templates.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ profile_template = await response.parse()
+ assert_matches_type(ProfileTemplateListResponse, profile_template, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncGcore) -> None:
+ async with async_client.security.profile_templates.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ profile_template = await response.parse()
+ assert_matches_type(ProfileTemplateListResponse, profile_template, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/security/test_profiles.py b/tests/api_resources/security/test_profiles.py
new file mode 100644
index 00000000..c79499ab
--- /dev/null
+++ b/tests/api_resources/security/test_profiles.py
@@ -0,0 +1,537 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from gcore import Gcore, AsyncGcore
+from tests.utils import assert_matches_type
+from gcore.types.security import (
+ ClientProfile,
+ ProfileListResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestProfiles:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: Gcore) -> None:
+ profile = client.security.profiles.create(
+ fields=[{"base_field": 1}],
+ profile_template=1,
+ site="GNC",
+ )
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ @parametrize
+ def test_method_create_with_all_params(self, client: Gcore) -> None:
+ profile = client.security.profiles.create(
+ fields=[
+ {
+ "base_field": 1,
+ "field_value": {},
+ }
+ ],
+ profile_template=1,
+ site="GNC",
+ ip_address="123.43.2.10",
+ )
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Gcore) -> None:
+ response = client.security.profiles.with_raw_response.create(
+ fields=[{"base_field": 1}],
+ profile_template=1,
+ site="GNC",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ profile = response.parse()
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Gcore) -> None:
+ with client.security.profiles.with_streaming_response.create(
+ fields=[{"base_field": 1}],
+ profile_template=1,
+ site="GNC",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ profile = response.parse()
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_list(self, client: Gcore) -> None:
+ profile = client.security.profiles.list()
+ assert_matches_type(ProfileListResponse, profile, path=["response"])
+
+ @parametrize
+ def test_method_list_with_all_params(self, client: Gcore) -> None:
+ profile = client.security.profiles.list(
+ exclude_empty_address=True,
+ include_deleted=True,
+ ip_address="ip_address",
+ site="site",
+ )
+ assert_matches_type(ProfileListResponse, profile, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Gcore) -> None:
+ response = client.security.profiles.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ profile = response.parse()
+ assert_matches_type(ProfileListResponse, profile, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Gcore) -> None:
+ with client.security.profiles.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ profile = response.parse()
+ assert_matches_type(ProfileListResponse, profile, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_delete(self, client: Gcore) -> None:
+ profile = client.security.profiles.delete(
+ 0,
+ )
+ assert profile is None
+
+ @parametrize
+ def test_raw_response_delete(self, client: Gcore) -> None:
+ response = client.security.profiles.with_raw_response.delete(
+ 0,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ profile = response.parse()
+ assert profile is None
+
+ @parametrize
+ def test_streaming_response_delete(self, client: Gcore) -> None:
+ with client.security.profiles.with_streaming_response.delete(
+ 0,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ profile = response.parse()
+ assert profile is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_get(self, client: Gcore) -> None:
+ profile = client.security.profiles.get(
+ 0,
+ )
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Gcore) -> None:
+ response = client.security.profiles.with_raw_response.get(
+ 0,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ profile = response.parse()
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Gcore) -> None:
+ with client.security.profiles.with_streaming_response.get(
+ 0,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ profile = response.parse()
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_recreate(self, client: Gcore) -> None:
+ profile = client.security.profiles.recreate(
+ id=0,
+ fields=[{"base_field": 1}],
+ profile_template=1,
+ )
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ @parametrize
+ def test_method_recreate_with_all_params(self, client: Gcore) -> None:
+ profile = client.security.profiles.recreate(
+ id=0,
+ fields=[
+ {
+ "base_field": 1,
+ "field_value": {},
+ }
+ ],
+ profile_template=1,
+ ip_address="ip_address",
+ site="ED",
+ )
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ @parametrize
+ def test_raw_response_recreate(self, client: Gcore) -> None:
+ response = client.security.profiles.with_raw_response.recreate(
+ id=0,
+ fields=[{"base_field": 1}],
+ profile_template=1,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ profile = response.parse()
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ @parametrize
+ def test_streaming_response_recreate(self, client: Gcore) -> None:
+ with client.security.profiles.with_streaming_response.recreate(
+ id=0,
+ fields=[{"base_field": 1}],
+ profile_template=1,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ profile = response.parse()
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_replace(self, client: Gcore) -> None:
+ profile = client.security.profiles.replace(
+ id=0,
+ fields=[{"base_field": 1}],
+ profile_template=1,
+ )
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ @parametrize
+ def test_method_replace_with_all_params(self, client: Gcore) -> None:
+ profile = client.security.profiles.replace(
+ id=0,
+ fields=[
+ {
+ "base_field": 1,
+ "field_value": {},
+ }
+ ],
+ profile_template=1,
+ ip_address="ip_address",
+ site="ED",
+ )
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ @parametrize
+ def test_raw_response_replace(self, client: Gcore) -> None:
+ response = client.security.profiles.with_raw_response.replace(
+ id=0,
+ fields=[{"base_field": 1}],
+ profile_template=1,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ profile = response.parse()
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ @parametrize
+ def test_streaming_response_replace(self, client: Gcore) -> None:
+ with client.security.profiles.with_streaming_response.replace(
+ id=0,
+ fields=[{"base_field": 1}],
+ profile_template=1,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ profile = response.parse()
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncProfiles:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_create(self, async_client: AsyncGcore) -> None:
+ profile = await async_client.security.profiles.create(
+ fields=[{"base_field": 1}],
+ profile_template=1,
+ site="GNC",
+ )
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ @parametrize
+ async def test_method_create_with_all_params(self, async_client: AsyncGcore) -> None:
+ profile = await async_client.security.profiles.create(
+ fields=[
+ {
+ "base_field": 1,
+ "field_value": {},
+ }
+ ],
+ profile_template=1,
+ site="GNC",
+ ip_address="123.43.2.10",
+ )
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncGcore) -> None:
+ response = await async_client.security.profiles.with_raw_response.create(
+ fields=[{"base_field": 1}],
+ profile_template=1,
+ site="GNC",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ profile = await response.parse()
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncGcore) -> None:
+ async with async_client.security.profiles.with_streaming_response.create(
+ fields=[{"base_field": 1}],
+ profile_template=1,
+ site="GNC",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ profile = await response.parse()
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncGcore) -> None:
+ profile = await async_client.security.profiles.list()
+ assert_matches_type(ProfileListResponse, profile, path=["response"])
+
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> None:
+ profile = await async_client.security.profiles.list(
+ exclude_empty_address=True,
+ include_deleted=True,
+ ip_address="ip_address",
+ site="site",
+ )
+ assert_matches_type(ProfileListResponse, profile, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncGcore) -> None:
+ response = await async_client.security.profiles.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ profile = await response.parse()
+ assert_matches_type(ProfileListResponse, profile, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncGcore) -> None:
+ async with async_client.security.profiles.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ profile = await response.parse()
+ assert_matches_type(ProfileListResponse, profile, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncGcore) -> None:
+ profile = await async_client.security.profiles.delete(
+ 0,
+ )
+ assert profile is None
+
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncGcore) -> None:
+ response = await async_client.security.profiles.with_raw_response.delete(
+ 0,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ profile = await response.parse()
+ assert profile is None
+
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncGcore) -> None:
+ async with async_client.security.profiles.with_streaming_response.delete(
+ 0,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ profile = await response.parse()
+ assert profile is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncGcore) -> None:
+ profile = await async_client.security.profiles.get(
+ 0,
+ )
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncGcore) -> None:
+ response = await async_client.security.profiles.with_raw_response.get(
+ 0,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ profile = await response.parse()
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncGcore) -> None:
+ async with async_client.security.profiles.with_streaming_response.get(
+ 0,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ profile = await response.parse()
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_recreate(self, async_client: AsyncGcore) -> None:
+ profile = await async_client.security.profiles.recreate(
+ id=0,
+ fields=[{"base_field": 1}],
+ profile_template=1,
+ )
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ @parametrize
+ async def test_method_recreate_with_all_params(self, async_client: AsyncGcore) -> None:
+ profile = await async_client.security.profiles.recreate(
+ id=0,
+ fields=[
+ {
+ "base_field": 1,
+ "field_value": {},
+ }
+ ],
+ profile_template=1,
+ ip_address="ip_address",
+ site="ED",
+ )
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ @parametrize
+ async def test_raw_response_recreate(self, async_client: AsyncGcore) -> None:
+ response = await async_client.security.profiles.with_raw_response.recreate(
+ id=0,
+ fields=[{"base_field": 1}],
+ profile_template=1,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ profile = await response.parse()
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_recreate(self, async_client: AsyncGcore) -> None:
+ async with async_client.security.profiles.with_streaming_response.recreate(
+ id=0,
+ fields=[{"base_field": 1}],
+ profile_template=1,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ profile = await response.parse()
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_replace(self, async_client: AsyncGcore) -> None:
+ profile = await async_client.security.profiles.replace(
+ id=0,
+ fields=[{"base_field": 1}],
+ profile_template=1,
+ )
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ @parametrize
+ async def test_method_replace_with_all_params(self, async_client: AsyncGcore) -> None:
+ profile = await async_client.security.profiles.replace(
+ id=0,
+ fields=[
+ {
+ "base_field": 1,
+ "field_value": {},
+ }
+ ],
+ profile_template=1,
+ ip_address="ip_address",
+ site="ED",
+ )
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ @parametrize
+ async def test_raw_response_replace(self, async_client: AsyncGcore) -> None:
+ response = await async_client.security.profiles.with_raw_response.replace(
+ id=0,
+ fields=[{"base_field": 1}],
+ profile_template=1,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ profile = await response.parse()
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_replace(self, async_client: AsyncGcore) -> None:
+ async with async_client.security.profiles.with_streaming_response.replace(
+ id=0,
+ fields=[{"base_field": 1}],
+ profile_template=1,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ profile = await response.parse()
+ assert_matches_type(ClientProfile, profile, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
From 27bc07acab63505e03f4a5b51e21544fe84877ec Mon Sep 17 00:00:00 2001
From: Pedro Oliveira <8281907+pedrodeoliveira@users.noreply.github.com>
Date: Tue, 4 Nov 2025 15:04:30 +0000
Subject: [PATCH 25/27] fix(cloud): members not optional in lb pools
create_and_poll
---
src/gcore/resources/cloud/load_balancers/pools/pools.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/gcore/resources/cloud/load_balancers/pools/pools.py b/src/gcore/resources/cloud/load_balancers/pools/pools.py
index 3dd5314b..121406f7 100644
--- a/src/gcore/resources/cloud/load_balancers/pools/pools.py
+++ b/src/gcore/resources/cloud/load_balancers/pools/pools.py
@@ -452,7 +452,7 @@ def create_and_poll(
healthmonitor: Optional[pool_create_params.Healthmonitor] | Omit = omit,
listener_id: Optional[str] | Omit = omit,
load_balancer_id: Optional[str] | Omit = omit,
- members: Optional[Iterable[pool_create_params.Member]] | Omit = omit,
+ members: Iterable[pool_create_params.Member] | Omit = omit,
secret_id: Optional[str] | Omit = omit,
session_persistence: Optional[pool_create_params.SessionPersistence] | Omit = omit,
timeout_client_data: Optional[int] | Omit = omit,
@@ -1019,7 +1019,7 @@ async def create_and_poll(
healthmonitor: Optional[pool_create_params.Healthmonitor] | Omit = omit,
listener_id: Optional[str] | Omit = omit,
load_balancer_id: Optional[str] | Omit = omit,
- members: Optional[Iterable[pool_create_params.Member]] | Omit = omit,
+ members: Iterable[pool_create_params.Member] | Omit = omit,
secret_id: Optional[str] | Omit = omit,
session_persistence: Optional[pool_create_params.SessionPersistence] | Omit = omit,
timeout_client_data: Optional[int] | Omit = omit,
From 2802edf3bbac88b644ba8ff4d5b83dc0606e4b48 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 4 Nov 2025 15:47:43 +0000
Subject: [PATCH 26/27] feat(cloud): add support for postgres
---
.stats.yml | 4 +-
api.md | 57 ++
src/gcore/resources/cloud/__init__.py | 14 +
src/gcore/resources/cloud/cloud.py | 32 +
.../resources/cloud/databases/__init__.py | 33 +
.../resources/cloud/databases/databases.py | 102 +++
.../cloud/databases/postgres/__init__.py | 61 ++
.../databases/postgres/clusters/__init__.py | 33 +
.../databases/postgres/clusters/clusters.py | 716 +++++++++++++++++
.../postgres/clusters/user_credentials.py | 281 +++++++
.../databases/postgres/configurations.py | 169 ++++
.../postgres/custom_configurations.py | 197 +++++
.../cloud/databases/postgres/postgres.py | 166 ++++
src/gcore/types/cloud/databases/__init__.py | 3 +
.../cloud/databases/postgres/__init__.py | 12 +
.../postgres/cluster_create_params.py | 108 +++
.../databases/postgres/cluster_list_params.py | 19 +
.../postgres/cluster_update_params.py | 102 +++
.../databases/postgres/clusters/__init__.py | 5 +
.../clusters/postgres_user_credentials.py | 13 +
.../custom_configuration_validate_params.py | 19 +
.../databases/postgres/pg_conf_validation.py | 15 +
.../databases/postgres/postgres_cluster.py | 118 +++
.../postgres/postgres_cluster_short.py | 22 +
.../postgres/postgres_configuration.py | 31 +
.../api_resources/cloud/databases/__init__.py | 1 +
.../cloud/databases/postgres/__init__.py | 1 +
.../databases/postgres/clusters/__init__.py | 1 +
.../clusters/test_user_credentials.py | 256 ++++++
.../cloud/databases/postgres/test_clusters.py | 731 ++++++++++++++++++
.../databases/postgres/test_configurations.py | 92 +++
.../postgres/test_custom_configurations.py | 104 +++
32 files changed, 3516 insertions(+), 2 deletions(-)
create mode 100644 src/gcore/resources/cloud/databases/__init__.py
create mode 100644 src/gcore/resources/cloud/databases/databases.py
create mode 100644 src/gcore/resources/cloud/databases/postgres/__init__.py
create mode 100644 src/gcore/resources/cloud/databases/postgres/clusters/__init__.py
create mode 100644 src/gcore/resources/cloud/databases/postgres/clusters/clusters.py
create mode 100644 src/gcore/resources/cloud/databases/postgres/clusters/user_credentials.py
create mode 100644 src/gcore/resources/cloud/databases/postgres/configurations.py
create mode 100644 src/gcore/resources/cloud/databases/postgres/custom_configurations.py
create mode 100644 src/gcore/resources/cloud/databases/postgres/postgres.py
create mode 100644 src/gcore/types/cloud/databases/__init__.py
create mode 100644 src/gcore/types/cloud/databases/postgres/__init__.py
create mode 100644 src/gcore/types/cloud/databases/postgres/cluster_create_params.py
create mode 100644 src/gcore/types/cloud/databases/postgres/cluster_list_params.py
create mode 100644 src/gcore/types/cloud/databases/postgres/cluster_update_params.py
create mode 100644 src/gcore/types/cloud/databases/postgres/clusters/__init__.py
create mode 100644 src/gcore/types/cloud/databases/postgres/clusters/postgres_user_credentials.py
create mode 100644 src/gcore/types/cloud/databases/postgres/custom_configuration_validate_params.py
create mode 100644 src/gcore/types/cloud/databases/postgres/pg_conf_validation.py
create mode 100644 src/gcore/types/cloud/databases/postgres/postgres_cluster.py
create mode 100644 src/gcore/types/cloud/databases/postgres/postgres_cluster_short.py
create mode 100644 src/gcore/types/cloud/databases/postgres/postgres_configuration.py
create mode 100644 tests/api_resources/cloud/databases/__init__.py
create mode 100644 tests/api_resources/cloud/databases/postgres/__init__.py
create mode 100644 tests/api_resources/cloud/databases/postgres/clusters/__init__.py
create mode 100644 tests/api_resources/cloud/databases/postgres/clusters/test_user_credentials.py
create mode 100644 tests/api_resources/cloud/databases/postgres/test_clusters.py
create mode 100644 tests/api_resources/cloud/databases/postgres/test_configurations.py
create mode 100644 tests/api_resources/cloud/databases/postgres/test_custom_configurations.py
diff --git a/.stats.yml b/.stats.yml
index 72bd8302..bb221715 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 609
+configured_endpoints: 618
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-1089f2c131ebee7df82e158c4210c07f019b47549d84fe6ea7f022117c83a008.yml
openapi_spec_hash: 9758acbadc1ee1bc0d826d4657e1ad4a
-config_hash: 4758209f53bb13d06f55e4cf6c952b6d
+config_hash: 79098512b2ff15053f2813524c207add
diff --git a/api.md b/api.md
index 6ff46915..180b482b 100644
--- a/api.md
+++ b/api.md
@@ -1006,6 +1006,63 @@ Methods:
- client.cloud.usage_reports.get(\*\*params) -> UsageReport
+## Databases
+
+### Postgres
+
+#### Clusters
+
+Types:
+
+```python
+from gcore.types.cloud.databases.postgres import PostgresCluster, PostgresClusterShort
+```
+
+Methods:
+
+- client.cloud.databases.postgres.clusters.create(\*, project_id, region_id, \*\*params) -> TaskIDList
+- client.cloud.databases.postgres.clusters.update(cluster_name, \*, project_id, region_id, \*\*params) -> TaskIDList
+- client.cloud.databases.postgres.clusters.list(\*, project_id, region_id, \*\*params) -> SyncOffsetPage[PostgresClusterShort]
+- client.cloud.databases.postgres.clusters.delete(cluster_name, \*, project_id, region_id) -> TaskIDList
+- client.cloud.databases.postgres.clusters.get(cluster_name, \*, project_id, region_id) -> PostgresCluster
+
+##### UserCredentials
+
+Types:
+
+```python
+from gcore.types.cloud.databases.postgres.clusters import PostgresUserCredentials
+```
+
+Methods:
+
+- client.cloud.databases.postgres.clusters.user_credentials.get(username, \*, project_id, region_id, cluster_name) -> PostgresUserCredentials
+- client.cloud.databases.postgres.clusters.user_credentials.regenerate(username, \*, project_id, region_id, cluster_name) -> PostgresUserCredentials
+
+#### Configurations
+
+Types:
+
+```python
+from gcore.types.cloud.databases.postgres import PostgresConfiguration
+```
+
+Methods:
+
+- client.cloud.databases.postgres.configurations.get(\*, project_id, region_id) -> PostgresConfiguration
+
+#### CustomConfigurations
+
+Types:
+
+```python
+from gcore.types.cloud.databases.postgres import PgConfValidation
+```
+
+Methods:
+
+- client.cloud.databases.postgres.custom_configurations.validate(\*, project_id, region_id, \*\*params) -> PgConfValidation
+
# Waap
Types:
diff --git a/src/gcore/resources/cloud/__init__.py b/src/gcore/resources/cloud/__init__.py
index c78945ec..b430fc7c 100644
--- a/src/gcore/resources/cloud/__init__.py
+++ b/src/gcore/resources/cloud/__init__.py
@@ -96,6 +96,14 @@
BaremetalResourceWithStreamingResponse,
AsyncBaremetalResourceWithStreamingResponse,
)
+from .databases import (
+ DatabasesResource,
+ AsyncDatabasesResource,
+ DatabasesResourceWithRawResponse,
+ AsyncDatabasesResourceWithRawResponse,
+ DatabasesResourceWithStreamingResponse,
+ AsyncDatabasesResourceWithStreamingResponse,
+)
from .inference import (
InferenceResource,
AsyncInferenceResource,
@@ -374,6 +382,12 @@
"AsyncUsageReportsResourceWithRawResponse",
"UsageReportsResourceWithStreamingResponse",
"AsyncUsageReportsResourceWithStreamingResponse",
+ "DatabasesResource",
+ "AsyncDatabasesResource",
+ "DatabasesResourceWithRawResponse",
+ "AsyncDatabasesResourceWithRawResponse",
+ "DatabasesResourceWithStreamingResponse",
+ "AsyncDatabasesResourceWithStreamingResponse",
"CloudResource",
"AsyncCloudResource",
"CloudResourceWithRawResponse",
diff --git a/src/gcore/resources/cloud/cloud.py b/src/gcore/resources/cloud/cloud.py
index 7628349c..6583dc98 100644
--- a/src/gcore/resources/cloud/cloud.py
+++ b/src/gcore/resources/cloud/cloud.py
@@ -140,6 +140,14 @@
BaremetalResourceWithStreamingResponse,
AsyncBaremetalResourceWithStreamingResponse,
)
+from .databases.databases import (
+ DatabasesResource,
+ AsyncDatabasesResource,
+ DatabasesResourceWithRawResponse,
+ AsyncDatabasesResourceWithRawResponse,
+ DatabasesResourceWithStreamingResponse,
+ AsyncDatabasesResourceWithStreamingResponse,
+)
from .inference.inference import (
InferenceResource,
AsyncInferenceResource,
@@ -328,6 +336,10 @@ def cost_reports(self) -> CostReportsResource:
def usage_reports(self) -> UsageReportsResource:
return UsageReportsResource(self._client)
+ @cached_property
+ def databases(self) -> DatabasesResource:
+ return DatabasesResource(self._client)
+
@cached_property
def with_raw_response(self) -> CloudResourceWithRawResponse:
"""
@@ -460,6 +472,10 @@ def cost_reports(self) -> AsyncCostReportsResource:
def usage_reports(self) -> AsyncUsageReportsResource:
return AsyncUsageReportsResource(self._client)
+ @cached_property
+ def databases(self) -> AsyncDatabasesResource:
+ return AsyncDatabasesResource(self._client)
+
@cached_property
def with_raw_response(self) -> AsyncCloudResourceWithRawResponse:
"""
@@ -595,6 +611,10 @@ def cost_reports(self) -> CostReportsResourceWithRawResponse:
def usage_reports(self) -> UsageReportsResourceWithRawResponse:
return UsageReportsResourceWithRawResponse(self._cloud.usage_reports)
+ @cached_property
+ def databases(self) -> DatabasesResourceWithRawResponse:
+ return DatabasesResourceWithRawResponse(self._cloud.databases)
+
class AsyncCloudResourceWithRawResponse:
def __init__(self, cloud: AsyncCloudResource) -> None:
@@ -711,6 +731,10 @@ def cost_reports(self) -> AsyncCostReportsResourceWithRawResponse:
def usage_reports(self) -> AsyncUsageReportsResourceWithRawResponse:
return AsyncUsageReportsResourceWithRawResponse(self._cloud.usage_reports)
+ @cached_property
+ def databases(self) -> AsyncDatabasesResourceWithRawResponse:
+ return AsyncDatabasesResourceWithRawResponse(self._cloud.databases)
+
class CloudResourceWithStreamingResponse:
def __init__(self, cloud: CloudResource) -> None:
@@ -827,6 +851,10 @@ def cost_reports(self) -> CostReportsResourceWithStreamingResponse:
def usage_reports(self) -> UsageReportsResourceWithStreamingResponse:
return UsageReportsResourceWithStreamingResponse(self._cloud.usage_reports)
+ @cached_property
+ def databases(self) -> DatabasesResourceWithStreamingResponse:
+ return DatabasesResourceWithStreamingResponse(self._cloud.databases)
+
class AsyncCloudResourceWithStreamingResponse:
def __init__(self, cloud: AsyncCloudResource) -> None:
@@ -942,3 +970,7 @@ def cost_reports(self) -> AsyncCostReportsResourceWithStreamingResponse:
@cached_property
def usage_reports(self) -> AsyncUsageReportsResourceWithStreamingResponse:
return AsyncUsageReportsResourceWithStreamingResponse(self._cloud.usage_reports)
+
+ @cached_property
+ def databases(self) -> AsyncDatabasesResourceWithStreamingResponse:
+ return AsyncDatabasesResourceWithStreamingResponse(self._cloud.databases)
diff --git a/src/gcore/resources/cloud/databases/__init__.py b/src/gcore/resources/cloud/databases/__init__.py
new file mode 100644
index 00000000..6935a4f7
--- /dev/null
+++ b/src/gcore/resources/cloud/databases/__init__.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .postgres import (
+ PostgresResource,
+ AsyncPostgresResource,
+ PostgresResourceWithRawResponse,
+ AsyncPostgresResourceWithRawResponse,
+ PostgresResourceWithStreamingResponse,
+ AsyncPostgresResourceWithStreamingResponse,
+)
+from .databases import (
+ DatabasesResource,
+ AsyncDatabasesResource,
+ DatabasesResourceWithRawResponse,
+ AsyncDatabasesResourceWithRawResponse,
+ DatabasesResourceWithStreamingResponse,
+ AsyncDatabasesResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "PostgresResource",
+ "AsyncPostgresResource",
+ "PostgresResourceWithRawResponse",
+ "AsyncPostgresResourceWithRawResponse",
+ "PostgresResourceWithStreamingResponse",
+ "AsyncPostgresResourceWithStreamingResponse",
+ "DatabasesResource",
+ "AsyncDatabasesResource",
+ "DatabasesResourceWithRawResponse",
+ "AsyncDatabasesResourceWithRawResponse",
+ "DatabasesResourceWithStreamingResponse",
+ "AsyncDatabasesResourceWithStreamingResponse",
+]
diff --git a/src/gcore/resources/cloud/databases/databases.py b/src/gcore/resources/cloud/databases/databases.py
new file mode 100644
index 00000000..baacc4af
--- /dev/null
+++ b/src/gcore/resources/cloud/databases/databases.py
@@ -0,0 +1,102 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from .postgres.postgres import (
+ PostgresResource,
+ AsyncPostgresResource,
+ PostgresResourceWithRawResponse,
+ AsyncPostgresResourceWithRawResponse,
+ PostgresResourceWithStreamingResponse,
+ AsyncPostgresResourceWithStreamingResponse,
+)
+
+__all__ = ["DatabasesResource", "AsyncDatabasesResource"]
+
+
+class DatabasesResource(SyncAPIResource):
+ @cached_property
+ def postgres(self) -> PostgresResource:
+ return PostgresResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> DatabasesResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
+ """
+ return DatabasesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> DatabasesResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
+ """
+ return DatabasesResourceWithStreamingResponse(self)
+
+
+class AsyncDatabasesResource(AsyncAPIResource):
+ @cached_property
+ def postgres(self) -> AsyncPostgresResource:
+ return AsyncPostgresResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncDatabasesResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncDatabasesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncDatabasesResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
+ """
+ return AsyncDatabasesResourceWithStreamingResponse(self)
+
+
+class DatabasesResourceWithRawResponse:
+ def __init__(self, databases: DatabasesResource) -> None:
+ self._databases = databases
+
+ @cached_property
+ def postgres(self) -> PostgresResourceWithRawResponse:
+ return PostgresResourceWithRawResponse(self._databases.postgres)
+
+
+class AsyncDatabasesResourceWithRawResponse:
+ def __init__(self, databases: AsyncDatabasesResource) -> None:
+ self._databases = databases
+
+ @cached_property
+ def postgres(self) -> AsyncPostgresResourceWithRawResponse:
+ return AsyncPostgresResourceWithRawResponse(self._databases.postgres)
+
+
+class DatabasesResourceWithStreamingResponse:
+ def __init__(self, databases: DatabasesResource) -> None:
+ self._databases = databases
+
+ @cached_property
+ def postgres(self) -> PostgresResourceWithStreamingResponse:
+ return PostgresResourceWithStreamingResponse(self._databases.postgres)
+
+
+class AsyncDatabasesResourceWithStreamingResponse:
+ def __init__(self, databases: AsyncDatabasesResource) -> None:
+ self._databases = databases
+
+ @cached_property
+ def postgres(self) -> AsyncPostgresResourceWithStreamingResponse:
+ return AsyncPostgresResourceWithStreamingResponse(self._databases.postgres)
diff --git a/src/gcore/resources/cloud/databases/postgres/__init__.py b/src/gcore/resources/cloud/databases/postgres/__init__.py
new file mode 100644
index 00000000..63128146
--- /dev/null
+++ b/src/gcore/resources/cloud/databases/postgres/__init__.py
@@ -0,0 +1,61 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .clusters import (
+ ClustersResource,
+ AsyncClustersResource,
+ ClustersResourceWithRawResponse,
+ AsyncClustersResourceWithRawResponse,
+ ClustersResourceWithStreamingResponse,
+ AsyncClustersResourceWithStreamingResponse,
+)
+from .postgres import (
+ PostgresResource,
+ AsyncPostgresResource,
+ PostgresResourceWithRawResponse,
+ AsyncPostgresResourceWithRawResponse,
+ PostgresResourceWithStreamingResponse,
+ AsyncPostgresResourceWithStreamingResponse,
+)
+from .configurations import (
+ ConfigurationsResource,
+ AsyncConfigurationsResource,
+ ConfigurationsResourceWithRawResponse,
+ AsyncConfigurationsResourceWithRawResponse,
+ ConfigurationsResourceWithStreamingResponse,
+ AsyncConfigurationsResourceWithStreamingResponse,
+)
+from .custom_configurations import (
+ CustomConfigurationsResource,
+ AsyncCustomConfigurationsResource,
+ CustomConfigurationsResourceWithRawResponse,
+ AsyncCustomConfigurationsResourceWithRawResponse,
+ CustomConfigurationsResourceWithStreamingResponse,
+ AsyncCustomConfigurationsResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "ClustersResource",
+ "AsyncClustersResource",
+ "ClustersResourceWithRawResponse",
+ "AsyncClustersResourceWithRawResponse",
+ "ClustersResourceWithStreamingResponse",
+ "AsyncClustersResourceWithStreamingResponse",
+ "ConfigurationsResource",
+ "AsyncConfigurationsResource",
+ "ConfigurationsResourceWithRawResponse",
+ "AsyncConfigurationsResourceWithRawResponse",
+ "ConfigurationsResourceWithStreamingResponse",
+ "AsyncConfigurationsResourceWithStreamingResponse",
+ "CustomConfigurationsResource",
+ "AsyncCustomConfigurationsResource",
+ "CustomConfigurationsResourceWithRawResponse",
+ "AsyncCustomConfigurationsResourceWithRawResponse",
+ "CustomConfigurationsResourceWithStreamingResponse",
+ "AsyncCustomConfigurationsResourceWithStreamingResponse",
+ "PostgresResource",
+ "AsyncPostgresResource",
+ "PostgresResourceWithRawResponse",
+ "AsyncPostgresResourceWithRawResponse",
+ "PostgresResourceWithStreamingResponse",
+ "AsyncPostgresResourceWithStreamingResponse",
+]
diff --git a/src/gcore/resources/cloud/databases/postgres/clusters/__init__.py b/src/gcore/resources/cloud/databases/postgres/clusters/__init__.py
new file mode 100644
index 00000000..677f309e
--- /dev/null
+++ b/src/gcore/resources/cloud/databases/postgres/clusters/__init__.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .clusters import (
+ ClustersResource,
+ AsyncClustersResource,
+ ClustersResourceWithRawResponse,
+ AsyncClustersResourceWithRawResponse,
+ ClustersResourceWithStreamingResponse,
+ AsyncClustersResourceWithStreamingResponse,
+)
+from .user_credentials import (
+ UserCredentialsResource,
+ AsyncUserCredentialsResource,
+ UserCredentialsResourceWithRawResponse,
+ AsyncUserCredentialsResourceWithRawResponse,
+ UserCredentialsResourceWithStreamingResponse,
+ AsyncUserCredentialsResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "UserCredentialsResource",
+ "AsyncUserCredentialsResource",
+ "UserCredentialsResourceWithRawResponse",
+ "AsyncUserCredentialsResourceWithRawResponse",
+ "UserCredentialsResourceWithStreamingResponse",
+ "AsyncUserCredentialsResourceWithStreamingResponse",
+ "ClustersResource",
+ "AsyncClustersResource",
+ "ClustersResourceWithRawResponse",
+ "AsyncClustersResourceWithRawResponse",
+ "ClustersResourceWithStreamingResponse",
+ "AsyncClustersResourceWithStreamingResponse",
+]
diff --git a/src/gcore/resources/cloud/databases/postgres/clusters/clusters.py b/src/gcore/resources/cloud/databases/postgres/clusters/clusters.py
new file mode 100644
index 00000000..bb01ed8b
--- /dev/null
+++ b/src/gcore/resources/cloud/databases/postgres/clusters/clusters.py
@@ -0,0 +1,716 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable, Optional
+
+import httpx
+
+from ......_types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ......_utils import maybe_transform, async_maybe_transform
+from ......_compat import cached_property
+from ......_resource import SyncAPIResource, AsyncAPIResource
+from ......_response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ......pagination import SyncOffsetPage, AsyncOffsetPage
+from .user_credentials import (
+ UserCredentialsResource,
+ AsyncUserCredentialsResource,
+ UserCredentialsResourceWithRawResponse,
+ AsyncUserCredentialsResourceWithRawResponse,
+ UserCredentialsResourceWithStreamingResponse,
+ AsyncUserCredentialsResourceWithStreamingResponse,
+)
+from ......_base_client import AsyncPaginator, make_request_options
+from ......types.cloud.task_id_list import TaskIDList
+from ......types.cloud.databases.postgres import cluster_list_params, cluster_create_params, cluster_update_params
+from ......types.cloud.databases.postgres.postgres_cluster import PostgresCluster
+from ......types.cloud.databases.postgres.postgres_cluster_short import PostgresClusterShort
+
+__all__ = ["ClustersResource", "AsyncClustersResource"]
+
+
+class ClustersResource(SyncAPIResource):
+ @cached_property
+ def user_credentials(self) -> UserCredentialsResource:
+ return UserCredentialsResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> ClustersResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
+ """
+ return ClustersResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> ClustersResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
+ """
+ return ClustersResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ project_id: int | None = None,
+ region_id: int | None = None,
+ cluster_name: str,
+ flavor: cluster_create_params.Flavor,
+ high_availability: Optional[cluster_create_params.HighAvailability],
+ network: cluster_create_params.Network,
+ pg_server_configuration: cluster_create_params.PgServerConfiguration,
+ storage: cluster_create_params.Storage,
+ databases: Iterable[cluster_create_params.Database] | Omit = omit,
+ users: Iterable[cluster_create_params.User] | Omit = omit,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> TaskIDList:
+ """
+ Create a new PostgreSQL cluster with the specified configuration.
+
+ Args:
+ cluster_name: PostgreSQL cluster name
+
+ flavor: Instance RAM and CPU
+
+ high_availability: High Availability settings
+
+ pg_server_configuration: PosgtreSQL cluster configuration
+
+ storage: Cluster's storage configuration
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if project_id is None:
+ project_id = self._client._get_cloud_project_id_path_param()
+ if region_id is None:
+ region_id = self._client._get_cloud_region_id_path_param()
+ return self._post(
+ f"/cloud/v1/dbaas/postgres/clusters/{project_id}/{region_id}",
+ body=maybe_transform(
+ {
+ "cluster_name": cluster_name,
+ "flavor": flavor,
+ "high_availability": high_availability,
+ "network": network,
+ "pg_server_configuration": pg_server_configuration,
+ "storage": storage,
+ "databases": databases,
+ "users": users,
+ },
+ cluster_create_params.ClusterCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=TaskIDList,
+ )
+
+ def update(
+ self,
+ cluster_name: str,
+ *,
+ project_id: int | None = None,
+ region_id: int | None = None,
+ databases: Iterable[cluster_update_params.Database] | Omit = omit,
+ flavor: Optional[cluster_update_params.Flavor] | Omit = omit,
+ high_availability: Optional[cluster_update_params.HighAvailability] | Omit = omit,
+ network: Optional[cluster_update_params.Network] | Omit = omit,
+ pg_server_configuration: Optional[cluster_update_params.PgServerConfiguration] | Omit = omit,
+ storage: Optional[cluster_update_params.Storage] | Omit = omit,
+ users: Iterable[cluster_update_params.User] | Omit = omit,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> TaskIDList:
+ """
+ Update the configuration of an existing PostgreSQL cluster.
+
+ Args:
+ flavor: New instance RAM and CPU
+
+ high_availability: New High Availability settings
+
+ pg_server_configuration: New PosgtreSQL cluster configuration
+
+ storage: New storage configuration
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if project_id is None:
+ project_id = self._client._get_cloud_project_id_path_param()
+ if region_id is None:
+ region_id = self._client._get_cloud_region_id_path_param()
+ if not cluster_name:
+ raise ValueError(f"Expected a non-empty value for `cluster_name` but received {cluster_name!r}")
+ return self._patch(
+ f"/cloud/v1/dbaas/postgres/clusters/{project_id}/{region_id}/{cluster_name}",
+ body=maybe_transform(
+ {
+ "databases": databases,
+ "flavor": flavor,
+ "high_availability": high_availability,
+ "network": network,
+ "pg_server_configuration": pg_server_configuration,
+ "storage": storage,
+ "users": users,
+ },
+ cluster_update_params.ClusterUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=TaskIDList,
+ )
+
+ def list(
+ self,
+ *,
+ project_id: int | None = None,
+ region_id: int | None = None,
+ limit: int | Omit = omit,
+ offset: int | Omit = omit,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> SyncOffsetPage[PostgresClusterShort]:
+ """List all PostgreSQL clusters in the specified project and region.
+
+ Results can be
+ filtered by search query and paginated.
+
+ Args:
+ limit: Maximum number of clusters to return
+
+ offset: Number of clusters to skip
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if project_id is None:
+ project_id = self._client._get_cloud_project_id_path_param()
+ if region_id is None:
+ region_id = self._client._get_cloud_region_id_path_param()
+ return self._get_api_list(
+ f"/cloud/v1/dbaas/postgres/clusters/{project_id}/{region_id}",
+ page=SyncOffsetPage[PostgresClusterShort],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "limit": limit,
+ "offset": offset,
+ },
+ cluster_list_params.ClusterListParams,
+ ),
+ ),
+ model=PostgresClusterShort,
+ )
+
+ def delete(
+ self,
+ cluster_name: str,
+ *,
+ project_id: int | None = None,
+ region_id: int | None = None,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> TaskIDList:
+ """
+ Delete a PostgreSQL cluster and all its associated resources.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if project_id is None:
+ project_id = self._client._get_cloud_project_id_path_param()
+ if region_id is None:
+ region_id = self._client._get_cloud_region_id_path_param()
+ if not cluster_name:
+ raise ValueError(f"Expected a non-empty value for `cluster_name` but received {cluster_name!r}")
+ return self._delete(
+ f"/cloud/v1/dbaas/postgres/clusters/{project_id}/{region_id}/{cluster_name}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=TaskIDList,
+ )
+
+ def get(
+ self,
+ cluster_name: str,
+ *,
+ project_id: int | None = None,
+ region_id: int | None = None,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> PostgresCluster:
+ """
+ Get detailed information about a specific PostgreSQL cluster.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if project_id is None:
+ project_id = self._client._get_cloud_project_id_path_param()
+ if region_id is None:
+ region_id = self._client._get_cloud_region_id_path_param()
+ if not cluster_name:
+ raise ValueError(f"Expected a non-empty value for `cluster_name` but received {cluster_name!r}")
+ return self._get(
+ f"/cloud/v1/dbaas/postgres/clusters/{project_id}/{region_id}/{cluster_name}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=PostgresCluster,
+ )
+
+
+class AsyncClustersResource(AsyncAPIResource):
+ @cached_property
+ def user_credentials(self) -> AsyncUserCredentialsResource:
+ return AsyncUserCredentialsResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncClustersResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncClustersResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncClustersResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
+ """
+ return AsyncClustersResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ *,
+ project_id: int | None = None,
+ region_id: int | None = None,
+ cluster_name: str,
+ flavor: cluster_create_params.Flavor,
+ high_availability: Optional[cluster_create_params.HighAvailability],
+ network: cluster_create_params.Network,
+ pg_server_configuration: cluster_create_params.PgServerConfiguration,
+ storage: cluster_create_params.Storage,
+ databases: Iterable[cluster_create_params.Database] | Omit = omit,
+ users: Iterable[cluster_create_params.User] | Omit = omit,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> TaskIDList:
+ """
+ Create a new PostgreSQL cluster with the specified configuration.
+
+ Args:
+ cluster_name: PostgreSQL cluster name
+
+ flavor: Instance RAM and CPU
+
+ high_availability: High Availability settings
+
+ pg_server_configuration: PosgtreSQL cluster configuration
+
+ storage: Cluster's storage configuration
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if project_id is None:
+ project_id = self._client._get_cloud_project_id_path_param()
+ if region_id is None:
+ region_id = self._client._get_cloud_region_id_path_param()
+ return await self._post(
+ f"/cloud/v1/dbaas/postgres/clusters/{project_id}/{region_id}",
+ body=await async_maybe_transform(
+ {
+ "cluster_name": cluster_name,
+ "flavor": flavor,
+ "high_availability": high_availability,
+ "network": network,
+ "pg_server_configuration": pg_server_configuration,
+ "storage": storage,
+ "databases": databases,
+ "users": users,
+ },
+ cluster_create_params.ClusterCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=TaskIDList,
+ )
+
+ async def update(
+ self,
+ cluster_name: str,
+ *,
+ project_id: int | None = None,
+ region_id: int | None = None,
+ databases: Iterable[cluster_update_params.Database] | Omit = omit,
+ flavor: Optional[cluster_update_params.Flavor] | Omit = omit,
+ high_availability: Optional[cluster_update_params.HighAvailability] | Omit = omit,
+ network: Optional[cluster_update_params.Network] | Omit = omit,
+ pg_server_configuration: Optional[cluster_update_params.PgServerConfiguration] | Omit = omit,
+ storage: Optional[cluster_update_params.Storage] | Omit = omit,
+ users: Iterable[cluster_update_params.User] | Omit = omit,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> TaskIDList:
+ """
+ Update the configuration of an existing PostgreSQL cluster.
+
+ Args:
+ flavor: New instance RAM and CPU
+
+ high_availability: New High Availability settings
+
+ pg_server_configuration: New PosgtreSQL cluster configuration
+
+ storage: New storage configuration
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if project_id is None:
+ project_id = self._client._get_cloud_project_id_path_param()
+ if region_id is None:
+ region_id = self._client._get_cloud_region_id_path_param()
+ if not cluster_name:
+ raise ValueError(f"Expected a non-empty value for `cluster_name` but received {cluster_name!r}")
+ return await self._patch(
+ f"/cloud/v1/dbaas/postgres/clusters/{project_id}/{region_id}/{cluster_name}",
+ body=await async_maybe_transform(
+ {
+ "databases": databases,
+ "flavor": flavor,
+ "high_availability": high_availability,
+ "network": network,
+ "pg_server_configuration": pg_server_configuration,
+ "storage": storage,
+ "users": users,
+ },
+ cluster_update_params.ClusterUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=TaskIDList,
+ )
+
+ def list(
+ self,
+ *,
+ project_id: int | None = None,
+ region_id: int | None = None,
+ limit: int | Omit = omit,
+ offset: int | Omit = omit,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> AsyncPaginator[PostgresClusterShort, AsyncOffsetPage[PostgresClusterShort]]:
+ """List all PostgreSQL clusters in the specified project and region.
+
+ Results can be
+ filtered by search query and paginated.
+
+ Args:
+ limit: Maximum number of clusters to return
+
+ offset: Number of clusters to skip
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if project_id is None:
+ project_id = self._client._get_cloud_project_id_path_param()
+ if region_id is None:
+ region_id = self._client._get_cloud_region_id_path_param()
+ return self._get_api_list(
+ f"/cloud/v1/dbaas/postgres/clusters/{project_id}/{region_id}",
+ page=AsyncOffsetPage[PostgresClusterShort],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "limit": limit,
+ "offset": offset,
+ },
+ cluster_list_params.ClusterListParams,
+ ),
+ ),
+ model=PostgresClusterShort,
+ )
+
+ async def delete(
+ self,
+ cluster_name: str,
+ *,
+ project_id: int | None = None,
+ region_id: int | None = None,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> TaskIDList:
+ """
+ Delete a PostgreSQL cluster and all its associated resources.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if project_id is None:
+ project_id = self._client._get_cloud_project_id_path_param()
+ if region_id is None:
+ region_id = self._client._get_cloud_region_id_path_param()
+ if not cluster_name:
+ raise ValueError(f"Expected a non-empty value for `cluster_name` but received {cluster_name!r}")
+ return await self._delete(
+ f"/cloud/v1/dbaas/postgres/clusters/{project_id}/{region_id}/{cluster_name}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=TaskIDList,
+ )
+
+ async def get(
+ self,
+ cluster_name: str,
+ *,
+ project_id: int | None = None,
+ region_id: int | None = None,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> PostgresCluster:
+ """
+ Get detailed information about a specific PostgreSQL cluster.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if project_id is None:
+ project_id = self._client._get_cloud_project_id_path_param()
+ if region_id is None:
+ region_id = self._client._get_cloud_region_id_path_param()
+ if not cluster_name:
+ raise ValueError(f"Expected a non-empty value for `cluster_name` but received {cluster_name!r}")
+ return await self._get(
+ f"/cloud/v1/dbaas/postgres/clusters/{project_id}/{region_id}/{cluster_name}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=PostgresCluster,
+ )
+
+
+class ClustersResourceWithRawResponse:
+ def __init__(self, clusters: ClustersResource) -> None:
+ self._clusters = clusters
+
+ self.create = to_raw_response_wrapper(
+ clusters.create,
+ )
+ self.update = to_raw_response_wrapper(
+ clusters.update,
+ )
+ self.list = to_raw_response_wrapper(
+ clusters.list,
+ )
+ self.delete = to_raw_response_wrapper(
+ clusters.delete,
+ )
+ self.get = to_raw_response_wrapper(
+ clusters.get,
+ )
+
+ @cached_property
+ def user_credentials(self) -> UserCredentialsResourceWithRawResponse:
+ return UserCredentialsResourceWithRawResponse(self._clusters.user_credentials)
+
+
+class AsyncClustersResourceWithRawResponse:
+ def __init__(self, clusters: AsyncClustersResource) -> None:
+ self._clusters = clusters
+
+ self.create = async_to_raw_response_wrapper(
+ clusters.create,
+ )
+ self.update = async_to_raw_response_wrapper(
+ clusters.update,
+ )
+ self.list = async_to_raw_response_wrapper(
+ clusters.list,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ clusters.delete,
+ )
+ self.get = async_to_raw_response_wrapper(
+ clusters.get,
+ )
+
+ @cached_property
+ def user_credentials(self) -> AsyncUserCredentialsResourceWithRawResponse:
+ return AsyncUserCredentialsResourceWithRawResponse(self._clusters.user_credentials)
+
+
+class ClustersResourceWithStreamingResponse:
+ def __init__(self, clusters: ClustersResource) -> None:
+ self._clusters = clusters
+
+ self.create = to_streamed_response_wrapper(
+ clusters.create,
+ )
+ self.update = to_streamed_response_wrapper(
+ clusters.update,
+ )
+ self.list = to_streamed_response_wrapper(
+ clusters.list,
+ )
+ self.delete = to_streamed_response_wrapper(
+ clusters.delete,
+ )
+ self.get = to_streamed_response_wrapper(
+ clusters.get,
+ )
+
+ @cached_property
+ def user_credentials(self) -> UserCredentialsResourceWithStreamingResponse:
+ return UserCredentialsResourceWithStreamingResponse(self._clusters.user_credentials)
+
+
+class AsyncClustersResourceWithStreamingResponse:
+ def __init__(self, clusters: AsyncClustersResource) -> None:
+ self._clusters = clusters
+
+ self.create = async_to_streamed_response_wrapper(
+ clusters.create,
+ )
+ self.update = async_to_streamed_response_wrapper(
+ clusters.update,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ clusters.list,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ clusters.delete,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ clusters.get,
+ )
+
+ @cached_property
+ def user_credentials(self) -> AsyncUserCredentialsResourceWithStreamingResponse:
+ return AsyncUserCredentialsResourceWithStreamingResponse(self._clusters.user_credentials)
diff --git a/src/gcore/resources/cloud/databases/postgres/clusters/user_credentials.py b/src/gcore/resources/cloud/databases/postgres/clusters/user_credentials.py
new file mode 100644
index 00000000..98ad25be
--- /dev/null
+++ b/src/gcore/resources/cloud/databases/postgres/clusters/user_credentials.py
@@ -0,0 +1,281 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from ......_types import Body, Query, Headers, NotGiven, not_given
+from ......_compat import cached_property
+from ......_resource import SyncAPIResource, AsyncAPIResource
+from ......_response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ......_base_client import make_request_options
+from ......types.cloud.databases.postgres.clusters.postgres_user_credentials import PostgresUserCredentials
+
+__all__ = ["UserCredentialsResource", "AsyncUserCredentialsResource"]
+
+
+class UserCredentialsResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> UserCredentialsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
+ """
+ return UserCredentialsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> UserCredentialsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
+ """
+ return UserCredentialsResourceWithStreamingResponse(self)
+
+ def get(
+ self,
+ username: str,
+ *,
+ project_id: int | None = None,
+ region_id: int | None = None,
+ cluster_name: 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> PostgresUserCredentials:
+ """Get the credentials for a specific user in a PostgreSQL cluster.
+
+ This endpoint
+ can only be used once per user.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if project_id is None:
+ project_id = self._client._get_cloud_project_id_path_param()
+ if region_id is None:
+ region_id = self._client._get_cloud_region_id_path_param()
+ if not cluster_name:
+ raise ValueError(f"Expected a non-empty value for `cluster_name` but received {cluster_name!r}")
+ if not username:
+ raise ValueError(f"Expected a non-empty value for `username` but received {username!r}")
+ return self._get(
+ f"/cloud/v1/dbaas/postgres/clusters/{project_id}/{region_id}/{cluster_name}/users/{username}/credentials",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=PostgresUserCredentials,
+ )
+
+ def regenerate(
+ self,
+ username: str,
+ *,
+ project_id: int | None = None,
+ region_id: int | None = None,
+ cluster_name: 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> PostgresUserCredentials:
+ """
+ Generate new credentials for a specific user in a PostgreSQL cluster.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if project_id is None:
+ project_id = self._client._get_cloud_project_id_path_param()
+ if region_id is None:
+ region_id = self._client._get_cloud_region_id_path_param()
+ if not cluster_name:
+ raise ValueError(f"Expected a non-empty value for `cluster_name` but received {cluster_name!r}")
+ if not username:
+ raise ValueError(f"Expected a non-empty value for `username` but received {username!r}")
+ return self._post(
+ f"/cloud/v1/dbaas/postgres/clusters/{project_id}/{region_id}/{cluster_name}/users/{username}/credentials",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=PostgresUserCredentials,
+ )
+
+
+class AsyncUserCredentialsResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncUserCredentialsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncUserCredentialsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncUserCredentialsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
+ """
+ return AsyncUserCredentialsResourceWithStreamingResponse(self)
+
+ async def get(
+ self,
+ username: str,
+ *,
+ project_id: int | None = None,
+ region_id: int | None = None,
+ cluster_name: 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> PostgresUserCredentials:
+ """Get the credentials for a specific user in a PostgreSQL cluster.
+
+ This endpoint
+ can only be used once per user.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if project_id is None:
+ project_id = self._client._get_cloud_project_id_path_param()
+ if region_id is None:
+ region_id = self._client._get_cloud_region_id_path_param()
+ if not cluster_name:
+ raise ValueError(f"Expected a non-empty value for `cluster_name` but received {cluster_name!r}")
+ if not username:
+ raise ValueError(f"Expected a non-empty value for `username` but received {username!r}")
+ return await self._get(
+ f"/cloud/v1/dbaas/postgres/clusters/{project_id}/{region_id}/{cluster_name}/users/{username}/credentials",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=PostgresUserCredentials,
+ )
+
+ async def regenerate(
+ self,
+ username: str,
+ *,
+ project_id: int | None = None,
+ region_id: int | None = None,
+ cluster_name: 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> PostgresUserCredentials:
+ """
+ Generate new credentials for a specific user in a PostgreSQL cluster.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if project_id is None:
+ project_id = self._client._get_cloud_project_id_path_param()
+ if region_id is None:
+ region_id = self._client._get_cloud_region_id_path_param()
+ if not cluster_name:
+ raise ValueError(f"Expected a non-empty value for `cluster_name` but received {cluster_name!r}")
+ if not username:
+ raise ValueError(f"Expected a non-empty value for `username` but received {username!r}")
+ return await self._post(
+ f"/cloud/v1/dbaas/postgres/clusters/{project_id}/{region_id}/{cluster_name}/users/{username}/credentials",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=PostgresUserCredentials,
+ )
+
+
+class UserCredentialsResourceWithRawResponse:
+ def __init__(self, user_credentials: UserCredentialsResource) -> None:
+ self._user_credentials = user_credentials
+
+ self.get = to_raw_response_wrapper(
+ user_credentials.get,
+ )
+ self.regenerate = to_raw_response_wrapper(
+ user_credentials.regenerate,
+ )
+
+
+class AsyncUserCredentialsResourceWithRawResponse:
+ def __init__(self, user_credentials: AsyncUserCredentialsResource) -> None:
+ self._user_credentials = user_credentials
+
+ self.get = async_to_raw_response_wrapper(
+ user_credentials.get,
+ )
+ self.regenerate = async_to_raw_response_wrapper(
+ user_credentials.regenerate,
+ )
+
+
+class UserCredentialsResourceWithStreamingResponse:
+ def __init__(self, user_credentials: UserCredentialsResource) -> None:
+ self._user_credentials = user_credentials
+
+ self.get = to_streamed_response_wrapper(
+ user_credentials.get,
+ )
+ self.regenerate = to_streamed_response_wrapper(
+ user_credentials.regenerate,
+ )
+
+
+class AsyncUserCredentialsResourceWithStreamingResponse:
+ def __init__(self, user_credentials: AsyncUserCredentialsResource) -> None:
+ self._user_credentials = user_credentials
+
+ self.get = async_to_streamed_response_wrapper(
+ user_credentials.get,
+ )
+ self.regenerate = async_to_streamed_response_wrapper(
+ user_credentials.regenerate,
+ )
diff --git a/src/gcore/resources/cloud/databases/postgres/configurations.py b/src/gcore/resources/cloud/databases/postgres/configurations.py
new file mode 100644
index 00000000..c9f30551
--- /dev/null
+++ b/src/gcore/resources/cloud/databases/postgres/configurations.py
@@ -0,0 +1,169 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from ....._types import Body, Query, Headers, NotGiven, not_given
+from ....._compat import cached_property
+from ....._resource import SyncAPIResource, AsyncAPIResource
+from ....._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ....._base_client import make_request_options
+from .....types.cloud.databases.postgres.postgres_configuration import PostgresConfiguration
+
+__all__ = ["ConfigurationsResource", "AsyncConfigurationsResource"]
+
+
+class ConfigurationsResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> ConfigurationsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
+ """
+ return ConfigurationsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> ConfigurationsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
+ """
+ return ConfigurationsResourceWithStreamingResponse(self)
+
+ def get(
+ self,
+ *,
+ project_id: int | None = None,
+ region_id: int | None = None,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> PostgresConfiguration:
+ """
+ Get all available PostgreSQL configurations for the specified region.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if project_id is None:
+ project_id = self._client._get_cloud_project_id_path_param()
+ if region_id is None:
+ region_id = self._client._get_cloud_region_id_path_param()
+ return self._get(
+ f"/cloud/v1/dbaas/postgres/configuration/{project_id}/{region_id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=PostgresConfiguration,
+ )
+
+
+class AsyncConfigurationsResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncConfigurationsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncConfigurationsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncConfigurationsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
+ """
+ return AsyncConfigurationsResourceWithStreamingResponse(self)
+
+ async def get(
+ self,
+ *,
+ project_id: int | None = None,
+ region_id: int | None = None,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> PostgresConfiguration:
+ """
+ Get all available PostgreSQL configurations for the specified region.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if project_id is None:
+ project_id = self._client._get_cloud_project_id_path_param()
+ if region_id is None:
+ region_id = self._client._get_cloud_region_id_path_param()
+ return await self._get(
+ f"/cloud/v1/dbaas/postgres/configuration/{project_id}/{region_id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=PostgresConfiguration,
+ )
+
+
+class ConfigurationsResourceWithRawResponse:
+ def __init__(self, configurations: ConfigurationsResource) -> None:
+ self._configurations = configurations
+
+ self.get = to_raw_response_wrapper(
+ configurations.get,
+ )
+
+
+class AsyncConfigurationsResourceWithRawResponse:
+ def __init__(self, configurations: AsyncConfigurationsResource) -> None:
+ self._configurations = configurations
+
+ self.get = async_to_raw_response_wrapper(
+ configurations.get,
+ )
+
+
+class ConfigurationsResourceWithStreamingResponse:
+ def __init__(self, configurations: ConfigurationsResource) -> None:
+ self._configurations = configurations
+
+ self.get = to_streamed_response_wrapper(
+ configurations.get,
+ )
+
+
+class AsyncConfigurationsResourceWithStreamingResponse:
+ def __init__(self, configurations: AsyncConfigurationsResource) -> None:
+ self._configurations = configurations
+
+ self.get = async_to_streamed_response_wrapper(
+ configurations.get,
+ )
diff --git a/src/gcore/resources/cloud/databases/postgres/custom_configurations.py b/src/gcore/resources/cloud/databases/postgres/custom_configurations.py
new file mode 100644
index 00000000..9ce396df
--- /dev/null
+++ b/src/gcore/resources/cloud/databases/postgres/custom_configurations.py
@@ -0,0 +1,197 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from ....._types import Body, Query, Headers, NotGiven, not_given
+from ....._utils import maybe_transform, async_maybe_transform
+from ....._compat import cached_property
+from ....._resource import SyncAPIResource, AsyncAPIResource
+from ....._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ....._base_client import make_request_options
+from .....types.cloud.databases.postgres import custom_configuration_validate_params
+from .....types.cloud.databases.postgres.pg_conf_validation import PgConfValidation
+
+__all__ = ["CustomConfigurationsResource", "AsyncCustomConfigurationsResource"]
+
+
+class CustomConfigurationsResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> CustomConfigurationsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
+ """
+ return CustomConfigurationsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> CustomConfigurationsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
+ """
+ return CustomConfigurationsResourceWithStreamingResponse(self)
+
+ def validate(
+ self,
+ *,
+ project_id: int | None = None,
+ region_id: int | None = None,
+ pg_conf: str,
+ version: 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> PgConfValidation:
+ """
+ Validate a custom PostgreSQL configuration file.
+
+ Args:
+ pg_conf: PostgreSQL configuration
+
+ version: PostgreSQL version
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if project_id is None:
+ project_id = self._client._get_cloud_project_id_path_param()
+ if region_id is None:
+ region_id = self._client._get_cloud_region_id_path_param()
+ return self._post(
+ f"/cloud/v1/dbaas/postgres/validate_pg_conf/{project_id}/{region_id}",
+ body=maybe_transform(
+ {
+ "pg_conf": pg_conf,
+ "version": version,
+ },
+ custom_configuration_validate_params.CustomConfigurationValidateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=PgConfValidation,
+ )
+
+
+class AsyncCustomConfigurationsResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncCustomConfigurationsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncCustomConfigurationsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncCustomConfigurationsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
+ """
+ return AsyncCustomConfigurationsResourceWithStreamingResponse(self)
+
+ async def validate(
+ self,
+ *,
+ project_id: int | None = None,
+ region_id: int | None = None,
+ pg_conf: str,
+ version: 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> PgConfValidation:
+ """
+ Validate a custom PostgreSQL configuration file.
+
+ Args:
+ pg_conf: PostgreSQL configuration
+
+ version: PostgreSQL version
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if project_id is None:
+ project_id = self._client._get_cloud_project_id_path_param()
+ if region_id is None:
+ region_id = self._client._get_cloud_region_id_path_param()
+ return await self._post(
+ f"/cloud/v1/dbaas/postgres/validate_pg_conf/{project_id}/{region_id}",
+ body=await async_maybe_transform(
+ {
+ "pg_conf": pg_conf,
+ "version": version,
+ },
+ custom_configuration_validate_params.CustomConfigurationValidateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=PgConfValidation,
+ )
+
+
+class CustomConfigurationsResourceWithRawResponse:
+ def __init__(self, custom_configurations: CustomConfigurationsResource) -> None:
+ self._custom_configurations = custom_configurations
+
+ self.validate = to_raw_response_wrapper(
+ custom_configurations.validate,
+ )
+
+
+class AsyncCustomConfigurationsResourceWithRawResponse:
+ def __init__(self, custom_configurations: AsyncCustomConfigurationsResource) -> None:
+ self._custom_configurations = custom_configurations
+
+ self.validate = async_to_raw_response_wrapper(
+ custom_configurations.validate,
+ )
+
+
+class CustomConfigurationsResourceWithStreamingResponse:
+ def __init__(self, custom_configurations: CustomConfigurationsResource) -> None:
+ self._custom_configurations = custom_configurations
+
+ self.validate = to_streamed_response_wrapper(
+ custom_configurations.validate,
+ )
+
+
+class AsyncCustomConfigurationsResourceWithStreamingResponse:
+ def __init__(self, custom_configurations: AsyncCustomConfigurationsResource) -> None:
+ self._custom_configurations = custom_configurations
+
+ self.validate = async_to_streamed_response_wrapper(
+ custom_configurations.validate,
+ )
diff --git a/src/gcore/resources/cloud/databases/postgres/postgres.py b/src/gcore/resources/cloud/databases/postgres/postgres.py
new file mode 100644
index 00000000..ce9c32b7
--- /dev/null
+++ b/src/gcore/resources/cloud/databases/postgres/postgres.py
@@ -0,0 +1,166 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from ....._compat import cached_property
+from ....._resource import SyncAPIResource, AsyncAPIResource
+from .configurations import (
+ ConfigurationsResource,
+ AsyncConfigurationsResource,
+ ConfigurationsResourceWithRawResponse,
+ AsyncConfigurationsResourceWithRawResponse,
+ ConfigurationsResourceWithStreamingResponse,
+ AsyncConfigurationsResourceWithStreamingResponse,
+)
+from .clusters.clusters import (
+ ClustersResource,
+ AsyncClustersResource,
+ ClustersResourceWithRawResponse,
+ AsyncClustersResourceWithRawResponse,
+ ClustersResourceWithStreamingResponse,
+ AsyncClustersResourceWithStreamingResponse,
+)
+from .custom_configurations import (
+ CustomConfigurationsResource,
+ AsyncCustomConfigurationsResource,
+ CustomConfigurationsResourceWithRawResponse,
+ AsyncCustomConfigurationsResourceWithRawResponse,
+ CustomConfigurationsResourceWithStreamingResponse,
+ AsyncCustomConfigurationsResourceWithStreamingResponse,
+)
+
+__all__ = ["PostgresResource", "AsyncPostgresResource"]
+
+
+class PostgresResource(SyncAPIResource):
+ @cached_property
+ def clusters(self) -> ClustersResource:
+ return ClustersResource(self._client)
+
+ @cached_property
+ def configurations(self) -> ConfigurationsResource:
+ return ConfigurationsResource(self._client)
+
+ @cached_property
+ def custom_configurations(self) -> CustomConfigurationsResource:
+ return CustomConfigurationsResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> PostgresResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
+ """
+ return PostgresResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> PostgresResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
+ """
+ return PostgresResourceWithStreamingResponse(self)
+
+
+class AsyncPostgresResource(AsyncAPIResource):
+ @cached_property
+ def clusters(self) -> AsyncClustersResource:
+ return AsyncClustersResource(self._client)
+
+ @cached_property
+ def configurations(self) -> AsyncConfigurationsResource:
+ return AsyncConfigurationsResource(self._client)
+
+ @cached_property
+ def custom_configurations(self) -> AsyncCustomConfigurationsResource:
+ return AsyncCustomConfigurationsResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncPostgresResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncPostgresResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncPostgresResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/G-Core/gcore-python#with_streaming_response
+ """
+ return AsyncPostgresResourceWithStreamingResponse(self)
+
+
+class PostgresResourceWithRawResponse:
+ def __init__(self, postgres: PostgresResource) -> None:
+ self._postgres = postgres
+
+ @cached_property
+ def clusters(self) -> ClustersResourceWithRawResponse:
+ return ClustersResourceWithRawResponse(self._postgres.clusters)
+
+ @cached_property
+ def configurations(self) -> ConfigurationsResourceWithRawResponse:
+ return ConfigurationsResourceWithRawResponse(self._postgres.configurations)
+
+ @cached_property
+ def custom_configurations(self) -> CustomConfigurationsResourceWithRawResponse:
+ return CustomConfigurationsResourceWithRawResponse(self._postgres.custom_configurations)
+
+
+class AsyncPostgresResourceWithRawResponse:
+ def __init__(self, postgres: AsyncPostgresResource) -> None:
+ self._postgres = postgres
+
+ @cached_property
+ def clusters(self) -> AsyncClustersResourceWithRawResponse:
+ return AsyncClustersResourceWithRawResponse(self._postgres.clusters)
+
+ @cached_property
+ def configurations(self) -> AsyncConfigurationsResourceWithRawResponse:
+ return AsyncConfigurationsResourceWithRawResponse(self._postgres.configurations)
+
+ @cached_property
+ def custom_configurations(self) -> AsyncCustomConfigurationsResourceWithRawResponse:
+ return AsyncCustomConfigurationsResourceWithRawResponse(self._postgres.custom_configurations)
+
+
+class PostgresResourceWithStreamingResponse:
+ def __init__(self, postgres: PostgresResource) -> None:
+ self._postgres = postgres
+
+ @cached_property
+ def clusters(self) -> ClustersResourceWithStreamingResponse:
+ return ClustersResourceWithStreamingResponse(self._postgres.clusters)
+
+ @cached_property
+ def configurations(self) -> ConfigurationsResourceWithStreamingResponse:
+ return ConfigurationsResourceWithStreamingResponse(self._postgres.configurations)
+
+ @cached_property
+ def custom_configurations(self) -> CustomConfigurationsResourceWithStreamingResponse:
+ return CustomConfigurationsResourceWithStreamingResponse(self._postgres.custom_configurations)
+
+
+class AsyncPostgresResourceWithStreamingResponse:
+ def __init__(self, postgres: AsyncPostgresResource) -> None:
+ self._postgres = postgres
+
+ @cached_property
+ def clusters(self) -> AsyncClustersResourceWithStreamingResponse:
+ return AsyncClustersResourceWithStreamingResponse(self._postgres.clusters)
+
+ @cached_property
+ def configurations(self) -> AsyncConfigurationsResourceWithStreamingResponse:
+ return AsyncConfigurationsResourceWithStreamingResponse(self._postgres.configurations)
+
+ @cached_property
+ def custom_configurations(self) -> AsyncCustomConfigurationsResourceWithStreamingResponse:
+ return AsyncCustomConfigurationsResourceWithStreamingResponse(self._postgres.custom_configurations)
diff --git a/src/gcore/types/cloud/databases/__init__.py b/src/gcore/types/cloud/databases/__init__.py
new file mode 100644
index 00000000..f8ee8b14
--- /dev/null
+++ b/src/gcore/types/cloud/databases/__init__.py
@@ -0,0 +1,3 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
diff --git a/src/gcore/types/cloud/databases/postgres/__init__.py b/src/gcore/types/cloud/databases/postgres/__init__.py
new file mode 100644
index 00000000..e4449e2b
--- /dev/null
+++ b/src/gcore/types/cloud/databases/postgres/__init__.py
@@ -0,0 +1,12 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .postgres_cluster import PostgresCluster as PostgresCluster
+from .pg_conf_validation import PgConfValidation as PgConfValidation
+from .cluster_list_params import ClusterListParams as ClusterListParams
+from .cluster_create_params import ClusterCreateParams as ClusterCreateParams
+from .cluster_update_params import ClusterUpdateParams as ClusterUpdateParams
+from .postgres_cluster_short import PostgresClusterShort as PostgresClusterShort
+from .postgres_configuration import PostgresConfiguration as PostgresConfiguration
+from .custom_configuration_validate_params import CustomConfigurationValidateParams as CustomConfigurationValidateParams
diff --git a/src/gcore/types/cloud/databases/postgres/cluster_create_params.py b/src/gcore/types/cloud/databases/postgres/cluster_create_params.py
new file mode 100644
index 00000000..7b569828
--- /dev/null
+++ b/src/gcore/types/cloud/databases/postgres/cluster_create_params.py
@@ -0,0 +1,108 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import List, Iterable, Optional
+from typing_extensions import Literal, Required, TypedDict
+
+from ....._types import SequenceNotStr
+
+__all__ = [
+ "ClusterCreateParams",
+ "Flavor",
+ "HighAvailability",
+ "Network",
+ "PgServerConfiguration",
+ "PgServerConfigurationPooler",
+ "Storage",
+ "Database",
+ "User",
+]
+
+
+class ClusterCreateParams(TypedDict, total=False):
+ project_id: int
+
+ region_id: int
+
+ cluster_name: Required[str]
+ """PostgreSQL cluster name"""
+
+ flavor: Required[Flavor]
+ """Instance RAM and CPU"""
+
+ high_availability: Required[Optional[HighAvailability]]
+ """High Availability settings"""
+
+ network: Required[Network]
+
+ pg_server_configuration: Required[PgServerConfiguration]
+ """PosgtreSQL cluster configuration"""
+
+ storage: Required[Storage]
+ """Cluster's storage configuration"""
+
+ databases: Iterable[Database]
+
+ users: Iterable[User]
+
+
+class Flavor(TypedDict, total=False):
+ cpu: Required[int]
+ """Maximum available cores for instance"""
+
+ memory_gib: Required[int]
+ """Maximum available RAM for instance"""
+
+
+class HighAvailability(TypedDict, total=False):
+ replication_mode: Required[Literal["async", "sync"]]
+ """Type of replication"""
+
+
+class Network(TypedDict, total=False):
+ acl: Required[SequenceNotStr[str]]
+ """Allowed IPs and subnets for incoming traffic"""
+
+ network_type: Required[Literal["public"]]
+ """Network Type"""
+
+
+class PgServerConfigurationPooler(TypedDict, total=False):
+ mode: Required[Literal["session", "statement", "transaction"]]
+
+ type: Literal["pgbouncer"]
+
+
+class PgServerConfiguration(TypedDict, total=False):
+ pg_conf: Required[str]
+ """pg.conf settings"""
+
+ version: Required[str]
+ """Cluster version"""
+
+ pooler: Optional[PgServerConfigurationPooler]
+
+
+class Storage(TypedDict, total=False):
+ size_gib: Required[int]
+ """Total available storage for database"""
+
+ type: Required[str]
+ """Storage type"""
+
+
+class Database(TypedDict, total=False):
+ name: Required[str]
+ """Database name"""
+
+ owner: Required[str]
+ """Database owner from users list"""
+
+
+class User(TypedDict, total=False):
+ name: Required[str]
+ """User name"""
+
+ role_attributes: Required[List[Literal["BYPASSRLS", "CREATEDB", "CREATEROLE", "INHERIT", "LOGIN", "NOLOGIN"]]]
+ """User's attributes"""
diff --git a/src/gcore/types/cloud/databases/postgres/cluster_list_params.py b/src/gcore/types/cloud/databases/postgres/cluster_list_params.py
new file mode 100644
index 00000000..301f22e4
--- /dev/null
+++ b/src/gcore/types/cloud/databases/postgres/cluster_list_params.py
@@ -0,0 +1,19 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+__all__ = ["ClusterListParams"]
+
+
+class ClusterListParams(TypedDict, total=False):
+ project_id: int
+
+ region_id: int
+
+ limit: int
+ """Maximum number of clusters to return"""
+
+ offset: int
+ """Number of clusters to skip"""
diff --git a/src/gcore/types/cloud/databases/postgres/cluster_update_params.py b/src/gcore/types/cloud/databases/postgres/cluster_update_params.py
new file mode 100644
index 00000000..075ee4df
--- /dev/null
+++ b/src/gcore/types/cloud/databases/postgres/cluster_update_params.py
@@ -0,0 +1,102 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import List, Iterable, Optional
+from typing_extensions import Literal, Required, TypedDict
+
+from ....._types import SequenceNotStr
+
+__all__ = [
+ "ClusterUpdateParams",
+ "Database",
+ "Flavor",
+ "HighAvailability",
+ "Network",
+ "PgServerConfiguration",
+ "PgServerConfigurationPooler",
+ "Storage",
+ "User",
+]
+
+
+class ClusterUpdateParams(TypedDict, total=False):
+ project_id: int
+
+ region_id: int
+
+ databases: Iterable[Database]
+
+ flavor: Optional[Flavor]
+ """New instance RAM and CPU"""
+
+ high_availability: Optional[HighAvailability]
+ """New High Availability settings"""
+
+ network: Optional[Network]
+
+ pg_server_configuration: Optional[PgServerConfiguration]
+ """New PosgtreSQL cluster configuration"""
+
+ storage: Optional[Storage]
+ """New storage configuration"""
+
+ users: Iterable[User]
+
+
+class Database(TypedDict, total=False):
+ name: Required[str]
+ """Database name"""
+
+ owner: Required[str]
+ """Database owner from users list"""
+
+
+class Flavor(TypedDict, total=False):
+ cpu: Required[int]
+ """Maximum available cores for instance"""
+
+ memory_gib: Required[int]
+ """Maximum available RAM for instance"""
+
+
+class HighAvailability(TypedDict, total=False):
+ replication_mode: Required[Literal["async", "sync"]]
+ """Type of replication"""
+
+
+class Network(TypedDict, total=False):
+ acl: Required[SequenceNotStr[str]]
+ """Allowed IPs and subnets for incoming traffic"""
+
+ network_type: Required[Literal["public"]]
+ """Network Type"""
+
+
+class PgServerConfigurationPooler(TypedDict, total=False):
+ mode: Required[Literal["session", "statement", "transaction"]]
+
+ type: Literal["pgbouncer"]
+
+
+class PgServerConfiguration(TypedDict, total=False):
+ pg_conf: Optional[str]
+ """New pg.conf file settings"""
+
+ pooler: Optional[PgServerConfigurationPooler]
+
+ version: Optional[str]
+ """New cluster version"""
+
+
+class Storage(TypedDict, total=False):
+ size_gib: Required[int]
+ """Total available storage for database"""
+
+
+class User(TypedDict, total=False):
+ name: Required[str]
+ """User name"""
+
+ role_attributes: Required[List[Literal["BYPASSRLS", "CREATEDB", "CREATEROLE", "INHERIT", "LOGIN", "NOLOGIN"]]]
+ """User's attributes"""
diff --git a/src/gcore/types/cloud/databases/postgres/clusters/__init__.py b/src/gcore/types/cloud/databases/postgres/clusters/__init__.py
new file mode 100644
index 00000000..254c35c0
--- /dev/null
+++ b/src/gcore/types/cloud/databases/postgres/clusters/__init__.py
@@ -0,0 +1,5 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .postgres_user_credentials import PostgresUserCredentials as PostgresUserCredentials
diff --git a/src/gcore/types/cloud/databases/postgres/clusters/postgres_user_credentials.py b/src/gcore/types/cloud/databases/postgres/clusters/postgres_user_credentials.py
new file mode 100644
index 00000000..fd38e6c6
--- /dev/null
+++ b/src/gcore/types/cloud/databases/postgres/clusters/postgres_user_credentials.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from ......_models import BaseModel
+
+__all__ = ["PostgresUserCredentials"]
+
+
+class PostgresUserCredentials(BaseModel):
+ password: str
+ """Password"""
+
+ username: str
+ """Username"""
diff --git a/src/gcore/types/cloud/databases/postgres/custom_configuration_validate_params.py b/src/gcore/types/cloud/databases/postgres/custom_configuration_validate_params.py
new file mode 100644
index 00000000..2cd791ae
--- /dev/null
+++ b/src/gcore/types/cloud/databases/postgres/custom_configuration_validate_params.py
@@ -0,0 +1,19 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["CustomConfigurationValidateParams"]
+
+
+class CustomConfigurationValidateParams(TypedDict, total=False):
+ project_id: int
+
+ region_id: int
+
+ pg_conf: Required[str]
+ """PostgreSQL configuration"""
+
+ version: Required[str]
+ """PostgreSQL version"""
diff --git a/src/gcore/types/cloud/databases/postgres/pg_conf_validation.py b/src/gcore/types/cloud/databases/postgres/pg_conf_validation.py
new file mode 100644
index 00000000..8e4ae232
--- /dev/null
+++ b/src/gcore/types/cloud/databases/postgres/pg_conf_validation.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+
+from ....._models import BaseModel
+
+__all__ = ["PgConfValidation"]
+
+
+class PgConfValidation(BaseModel):
+ errors: List[str]
+ """Errors list"""
+
+ is_valid: bool
+ """Validity of pg.conf file"""
diff --git a/src/gcore/types/cloud/databases/postgres/postgres_cluster.py b/src/gcore/types/cloud/databases/postgres/postgres_cluster.py
new file mode 100644
index 00000000..445ba8e3
--- /dev/null
+++ b/src/gcore/types/cloud/databases/postgres/postgres_cluster.py
@@ -0,0 +1,118 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ....._models import BaseModel
+
+__all__ = [
+ "PostgresCluster",
+ "Database",
+ "Flavor",
+ "HighAvailability",
+ "Network",
+ "PgServerConfiguration",
+ "PgServerConfigurationPooler",
+ "Storage",
+ "User",
+]
+
+
+class Database(BaseModel):
+ name: str
+ """Database name"""
+
+ owner: str
+ """Database owner from users list"""
+
+ size: int
+ """Size in bytes"""
+
+
+class Flavor(BaseModel):
+ cpu: int
+ """Maximum available cores for instance"""
+
+ memory_gib: int
+ """Maximum available RAM for instance"""
+
+
+class HighAvailability(BaseModel):
+ replication_mode: Literal["async", "sync"]
+ """Type of replication"""
+
+
+class Network(BaseModel):
+ acl: List[str]
+ """Allowed IPs and subnets for incoming traffic"""
+
+ connection_string: str
+ """Connection string to main database"""
+
+ host: str
+ """database hostname"""
+
+ network_type: Literal["public"]
+ """Network Type"""
+
+
+class PgServerConfigurationPooler(BaseModel):
+ mode: Literal["session", "statement", "transaction"]
+
+ type: Optional[Literal["pgbouncer"]] = None
+
+
+class PgServerConfiguration(BaseModel):
+ pg_conf: str
+ """pg.conf settings"""
+
+ version: str
+ """Cluster version"""
+
+ pooler: Optional[PgServerConfigurationPooler] = None
+
+
+class Storage(BaseModel):
+ size_gib: int
+ """Total available storage for database"""
+
+ type: str
+ """Storage type"""
+
+
+class User(BaseModel):
+ is_secret_revealed: bool
+ """Display was secret revealed or not"""
+
+ name: str
+ """User name"""
+
+ role_attributes: List[Literal["BYPASSRLS", "CREATEDB", "CREATEROLE", "INHERIT", "LOGIN", "NOLOGIN"]]
+ """User's attributes"""
+
+
+class PostgresCluster(BaseModel):
+ cluster_name: str
+
+ created_at: datetime
+
+ databases: List[Database]
+
+ flavor: Flavor
+ """Instance RAM and CPU"""
+
+ high_availability: Optional[HighAvailability] = None
+
+ network: Network
+
+ pg_server_configuration: PgServerConfiguration
+ """Main PG configuration"""
+
+ status: Literal["DELETING", "FAILED", "PREPARING", "READY", "UNHEALTHY", "UNKNOWN", "UPDATING"]
+ """Current cluster status"""
+
+ storage: Storage
+ """PG's storage configuration"""
+
+ users: List[User]
diff --git a/src/gcore/types/cloud/databases/postgres/postgres_cluster_short.py b/src/gcore/types/cloud/databases/postgres/postgres_cluster_short.py
new file mode 100644
index 00000000..1a197123
--- /dev/null
+++ b/src/gcore/types/cloud/databases/postgres/postgres_cluster_short.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 ....._models import BaseModel
+
+__all__ = ["PostgresClusterShort"]
+
+
+class PostgresClusterShort(BaseModel):
+ cluster_name: str
+ """PostgreSQL cluster name"""
+
+ created_at: datetime
+ """Creation timestamp"""
+
+ status: Literal["DELETING", "FAILED", "PREPARING", "READY", "UNHEALTHY", "UNKNOWN", "UPDATING"]
+ """Current cluster status"""
+
+ version: str
+ """Cluster version"""
diff --git a/src/gcore/types/cloud/databases/postgres/postgres_configuration.py b/src/gcore/types/cloud/databases/postgres/postgres_configuration.py
new file mode 100644
index 00000000..8be36800
--- /dev/null
+++ b/src/gcore/types/cloud/databases/postgres/postgres_configuration.py
@@ -0,0 +1,31 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+
+from ....._models import BaseModel
+
+__all__ = ["PostgresConfiguration", "Flavor", "StorageClass"]
+
+
+class Flavor(BaseModel):
+ cpu: int
+ """Maximum available cores for instance"""
+
+ memory_gib: int
+ """Maximum available RAM for instance"""
+
+ pg_conf: str
+
+
+class StorageClass(BaseModel):
+ name: str
+ """Storage type"""
+
+
+class PostgresConfiguration(BaseModel):
+ flavors: List[Flavor]
+
+ storage_classes: List[StorageClass]
+
+ versions: List[str]
+ """Available versions"""
diff --git a/tests/api_resources/cloud/databases/__init__.py b/tests/api_resources/cloud/databases/__init__.py
new file mode 100644
index 00000000..fd8019a9
--- /dev/null
+++ b/tests/api_resources/cloud/databases/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/cloud/databases/postgres/__init__.py b/tests/api_resources/cloud/databases/postgres/__init__.py
new file mode 100644
index 00000000..fd8019a9
--- /dev/null
+++ b/tests/api_resources/cloud/databases/postgres/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/cloud/databases/postgres/clusters/__init__.py b/tests/api_resources/cloud/databases/postgres/clusters/__init__.py
new file mode 100644
index 00000000..fd8019a9
--- /dev/null
+++ b/tests/api_resources/cloud/databases/postgres/clusters/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/cloud/databases/postgres/clusters/test_user_credentials.py b/tests/api_resources/cloud/databases/postgres/clusters/test_user_credentials.py
new file mode 100644
index 00000000..28169d78
--- /dev/null
+++ b/tests/api_resources/cloud/databases/postgres/clusters/test_user_credentials.py
@@ -0,0 +1,256 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from gcore import Gcore, AsyncGcore
+from tests.utils import assert_matches_type
+from gcore.types.cloud.databases.postgres.clusters import PostgresUserCredentials
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestUserCredentials:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_get(self, client: Gcore) -> None:
+ user_credential = client.cloud.databases.postgres.clusters.user_credentials.get(
+ username="username",
+ project_id=0,
+ region_id=0,
+ cluster_name="cluster_name",
+ )
+ assert_matches_type(PostgresUserCredentials, user_credential, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Gcore) -> None:
+ response = client.cloud.databases.postgres.clusters.user_credentials.with_raw_response.get(
+ username="username",
+ project_id=0,
+ region_id=0,
+ cluster_name="cluster_name",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ user_credential = response.parse()
+ assert_matches_type(PostgresUserCredentials, user_credential, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Gcore) -> None:
+ with client.cloud.databases.postgres.clusters.user_credentials.with_streaming_response.get(
+ username="username",
+ project_id=0,
+ region_id=0,
+ cluster_name="cluster_name",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ user_credential = response.parse()
+ assert_matches_type(PostgresUserCredentials, user_credential, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_get(self, client: Gcore) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cluster_name` but received ''"):
+ client.cloud.databases.postgres.clusters.user_credentials.with_raw_response.get(
+ username="username",
+ project_id=0,
+ region_id=0,
+ cluster_name="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `username` but received ''"):
+ client.cloud.databases.postgres.clusters.user_credentials.with_raw_response.get(
+ username="",
+ project_id=0,
+ region_id=0,
+ cluster_name="cluster_name",
+ )
+
+ @parametrize
+ def test_method_regenerate(self, client: Gcore) -> None:
+ user_credential = client.cloud.databases.postgres.clusters.user_credentials.regenerate(
+ username="username",
+ project_id=0,
+ region_id=0,
+ cluster_name="cluster_name",
+ )
+ assert_matches_type(PostgresUserCredentials, user_credential, path=["response"])
+
+ @parametrize
+ def test_raw_response_regenerate(self, client: Gcore) -> None:
+ response = client.cloud.databases.postgres.clusters.user_credentials.with_raw_response.regenerate(
+ username="username",
+ project_id=0,
+ region_id=0,
+ cluster_name="cluster_name",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ user_credential = response.parse()
+ assert_matches_type(PostgresUserCredentials, user_credential, path=["response"])
+
+ @parametrize
+ def test_streaming_response_regenerate(self, client: Gcore) -> None:
+ with client.cloud.databases.postgres.clusters.user_credentials.with_streaming_response.regenerate(
+ username="username",
+ project_id=0,
+ region_id=0,
+ cluster_name="cluster_name",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ user_credential = response.parse()
+ assert_matches_type(PostgresUserCredentials, user_credential, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_regenerate(self, client: Gcore) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cluster_name` but received ''"):
+ client.cloud.databases.postgres.clusters.user_credentials.with_raw_response.regenerate(
+ username="username",
+ project_id=0,
+ region_id=0,
+ cluster_name="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `username` but received ''"):
+ client.cloud.databases.postgres.clusters.user_credentials.with_raw_response.regenerate(
+ username="",
+ project_id=0,
+ region_id=0,
+ cluster_name="cluster_name",
+ )
+
+
+class TestAsyncUserCredentials:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncGcore) -> None:
+ user_credential = await async_client.cloud.databases.postgres.clusters.user_credentials.get(
+ username="username",
+ project_id=0,
+ region_id=0,
+ cluster_name="cluster_name",
+ )
+ assert_matches_type(PostgresUserCredentials, user_credential, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncGcore) -> None:
+ response = await async_client.cloud.databases.postgres.clusters.user_credentials.with_raw_response.get(
+ username="username",
+ project_id=0,
+ region_id=0,
+ cluster_name="cluster_name",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ user_credential = await response.parse()
+ assert_matches_type(PostgresUserCredentials, user_credential, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncGcore) -> None:
+ async with async_client.cloud.databases.postgres.clusters.user_credentials.with_streaming_response.get(
+ username="username",
+ project_id=0,
+ region_id=0,
+ cluster_name="cluster_name",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ user_credential = await response.parse()
+ assert_matches_type(PostgresUserCredentials, user_credential, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_get(self, async_client: AsyncGcore) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cluster_name` but received ''"):
+ await async_client.cloud.databases.postgres.clusters.user_credentials.with_raw_response.get(
+ username="username",
+ project_id=0,
+ region_id=0,
+ cluster_name="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `username` but received ''"):
+ await async_client.cloud.databases.postgres.clusters.user_credentials.with_raw_response.get(
+ username="",
+ project_id=0,
+ region_id=0,
+ cluster_name="cluster_name",
+ )
+
+ @parametrize
+ async def test_method_regenerate(self, async_client: AsyncGcore) -> None:
+ user_credential = await async_client.cloud.databases.postgres.clusters.user_credentials.regenerate(
+ username="username",
+ project_id=0,
+ region_id=0,
+ cluster_name="cluster_name",
+ )
+ assert_matches_type(PostgresUserCredentials, user_credential, path=["response"])
+
+ @parametrize
+ async def test_raw_response_regenerate(self, async_client: AsyncGcore) -> None:
+ response = await async_client.cloud.databases.postgres.clusters.user_credentials.with_raw_response.regenerate(
+ username="username",
+ project_id=0,
+ region_id=0,
+ cluster_name="cluster_name",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ user_credential = await response.parse()
+ assert_matches_type(PostgresUserCredentials, user_credential, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_regenerate(self, async_client: AsyncGcore) -> None:
+ async with async_client.cloud.databases.postgres.clusters.user_credentials.with_streaming_response.regenerate(
+ username="username",
+ project_id=0,
+ region_id=0,
+ cluster_name="cluster_name",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ user_credential = await response.parse()
+ assert_matches_type(PostgresUserCredentials, user_credential, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_regenerate(self, async_client: AsyncGcore) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cluster_name` but received ''"):
+ await async_client.cloud.databases.postgres.clusters.user_credentials.with_raw_response.regenerate(
+ username="username",
+ project_id=0,
+ region_id=0,
+ cluster_name="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `username` but received ''"):
+ await async_client.cloud.databases.postgres.clusters.user_credentials.with_raw_response.regenerate(
+ username="",
+ project_id=0,
+ region_id=0,
+ cluster_name="cluster_name",
+ )
diff --git a/tests/api_resources/cloud/databases/postgres/test_clusters.py b/tests/api_resources/cloud/databases/postgres/test_clusters.py
new file mode 100644
index 00000000..224aa613
--- /dev/null
+++ b/tests/api_resources/cloud/databases/postgres/test_clusters.py
@@ -0,0 +1,731 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from gcore import Gcore, AsyncGcore
+from tests.utils import assert_matches_type
+from gcore.pagination import SyncOffsetPage, AsyncOffsetPage
+from gcore.types.cloud import TaskIDList
+from gcore.types.cloud.databases.postgres import (
+ PostgresCluster,
+ PostgresClusterShort,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestClusters:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: Gcore) -> None:
+ cluster = client.cloud.databases.postgres.clusters.create(
+ project_id=0,
+ region_id=0,
+ cluster_name="3",
+ flavor={
+ "cpu": 1,
+ "memory_gib": 1,
+ },
+ high_availability={"replication_mode": "sync"},
+ network={
+ "acl": ["92.33.34.127"],
+ "network_type": "public",
+ },
+ pg_server_configuration={
+ "pg_conf": "\nlisten_addresses = 'localhost'\nport = 5432\nmax_connections = 100\nshared_buffers = 128MB\nlogging_collector = on",
+ "version": "version",
+ },
+ storage={
+ "size_gib": 100,
+ "type": "ssd-hiiops",
+ },
+ )
+ assert_matches_type(TaskIDList, cluster, path=["response"])
+
+ @parametrize
+ def test_method_create_with_all_params(self, client: Gcore) -> None:
+ cluster = client.cloud.databases.postgres.clusters.create(
+ project_id=0,
+ region_id=0,
+ cluster_name="3",
+ flavor={
+ "cpu": 1,
+ "memory_gib": 1,
+ },
+ high_availability={"replication_mode": "sync"},
+ network={
+ "acl": ["92.33.34.127"],
+ "network_type": "public",
+ },
+ pg_server_configuration={
+ "pg_conf": "\nlisten_addresses = 'localhost'\nport = 5432\nmax_connections = 100\nshared_buffers = 128MB\nlogging_collector = on",
+ "version": "version",
+ "pooler": {
+ "mode": "transaction",
+ "type": "pgbouncer",
+ },
+ },
+ storage={
+ "size_gib": 100,
+ "type": "ssd-hiiops",
+ },
+ databases=[
+ {
+ "name": "mydatabase",
+ "owner": "myuser",
+ }
+ ],
+ users=[
+ {
+ "name": "myuser",
+ "role_attributes": ["INHERIT"],
+ }
+ ],
+ )
+ assert_matches_type(TaskIDList, cluster, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Gcore) -> None:
+ response = client.cloud.databases.postgres.clusters.with_raw_response.create(
+ project_id=0,
+ region_id=0,
+ cluster_name="3",
+ flavor={
+ "cpu": 1,
+ "memory_gib": 1,
+ },
+ high_availability={"replication_mode": "sync"},
+ network={
+ "acl": ["92.33.34.127"],
+ "network_type": "public",
+ },
+ pg_server_configuration={
+ "pg_conf": "\nlisten_addresses = 'localhost'\nport = 5432\nmax_connections = 100\nshared_buffers = 128MB\nlogging_collector = on",
+ "version": "version",
+ },
+ storage={
+ "size_gib": 100,
+ "type": "ssd-hiiops",
+ },
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cluster = response.parse()
+ assert_matches_type(TaskIDList, cluster, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Gcore) -> None:
+ with client.cloud.databases.postgres.clusters.with_streaming_response.create(
+ project_id=0,
+ region_id=0,
+ cluster_name="3",
+ flavor={
+ "cpu": 1,
+ "memory_gib": 1,
+ },
+ high_availability={"replication_mode": "sync"},
+ network={
+ "acl": ["92.33.34.127"],
+ "network_type": "public",
+ },
+ pg_server_configuration={
+ "pg_conf": "\nlisten_addresses = 'localhost'\nport = 5432\nmax_connections = 100\nshared_buffers = 128MB\nlogging_collector = on",
+ "version": "version",
+ },
+ storage={
+ "size_gib": 100,
+ "type": "ssd-hiiops",
+ },
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cluster = response.parse()
+ assert_matches_type(TaskIDList, cluster, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_update(self, client: Gcore) -> None:
+ cluster = client.cloud.databases.postgres.clusters.update(
+ cluster_name="cluster_name",
+ project_id=0,
+ region_id=0,
+ )
+ assert_matches_type(TaskIDList, cluster, path=["response"])
+
+ @parametrize
+ def test_method_update_with_all_params(self, client: Gcore) -> None:
+ cluster = client.cloud.databases.postgres.clusters.update(
+ cluster_name="cluster_name",
+ project_id=0,
+ region_id=0,
+ databases=[
+ {
+ "name": "mydatabase",
+ "owner": "myuser",
+ }
+ ],
+ flavor={
+ "cpu": 1,
+ "memory_gib": 1,
+ },
+ high_availability={"replication_mode": "sync"},
+ network={
+ "acl": ["92.33.34.127"],
+ "network_type": "public",
+ },
+ pg_server_configuration={
+ "pg_conf": "\nlisten_addresses = 'localhost'\nport = 5432\nmax_connections = 100\nshared_buffers = 128MB\nlogging_collector = on",
+ "pooler": {
+ "mode": "transaction",
+ "type": "pgbouncer",
+ },
+ "version": "15",
+ },
+ storage={"size_gib": 100},
+ users=[
+ {
+ "name": "myuser",
+ "role_attributes": ["INHERIT"],
+ }
+ ],
+ )
+ assert_matches_type(TaskIDList, cluster, path=["response"])
+
+ @parametrize
+ def test_raw_response_update(self, client: Gcore) -> None:
+ response = client.cloud.databases.postgres.clusters.with_raw_response.update(
+ cluster_name="cluster_name",
+ project_id=0,
+ region_id=0,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cluster = response.parse()
+ assert_matches_type(TaskIDList, cluster, path=["response"])
+
+ @parametrize
+ def test_streaming_response_update(self, client: Gcore) -> None:
+ with client.cloud.databases.postgres.clusters.with_streaming_response.update(
+ cluster_name="cluster_name",
+ project_id=0,
+ region_id=0,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cluster = response.parse()
+ assert_matches_type(TaskIDList, cluster, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_update(self, client: Gcore) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cluster_name` but received ''"):
+ client.cloud.databases.postgres.clusters.with_raw_response.update(
+ cluster_name="",
+ project_id=0,
+ region_id=0,
+ )
+
+ @parametrize
+ def test_method_list(self, client: Gcore) -> None:
+ cluster = client.cloud.databases.postgres.clusters.list(
+ project_id=0,
+ region_id=0,
+ )
+ assert_matches_type(SyncOffsetPage[PostgresClusterShort], cluster, path=["response"])
+
+ @parametrize
+ def test_method_list_with_all_params(self, client: Gcore) -> None:
+ cluster = client.cloud.databases.postgres.clusters.list(
+ project_id=0,
+ region_id=0,
+ limit=0,
+ offset=0,
+ )
+ assert_matches_type(SyncOffsetPage[PostgresClusterShort], cluster, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Gcore) -> None:
+ response = client.cloud.databases.postgres.clusters.with_raw_response.list(
+ project_id=0,
+ region_id=0,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cluster = response.parse()
+ assert_matches_type(SyncOffsetPage[PostgresClusterShort], cluster, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Gcore) -> None:
+ with client.cloud.databases.postgres.clusters.with_streaming_response.list(
+ project_id=0,
+ region_id=0,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cluster = response.parse()
+ assert_matches_type(SyncOffsetPage[PostgresClusterShort], cluster, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_delete(self, client: Gcore) -> None:
+ cluster = client.cloud.databases.postgres.clusters.delete(
+ cluster_name="cluster_name",
+ project_id=0,
+ region_id=0,
+ )
+ assert_matches_type(TaskIDList, cluster, path=["response"])
+
+ @parametrize
+ def test_raw_response_delete(self, client: Gcore) -> None:
+ response = client.cloud.databases.postgres.clusters.with_raw_response.delete(
+ cluster_name="cluster_name",
+ project_id=0,
+ region_id=0,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cluster = response.parse()
+ assert_matches_type(TaskIDList, cluster, path=["response"])
+
+ @parametrize
+ def test_streaming_response_delete(self, client: Gcore) -> None:
+ with client.cloud.databases.postgres.clusters.with_streaming_response.delete(
+ cluster_name="cluster_name",
+ project_id=0,
+ region_id=0,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cluster = response.parse()
+ assert_matches_type(TaskIDList, cluster, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_delete(self, client: Gcore) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cluster_name` but received ''"):
+ client.cloud.databases.postgres.clusters.with_raw_response.delete(
+ cluster_name="",
+ project_id=0,
+ region_id=0,
+ )
+
+ @parametrize
+ def test_method_get(self, client: Gcore) -> None:
+ cluster = client.cloud.databases.postgres.clusters.get(
+ cluster_name="cluster_name",
+ project_id=0,
+ region_id=0,
+ )
+ assert_matches_type(PostgresCluster, cluster, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Gcore) -> None:
+ response = client.cloud.databases.postgres.clusters.with_raw_response.get(
+ cluster_name="cluster_name",
+ project_id=0,
+ region_id=0,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cluster = response.parse()
+ assert_matches_type(PostgresCluster, cluster, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Gcore) -> None:
+ with client.cloud.databases.postgres.clusters.with_streaming_response.get(
+ cluster_name="cluster_name",
+ project_id=0,
+ region_id=0,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cluster = response.parse()
+ assert_matches_type(PostgresCluster, cluster, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_get(self, client: Gcore) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cluster_name` but received ''"):
+ client.cloud.databases.postgres.clusters.with_raw_response.get(
+ cluster_name="",
+ project_id=0,
+ region_id=0,
+ )
+
+
+class TestAsyncClusters:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_create(self, async_client: AsyncGcore) -> None:
+ cluster = await async_client.cloud.databases.postgres.clusters.create(
+ project_id=0,
+ region_id=0,
+ cluster_name="3",
+ flavor={
+ "cpu": 1,
+ "memory_gib": 1,
+ },
+ high_availability={"replication_mode": "sync"},
+ network={
+ "acl": ["92.33.34.127"],
+ "network_type": "public",
+ },
+ pg_server_configuration={
+ "pg_conf": "\nlisten_addresses = 'localhost'\nport = 5432\nmax_connections = 100\nshared_buffers = 128MB\nlogging_collector = on",
+ "version": "version",
+ },
+ storage={
+ "size_gib": 100,
+ "type": "ssd-hiiops",
+ },
+ )
+ assert_matches_type(TaskIDList, cluster, path=["response"])
+
+ @parametrize
+ async def test_method_create_with_all_params(self, async_client: AsyncGcore) -> None:
+ cluster = await async_client.cloud.databases.postgres.clusters.create(
+ project_id=0,
+ region_id=0,
+ cluster_name="3",
+ flavor={
+ "cpu": 1,
+ "memory_gib": 1,
+ },
+ high_availability={"replication_mode": "sync"},
+ network={
+ "acl": ["92.33.34.127"],
+ "network_type": "public",
+ },
+ pg_server_configuration={
+ "pg_conf": "\nlisten_addresses = 'localhost'\nport = 5432\nmax_connections = 100\nshared_buffers = 128MB\nlogging_collector = on",
+ "version": "version",
+ "pooler": {
+ "mode": "transaction",
+ "type": "pgbouncer",
+ },
+ },
+ storage={
+ "size_gib": 100,
+ "type": "ssd-hiiops",
+ },
+ databases=[
+ {
+ "name": "mydatabase",
+ "owner": "myuser",
+ }
+ ],
+ users=[
+ {
+ "name": "myuser",
+ "role_attributes": ["INHERIT"],
+ }
+ ],
+ )
+ assert_matches_type(TaskIDList, cluster, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncGcore) -> None:
+ response = await async_client.cloud.databases.postgres.clusters.with_raw_response.create(
+ project_id=0,
+ region_id=0,
+ cluster_name="3",
+ flavor={
+ "cpu": 1,
+ "memory_gib": 1,
+ },
+ high_availability={"replication_mode": "sync"},
+ network={
+ "acl": ["92.33.34.127"],
+ "network_type": "public",
+ },
+ pg_server_configuration={
+ "pg_conf": "\nlisten_addresses = 'localhost'\nport = 5432\nmax_connections = 100\nshared_buffers = 128MB\nlogging_collector = on",
+ "version": "version",
+ },
+ storage={
+ "size_gib": 100,
+ "type": "ssd-hiiops",
+ },
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cluster = await response.parse()
+ assert_matches_type(TaskIDList, cluster, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncGcore) -> None:
+ async with async_client.cloud.databases.postgres.clusters.with_streaming_response.create(
+ project_id=0,
+ region_id=0,
+ cluster_name="3",
+ flavor={
+ "cpu": 1,
+ "memory_gib": 1,
+ },
+ high_availability={"replication_mode": "sync"},
+ network={
+ "acl": ["92.33.34.127"],
+ "network_type": "public",
+ },
+ pg_server_configuration={
+ "pg_conf": "\nlisten_addresses = 'localhost'\nport = 5432\nmax_connections = 100\nshared_buffers = 128MB\nlogging_collector = on",
+ "version": "version",
+ },
+ storage={
+ "size_gib": 100,
+ "type": "ssd-hiiops",
+ },
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cluster = await response.parse()
+ assert_matches_type(TaskIDList, cluster, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_update(self, async_client: AsyncGcore) -> None:
+ cluster = await async_client.cloud.databases.postgres.clusters.update(
+ cluster_name="cluster_name",
+ project_id=0,
+ region_id=0,
+ )
+ assert_matches_type(TaskIDList, cluster, path=["response"])
+
+ @parametrize
+ async def test_method_update_with_all_params(self, async_client: AsyncGcore) -> None:
+ cluster = await async_client.cloud.databases.postgres.clusters.update(
+ cluster_name="cluster_name",
+ project_id=0,
+ region_id=0,
+ databases=[
+ {
+ "name": "mydatabase",
+ "owner": "myuser",
+ }
+ ],
+ flavor={
+ "cpu": 1,
+ "memory_gib": 1,
+ },
+ high_availability={"replication_mode": "sync"},
+ network={
+ "acl": ["92.33.34.127"],
+ "network_type": "public",
+ },
+ pg_server_configuration={
+ "pg_conf": "\nlisten_addresses = 'localhost'\nport = 5432\nmax_connections = 100\nshared_buffers = 128MB\nlogging_collector = on",
+ "pooler": {
+ "mode": "transaction",
+ "type": "pgbouncer",
+ },
+ "version": "15",
+ },
+ storage={"size_gib": 100},
+ users=[
+ {
+ "name": "myuser",
+ "role_attributes": ["INHERIT"],
+ }
+ ],
+ )
+ assert_matches_type(TaskIDList, cluster, path=["response"])
+
+ @parametrize
+ async def test_raw_response_update(self, async_client: AsyncGcore) -> None:
+ response = await async_client.cloud.databases.postgres.clusters.with_raw_response.update(
+ cluster_name="cluster_name",
+ project_id=0,
+ region_id=0,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cluster = await response.parse()
+ assert_matches_type(TaskIDList, cluster, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_update(self, async_client: AsyncGcore) -> None:
+ async with async_client.cloud.databases.postgres.clusters.with_streaming_response.update(
+ cluster_name="cluster_name",
+ project_id=0,
+ region_id=0,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cluster = await response.parse()
+ assert_matches_type(TaskIDList, cluster, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_update(self, async_client: AsyncGcore) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cluster_name` but received ''"):
+ await async_client.cloud.databases.postgres.clusters.with_raw_response.update(
+ cluster_name="",
+ project_id=0,
+ region_id=0,
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncGcore) -> None:
+ cluster = await async_client.cloud.databases.postgres.clusters.list(
+ project_id=0,
+ region_id=0,
+ )
+ assert_matches_type(AsyncOffsetPage[PostgresClusterShort], cluster, path=["response"])
+
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> None:
+ cluster = await async_client.cloud.databases.postgres.clusters.list(
+ project_id=0,
+ region_id=0,
+ limit=0,
+ offset=0,
+ )
+ assert_matches_type(AsyncOffsetPage[PostgresClusterShort], cluster, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncGcore) -> None:
+ response = await async_client.cloud.databases.postgres.clusters.with_raw_response.list(
+ project_id=0,
+ region_id=0,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cluster = await response.parse()
+ assert_matches_type(AsyncOffsetPage[PostgresClusterShort], cluster, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncGcore) -> None:
+ async with async_client.cloud.databases.postgres.clusters.with_streaming_response.list(
+ project_id=0,
+ region_id=0,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cluster = await response.parse()
+ assert_matches_type(AsyncOffsetPage[PostgresClusterShort], cluster, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncGcore) -> None:
+ cluster = await async_client.cloud.databases.postgres.clusters.delete(
+ cluster_name="cluster_name",
+ project_id=0,
+ region_id=0,
+ )
+ assert_matches_type(TaskIDList, cluster, path=["response"])
+
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncGcore) -> None:
+ response = await async_client.cloud.databases.postgres.clusters.with_raw_response.delete(
+ cluster_name="cluster_name",
+ project_id=0,
+ region_id=0,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cluster = await response.parse()
+ assert_matches_type(TaskIDList, cluster, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncGcore) -> None:
+ async with async_client.cloud.databases.postgres.clusters.with_streaming_response.delete(
+ cluster_name="cluster_name",
+ project_id=0,
+ region_id=0,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cluster = await response.parse()
+ assert_matches_type(TaskIDList, cluster, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_delete(self, async_client: AsyncGcore) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cluster_name` but received ''"):
+ await async_client.cloud.databases.postgres.clusters.with_raw_response.delete(
+ cluster_name="",
+ project_id=0,
+ region_id=0,
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncGcore) -> None:
+ cluster = await async_client.cloud.databases.postgres.clusters.get(
+ cluster_name="cluster_name",
+ project_id=0,
+ region_id=0,
+ )
+ assert_matches_type(PostgresCluster, cluster, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncGcore) -> None:
+ response = await async_client.cloud.databases.postgres.clusters.with_raw_response.get(
+ cluster_name="cluster_name",
+ project_id=0,
+ region_id=0,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cluster = await response.parse()
+ assert_matches_type(PostgresCluster, cluster, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncGcore) -> None:
+ async with async_client.cloud.databases.postgres.clusters.with_streaming_response.get(
+ cluster_name="cluster_name",
+ project_id=0,
+ region_id=0,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cluster = await response.parse()
+ assert_matches_type(PostgresCluster, cluster, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_get(self, async_client: AsyncGcore) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cluster_name` but received ''"):
+ await async_client.cloud.databases.postgres.clusters.with_raw_response.get(
+ cluster_name="",
+ project_id=0,
+ region_id=0,
+ )
diff --git a/tests/api_resources/cloud/databases/postgres/test_configurations.py b/tests/api_resources/cloud/databases/postgres/test_configurations.py
new file mode 100644
index 00000000..635483f0
--- /dev/null
+++ b/tests/api_resources/cloud/databases/postgres/test_configurations.py
@@ -0,0 +1,92 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from gcore import Gcore, AsyncGcore
+from tests.utils import assert_matches_type
+from gcore.types.cloud.databases.postgres import PostgresConfiguration
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestConfigurations:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_get(self, client: Gcore) -> None:
+ configuration = client.cloud.databases.postgres.configurations.get(
+ project_id=0,
+ region_id=0,
+ )
+ assert_matches_type(PostgresConfiguration, configuration, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Gcore) -> None:
+ response = client.cloud.databases.postgres.configurations.with_raw_response.get(
+ project_id=0,
+ region_id=0,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ configuration = response.parse()
+ assert_matches_type(PostgresConfiguration, configuration, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Gcore) -> None:
+ with client.cloud.databases.postgres.configurations.with_streaming_response.get(
+ project_id=0,
+ region_id=0,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ configuration = response.parse()
+ assert_matches_type(PostgresConfiguration, configuration, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncConfigurations:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncGcore) -> None:
+ configuration = await async_client.cloud.databases.postgres.configurations.get(
+ project_id=0,
+ region_id=0,
+ )
+ assert_matches_type(PostgresConfiguration, configuration, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncGcore) -> None:
+ response = await async_client.cloud.databases.postgres.configurations.with_raw_response.get(
+ project_id=0,
+ region_id=0,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ configuration = await response.parse()
+ assert_matches_type(PostgresConfiguration, configuration, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncGcore) -> None:
+ async with async_client.cloud.databases.postgres.configurations.with_streaming_response.get(
+ project_id=0,
+ region_id=0,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ configuration = await response.parse()
+ assert_matches_type(PostgresConfiguration, configuration, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/cloud/databases/postgres/test_custom_configurations.py b/tests/api_resources/cloud/databases/postgres/test_custom_configurations.py
new file mode 100644
index 00000000..1f6935d3
--- /dev/null
+++ b/tests/api_resources/cloud/databases/postgres/test_custom_configurations.py
@@ -0,0 +1,104 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from gcore import Gcore, AsyncGcore
+from tests.utils import assert_matches_type
+from gcore.types.cloud.databases.postgres import PgConfValidation
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestCustomConfigurations:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_validate(self, client: Gcore) -> None:
+ custom_configuration = client.cloud.databases.postgres.custom_configurations.validate(
+ project_id=0,
+ region_id=0,
+ pg_conf="\nlisten_addresses = 'localhost'\nport = 5432\nmax_connections = 100\nshared_buffers = 128MB\nlogging_collector = on",
+ version="15",
+ )
+ assert_matches_type(PgConfValidation, custom_configuration, path=["response"])
+
+ @parametrize
+ def test_raw_response_validate(self, client: Gcore) -> None:
+ response = client.cloud.databases.postgres.custom_configurations.with_raw_response.validate(
+ project_id=0,
+ region_id=0,
+ pg_conf="\nlisten_addresses = 'localhost'\nport = 5432\nmax_connections = 100\nshared_buffers = 128MB\nlogging_collector = on",
+ version="15",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ custom_configuration = response.parse()
+ assert_matches_type(PgConfValidation, custom_configuration, path=["response"])
+
+ @parametrize
+ def test_streaming_response_validate(self, client: Gcore) -> None:
+ with client.cloud.databases.postgres.custom_configurations.with_streaming_response.validate(
+ project_id=0,
+ region_id=0,
+ pg_conf="\nlisten_addresses = 'localhost'\nport = 5432\nmax_connections = 100\nshared_buffers = 128MB\nlogging_collector = on",
+ version="15",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ custom_configuration = response.parse()
+ assert_matches_type(PgConfValidation, custom_configuration, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncCustomConfigurations:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_validate(self, async_client: AsyncGcore) -> None:
+ custom_configuration = await async_client.cloud.databases.postgres.custom_configurations.validate(
+ project_id=0,
+ region_id=0,
+ pg_conf="\nlisten_addresses = 'localhost'\nport = 5432\nmax_connections = 100\nshared_buffers = 128MB\nlogging_collector = on",
+ version="15",
+ )
+ assert_matches_type(PgConfValidation, custom_configuration, path=["response"])
+
+ @parametrize
+ async def test_raw_response_validate(self, async_client: AsyncGcore) -> None:
+ response = await async_client.cloud.databases.postgres.custom_configurations.with_raw_response.validate(
+ project_id=0,
+ region_id=0,
+ pg_conf="\nlisten_addresses = 'localhost'\nport = 5432\nmax_connections = 100\nshared_buffers = 128MB\nlogging_collector = on",
+ version="15",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ custom_configuration = await response.parse()
+ assert_matches_type(PgConfValidation, custom_configuration, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_validate(self, async_client: AsyncGcore) -> None:
+ async with async_client.cloud.databases.postgres.custom_configurations.with_streaming_response.validate(
+ project_id=0,
+ region_id=0,
+ pg_conf="\nlisten_addresses = 'localhost'\nport = 5432\nmax_connections = 100\nshared_buffers = 128MB\nlogging_collector = on",
+ version="15",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ custom_configuration = await response.parse()
+ assert_matches_type(PgConfValidation, custom_configuration, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
From 286449dce9f2ef848b2abdd1206252e3e5f2cc77 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 4 Nov 2025 15:48:16 +0000
Subject: [PATCH 27/27] release: 0.18.0
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 30 ++++++++++++++++++++++++++++++
pyproject.toml | 2 +-
src/gcore/_version.py | 2 +-
4 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 6db19b95..4ad3fef3 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.17.0"
+ ".": "0.18.0"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3433ecf3..f73fd479 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,35 @@
# Changelog
+## 0.18.0 (2025-11-04)
+
+Full Changelog: [v0.17.0...v0.18.0](https://github.com/G-Core/gcore-python/compare/v0.17.0...v0.18.0)
+
+### Features
+
+* **api:** aggregated API specs update ([c69f622](https://github.com/G-Core/gcore-python/commit/c69f622f4d085d5c93978edbf4deb2ecbe4279d6))
+* **api:** aggregated API specs update ([e008291](https://github.com/G-Core/gcore-python/commit/e008291499f90553d12deffbcef5c4a9b6752f61))
+* **api:** aggregated API specs update ([7e17f98](https://github.com/G-Core/gcore-python/commit/7e17f98624fecfb8d1ad5a53a001dcd20ca15214))
+* **api:** aggregated API specs update ([01c7469](https://github.com/G-Core/gcore-python/commit/01c746977c89d813e54b97c87513960a5cba42c3))
+* **api:** aggregated API specs update ([3ef8586](https://github.com/G-Core/gcore-python/commit/3ef8586481df9533a0627310458bb72b9b458d2f))
+* **api:** aggregated API specs update ([af54c88](https://github.com/G-Core/gcore-python/commit/af54c886222ea41e6ef57d8683fbb64e2b688a15))
+* **api:** aggregated API specs update ([4e62953](https://github.com/G-Core/gcore-python/commit/4e629534e07db80d93c46e5ccc5e3d2ba48d9eb4))
+* **api:** aggregated API specs update ([18614cb](https://github.com/G-Core/gcore-python/commit/18614cb786fd3ea9020cee18c2a23c4c81f116f3))
+* **api:** aggregated API specs update ([926c0dd](https://github.com/G-Core/gcore-python/commit/926c0ddfcef420ba47eca7b399ea43462a18371a))
+* **cloud:** add support for postgres ([2802edf](https://github.com/G-Core/gcore-python/commit/2802edf3bbac88b644ba8ff4d5b83dc0606e4b48))
+
+
+### Bug Fixes
+
+* **client:** close streams without requiring full consumption ([cd7152c](https://github.com/G-Core/gcore-python/commit/cd7152cd959a9984e5c60edb41d16fa2db342012))
+* **cloud:** members not optional in lb pools create_and_poll ([27bc07a](https://github.com/G-Core/gcore-python/commit/27bc07acab63505e03f4a5b51e21544fe84877ec))
+
+
+### Chores
+
+* **cloud:** add *_and_poll() to *WithRawResponse and *WithStreaming ([d8886ce](https://github.com/G-Core/gcore-python/commit/d8886ce4abeadd3d260c3f533e72b778d521482c))
+* **internal/tests:** avoid race condition with implicit client cleanup ([67e4c77](https://github.com/G-Core/gcore-python/commit/67e4c77936fca0b2192b931ec71003dd62383c81))
+* **internal:** grammar fix (it's -> its) ([9bf8a18](https://github.com/G-Core/gcore-python/commit/9bf8a18f42a2122f43d9084ff3287e4d1aa7dd95))
+
## 0.17.0 (2025-10-21)
Full Changelog: [v0.16.0...v0.17.0](https://github.com/G-Core/gcore-python/compare/v0.16.0...v0.17.0)
diff --git a/pyproject.toml b/pyproject.toml
index 2b3a98de..9de98340 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "gcore"
-version = "0.17.0"
+version = "0.18.0"
description = "The official Python library for the gcore API"
dynamic = ["readme"]
license = "Apache-2.0"
diff --git a/src/gcore/_version.py b/src/gcore/_version.py
index 4e59998e..4e588aa0 100644
--- a/src/gcore/_version.py
+++ b/src/gcore/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "gcore"
-__version__ = "0.17.0" # x-release-please-version
+__version__ = "0.18.0" # x-release-please-version