diff --git a/.release-please-manifest.json b/.release-please-manifest.json index ea2682c30..52afe059d 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.41.0" + ".": "0.42.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 0b6c3449e..f3ae73c61 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 658 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-e7708c017357421a39e6de2f7141415c93951bbc835742909b0d9d6f0825a318.yml -openapi_spec_hash: 2abb653b57137b808c182cb1e778a429 -config_hash: ab6b5443d52ca04e4e0e12def131f8e6 +configured_endpoints: 657 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-e8141952a77a5faabf98feca4f964baaef5b84aa66d785c8b35357e48928df9c.yml +openapi_spec_hash: a5ff6021de586dafea9df886214ceb2c +config_hash: 0b9fe3822aef92ebe43ad609b931bfc8 diff --git a/CHANGELOG.md b/CHANGELOG.md index cc98f8e36..410c7460a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,50 @@ # Changelog +## 0.42.0 (2026-04-17) + +Full Changelog: [v0.41.0...v0.42.0](https://github.com/G-Core/gcore-python/compare/v0.41.0...v0.42.0) + +### ⚠ BREAKING CHANGES + +* **cloud:** remove deprecated cloud.inference.deployments.get_api_key + +### Features + +* **api:** aggregated API specs update ([284df4c](https://github.com/G-Core/gcore-python/commit/284df4cedcfac4b86c746c963fc69b5af183d014)) +* **api:** aggregated API specs update ([0110236](https://github.com/G-Core/gcore-python/commit/0110236e7efb9269398475d2500e078c599037f6)) +* **api:** aggregated API specs update ([51ad9c9](https://github.com/G-Core/gcore-python/commit/51ad9c97608b81a0358c3c8e06b3321cb331a06b)) +* **api:** aggregated API specs update ([eda0539](https://github.com/G-Core/gcore-python/commit/eda0539c7bac06e3451703469aabf50fb5290467)) +* **api:** aggregated API specs update ([01be2f5](https://github.com/G-Core/gcore-python/commit/01be2f5ba1c94daeff5e61a4672b9ff8b0bac7cc)) +* **api:** aggregated API specs update ([7beaf49](https://github.com/G-Core/gcore-python/commit/7beaf49ae0cd289d6a60a79de18ed722a9cbf088)) +* **api:** aggregated API specs update ([2f8fb0a](https://github.com/G-Core/gcore-python/commit/2f8fb0a0a1493b19a84a8d4fcb863ddfc2f66db8)) +* **api:** fix(cdn): harmonize pagination across CDN list endpoints ([c95a0b8](https://github.com/G-Core/gcore-python/commit/c95a0b8b047bb8f7370934fe35576648163e3a3e)) +* **cloud:** add delete_and_poll and examples for GPU baremetal clusters ([adc8f40](https://github.com/G-Core/gcore-python/commit/adc8f408f925862f13e19ac30c96684f40395aca)) +* **cloud:** add polling methods and examples for GPU virtual clusters ([1ed9b85](https://github.com/G-Core/gcore-python/commit/1ed9b85b772bd52971503e21a7e484af6812f5b4)) + + +### Bug Fixes + +* **client:** preserve hardcoded query params when merging with user params ([0971eaa](https://github.com/G-Core/gcore-python/commit/0971eaa023789ebaf5baeae39f4977cba3cbab1d)) +* **cloud:** align polling methods with underlying base method ([4b99901](https://github.com/G-Core/gcore-python/commit/4b999011b48a859a6f95649246ac3a5ba67ff62e)) +* **dns:** update network-mappings get_by_name to new endpoint path ([de11047](https://github.com/G-Core/gcore-python/commit/de110478944f7c9dc61ac3481dba876912e05ff6)) +* ensure file data are only sent as 1 parameter ([16f4262](https://github.com/G-Core/gcore-python/commit/16f4262f6ca89edcefe0315c13963e2d84f945c2)) +* **examples:** update baremetal image examples to use BaremetalImage type ([7e924f8](https://github.com/G-Core/gcore-python/commit/7e924f830c234be00e8c6cb940fe59ff4629a626)) + + +### Chores + +* **cloud:** remove deprecated cloud.inference.deployments.get_api_key ([1bf3513](https://github.com/G-Core/gcore-python/commit/1bf3513b19eda2cd35230947dd36a1b09f66e419)) + + +### Documentation + +* update examples ([fa05d93](https://github.com/G-Core/gcore-python/commit/fa05d9370764f706015b7628abd3ba0f12f880d7)) + + +### Refactors + +* **cloud:** split instance and baremetal image models ([fce124a](https://github.com/G-Core/gcore-python/commit/fce124a98b3eb6cec5bbcb46e60e424b4c6da298)) + ## 0.41.0 (2026-04-03) Full Changelog: [v0.40.0...v0.41.0](https://github.com/G-Core/gcore-python/compare/v0.40.0...v0.41.0) diff --git a/examples/cloud/baremetal.py b/examples/cloud/baremetal.py index 07cc99660..d9f1a51d6 100644 --- a/examples/cloud/baremetal.py +++ b/examples/cloud/baremetal.py @@ -1,8 +1,8 @@ from typing import List from gcore import Gcore -from gcore.types.cloud.image import Image from gcore.types.cloud.baremetal_flavor import BaremetalFlavor +from gcore.types.cloud.baremetal.baremetal_image import BaremetalImage from gcore.types.cloud.baremetal.server_create_params import ( InterfaceCreateBareMetalExternalInterfaceSerializer, ) @@ -80,7 +80,7 @@ def list_flavors(*, client: Gcore) -> List[BaremetalFlavor]: return flavors.results -def list_images(*, client: Gcore) -> List[Image]: +def list_images(*, client: Gcore) -> List[BaremetalImage]: print("\n=== LIST BAREMETAL IMAGES ===") images = client.cloud.baremetal.images.list() _print_image_details(images.results) @@ -108,7 +108,7 @@ def _print_flavor_details(flavors: List[BaremetalFlavor]) -> None: print(f" ... and {len(flavors) - display_count} more flavors") -def _print_image_details(images: List[Image]) -> None: +def _print_image_details(images: List[BaremetalImage]) -> None: display_count = 3 if len(images) < display_count: display_count = len(images) @@ -133,15 +133,15 @@ def _get_smallest_flavor(flavors: List[BaremetalFlavor]) -> str: return smallest_flavor.flavor_id -def _get_ubuntu_image(images: List[Image]) -> str: +def _get_ubuntu_image(images: List[BaremetalImage]) -> str: return _get_os_image(images, "ubuntu") -def _get_debian_image(images: List[Image]) -> str: +def _get_debian_image(images: List[BaremetalImage]) -> str: return _get_os_image(images, "debian") -def _get_os_image(images: List[Image], os_name: str) -> str: +def _get_os_image(images: List[BaremetalImage], os_name: str) -> str: os_images = [img for img in images if os_name.lower() in img.name.lower()] if not os_images: linux_images = [img for img in images if img.os_type.lower() == "linux"] diff --git a/examples/cloud/baremetal_async.py b/examples/cloud/baremetal_async.py index 2e1ec482a..bea2ec6d3 100644 --- a/examples/cloud/baremetal_async.py +++ b/examples/cloud/baremetal_async.py @@ -2,8 +2,8 @@ from typing import List from gcore import AsyncGcore -from gcore.types.cloud.image import Image from gcore.types.cloud.baremetal_flavor import BaremetalFlavor +from gcore.types.cloud.baremetal.baremetal_image import BaremetalImage from gcore.types.cloud.baremetal.server_create_params import ( InterfaceCreateBareMetalExternalInterfaceSerializer, ) @@ -83,7 +83,7 @@ async def list_flavors(*, client: AsyncGcore) -> List[BaremetalFlavor]: return flavors.results -async def list_images(*, client: AsyncGcore) -> List[Image]: +async def list_images(*, client: AsyncGcore) -> List[BaremetalImage]: print("\n=== LIST BAREMETAL IMAGES ===") images = await client.cloud.baremetal.images.list() _print_image_details(images.results) @@ -111,7 +111,7 @@ def _print_flavor_details(flavors: List[BaremetalFlavor]) -> None: print(f" ... and {len(flavors) - display_count} more flavors") -def _print_image_details(images: List[Image]) -> None: +def _print_image_details(images: List[BaremetalImage]) -> None: display_count = 3 if len(images) < display_count: display_count = len(images) @@ -136,15 +136,15 @@ def _get_smallest_flavor(flavors: List[BaremetalFlavor]) -> str: return smallest_flavor.flavor_id -def _get_ubuntu_image(images: List[Image]) -> str: +def _get_ubuntu_image(images: List[BaremetalImage]) -> str: return _get_os_image(images, "ubuntu") -def _get_debian_image(images: List[Image]) -> str: +def _get_debian_image(images: List[BaremetalImage]) -> str: return _get_os_image(images, "debian") -def _get_os_image(images: List[Image], os_name: str) -> str: +def _get_os_image(images: List[BaremetalImage], os_name: str) -> str: os_images = [img for img in images if os_name.lower() in img.name.lower()] if not os_images: linux_images = [img for img in images if img.os_type.lower() == "linux"] diff --git a/examples/cloud/gpu_baremetal_clusters.py b/examples/cloud/gpu_baremetal_clusters.py new file mode 100644 index 000000000..ebb276cb3 --- /dev/null +++ b/examples/cloud/gpu_baremetal_clusters.py @@ -0,0 +1,190 @@ +from typing import List + +from gcore import Gcore +from gcore.types.cloud.gpu_image import GPUImage +from gcore.types.cloud.network_interface import NetworkInterface +from gcore.types.cloud.gpu_baremetal.cluster_create_params import ( + ServersSettings, + ServersSettingsInterfaceExternalInterfaceInputSerializer, +) +from gcore.types.cloud.gpu_baremetal.gpu_baremetal_cluster import GPUBaremetalCluster +from gcore.types.cloud.gpu_baremetal.clusters.gpu_baremetal_flavor import GPUBaremetalFlavor + + +def main() -> None: + # TODO set API key before running + # api_key = os.environ["GCORE_API_KEY"] + # TODO set cloud project ID before running + # cloud_project_id = os.environ["GCORE_CLOUD_PROJECT_ID"] + # TODO set cloud region ID before running + # cloud_region_id = os.environ["GCORE_CLOUD_REGION_ID"] + + gcore = Gcore( + # No need to explicitly pass to Gcore constructor if using environment variables + # api_key=api_key, + # cloud_project_id=cloud_project_id, + # cloud_region_id=cloud_region_id, + ) + + # Flavors + flavors = list_flavors(client=gcore) + + # Images + images = list_images(client=gcore) + + # Clusters + flavor_name = _get_first_available_flavor(flavors) + image_id = _get_first_image(images) + cluster = create_cluster(client=gcore, flavor=flavor_name, image_id=image_id) + get_cluster(client=gcore, cluster_id=cluster.id) + list_clusters(client=gcore) + update_cluster(client=gcore, cluster_id=cluster.id) + + # Interfaces + list_interfaces(client=gcore, cluster_id=cluster.id) + + # Servers + list_servers(client=gcore, cluster_id=cluster.id) + + # Delete + delete_cluster(client=gcore, cluster_id=cluster.id) + + +def create_cluster(*, client: Gcore, flavor: str, image_id: str) -> GPUBaremetalCluster: + print("\n=== CREATE GPU BAREMETAL CLUSTER ===") + cluster = client.cloud.gpu_baremetal.clusters.create_and_poll( + name="gcore-python-example-gpu-baremetal", + flavor=flavor, + image_id=image_id, + servers_count=1, + servers_settings=ServersSettings( + interfaces=[ + ServersSettingsInterfaceExternalInterfaceInputSerializer(type="external"), + ], + ), + tags={"name": "gcore-python-example"}, + ) + print(f"Created cluster: ID={cluster.id}, name={cluster.name}, status={cluster.status}") + print("========================") + return cluster + + +def get_cluster(*, client: Gcore, cluster_id: str) -> GPUBaremetalCluster: + print("\n=== GET GPU BAREMETAL CLUSTER ===") + cluster = client.cloud.gpu_baremetal.clusters.get(cluster_id=cluster_id) + print(f"Cluster: ID={cluster.id}, name={cluster.name}, status={cluster.status}") + print("========================") + return cluster + + +def list_clusters(*, client: Gcore) -> None: + print("\n=== LIST GPU BAREMETAL CLUSTERS ===") + clusters = client.cloud.gpu_baremetal.clusters.list() + for count, cluster in enumerate(clusters, 1): + print(f" {count}. Cluster: ID={cluster.id}, name={cluster.name}, status={cluster.status}") + print("========================") + + +def update_cluster(*, client: Gcore, cluster_id: str) -> None: + print("\n=== UPDATE GPU BAREMETAL CLUSTER ===") + cluster = client.cloud.gpu_baremetal.clusters.update( + cluster_id=cluster_id, name="gcore-python-example-gpu-baremetal-updated" + ) + print(f"Updated cluster: ID={cluster.id}, name={cluster.name}") + print("========================") + + +def delete_cluster(*, client: Gcore, cluster_id: str) -> None: + print("\n=== DELETE GPU BAREMETAL CLUSTER ===") + client.cloud.gpu_baremetal.clusters.delete_and_poll( + cluster_id=cluster_id, + all_floating_ips=True, + ) + print(f"Deleted cluster: ID={cluster_id}") + print("========================") + + +def list_interfaces(*, client: Gcore, cluster_id: str) -> List[NetworkInterface]: + print("\n=== LIST GPU BAREMETAL CLUSTER INTERFACES ===") + interfaces = client.cloud.gpu_baremetal.clusters.interfaces.list(cluster_id=cluster_id) + for count, interface in enumerate(interfaces.results, 1): + print(f" {count}. Interface: PortID={interface.port_id}, NetworkID={interface.network_id}") + print("========================") + return interfaces.results + + +def list_servers(*, client: Gcore, cluster_id: str) -> None: + print("\n=== LIST GPU BAREMETAL CLUSTER SERVERS ===") + servers = client.cloud.gpu_baremetal.clusters.servers.list(cluster_id=cluster_id) + for count, server in enumerate(servers.results, 1): + print(f" {count}. Server: ID={server.id}, name={server.name}, status={server.status}") + print("========================") + + +def list_flavors(*, client: Gcore) -> List[GPUBaremetalFlavor]: + print("\n=== LIST GPU BAREMETAL FLAVORS ===") + flavors = client.cloud.gpu_baremetal.clusters.flavors.list() + _print_flavor_details(flavors.results) + print("========================") + return flavors.results + + +def list_images(*, client: Gcore) -> List[GPUImage]: + print("\n=== LIST GPU BAREMETAL IMAGES ===") + images = client.cloud.gpu_baremetal.clusters.images.list() + _print_image_details(images.results) + print("========================") + return images.results + + +def _print_flavor_details(flavors: List[GPUBaremetalFlavor]) -> None: + display_count = 3 + if len(flavors) < display_count: + display_count = len(flavors) + + for i in range(display_count): + flavor = flavors[i] + print(f" {i + 1}. Flavor: name={flavor.name}") + print(f" Capacity: {flavor.capacity}") + status = "AVAILABLE" + if flavor.disabled: + status = "DISABLED" + print(f" Status: {status}") + print() + + if len(flavors) > display_count: + print(f" ... and {len(flavors) - display_count} more flavors") + + +def _print_image_details(images: List[GPUImage]) -> None: + display_count = 3 + if len(images) < display_count: + display_count = len(images) + + for i in range(display_count): + img = images[i] + print(f" {i + 1}. Image ID: {img.id}, name: {img.name}, OS type: {img.os_type}, status: {img.status}") + + if len(images) > display_count: + print(f" ... and {len(images) - display_count} more images") + + +def _get_first_available_flavor(flavors: List[GPUBaremetalFlavor]) -> str: + available_flavors = [f for f in flavors if not f.disabled and f.capacity > 0] + if not available_flavors: + raise ValueError("No available flavors with capacity found") + selected = available_flavors[0] + print(f"Selected flavor: {selected.name} (Capacity: {selected.capacity})") + return selected.name + + +def _get_first_image(images: List[GPUImage]) -> str: + if not images: + raise ValueError("No images found") + selected = images[0] + print(f"Selected image: {selected.name} (ID: {selected.id})") + return selected.id + + +if __name__ == "__main__": + main() diff --git a/examples/cloud/gpu_baremetal_clusters_async.py b/examples/cloud/gpu_baremetal_clusters_async.py new file mode 100644 index 000000000..44b88c4c9 --- /dev/null +++ b/examples/cloud/gpu_baremetal_clusters_async.py @@ -0,0 +1,193 @@ +import asyncio +from typing import List + +from gcore import AsyncGcore +from gcore.types.cloud.gpu_image import GPUImage +from gcore.types.cloud.network_interface import NetworkInterface +from gcore.types.cloud.gpu_baremetal.cluster_create_params import ( + ServersSettings, + ServersSettingsInterfaceExternalInterfaceInputSerializer, +) +from gcore.types.cloud.gpu_baremetal.gpu_baremetal_cluster import GPUBaremetalCluster +from gcore.types.cloud.gpu_baremetal.clusters.gpu_baremetal_flavor import GPUBaremetalFlavor + + +async def main() -> None: + # TODO set API key before running + # api_key = os.environ["GCORE_API_KEY"] + # TODO set cloud project ID before running + # cloud_project_id = os.environ["GCORE_CLOUD_PROJECT_ID"] + # TODO set cloud region ID before running + # cloud_region_id = os.environ["GCORE_CLOUD_REGION_ID"] + + gcore = AsyncGcore( + # No need to explicitly pass to AsyncGcore constructor if using environment variables + # api_key=api_key, + # cloud_project_id=cloud_project_id, + # cloud_region_id=cloud_region_id, + ) + + # Flavors + flavors = await list_flavors(client=gcore) + + # Images + images = await list_images(client=gcore) + + # Clusters + flavor_name = _get_first_available_flavor(flavors) + image_id = _get_first_image(images) + cluster = await create_cluster(client=gcore, flavor=flavor_name, image_id=image_id) + await get_cluster(client=gcore, cluster_id=cluster.id) + await list_clusters(client=gcore) + await update_cluster(client=gcore, cluster_id=cluster.id) + + # Interfaces + await list_interfaces(client=gcore, cluster_id=cluster.id) + + # Servers + await list_servers(client=gcore, cluster_id=cluster.id) + + # Delete + await delete_cluster(client=gcore, cluster_id=cluster.id) + + +async def create_cluster(*, client: AsyncGcore, flavor: str, image_id: str) -> GPUBaremetalCluster: + print("\n=== CREATE GPU BAREMETAL CLUSTER ===") + cluster = await client.cloud.gpu_baremetal.clusters.create_and_poll( + name="gcore-python-example-gpu-baremetal", + flavor=flavor, + image_id=image_id, + servers_count=1, + servers_settings=ServersSettings( + interfaces=[ + ServersSettingsInterfaceExternalInterfaceInputSerializer(type="external"), + ], + ), + tags={"name": "gcore-python-example"}, + ) + print(f"Created cluster: ID={cluster.id}, name={cluster.name}, status={cluster.status}") + print("========================") + return cluster + + +async def get_cluster(*, client: AsyncGcore, cluster_id: str) -> GPUBaremetalCluster: + print("\n=== GET GPU BAREMETAL CLUSTER ===") + cluster = await client.cloud.gpu_baremetal.clusters.get(cluster_id=cluster_id) + print(f"Cluster: ID={cluster.id}, name={cluster.name}, status={cluster.status}") + print("========================") + return cluster + + +async def list_clusters(*, client: AsyncGcore) -> None: + print("\n=== LIST GPU BAREMETAL CLUSTERS ===") + clusters = await client.cloud.gpu_baremetal.clusters.list() + count = 0 + async for cluster in clusters: + count += 1 + print(f" {count}. Cluster: ID={cluster.id}, name={cluster.name}, status={cluster.status}") + print("========================") + + +async def update_cluster(*, client: AsyncGcore, cluster_id: str) -> None: + print("\n=== UPDATE GPU BAREMETAL CLUSTER ===") + cluster = await client.cloud.gpu_baremetal.clusters.update( + cluster_id=cluster_id, name="gcore-python-example-gpu-baremetal-updated" + ) + print(f"Updated cluster: ID={cluster.id}, name={cluster.name}") + print("========================") + + +async def delete_cluster(*, client: AsyncGcore, cluster_id: str) -> None: + print("\n=== DELETE GPU BAREMETAL CLUSTER ===") + await client.cloud.gpu_baremetal.clusters.delete_and_poll( + cluster_id=cluster_id, + all_floating_ips=True, + ) + print(f"Deleted cluster: ID={cluster_id}") + print("========================") + + +async def list_interfaces(*, client: AsyncGcore, cluster_id: str) -> List[NetworkInterface]: + print("\n=== LIST GPU BAREMETAL CLUSTER INTERFACES ===") + interfaces = await client.cloud.gpu_baremetal.clusters.interfaces.list(cluster_id=cluster_id) + for count, interface in enumerate(interfaces.results, 1): + print(f" {count}. Interface: PortID={interface.port_id}, NetworkID={interface.network_id}") + print("========================") + return interfaces.results + + +async def list_servers(*, client: AsyncGcore, cluster_id: str) -> None: + print("\n=== LIST GPU BAREMETAL CLUSTER SERVERS ===") + servers = await client.cloud.gpu_baremetal.clusters.servers.list(cluster_id=cluster_id) + for count, server in enumerate(servers.results, 1): + print(f" {count}. Server: ID={server.id}, name={server.name}, status={server.status}") + print("========================") + + +async def list_flavors(*, client: AsyncGcore) -> List[GPUBaremetalFlavor]: + print("\n=== LIST GPU BAREMETAL FLAVORS ===") + flavors = await client.cloud.gpu_baremetal.clusters.flavors.list() + _print_flavor_details(flavors.results) + print("========================") + return flavors.results + + +async def list_images(*, client: AsyncGcore) -> List[GPUImage]: + print("\n=== LIST GPU BAREMETAL IMAGES ===") + images = await client.cloud.gpu_baremetal.clusters.images.list() + _print_image_details(images.results) + print("========================") + return images.results + + +def _print_flavor_details(flavors: List[GPUBaremetalFlavor]) -> None: + display_count = 3 + if len(flavors) < display_count: + display_count = len(flavors) + + for i in range(display_count): + flavor = flavors[i] + print(f" {i + 1}. Flavor: name={flavor.name}") + print(f" Capacity: {flavor.capacity}") + status = "AVAILABLE" + if flavor.disabled: + status = "DISABLED" + print(f" Status: {status}") + print() + + if len(flavors) > display_count: + print(f" ... and {len(flavors) - display_count} more flavors") + + +def _print_image_details(images: List[GPUImage]) -> None: + display_count = 3 + if len(images) < display_count: + display_count = len(images) + + for i in range(display_count): + img = images[i] + print(f" {i + 1}. Image ID: {img.id}, name: {img.name}, OS type: {img.os_type}, status: {img.status}") + + if len(images) > display_count: + print(f" ... and {len(images) - display_count} more images") + + +def _get_first_available_flavor(flavors: List[GPUBaremetalFlavor]) -> str: + available_flavors = [f for f in flavors if not f.disabled and f.capacity > 0] + if not available_flavors: + raise ValueError("No available flavors with capacity found") + selected = available_flavors[0] + print(f"Selected flavor: {selected.name} (Capacity: {selected.capacity})") + return selected.name + + +def _get_first_image(images: List[GPUImage]) -> str: + if not images: + raise ValueError("No images found") + selected = images[0] + print(f"Selected image: {selected.name} (ID: {selected.id})") + return selected.id + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/cloud/gpu_virtual_clusters.py b/examples/cloud/gpu_virtual_clusters.py new file mode 100644 index 000000000..16a713d6f --- /dev/null +++ b/examples/cloud/gpu_virtual_clusters.py @@ -0,0 +1,188 @@ +from typing import List + +from gcore import Gcore +from gcore.types.cloud.gpu_image import GPUImage +from gcore.types.cloud.gpu_virtual.gpu_virtual_cluster import GPUVirtualCluster +from gcore.types.cloud.gpu_virtual.cluster_create_params import ( + ServersSettings, + ServersSettingsVolumeImageVolumeInputSerializer, + ServersSettingsInterfaceExternalInterfaceInputSerializer, +) +from gcore.types.cloud.gpu_virtual.clusters.gpu_virtual_flavor import GPUVirtualFlavor + + +def main() -> None: + # TODO set API key before running + # api_key = os.environ["GCORE_API_KEY"] + # TODO set cloud project ID before running + # cloud_project_id = os.environ["GCORE_CLOUD_PROJECT_ID"] + # TODO set cloud region ID before running + # cloud_region_id = os.environ["GCORE_CLOUD_REGION_ID"] + + gcore = Gcore( + # No need to explicitly pass to Gcore constructor if using environment variables + # api_key=api_key, + # cloud_project_id=cloud_project_id, + # cloud_region_id=cloud_region_id, + ) + + # Flavors + flavors = list_flavors(client=gcore) + + # Images + images = list_images(client=gcore) + + # Clusters + flavor_name = _get_first_available_flavor(flavors) + image_id = _get_first_image(images) + cluster = create_cluster(client=gcore, flavor=flavor_name, image_id=image_id) + get_cluster(client=gcore, cluster_id=cluster.id) + list_clusters(client=gcore) + update_cluster(client=gcore, cluster_id=cluster.id) + + # Servers + list_servers(client=gcore, cluster_id=cluster.id) + + # Delete + delete_cluster(client=gcore, cluster_id=cluster.id) + + +def create_cluster(*, client: Gcore, flavor: str, image_id: str) -> GPUVirtualCluster: + print("\n=== CREATE GPU VIRTUAL CLUSTER ===") + cluster = client.cloud.gpu_virtual.clusters.create_and_poll( + name="gcore-python-example-gpu-virtual", + flavor=flavor, + servers_count=1, + servers_settings=ServersSettings( + interfaces=[ + ServersSettingsInterfaceExternalInterfaceInputSerializer(type="external"), + ], + volumes=[ + ServersSettingsVolumeImageVolumeInputSerializer( + name="gcore-python-example-volume", + size=50, + type="standard", + source="image", + image_id=image_id, + boot_index=0, + ), + ], + ), + tags={"name": "gcore-python-example"}, + ) + print(f"Created cluster: ID={cluster.id}, name={cluster.name}, status={cluster.status}") + print("========================") + return cluster + + +def get_cluster(*, client: Gcore, cluster_id: str) -> GPUVirtualCluster: + print("\n=== GET GPU VIRTUAL CLUSTER ===") + cluster = client.cloud.gpu_virtual.clusters.get(cluster_id=cluster_id) + print(f"Cluster: ID={cluster.id}, name={cluster.name}, status={cluster.status}") + print("========================") + return cluster + + +def list_clusters(*, client: Gcore) -> None: + print("\n=== LIST GPU VIRTUAL CLUSTERS ===") + clusters = client.cloud.gpu_virtual.clusters.list() + for count, cluster in enumerate(clusters, 1): + print(f" {count}. Cluster: ID={cluster.id}, name={cluster.name}, status={cluster.status}") + print("========================") + + +def update_cluster(*, client: Gcore, cluster_id: str) -> None: + print("\n=== UPDATE GPU VIRTUAL CLUSTER ===") + cluster = client.cloud.gpu_virtual.clusters.update( + cluster_id=cluster_id, name="gcore-python-example-gpu-virtual-updated" + ) + print(f"Updated cluster: ID={cluster.id}, name={cluster.name}") + print("========================") + + +def delete_cluster(*, client: Gcore, cluster_id: str) -> None: + print("\n=== DELETE GPU VIRTUAL CLUSTER ===") + client.cloud.gpu_virtual.clusters.delete_and_poll( + cluster_id=cluster_id, + all_volumes=True, + all_floating_ips=True, + ) + print(f"Deleted cluster: ID={cluster_id}") + print("========================") + + +def list_servers(*, client: Gcore, cluster_id: str) -> None: + print("\n=== LIST GPU VIRTUAL CLUSTER SERVERS ===") + servers = client.cloud.gpu_virtual.clusters.servers.list(cluster_id=cluster_id) + for count, server in enumerate(servers.results, 1): + print(f" {count}. Server: ID={server.id}, name={server.name}, status={server.status}") + print("========================") + + +def list_flavors(*, client: Gcore) -> List[GPUVirtualFlavor]: + print("\n=== LIST GPU VIRTUAL FLAVORS ===") + flavors = client.cloud.gpu_virtual.clusters.flavors.list() + _print_flavor_details(flavors.results) + print("========================") + return flavors.results + + +def list_images(*, client: Gcore) -> List[GPUImage]: + print("\n=== LIST GPU VIRTUAL IMAGES ===") + images = client.cloud.gpu_virtual.clusters.images.list() + _print_image_details(images.results) + print("========================") + return images.results + + +def _print_flavor_details(flavors: List[GPUVirtualFlavor]) -> None: + display_count = 3 + if len(flavors) < display_count: + display_count = len(flavors) + + for i in range(display_count): + flavor = flavors[i] + print(f" {i + 1}. Flavor: name={flavor.name}") + print(f" Capacity: {flavor.capacity}") + status = "AVAILABLE" + if flavor.disabled: + status = "DISABLED" + print(f" Status: {status}") + print() + + if len(flavors) > display_count: + print(f" ... and {len(flavors) - display_count} more flavors") + + +def _print_image_details(images: List[GPUImage]) -> None: + display_count = 3 + if len(images) < display_count: + display_count = len(images) + + for i in range(display_count): + img = images[i] + print(f" {i + 1}. Image ID: {img.id}, name: {img.name}, OS type: {img.os_type}, status: {img.status}") + + if len(images) > display_count: + print(f" ... and {len(images) - display_count} more images") + + +def _get_first_available_flavor(flavors: List[GPUVirtualFlavor]) -> str: + available_flavors = [f for f in flavors if not f.disabled and f.capacity > 0] + if not available_flavors: + raise ValueError("No available flavors with capacity found") + selected = available_flavors[0] + print(f"Selected flavor: {selected.name} (Capacity: {selected.capacity})") + return selected.name + + +def _get_first_image(images: List[GPUImage]) -> str: + if not images: + raise ValueError("No images found") + selected = images[0] + print(f"Selected image: {selected.name} (ID: {selected.id})") + return selected.id + + +if __name__ == "__main__": + main() diff --git a/examples/cloud/gpu_virtual_clusters_async.py b/examples/cloud/gpu_virtual_clusters_async.py new file mode 100644 index 000000000..409d8d68c --- /dev/null +++ b/examples/cloud/gpu_virtual_clusters_async.py @@ -0,0 +1,191 @@ +import asyncio +from typing import List + +from gcore import AsyncGcore +from gcore.types.cloud.gpu_image import GPUImage +from gcore.types.cloud.gpu_virtual.gpu_virtual_cluster import GPUVirtualCluster +from gcore.types.cloud.gpu_virtual.cluster_create_params import ( + ServersSettings, + ServersSettingsVolumeImageVolumeInputSerializer, + ServersSettingsInterfaceExternalInterfaceInputSerializer, +) +from gcore.types.cloud.gpu_virtual.clusters.gpu_virtual_flavor import GPUVirtualFlavor + + +async def main() -> None: + # TODO set API key before running + # api_key = os.environ["GCORE_API_KEY"] + # TODO set cloud project ID before running + # cloud_project_id = os.environ["GCORE_CLOUD_PROJECT_ID"] + # TODO set cloud region ID before running + # cloud_region_id = os.environ["GCORE_CLOUD_REGION_ID"] + + gcore = AsyncGcore( + # No need to explicitly pass to AsyncGcore constructor if using environment variables + # api_key=api_key, + # cloud_project_id=cloud_project_id, + # cloud_region_id=cloud_region_id, + ) + + # Flavors + flavors = await list_flavors(client=gcore) + + # Images + images = await list_images(client=gcore) + + # Clusters + flavor_name = _get_first_available_flavor(flavors) + image_id = _get_first_image(images) + cluster = await create_cluster(client=gcore, flavor=flavor_name, image_id=image_id) + await get_cluster(client=gcore, cluster_id=cluster.id) + await list_clusters(client=gcore) + await update_cluster(client=gcore, cluster_id=cluster.id) + + # Servers + await list_servers(client=gcore, cluster_id=cluster.id) + + # Delete + await delete_cluster(client=gcore, cluster_id=cluster.id) + + +async def create_cluster(*, client: AsyncGcore, flavor: str, image_id: str) -> GPUVirtualCluster: + print("\n=== CREATE GPU VIRTUAL CLUSTER ===") + cluster = await client.cloud.gpu_virtual.clusters.create_and_poll( + name="gcore-python-example-gpu-virtual", + flavor=flavor, + servers_count=1, + servers_settings=ServersSettings( + interfaces=[ + ServersSettingsInterfaceExternalInterfaceInputSerializer(type="external"), + ], + volumes=[ + ServersSettingsVolumeImageVolumeInputSerializer( + name="gcore-python-example-volume", + size=50, + type="standard", + source="image", + image_id=image_id, + boot_index=0, + ), + ], + ), + tags={"name": "gcore-python-example"}, + ) + print(f"Created cluster: ID={cluster.id}, name={cluster.name}, status={cluster.status}") + print("========================") + return cluster + + +async def get_cluster(*, client: AsyncGcore, cluster_id: str) -> GPUVirtualCluster: + print("\n=== GET GPU VIRTUAL CLUSTER ===") + cluster = await client.cloud.gpu_virtual.clusters.get(cluster_id=cluster_id) + print(f"Cluster: ID={cluster.id}, name={cluster.name}, status={cluster.status}") + print("========================") + return cluster + + +async def list_clusters(*, client: AsyncGcore) -> None: + print("\n=== LIST GPU VIRTUAL CLUSTERS ===") + clusters = await client.cloud.gpu_virtual.clusters.list() + count = 0 + async for cluster in clusters: + count += 1 + print(f" {count}. Cluster: ID={cluster.id}, name={cluster.name}, status={cluster.status}") + print("========================") + + +async def update_cluster(*, client: AsyncGcore, cluster_id: str) -> None: + print("\n=== UPDATE GPU VIRTUAL CLUSTER ===") + cluster = await client.cloud.gpu_virtual.clusters.update( + cluster_id=cluster_id, name="gcore-python-example-gpu-virtual-updated" + ) + print(f"Updated cluster: ID={cluster.id}, name={cluster.name}") + print("========================") + + +async def delete_cluster(*, client: AsyncGcore, cluster_id: str) -> None: + print("\n=== DELETE GPU VIRTUAL CLUSTER ===") + await client.cloud.gpu_virtual.clusters.delete_and_poll( + cluster_id=cluster_id, + all_volumes=True, + all_floating_ips=True, + ) + print(f"Deleted cluster: ID={cluster_id}") + print("========================") + + +async def list_servers(*, client: AsyncGcore, cluster_id: str) -> None: + print("\n=== LIST GPU VIRTUAL CLUSTER SERVERS ===") + servers = await client.cloud.gpu_virtual.clusters.servers.list(cluster_id=cluster_id) + for count, server in enumerate(servers.results, 1): + print(f" {count}. Server: ID={server.id}, name={server.name}, status={server.status}") + print("========================") + + +async def list_flavors(*, client: AsyncGcore) -> List[GPUVirtualFlavor]: + print("\n=== LIST GPU VIRTUAL FLAVORS ===") + flavors = await client.cloud.gpu_virtual.clusters.flavors.list() + _print_flavor_details(flavors.results) + print("========================") + return flavors.results + + +async def list_images(*, client: AsyncGcore) -> List[GPUImage]: + print("\n=== LIST GPU VIRTUAL IMAGES ===") + images = await client.cloud.gpu_virtual.clusters.images.list() + _print_image_details(images.results) + print("========================") + return images.results + + +def _print_flavor_details(flavors: List[GPUVirtualFlavor]) -> None: + display_count = 3 + if len(flavors) < display_count: + display_count = len(flavors) + + for i in range(display_count): + flavor = flavors[i] + print(f" {i + 1}. Flavor: name={flavor.name}") + print(f" Capacity: {flavor.capacity}") + status = "AVAILABLE" + if flavor.disabled: + status = "DISABLED" + print(f" Status: {status}") + print() + + if len(flavors) > display_count: + print(f" ... and {len(flavors) - display_count} more flavors") + + +def _print_image_details(images: List[GPUImage]) -> None: + display_count = 3 + if len(images) < display_count: + display_count = len(images) + + for i in range(display_count): + img = images[i] + print(f" {i + 1}. Image ID: {img.id}, name: {img.name}, OS type: {img.os_type}, status: {img.status}") + + if len(images) > display_count: + print(f" ... and {len(images) - display_count} more images") + + +def _get_first_available_flavor(flavors: List[GPUVirtualFlavor]) -> str: + available_flavors = [f for f in flavors if not f.disabled and f.capacity > 0] + if not available_flavors: + raise ValueError("No available flavors with capacity found") + selected = available_flavors[0] + print(f"Selected flavor: {selected.name} (Capacity: {selected.capacity})") + return selected.name + + +def _get_first_image(images: List[GPUImage]) -> str: + if not images: + raise ValueError("No images found") + selected = images[0] + print(f"Selected image: {selected.name} (ID: {selected.id})") + return selected.id + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/pyproject.toml b/pyproject.toml index 5f2b6b358..5002951b4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "gcore" -version = "0.41.0" +version = "0.42.0" description = "The official Python library for the gcore API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/gcore/_base_client.py b/src/gcore/_base_client.py index e797b152c..e3e40a425 100644 --- a/src/gcore/_base_client.py +++ b/src/gcore/_base_client.py @@ -540,6 +540,10 @@ def _build_request( files = cast(HttpxRequestFiles, ForceMultipartDict()) prepared_url = self._prepare_url(options.url) + # preserve hard-coded query params from the url + if params and prepared_url.query: + params = {**dict(prepared_url.params.items()), **params} + prepared_url = prepared_url.copy_with(raw_path=prepared_url.raw_path.split(b"?", 1)[0]) if "_" in prepared_url.host: # work around https://github.com/encode/httpx/discussions/2880 kwargs["extensions"] = {"sni_hostname": prepared_url.host.replace("_", "-")} diff --git a/src/gcore/_utils/_utils.py b/src/gcore/_utils/_utils.py index eec7f4a1f..63b8cd602 100644 --- a/src/gcore/_utils/_utils.py +++ b/src/gcore/_utils/_utils.py @@ -86,8 +86,9 @@ def _extract_items( index += 1 if is_dict(obj): try: - # We are at the last entry in the path so we must remove the field - if (len(path)) == index: + # Remove the field if there are no more dict keys in the path, + # only "" traversal markers or end. + if all(p == "" for p in path[index:]): item = obj.pop(key) else: item = obj[key] diff --git a/src/gcore/_version.py b/src/gcore/_version.py index 139c4ad2f..b88cfcf03 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.41.0" # x-release-please-version +__version__ = "0.42.0" # x-release-please-version diff --git a/src/gcore/resources/cdn/api.md b/src/gcore/resources/cdn/api.md index 70a857738..002855e7a 100644 --- a/src/gcore/resources/cdn/api.md +++ b/src/gcore/resources/cdn/api.md @@ -69,7 +69,7 @@ Methods: - client.cdn.cdn_resources.rules.create(resource_id, \*\*params) -> CDNResourceRule - client.cdn.cdn_resources.rules.update(rule_id, \*, resource_id, \*\*params) -> CDNResourceRule -- client.cdn.cdn_resources.rules.list(resource_id, \*\*params) -> SyncOffsetPage[CDNResourceRule] +- client.cdn.cdn_resources.rules.list(resource_id, \*\*params) -> CDNResourceRuleList - client.cdn.cdn_resources.rules.delete(rule_id, \*, resource_id) -> None - client.cdn.cdn_resources.rules.get(rule_id, \*, resource_id) -> CDNResourceRule - client.cdn.cdn_resources.rules.replace(rule_id, \*, resource_id, \*\*params) -> CDNResourceRule @@ -84,7 +84,7 @@ from gcore.types.cdn import ShieldListResponse Methods: -- client.cdn.shields.list(\*\*params) -> SyncOffsetPage[ShieldListResponse] +- client.cdn.shields.list(\*\*params) -> ShieldListResponse ## OriginGroups @@ -115,7 +115,7 @@ Methods: - client.cdn.rule_templates.create(\*\*params) -> RuleTemplate - client.cdn.rule_templates.update(rule_template_id, \*\*params) -> RuleTemplate -- client.cdn.rule_templates.list(\*\*params) -> SyncOffsetPage[RuleTemplate] +- client.cdn.rule_templates.list(\*\*params) -> RuleTemplateList - client.cdn.rule_templates.delete(rule_template_id) -> None - client.cdn.rule_templates.get(rule_template_id) -> RuleTemplate - client.cdn.rule_templates.replace(rule_template_id, \*\*params) -> RuleTemplate diff --git a/src/gcore/resources/cdn/cdn_resources/rules.py b/src/gcore/resources/cdn/cdn_resources/rules.py index 2fabd405e..bb3ae8ed6 100644 --- a/src/gcore/resources/cdn/cdn_resources/rules.py +++ b/src/gcore/resources/cdn/cdn_resources/rules.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Optional +from typing import Any, Optional, cast from typing_extensions import Literal import httpx @@ -17,10 +17,10 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) -from ....pagination import SyncOffsetPage, AsyncOffsetPage -from ...._base_client import AsyncPaginator, make_request_options +from ...._base_client import make_request_options from ....types.cdn.cdn_resources import rule_list_params, rule_create_params, rule_update_params, rule_replace_params from ....types.cdn.cdn_resources.cdn_resource_rule import CDNResourceRule +from ....types.cdn.cdn_resources.cdn_resource_rule_list import CDNResourceRuleList __all__ = ["RulesResource", "AsyncRulesResource"] @@ -272,7 +272,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncOffsetPage[CDNResourceRule]: + ) -> CDNResourceRuleList: """Get rules list Args: @@ -290,23 +290,27 @@ def list( timeout: Override the client-level default timeout for this request, in seconds """ - return self._get_api_list( - path_template("/cdn/resources/{resource_id}/rules", resource_id=resource_id), - page=SyncOffsetPage[CDNResourceRule], - 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, - }, - rule_list_params.RuleListParams, + return cast( + CDNResourceRuleList, + self._get( + path_template("/cdn/resources/{resource_id}/rules", resource_id=resource_id), + 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, + }, + rule_list_params.RuleListParams, + ), ), + cast_to=cast( + Any, CDNResourceRuleList + ), # Union types cannot be passed in as arguments in the type system ), - model=CDNResourceRule, ) def delete( @@ -723,7 +727,7 @@ async def update( cast_to=CDNResourceRule, ) - def list( + async def list( self, resource_id: int, *, @@ -735,7 +739,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[CDNResourceRule, AsyncOffsetPage[CDNResourceRule]]: + ) -> CDNResourceRuleList: """Get rules list Args: @@ -753,23 +757,27 @@ def list( timeout: Override the client-level default timeout for this request, in seconds """ - return self._get_api_list( - path_template("/cdn/resources/{resource_id}/rules", resource_id=resource_id), - page=AsyncOffsetPage[CDNResourceRule], - 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, - }, - rule_list_params.RuleListParams, + return cast( + CDNResourceRuleList, + await self._get( + path_template("/cdn/resources/{resource_id}/rules", resource_id=resource_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "limit": limit, + "offset": offset, + }, + rule_list_params.RuleListParams, + ), ), + cast_to=cast( + Any, CDNResourceRuleList + ), # Union types cannot be passed in as arguments in the type system ), - model=CDNResourceRule, ) async def delete( diff --git a/src/gcore/resources/cdn/origin_groups.py b/src/gcore/resources/cdn/origin_groups.py index 01a4a9192..d3ba0dbbc 100644 --- a/src/gcore/resources/cdn/origin_groups.py +++ b/src/gcore/resources/cdn/origin_groups.py @@ -76,7 +76,9 @@ def create( Args: name: Origin group name. - auth_type: Origin authentication type. + auth_type: **Deprecated.** No longer necessary. Defaults to `none`. + + Origin authentication type. Possible values: @@ -139,9 +141,15 @@ def create( Create an origin group with one or more origin sources. Args: - auth: Credentials to access the private bucket. + auth: **Deprecated.** To create S3 origins, configure them directly in sources with + `origin_type` and `config` instead. + + Credentials to access the private bucket. + + auth_type: **Deprecated.** To create S3 origins, configure them directly in sources with + `origin_type` and `config` instead. - auth_type: Authentication type. + Authentication type. **awsSignatureV4** value is used for S3 storage. @@ -246,14 +254,19 @@ def update( Args: name: Origin group name. - auth_type: Origin authentication type. + auth_type: **Deprecated.** No longer necessary. Defaults to `none`. + + Origin authentication type. Possible values: - **none** - Used for public origins. - **awsSignatureV4** - Used for S3 storage. - path: Parameter is **deprecated**. + path: **Deprecated.** No longer necessary. Omit this field and the default origin path + behavior will be used. + + Origin path prefix. proxy_next_upstream: Defines cases when the request should be passed on to the next origin. @@ -313,15 +326,24 @@ def update( Change origin group Args: - auth: Credentials to access the private bucket. + auth: **Deprecated.** To create S3 origins, configure them directly in sources with + `origin_type` and `config` instead. - auth_type: Authentication type. + Credentials to access the private bucket. + + auth_type: **Deprecated.** To create S3 origins, configure them directly in sources with + `origin_type` and `config` instead. + + Authentication type. **awsSignatureV4** value is used for S3 storage. name: Origin group name. - path: Parameter is **deprecated**. + path: **Deprecated.** No longer necessary. Omit this field and the default origin path + behavior will be used. + + Origin path prefix. proxy_next_upstream: Defines cases when the request should be passed on to the next origin. @@ -537,11 +559,11 @@ def replace( self, origin_group_id: int, *, - auth_type: str, name: str, - path: str, sources: Iterable[origin_group_replace_params.NoneAuthSource], use_next: bool, + auth_type: str | Omit = omit, + path: str | Omit = omit, proxy_next_upstream: SequenceNotStr[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. @@ -554,17 +576,8 @@ def replace( Change origin group Args: - auth_type: Origin authentication type. - - Possible values: - - - **none** - Used for public origins. - - **awsSignatureV4** - Used for S3 storage. - name: Origin group name. - path: Parameter is **deprecated**. - use_next: Defines whether to use the next origin from the origin group if origin responds with the cases specified in `proxy_next_upstream`. If you enable it, you must specify cases in `proxy_next_upstream`. @@ -574,6 +587,20 @@ def replace( - **true** - Option is enabled. - **false** - Option is disabled. + auth_type: **Deprecated.** No longer necessary. Defaults to `none`. + + Origin authentication type. + + Possible values: + + - **none** - Used for public origins. + - **awsSignatureV4** - Used for S3 storage. + + path: **Deprecated.** No longer necessary. Omit this field and the default origin path + behavior will be used. + + Origin path prefix. + proxy_next_upstream: Defines cases when the request should be passed on to the next origin. Possible values: @@ -609,8 +636,8 @@ def replace( auth: origin_group_replace_params.AwsSignatureV4Auth, auth_type: str, name: str, - path: str, use_next: bool, + path: str | Omit = omit, proxy_next_upstream: SequenceNotStr[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. @@ -623,16 +650,20 @@ def replace( Change origin group Args: - auth: Credentials to access the private bucket. + auth: **Deprecated.** To create S3 origins, configure them directly in sources with + `origin_type` and `config` instead. + + Credentials to access the private bucket. + + auth_type: **Deprecated.** To create S3 origins, configure them directly in sources with + `origin_type` and `config` instead. - auth_type: Authentication type. + Authentication type. **awsSignatureV4** value is used for S3 storage. name: Origin group name. - path: Parameter is **deprecated**. - use_next: Defines whether to use the next origin from the origin group if origin responds with the cases specified in `proxy_next_upstream`. If you enable it, you must specify cases in `proxy_next_upstream`. @@ -642,6 +673,11 @@ def replace( - **true** - Option is enabled. - **false** - Option is disabled. + path: **Deprecated.** No longer necessary. Omit this field and the default origin path + behavior will be used. + + Origin path prefix. + proxy_next_upstream: Defines cases when the request should be passed on to the next origin. Possible values: @@ -669,18 +705,16 @@ def replace( """ ... - @required_args( - ["auth_type", "name", "path", "sources", "use_next"], ["auth", "auth_type", "name", "path", "use_next"] - ) + @required_args(["name", "sources", "use_next"], ["auth", "auth_type", "name", "use_next"]) def replace( self, origin_group_id: int, *, - auth_type: str, name: str, - path: str, sources: Iterable[origin_group_replace_params.NoneAuthSource] | Omit = omit, use_next: bool, + auth_type: str | Omit = omit, + path: str | Omit = omit, proxy_next_upstream: SequenceNotStr[str] | Omit = omit, auth: origin_group_replace_params.AwsSignatureV4Auth | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -696,11 +730,11 @@ def replace( path_template("/cdn/origin_groups/{origin_group_id}", origin_group_id=origin_group_id), body=maybe_transform( { - "auth_type": auth_type, "name": name, - "path": path, "sources": sources, "use_next": use_next, + "auth_type": auth_type, + "path": path, "proxy_next_upstream": proxy_next_upstream, "auth": auth, }, @@ -760,7 +794,9 @@ async def create( Args: name: Origin group name. - auth_type: Origin authentication type. + auth_type: **Deprecated.** No longer necessary. Defaults to `none`. + + Origin authentication type. Possible values: @@ -823,9 +859,15 @@ async def create( Create an origin group with one or more origin sources. Args: - auth: Credentials to access the private bucket. + auth: **Deprecated.** To create S3 origins, configure them directly in sources with + `origin_type` and `config` instead. + + Credentials to access the private bucket. + + auth_type: **Deprecated.** To create S3 origins, configure them directly in sources with + `origin_type` and `config` instead. - auth_type: Authentication type. + Authentication type. **awsSignatureV4** value is used for S3 storage. @@ -930,14 +972,19 @@ async def update( Args: name: Origin group name. - auth_type: Origin authentication type. + auth_type: **Deprecated.** No longer necessary. Defaults to `none`. + + Origin authentication type. Possible values: - **none** - Used for public origins. - **awsSignatureV4** - Used for S3 storage. - path: Parameter is **deprecated**. + path: **Deprecated.** No longer necessary. Omit this field and the default origin path + behavior will be used. + + Origin path prefix. proxy_next_upstream: Defines cases when the request should be passed on to the next origin. @@ -997,15 +1044,24 @@ async def update( Change origin group Args: - auth: Credentials to access the private bucket. + auth: **Deprecated.** To create S3 origins, configure them directly in sources with + `origin_type` and `config` instead. - auth_type: Authentication type. + Credentials to access the private bucket. + + auth_type: **Deprecated.** To create S3 origins, configure them directly in sources with + `origin_type` and `config` instead. + + Authentication type. **awsSignatureV4** value is used for S3 storage. name: Origin group name. - path: Parameter is **deprecated**. + path: **Deprecated.** No longer necessary. Omit this field and the default origin path + behavior will be used. + + Origin path prefix. proxy_next_upstream: Defines cases when the request should be passed on to the next origin. @@ -1221,11 +1277,11 @@ async def replace( self, origin_group_id: int, *, - auth_type: str, name: str, - path: str, sources: Iterable[origin_group_replace_params.NoneAuthSource], use_next: bool, + auth_type: str | Omit = omit, + path: str | Omit = omit, proxy_next_upstream: SequenceNotStr[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. @@ -1238,17 +1294,8 @@ async def replace( Change origin group Args: - auth_type: Origin authentication type. - - Possible values: - - - **none** - Used for public origins. - - **awsSignatureV4** - Used for S3 storage. - name: Origin group name. - path: Parameter is **deprecated**. - use_next: Defines whether to use the next origin from the origin group if origin responds with the cases specified in `proxy_next_upstream`. If you enable it, you must specify cases in `proxy_next_upstream`. @@ -1258,6 +1305,20 @@ async def replace( - **true** - Option is enabled. - **false** - Option is disabled. + auth_type: **Deprecated.** No longer necessary. Defaults to `none`. + + Origin authentication type. + + Possible values: + + - **none** - Used for public origins. + - **awsSignatureV4** - Used for S3 storage. + + path: **Deprecated.** No longer necessary. Omit this field and the default origin path + behavior will be used. + + Origin path prefix. + proxy_next_upstream: Defines cases when the request should be passed on to the next origin. Possible values: @@ -1293,8 +1354,8 @@ async def replace( auth: origin_group_replace_params.AwsSignatureV4Auth, auth_type: str, name: str, - path: str, use_next: bool, + path: str | Omit = omit, proxy_next_upstream: SequenceNotStr[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. @@ -1307,16 +1368,20 @@ async def replace( Change origin group Args: - auth: Credentials to access the private bucket. + auth: **Deprecated.** To create S3 origins, configure them directly in sources with + `origin_type` and `config` instead. + + Credentials to access the private bucket. + + auth_type: **Deprecated.** To create S3 origins, configure them directly in sources with + `origin_type` and `config` instead. - auth_type: Authentication type. + Authentication type. **awsSignatureV4** value is used for S3 storage. name: Origin group name. - path: Parameter is **deprecated**. - use_next: Defines whether to use the next origin from the origin group if origin responds with the cases specified in `proxy_next_upstream`. If you enable it, you must specify cases in `proxy_next_upstream`. @@ -1326,6 +1391,11 @@ async def replace( - **true** - Option is enabled. - **false** - Option is disabled. + path: **Deprecated.** No longer necessary. Omit this field and the default origin path + behavior will be used. + + Origin path prefix. + proxy_next_upstream: Defines cases when the request should be passed on to the next origin. Possible values: @@ -1353,18 +1423,16 @@ async def replace( """ ... - @required_args( - ["auth_type", "name", "path", "sources", "use_next"], ["auth", "auth_type", "name", "path", "use_next"] - ) + @required_args(["name", "sources", "use_next"], ["auth", "auth_type", "name", "use_next"]) async def replace( self, origin_group_id: int, *, - auth_type: str, name: str, - path: str, sources: Iterable[origin_group_replace_params.NoneAuthSource] | Omit = omit, use_next: bool, + auth_type: str | Omit = omit, + path: str | Omit = omit, proxy_next_upstream: SequenceNotStr[str] | Omit = omit, auth: origin_group_replace_params.AwsSignatureV4Auth | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -1380,11 +1448,11 @@ async def replace( path_template("/cdn/origin_groups/{origin_group_id}", origin_group_id=origin_group_id), body=await async_maybe_transform( { - "auth_type": auth_type, "name": name, - "path": path, "sources": sources, "use_next": use_next, + "auth_type": auth_type, + "path": path, "proxy_next_upstream": proxy_next_upstream, "auth": auth, }, diff --git a/src/gcore/resources/cdn/rule_templates.py b/src/gcore/resources/cdn/rule_templates.py index 7080e0404..86f670b38 100644 --- a/src/gcore/resources/cdn/rule_templates.py +++ b/src/gcore/resources/cdn/rule_templates.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Optional +from typing import Any, Optional, cast from typing_extensions import Literal import httpx @@ -23,9 +23,9 @@ rule_template_update_params, rule_template_replace_params, ) -from ...pagination import SyncOffsetPage, AsyncOffsetPage -from ..._base_client import AsyncPaginator, make_request_options +from ..._base_client import make_request_options from ...types.cdn.rule_template import RuleTemplate +from ...types.cdn.rule_template_list import RuleTemplateList __all__ = ["RuleTemplatesResource", "AsyncRuleTemplatesResource"] @@ -242,7 +242,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncOffsetPage[RuleTemplate]: + ) -> RuleTemplateList: """ Get rule templates list @@ -259,23 +259,25 @@ def list( timeout: Override the client-level default timeout for this request, in seconds """ - return self._get_api_list( - "/cdn/resources/rule_templates", - page=SyncOffsetPage[RuleTemplate], - 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, - }, - rule_template_list_params.RuleTemplateListParams, + return cast( + RuleTemplateList, + self._get( + "/cdn/resources/rule_templates", + 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, + }, + rule_template_list_params.RuleTemplateListParams, + ), ), + cast_to=cast(Any, RuleTemplateList), # Union types cannot be passed in as arguments in the type system ), - model=RuleTemplate, ) def delete( @@ -632,7 +634,7 @@ async def update( cast_to=RuleTemplate, ) - def list( + async def list( self, *, limit: int | Omit = omit, @@ -643,7 +645,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[RuleTemplate, AsyncOffsetPage[RuleTemplate]]: + ) -> RuleTemplateList: """ Get rule templates list @@ -660,23 +662,25 @@ def list( timeout: Override the client-level default timeout for this request, in seconds """ - return self._get_api_list( - "/cdn/resources/rule_templates", - page=AsyncOffsetPage[RuleTemplate], - 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, - }, - rule_template_list_params.RuleTemplateListParams, + return cast( + RuleTemplateList, + await self._get( + "/cdn/resources/rule_templates", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "limit": limit, + "offset": offset, + }, + rule_template_list_params.RuleTemplateListParams, + ), ), + cast_to=cast(Any, RuleTemplateList), # Union types cannot be passed in as arguments in the type system ), - model=RuleTemplate, ) async def delete( diff --git a/src/gcore/resources/cdn/shields.py b/src/gcore/resources/cdn/shields.py index 8eb3ed5f9..51807bf05 100644 --- a/src/gcore/resources/cdn/shields.py +++ b/src/gcore/resources/cdn/shields.py @@ -2,10 +2,12 @@ from __future__ import annotations +from typing import Any, cast + import httpx from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ..._utils import maybe_transform +from ..._utils import maybe_transform, async_maybe_transform from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import ( @@ -15,8 +17,7 @@ async_to_streamed_response_wrapper, ) from ...types.cdn import shield_list_params -from ...pagination import SyncOffsetPage, AsyncOffsetPage -from ..._base_client import AsyncPaginator, make_request_options +from ..._base_client import make_request_options from ...types.cdn.shield_list_response import ShieldListResponse __all__ = ["ShieldsResource", "AsyncShieldsResource"] @@ -53,7 +54,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncOffsetPage[ShieldListResponse]: + ) -> ShieldListResponse: """ Get information about all origin shielding locations available in the account. @@ -70,23 +71,27 @@ def list( timeout: Override the client-level default timeout for this request, in seconds """ - return self._get_api_list( - "/cdn/shieldingpop_v2", - page=SyncOffsetPage[ShieldListResponse], - 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, - }, - shield_list_params.ShieldListParams, + return cast( + ShieldListResponse, + self._get( + "/cdn/shieldingpop_v2", + 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, + }, + shield_list_params.ShieldListParams, + ), ), + cast_to=cast( + Any, ShieldListResponse + ), # Union types cannot be passed in as arguments in the type system ), - model=ShieldListResponse, ) @@ -110,7 +115,7 @@ def with_streaming_response(self) -> AsyncShieldsResourceWithStreamingResponse: """ return AsyncShieldsResourceWithStreamingResponse(self) - def list( + async def list( self, *, limit: int | Omit = omit, @@ -121,7 +126,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[ShieldListResponse, AsyncOffsetPage[ShieldListResponse]]: + ) -> ShieldListResponse: """ Get information about all origin shielding locations available in the account. @@ -138,23 +143,27 @@ def list( timeout: Override the client-level default timeout for this request, in seconds """ - return self._get_api_list( - "/cdn/shieldingpop_v2", - page=AsyncOffsetPage[ShieldListResponse], - 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, - }, - shield_list_params.ShieldListParams, + return cast( + ShieldListResponse, + await self._get( + "/cdn/shieldingpop_v2", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "limit": limit, + "offset": offset, + }, + shield_list_params.ShieldListParams, + ), ), + cast_to=cast( + Any, ShieldListResponse + ), # Union types cannot be passed in as arguments in the type system ), - model=ShieldListResponse, ) diff --git a/src/gcore/resources/cloud/api.md b/src/gcore/resources/cloud/api.md index fb309d36c..bfdb6c927 100644 --- a/src/gcore/resources/cloud/api.md +++ b/src/gcore/resources/cloud/api.md @@ -24,8 +24,6 @@ from gcore.types.cloud import ( GPUImage, GPUImageList, HTTPMethod, - Image, - ImageList, Instance, InstanceIsolation, InstanceList, @@ -237,7 +235,7 @@ Methods: - client.cloud.load_balancers.l7_policies.create(\*, project_id, region_id, \*\*params) -> TaskIDList - client.cloud.load_balancers.l7_policies.update(l7policy_id, \*, project_id, region_id, \*\*params) -> TaskIDList -- client.cloud.load_balancers.l7_policies.list(\*, project_id, region_id) -> LoadBalancerL7PolicyList +- client.cloud.load_balancers.l7_policies.list(\*, project_id, region_id, \*\*params) -> LoadBalancerL7PolicyList - client.cloud.load_balancers.l7_policies.delete(l7policy_id, \*, project_id, region_id) -> TaskIDList - client.cloud.load_balancers.l7_policies.get(l7policy_id, \*, project_id, region_id) -> LoadBalancerL7Policy @@ -246,7 +244,7 @@ Methods: Methods: - client.cloud.load_balancers.l7_policies.rules.create(l7policy_id, \*, project_id, region_id, \*\*params) -> TaskIDList -- client.cloud.load_balancers.l7_policies.rules.list(l7policy_id, \*, project_id, region_id) -> LoadBalancerL7RuleList +- client.cloud.load_balancers.l7_policies.rules.list(l7policy_id, \*, project_id, region_id, \*\*params) -> LoadBalancerL7RuleList - client.cloud.load_balancers.l7_policies.rules.delete(l7rule_id, \*, project_id, region_id, l7policy_id) -> TaskIDList - client.cloud.load_balancers.l7_policies.rules.get(l7rule_id, \*, project_id, region_id, l7policy_id) -> LoadBalancerL7Rule - client.cloud.load_balancers.l7_policies.rules.replace(l7rule_id, \*, project_id, region_id, l7policy_id, \*\*params) -> TaskIDList @@ -526,7 +524,6 @@ Methods: - client.cloud.inference.deployments.list(\*, project_id, \*\*params) -> SyncOffsetPage[InferenceDeployment] - client.cloud.inference.deployments.delete(deployment_name, \*, project_id) -> TaskIDList - client.cloud.inference.deployments.get(deployment_name, \*, project_id) -> InferenceDeployment -- client.cloud.inference.deployments.get_api_key(deployment_name, \*, project_id) -> InferenceDeploymentAPIKey - client.cloud.inference.deployments.start(deployment_name, \*, project_id) -> None - client.cloud.inference.deployments.stop(deployment_name, \*, project_id) -> None @@ -646,9 +643,15 @@ Methods: ### Images +Types: + +```python +from gcore.types.cloud.baremetal import BaremetalImage, BaremetalImageList +``` + Methods: -- client.cloud.baremetal.images.list(\*, project_id, region_id, \*\*params) -> ImageList +- client.cloud.baremetal.images.list(\*, project_id, region_id, \*\*params) -> BaremetalImageList ### Flavors @@ -993,13 +996,19 @@ Methods: ### Images +Types: + +```python +from gcore.types.cloud.instances import Image, ImageList +``` + Methods: -- client.cloud.instances.images.update(image_id, \*, project_id, region_id, \*\*params) -> Image -- client.cloud.instances.images.list(\*, project_id, region_id, \*\*params) -> ImageList +- client.cloud.instances.images.update(image_id, \*, project_id, region_id, \*\*params) -> Image +- client.cloud.instances.images.list(\*, project_id, region_id, \*\*params) -> ImageList - client.cloud.instances.images.delete(image_id, \*, project_id, region_id) -> TaskIDList - client.cloud.instances.images.create_from_volume(\*, project_id, region_id, \*\*params) -> TaskIDList -- client.cloud.instances.images.get(image_id, \*, project_id, region_id, \*\*params) -> Image +- client.cloud.instances.images.get(image_id, \*, project_id, region_id, \*\*params) -> Image - client.cloud.instances.images.upload(\*, project_id, region_id, \*\*params) -> TaskIDList ### Metrics diff --git a/src/gcore/resources/cloud/baremetal/images.py b/src/gcore/resources/cloud/baremetal/images.py index cbd700b51..6cfd73023 100644 --- a/src/gcore/resources/cloud/baremetal/images.py +++ b/src/gcore/resources/cloud/baremetal/images.py @@ -18,7 +18,7 @@ ) from ...._base_client import make_request_options from ....types.cloud.baremetal import image_list_params -from ....types.cloud.image_list import ImageList +from ....types.cloud.baremetal.baremetal_image_list import BaremetalImageList __all__ = ["ImagesResource", "AsyncImagesResource"] @@ -59,7 +59,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> ImageList: + ) -> BaremetalImageList: """Retrieve a list of available images for bare metal servers. The list can be @@ -67,13 +67,17 @@ def list( not be owned by the project. Args: - include_prices: Show price + project_id: Project ID + + region_id: Region ID + + include_prices: Show price. private: Any value to show private images - tag_key: Filter by tag keys. + tag_key: Optional. Filter by tag keys. ?`tag_key`=key1&`tag_key`=key2 - tag_key_value: Filter by tag key-value pairs. Must be a valid JSON string. + tag_key_value: Optional. Filter by tag key-value pairs. visibility: Image visibility. Globally visible images are public @@ -107,7 +111,7 @@ def list( image_list_params.ImageListParams, ), ), - cast_to=ImageList, + cast_to=BaremetalImageList, ) @@ -147,7 +151,7 @@ async def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> ImageList: + ) -> BaremetalImageList: """Retrieve a list of available images for bare metal servers. The list can be @@ -155,13 +159,17 @@ async def list( not be owned by the project. Args: - include_prices: Show price + project_id: Project ID + + region_id: Region ID + + include_prices: Show price. private: Any value to show private images - tag_key: Filter by tag keys. + tag_key: Optional. Filter by tag keys. ?`tag_key`=key1&`tag_key`=key2 - tag_key_value: Filter by tag key-value pairs. Must be a valid JSON string. + tag_key_value: Optional. Filter by tag key-value pairs. visibility: Image visibility. Globally visible images are public @@ -195,7 +203,7 @@ async def list( image_list_params.ImageListParams, ), ), - cast_to=ImageList, + cast_to=BaremetalImageList, ) diff --git a/src/gcore/resources/cloud/gpu_baremetal/clusters/clusters.py b/src/gcore/resources/cloud/gpu_baremetal/clusters/clusters.py index cfd9a4a15..74a1b4a27 100644 --- a/src/gcore/resources/cloud/gpu_baremetal/clusters/clusters.py +++ b/src/gcore/resources/cloud/gpu_baremetal/clusters/clusters.py @@ -885,6 +885,52 @@ def resize_and_poll( timeout=timeout, ) + def delete_and_poll( + self, + cluster_id: str, + *, + project_id: int | None = None, + region_id: int | None = None, + all_floating_ips: bool | Omit = omit, + all_reserved_fixed_ips: bool | Omit = omit, + floating_ip_ids: SequenceNotStr[str] | Omit = omit, + reserved_fixed_ip_ids: SequenceNotStr[str] | Omit = omit, + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: 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, + ) -> None: + """ + Delete a bare metal GPU cluster and poll for the result. Only the first task will be polled. If you need to poll more tasks, use the `tasks.poll` method. + """ + response = self.delete( + cluster_id=cluster_id, + project_id=project_id, + region_id=region_id, + all_floating_ips=all_floating_ips, + all_reserved_fixed_ips=all_reserved_fixed_ips, + floating_ip_ids=floating_ip_ids, + reserved_fixed_ip_ids=reserved_fixed_ip_ids, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ) + if not response.tasks or len(response.tasks) < 1: + raise ValueError("Expected at least one task to be created") + self._client.cloud.tasks.poll( + response.tasks[0], + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + polling_interval_seconds=polling_interval_seconds, + polling_timeout_seconds=polling_timeout_seconds, + ) + class AsyncClustersResource(AsyncAPIResource): @cached_property @@ -1705,6 +1751,52 @@ async def resize_and_poll( timeout=timeout, ) + async def delete_and_poll( + self, + cluster_id: str, + *, + project_id: int | None = None, + region_id: int | None = None, + all_floating_ips: bool | Omit = omit, + all_reserved_fixed_ips: bool | Omit = omit, + floating_ip_ids: SequenceNotStr[str] | Omit = omit, + reserved_fixed_ip_ids: SequenceNotStr[str] | Omit = omit, + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: 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, + ) -> None: + """ + Delete a bare metal GPU cluster and poll for the result. Only the first task will be polled. If you need to poll more tasks, use the `tasks.poll` method. + """ + response = await self.delete( + cluster_id=cluster_id, + project_id=project_id, + region_id=region_id, + all_floating_ips=all_floating_ips, + all_reserved_fixed_ips=all_reserved_fixed_ips, + floating_ip_ids=floating_ip_ids, + reserved_fixed_ip_ids=reserved_fixed_ip_ids, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ) + if not response.tasks or len(response.tasks) < 1: + raise ValueError("Expected at least one task to be created") + await self._client.cloud.tasks.poll( + response.tasks[0], + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + polling_interval_seconds=polling_interval_seconds, + polling_timeout_seconds=polling_timeout_seconds, + ) + class ClustersResourceWithRawResponse: def __init__(self, clusters: ClustersResource) -> None: @@ -1753,6 +1845,9 @@ def __init__(self, clusters: ClustersResource) -> None: self.resize_and_poll = to_raw_response_wrapper( clusters.resize_and_poll, ) + self.delete_and_poll = to_raw_response_wrapper( + clusters.delete_and_poll, + ) @cached_property def interfaces(self) -> InterfacesResourceWithRawResponse: @@ -1819,6 +1914,9 @@ def __init__(self, clusters: AsyncClustersResource) -> None: self.resize_and_poll = async_to_raw_response_wrapper( clusters.resize_and_poll, ) + self.delete_and_poll = async_to_raw_response_wrapper( + clusters.delete_and_poll, + ) @cached_property def interfaces(self) -> AsyncInterfacesResourceWithRawResponse: @@ -1885,6 +1983,9 @@ def __init__(self, clusters: ClustersResource) -> None: self.resize_and_poll = to_streamed_response_wrapper( clusters.resize_and_poll, ) + self.delete_and_poll = to_streamed_response_wrapper( + clusters.delete_and_poll, + ) @cached_property def interfaces(self) -> InterfacesResourceWithStreamingResponse: @@ -1951,6 +2052,9 @@ def __init__(self, clusters: AsyncClustersResource) -> None: self.resize_and_poll = async_to_streamed_response_wrapper( clusters.resize_and_poll, ) + self.delete_and_poll = async_to_streamed_response_wrapper( + clusters.delete_and_poll, + ) @cached_property def interfaces(self) -> AsyncInterfacesResourceWithStreamingResponse: diff --git a/src/gcore/resources/cloud/gpu_virtual/clusters/clusters.py b/src/gcore/resources/cloud/gpu_virtual/clusters/clusters.py index a5647c604..5af28edfd 100644 --- a/src/gcore/resources/cloud/gpu_virtual/clusters/clusters.py +++ b/src/gcore/resources/cloud/gpu_virtual/clusters/clusters.py @@ -714,6 +714,275 @@ def get( cast_to=GPUVirtualCluster, ) + def create_and_poll( + self, + *, + project_id: int | None = None, + region_id: int | None = None, + flavor: str, + name: str, + servers_count: int, + servers_settings: cluster_create_params.ServersSettings, + tags: Dict[str, str] | Omit = omit, + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: 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, + ) -> GPUVirtualCluster: + """ + Create a virtual GPU cluster and wait for it to be ready. + """ + response = self.create( + project_id=project_id, + region_id=region_id, + flavor=flavor, + name=name, + servers_count=servers_count, + servers_settings=servers_settings, + tags=tags, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ) + if not response.tasks or len(response.tasks) != 1: + raise ValueError(f"Expected exactly one task to be created") + task = self._client.cloud.tasks.poll( + response.tasks[0], + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + polling_interval_seconds=polling_interval_seconds, + polling_timeout_seconds=polling_timeout_seconds, + ) + if not task.created_resources or not task.created_resources.clusters: + raise ValueError("No cluster was created") + cluster_id = task.created_resources.clusters[0] + return self.get( + cluster_id=cluster_id, + project_id=project_id, + region_id=region_id, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ) + + def delete_and_poll( + self, + cluster_id: str, + *, + project_id: int | None = None, + region_id: int | None = None, + all_floating_ips: bool | Omit = omit, + all_reserved_fixed_ips: bool | Omit = omit, + all_volumes: bool | Omit = omit, + floating_ip_ids: SequenceNotStr[str] | Omit = omit, + reserved_fixed_ip_ids: SequenceNotStr[str] | Omit = omit, + volume_ids: SequenceNotStr[str] | Omit = omit, + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: 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, + ) -> None: + """ + Delete a virtual GPU cluster and poll for the result. Only the first task will be polled. If you need to poll more tasks, use the `tasks.poll` method. + """ + response = self.delete( + cluster_id=cluster_id, + project_id=project_id, + region_id=region_id, + all_floating_ips=all_floating_ips, + all_reserved_fixed_ips=all_reserved_fixed_ips, + all_volumes=all_volumes, + floating_ip_ids=floating_ip_ids, + reserved_fixed_ip_ids=reserved_fixed_ip_ids, + volume_ids=volume_ids, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ) + if not response.tasks or len(response.tasks) < 1: + raise ValueError("Expected at least one task to be created") + self._client.cloud.tasks.poll( + response.tasks[0], + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + polling_interval_seconds=polling_interval_seconds, + polling_timeout_seconds=polling_timeout_seconds, + ) + + @overload + def action_and_poll( + self, + cluster_id: str, + *, + project_id: int | None = None, + region_id: int | None = None, + action: Literal["start"], + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: int | Omit = omit, + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> GPUVirtualCluster: + """Perform an action on a virtual GPU cluster and poll for the result. Only the first task will be polled. If you need to poll more tasks, use the `tasks.poll` method.""" + ... + + @overload + def action_and_poll( + self, + cluster_id: str, + *, + project_id: int | None = None, + region_id: int | None = None, + action: Literal["stop"], + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: int | Omit = omit, + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> GPUVirtualCluster: + """Perform an action on a virtual GPU cluster and poll for the result. Only the first task will be polled. If you need to poll more tasks, use the `tasks.poll` method.""" + ... + + @overload + def action_and_poll( + self, + cluster_id: str, + *, + project_id: int | None = None, + region_id: int | None = None, + action: Literal["soft_reboot"], + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: int | Omit = omit, + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> GPUVirtualCluster: + """Perform an action on a virtual GPU cluster and poll for the result. Only the first task will be polled. If you need to poll more tasks, use the `tasks.poll` method.""" + ... + + @overload + def action_and_poll( + self, + cluster_id: str, + *, + project_id: int | None = None, + region_id: int | None = None, + action: Literal["hard_reboot"], + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: int | Omit = omit, + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> GPUVirtualCluster: + """Perform an action on a virtual GPU cluster and poll for the result. Only the first task will be polled. If you need to poll more tasks, use the `tasks.poll` method.""" + ... + + @overload + def action_and_poll( + self, + cluster_id: str, + *, + project_id: int | None = None, + region_id: int | None = None, + action: Literal["resize"], + servers_count: int, + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: int | Omit = omit, + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> GPUVirtualCluster: + """Perform an action on a virtual GPU cluster and poll for the result. Only the first task will be polled. If you need to poll more tasks, use the `tasks.poll` method.""" + ... + + @required_args(["action"], ["action", "servers_count"]) + def action_and_poll( + self, + cluster_id: str, + *, + project_id: int | None = None, + region_id: int | None = None, + action: Literal["start"] + | Literal["stop"] + | Literal["soft_reboot"] + | Literal["hard_reboot"] + | Literal["resize"], + servers_count: int | Omit = omit, + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: 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, + ) -> GPUVirtualCluster: + """ + Perform an action on a virtual GPU cluster and poll for the result. Only the first task will be polled. If you need to poll more tasks, use the `tasks.poll` method. + """ + 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_id: + raise ValueError(f"Expected a non-empty value for `cluster_id` but received {cluster_id!r}") + response = self._post( + path_template( + "/cloud/v3/gpu/virtual/{project_id}/{region_id}/clusters/{cluster_id}/action", + project_id=project_id, + region_id=region_id, + cluster_id=cluster_id, + ), + body=maybe_transform( + { + "action": action, + "servers_count": servers_count, + }, + cluster_action_params.ClusterActionParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=TaskIDList, + ) + if not response.tasks: + raise ValueError("Expected at least one task to be created") + self._client.cloud.tasks.poll( + response.tasks[0], + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + polling_interval_seconds=polling_interval_seconds, + polling_timeout_seconds=polling_timeout_seconds, + ) + return self.get( + cluster_id=cluster_id, + project_id=project_id, + region_id=region_id, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ) + class AsyncClustersResource(AsyncAPIResource): """ @@ -1356,6 +1625,275 @@ async def get( cast_to=GPUVirtualCluster, ) + async def create_and_poll( + self, + *, + project_id: int | None = None, + region_id: int | None = None, + flavor: str, + name: str, + servers_count: int, + servers_settings: cluster_create_params.ServersSettings, + tags: Dict[str, str] | Omit = omit, + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: 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, + ) -> GPUVirtualCluster: + """ + Create a virtual GPU cluster and wait for it to be ready. + """ + response = await self.create( + project_id=project_id, + region_id=region_id, + flavor=flavor, + name=name, + servers_count=servers_count, + servers_settings=servers_settings, + tags=tags, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ) + if not response.tasks or len(response.tasks) != 1: + raise ValueError(f"Expected exactly one task to be created") + task = await self._client.cloud.tasks.poll( + response.tasks[0], + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + polling_interval_seconds=polling_interval_seconds, + polling_timeout_seconds=polling_timeout_seconds, + ) + if not task.created_resources or not task.created_resources.clusters: + raise ValueError("No cluster was created") + cluster_id = task.created_resources.clusters[0] + return await self.get( + cluster_id=cluster_id, + project_id=project_id, + region_id=region_id, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ) + + async def delete_and_poll( + self, + cluster_id: str, + *, + project_id: int | None = None, + region_id: int | None = None, + all_floating_ips: bool | Omit = omit, + all_reserved_fixed_ips: bool | Omit = omit, + all_volumes: bool | Omit = omit, + floating_ip_ids: SequenceNotStr[str] | Omit = omit, + reserved_fixed_ip_ids: SequenceNotStr[str] | Omit = omit, + volume_ids: SequenceNotStr[str] | Omit = omit, + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: 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, + ) -> None: + """ + Delete a virtual GPU cluster and poll for the result. Only the first task will be polled. If you need to poll more tasks, use the `tasks.poll` method. + """ + response = await self.delete( + cluster_id=cluster_id, + project_id=project_id, + region_id=region_id, + all_floating_ips=all_floating_ips, + all_reserved_fixed_ips=all_reserved_fixed_ips, + all_volumes=all_volumes, + floating_ip_ids=floating_ip_ids, + reserved_fixed_ip_ids=reserved_fixed_ip_ids, + volume_ids=volume_ids, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ) + if not response.tasks or len(response.tasks) < 1: + raise ValueError("Expected at least one task to be created") + await self._client.cloud.tasks.poll( + response.tasks[0], + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + polling_interval_seconds=polling_interval_seconds, + polling_timeout_seconds=polling_timeout_seconds, + ) + + @overload + async def action_and_poll( + self, + cluster_id: str, + *, + project_id: int | None = None, + region_id: int | None = None, + action: Literal["start"], + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: int | Omit = omit, + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> GPUVirtualCluster: + """Perform an action on a virtual GPU cluster and poll for the result. Only the first task will be polled. If you need to poll more tasks, use the `tasks.poll` method.""" + ... + + @overload + async def action_and_poll( + self, + cluster_id: str, + *, + project_id: int | None = None, + region_id: int | None = None, + action: Literal["stop"], + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: int | Omit = omit, + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> GPUVirtualCluster: + """Perform an action on a virtual GPU cluster and poll for the result. Only the first task will be polled. If you need to poll more tasks, use the `tasks.poll` method.""" + ... + + @overload + async def action_and_poll( + self, + cluster_id: str, + *, + project_id: int | None = None, + region_id: int | None = None, + action: Literal["soft_reboot"], + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: int | Omit = omit, + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> GPUVirtualCluster: + """Perform an action on a virtual GPU cluster and poll for the result. Only the first task will be polled. If you need to poll more tasks, use the `tasks.poll` method.""" + ... + + @overload + async def action_and_poll( + self, + cluster_id: str, + *, + project_id: int | None = None, + region_id: int | None = None, + action: Literal["hard_reboot"], + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: int | Omit = omit, + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> GPUVirtualCluster: + """Perform an action on a virtual GPU cluster and poll for the result. Only the first task will be polled. If you need to poll more tasks, use the `tasks.poll` method.""" + ... + + @overload + async def action_and_poll( + self, + cluster_id: str, + *, + project_id: int | None = None, + region_id: int | None = None, + action: Literal["resize"], + servers_count: int, + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: int | Omit = omit, + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> GPUVirtualCluster: + """Perform an action on a virtual GPU cluster and poll for the result. Only the first task will be polled. If you need to poll more tasks, use the `tasks.poll` method.""" + ... + + @required_args(["action"], ["action", "servers_count"]) + async def action_and_poll( + self, + cluster_id: str, + *, + project_id: int | None = None, + region_id: int | None = None, + action: Literal["start"] + | Literal["stop"] + | Literal["soft_reboot"] + | Literal["hard_reboot"] + | Literal["resize"], + servers_count: int | Omit = omit, + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: 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, + ) -> GPUVirtualCluster: + """ + Perform an action on a virtual GPU cluster and poll for the result. Only the first task will be polled. If you need to poll more tasks, use the `tasks.poll` method. + """ + 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_id: + raise ValueError(f"Expected a non-empty value for `cluster_id` but received {cluster_id!r}") + response = await self._post( + path_template( + "/cloud/v3/gpu/virtual/{project_id}/{region_id}/clusters/{cluster_id}/action", + project_id=project_id, + region_id=region_id, + cluster_id=cluster_id, + ), + body=await async_maybe_transform( + { + "action": action, + "servers_count": servers_count, + }, + cluster_action_params.ClusterActionParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=TaskIDList, + ) + if not response.tasks: + raise ValueError("Expected at least one task to be created") + await self._client.cloud.tasks.poll( + response.tasks[0], + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + polling_interval_seconds=polling_interval_seconds, + polling_timeout_seconds=polling_timeout_seconds, + ) + return await self.get( + cluster_id=cluster_id, + project_id=project_id, + region_id=region_id, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ) + class ClustersResourceWithRawResponse: def __init__(self, clusters: ClustersResource) -> None: @@ -1379,6 +1917,15 @@ def __init__(self, clusters: ClustersResource) -> None: self.get = to_raw_response_wrapper( clusters.get, ) + self.create_and_poll = to_raw_response_wrapper( + clusters.create_and_poll, + ) + self.delete_and_poll = to_raw_response_wrapper( + clusters.delete_and_poll, + ) + self.action_and_poll = to_raw_response_wrapper( + clusters.action_and_poll, + ) @cached_property def servers(self) -> ServersResourceWithRawResponse: @@ -1424,6 +1971,15 @@ def __init__(self, clusters: AsyncClustersResource) -> None: self.get = async_to_raw_response_wrapper( clusters.get, ) + self.create_and_poll = async_to_raw_response_wrapper( + clusters.create_and_poll, + ) + self.delete_and_poll = async_to_raw_response_wrapper( + clusters.delete_and_poll, + ) + self.action_and_poll = async_to_raw_response_wrapper( + clusters.action_and_poll, + ) @cached_property def servers(self) -> AsyncServersResourceWithRawResponse: @@ -1469,6 +2025,15 @@ def __init__(self, clusters: ClustersResource) -> None: self.get = to_streamed_response_wrapper( clusters.get, ) + self.create_and_poll = to_streamed_response_wrapper( + clusters.create_and_poll, + ) + self.delete_and_poll = to_streamed_response_wrapper( + clusters.delete_and_poll, + ) + self.action_and_poll = to_streamed_response_wrapper( + clusters.action_and_poll, + ) @cached_property def servers(self) -> ServersResourceWithStreamingResponse: @@ -1514,6 +2079,15 @@ def __init__(self, clusters: AsyncClustersResource) -> None: self.get = async_to_streamed_response_wrapper( clusters.get, ) + self.create_and_poll = async_to_streamed_response_wrapper( + clusters.create_and_poll, + ) + self.delete_and_poll = async_to_streamed_response_wrapper( + clusters.delete_and_poll, + ) + self.action_and_poll = async_to_streamed_response_wrapper( + clusters.action_and_poll, + ) @cached_property def servers(self) -> AsyncServersResourceWithStreamingResponse: diff --git a/src/gcore/resources/cloud/gpu_virtual/clusters/images.py b/src/gcore/resources/cloud/gpu_virtual/clusters/images.py index f68f25265..1b73fea6e 100644 --- a/src/gcore/resources/cloud/gpu_virtual/clusters/images.py +++ b/src/gcore/resources/cloud/gpu_virtual/clusters/images.py @@ -283,6 +283,112 @@ def upload( cast_to=TaskIDList, ) + def delete_and_poll( + self, + image_id: str, + *, + project_id: int | None = None, + region_id: int | None = None, + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: 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, + ) -> None: + """ + Delete a virtual GPU image and poll for the result. Only the first task will be polled. If you need to poll more tasks, use the `tasks.poll` method. + """ + response = self.delete( + image_id=image_id, + project_id=project_id, + region_id=region_id, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ) + if not response.tasks or len(response.tasks) < 1: + raise ValueError("Expected at least one task to be created") + self._client.cloud.tasks.poll( + response.tasks[0], + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + polling_interval_seconds=polling_interval_seconds, + polling_timeout_seconds=polling_timeout_seconds, + ) + + def upload_and_poll( + self, + *, + project_id: int | None = None, + region_id: int | None = None, + name: str, + url: str, + architecture: Optional[Literal["aarch64", "x86_64"]] | Omit = omit, + cow_format: bool | Omit = omit, + hw_firmware_type: Optional[Literal["bios", "uefi"]] | Omit = omit, + os_distro: Optional[str] | Omit = omit, + os_type: Optional[Literal["linux", "windows"]] | Omit = omit, + os_version: Optional[str] | Omit = omit, + ssh_key: Literal["allow", "deny", "required"] | Omit = omit, + tags: Dict[str, str] | Omit = omit, + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: 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, + ) -> GPUImage: + """ + Upload a new virtual GPU image and wait for the upload to complete. + """ + response = self.upload( + project_id=project_id, + region_id=region_id, + name=name, + url=url, + architecture=architecture, + cow_format=cow_format, + hw_firmware_type=hw_firmware_type, + os_distro=os_distro, + os_type=os_type, + os_version=os_version, + ssh_key=ssh_key, + tags=tags, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ) + if not response.tasks or len(response.tasks) != 1: + raise ValueError(f"Expected exactly one task to be created") + task = self._client.cloud.tasks.poll( + response.tasks[0], + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + polling_interval_seconds=polling_interval_seconds, + polling_timeout_seconds=polling_timeout_seconds, + ) + if not task.created_resources or not task.created_resources.images: + raise ValueError("No image was created") + image_id = task.created_resources.images[0] + return self.get( + image_id=image_id, + project_id=project_id, + region_id=region_id, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ) + class AsyncImagesResource(AsyncAPIResource): """GPU virtual images are custom boot images for virtual GPU cluster instances.""" @@ -541,6 +647,112 @@ async def upload( cast_to=TaskIDList, ) + async def delete_and_poll( + self, + image_id: str, + *, + project_id: int | None = None, + region_id: int | None = None, + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: 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, + ) -> None: + """ + Delete a virtual GPU image and poll for the result. Only the first task will be polled. If you need to poll more tasks, use the `tasks.poll` method. + """ + response = await self.delete( + image_id=image_id, + project_id=project_id, + region_id=region_id, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ) + if not response.tasks or len(response.tasks) < 1: + raise ValueError("Expected at least one task to be created") + await self._client.cloud.tasks.poll( + response.tasks[0], + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + polling_interval_seconds=polling_interval_seconds, + polling_timeout_seconds=polling_timeout_seconds, + ) + + async def upload_and_poll( + self, + *, + project_id: int | None = None, + region_id: int | None = None, + name: str, + url: str, + architecture: Optional[Literal["aarch64", "x86_64"]] | Omit = omit, + cow_format: bool | Omit = omit, + hw_firmware_type: Optional[Literal["bios", "uefi"]] | Omit = omit, + os_distro: Optional[str] | Omit = omit, + os_type: Optional[Literal["linux", "windows"]] | Omit = omit, + os_version: Optional[str] | Omit = omit, + ssh_key: Literal["allow", "deny", "required"] | Omit = omit, + tags: Dict[str, str] | Omit = omit, + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: 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, + ) -> GPUImage: + """ + Upload a new virtual GPU image and wait for the upload to complete. + """ + response = await self.upload( + project_id=project_id, + region_id=region_id, + name=name, + url=url, + architecture=architecture, + cow_format=cow_format, + hw_firmware_type=hw_firmware_type, + os_distro=os_distro, + os_type=os_type, + os_version=os_version, + ssh_key=ssh_key, + tags=tags, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ) + if not response.tasks or len(response.tasks) != 1: + raise ValueError(f"Expected exactly one task to be created") + task = await self._client.cloud.tasks.poll( + response.tasks[0], + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + polling_interval_seconds=polling_interval_seconds, + polling_timeout_seconds=polling_timeout_seconds, + ) + if not task.created_resources or not task.created_resources.images: + raise ValueError("No image was created") + image_id = task.created_resources.images[0] + return await self.get( + image_id=image_id, + project_id=project_id, + region_id=region_id, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ) + class ImagesResourceWithRawResponse: def __init__(self, images: ImagesResource) -> None: @@ -558,6 +770,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: @@ -576,6 +794,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: @@ -594,6 +818,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: @@ -612,3 +842,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_virtual/clusters/servers.py b/src/gcore/resources/cloud/gpu_virtual/clusters/servers.py index 08683b79f..f7c47c615 100644 --- a/src/gcore/resources/cloud/gpu_virtual/clusters/servers.py +++ b/src/gcore/resources/cloud/gpu_virtual/clusters/servers.py @@ -252,6 +252,58 @@ def delete( cast_to=TaskIDList, ) + def delete_and_poll( + self, + server_id: str, + *, + project_id: int | None = None, + region_id: int | None = None, + cluster_id: str, + all_floating_ips: bool | Omit = omit, + all_reserved_fixed_ips: bool | Omit = omit, + all_volumes: bool | Omit = omit, + floating_ip_ids: SequenceNotStr[str] | Omit = omit, + reserved_fixed_ip_ids: SequenceNotStr[str] | Omit = omit, + volume_ids: SequenceNotStr[str] | Omit = omit, + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: 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, + ) -> None: + """ + Delete a server from a virtual GPU cluster and poll for the result. Only the first task will be polled. If you need to poll more tasks, use the `tasks.poll` method. + """ + response = self.delete( + server_id=server_id, + project_id=project_id, + region_id=region_id, + cluster_id=cluster_id, + all_floating_ips=all_floating_ips, + all_reserved_fixed_ips=all_reserved_fixed_ips, + all_volumes=all_volumes, + floating_ip_ids=floating_ip_ids, + reserved_fixed_ip_ids=reserved_fixed_ip_ids, + volume_ids=volume_ids, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ) + if not response.tasks or len(response.tasks) < 1: + raise ValueError("Expected at least one task to be created") + self._client.cloud.tasks.poll( + response.tasks[0], + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + polling_interval_seconds=polling_interval_seconds, + polling_timeout_seconds=polling_timeout_seconds, + ) + class AsyncServersResource(AsyncAPIResource): @cached_property @@ -479,6 +531,58 @@ async def delete( cast_to=TaskIDList, ) + async def delete_and_poll( + self, + server_id: str, + *, + project_id: int | None = None, + region_id: int | None = None, + cluster_id: str, + all_floating_ips: bool | Omit = omit, + all_reserved_fixed_ips: bool | Omit = omit, + all_volumes: bool | Omit = omit, + floating_ip_ids: SequenceNotStr[str] | Omit = omit, + reserved_fixed_ip_ids: SequenceNotStr[str] | Omit = omit, + volume_ids: SequenceNotStr[str] | Omit = omit, + polling_interval_seconds: int | Omit = omit, + polling_timeout_seconds: 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, + ) -> None: + """ + Delete a server from a virtual GPU cluster and poll for the result. Only the first task will be polled. If you need to poll more tasks, use the `tasks.poll` method. + """ + response = await self.delete( + server_id=server_id, + project_id=project_id, + region_id=region_id, + cluster_id=cluster_id, + all_floating_ips=all_floating_ips, + all_reserved_fixed_ips=all_reserved_fixed_ips, + all_volumes=all_volumes, + floating_ip_ids=floating_ip_ids, + reserved_fixed_ip_ids=reserved_fixed_ip_ids, + volume_ids=volume_ids, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ) + if not response.tasks or len(response.tasks) < 1: + raise ValueError("Expected at least one task to be created") + await self._client.cloud.tasks.poll( + response.tasks[0], + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + polling_interval_seconds=polling_interval_seconds, + polling_timeout_seconds=polling_timeout_seconds, + ) + class ServersResourceWithRawResponse: def __init__(self, servers: ServersResource) -> None: @@ -490,6 +594,9 @@ def __init__(self, servers: ServersResource) -> None: self.delete = to_raw_response_wrapper( servers.delete, ) + self.delete_and_poll = to_raw_response_wrapper( + servers.delete_and_poll, + ) class AsyncServersResourceWithRawResponse: @@ -502,6 +609,9 @@ def __init__(self, servers: AsyncServersResource) -> None: self.delete = async_to_raw_response_wrapper( servers.delete, ) + self.delete_and_poll = async_to_raw_response_wrapper( + servers.delete_and_poll, + ) class ServersResourceWithStreamingResponse: @@ -514,6 +624,9 @@ def __init__(self, servers: ServersResource) -> None: self.delete = to_streamed_response_wrapper( servers.delete, ) + self.delete_and_poll = to_streamed_response_wrapper( + servers.delete_and_poll, + ) class AsyncServersResourceWithStreamingResponse: @@ -526,3 +639,6 @@ def __init__(self, servers: AsyncServersResource) -> None: self.delete = async_to_streamed_response_wrapper( servers.delete, ) + 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 cd0bafa77..a5bc55051 100644 --- a/src/gcore/resources/cloud/inference/deployments/deployments.py +++ b/src/gcore/resources/cloud/inference/deployments/deployments.py @@ -2,7 +2,6 @@ from __future__ import annotations -import typing_extensions from typing import Dict, Iterable, Optional import httpx @@ -30,7 +29,6 @@ from .....types.cloud.inference import deployment_list_params, deployment_create_params, deployment_update_params from .....types.cloud.task_id_list import TaskIDList from .....types.cloud.inference.inference_deployment import InferenceDeployment -from .....types.cloud.inference.inference_deployment_api_key import InferenceDeploymentAPIKey __all__ = ["DeploymentsResource", "AsyncDeploymentsResource"] @@ -439,51 +437,6 @@ def get( cast_to=InferenceDeployment, ) - @typing_extensions.deprecated("deprecated") - def get_api_key( - self, - deployment_name: str, - *, - project_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, - ) -> InferenceDeploymentAPIKey: - """ - Get inference deployment API key - - Args: - project_id: Project ID - - deployment_name: Inference instance name. - - 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 not deployment_name: - raise ValueError(f"Expected a non-empty value for `deployment_name` but received {deployment_name!r}") - return self._get( - path_template( - "/cloud/v3/inference/{project_id}/deployments/{deployment_name}/apikey", - project_id=project_id, - deployment_name=deployment_name, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=InferenceDeploymentAPIKey, - ) - def start( self, deployment_name: str, @@ -1166,51 +1119,6 @@ async def get( cast_to=InferenceDeployment, ) - @typing_extensions.deprecated("deprecated") - async def get_api_key( - self, - deployment_name: str, - *, - project_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, - ) -> InferenceDeploymentAPIKey: - """ - Get inference deployment API key - - Args: - project_id: Project ID - - deployment_name: Inference instance name. - - 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 not deployment_name: - raise ValueError(f"Expected a non-empty value for `deployment_name` but received {deployment_name!r}") - return await self._get( - path_template( - "/cloud/v3/inference/{project_id}/deployments/{deployment_name}/apikey", - project_id=project_id, - deployment_name=deployment_name, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=InferenceDeploymentAPIKey, - ) - async def start( self, deployment_name: str, @@ -1508,11 +1416,6 @@ def __init__(self, deployments: DeploymentsResource) -> None: self.get = to_raw_response_wrapper( deployments.get, ) - self.get_api_key = ( # pyright: ignore[reportDeprecated] - to_raw_response_wrapper( - deployments.get_api_key, # pyright: ignore[reportDeprecated], - ) - ) self.start = to_raw_response_wrapper( deployments.start, ) @@ -1553,11 +1456,6 @@ def __init__(self, deployments: AsyncDeploymentsResource) -> None: self.get = async_to_raw_response_wrapper( deployments.get, ) - self.get_api_key = ( # pyright: ignore[reportDeprecated] - async_to_raw_response_wrapper( - deployments.get_api_key, # pyright: ignore[reportDeprecated], - ) - ) self.start = async_to_raw_response_wrapper( deployments.start, ) @@ -1598,11 +1496,6 @@ def __init__(self, deployments: DeploymentsResource) -> None: self.get = to_streamed_response_wrapper( deployments.get, ) - self.get_api_key = ( # pyright: ignore[reportDeprecated] - to_streamed_response_wrapper( - deployments.get_api_key, # pyright: ignore[reportDeprecated], - ) - ) self.start = to_streamed_response_wrapper( deployments.start, ) @@ -1643,11 +1536,6 @@ def __init__(self, deployments: AsyncDeploymentsResource) -> None: self.get = async_to_streamed_response_wrapper( deployments.get, ) - self.get_api_key = ( # pyright: ignore[reportDeprecated] - async_to_streamed_response_wrapper( - deployments.get_api_key, # pyright: ignore[reportDeprecated], - ) - ) self.start = async_to_streamed_response_wrapper( deployments.start, ) diff --git a/src/gcore/resources/cloud/instances/images.py b/src/gcore/resources/cloud/instances/images.py index 6599d48b4..97d689cf3 100644 --- a/src/gcore/resources/cloud/instances/images.py +++ b/src/gcore/resources/cloud/instances/images.py @@ -18,7 +18,6 @@ async_to_streamed_response_wrapper, ) from ...._base_client import make_request_options -from ....types.cloud.image import Image from ....types.cloud.instances import ( image_get_params, image_list_params, @@ -26,8 +25,9 @@ image_upload_params, image_create_from_volume_params, ) -from ....types.cloud.image_list import ImageList from ....types.cloud.task_id_list import TaskIDList +from ....types.cloud.instances.image import Image +from ....types.cloud.instances.image_list import ImageList from ....types.cloud.tag_update_map_param import TagUpdateMapParam __all__ = ["ImagesResource", "AsyncImagesResource"] @@ -163,13 +163,17 @@ def list( by the project or are public/shared with the client. Args: - include_prices: Show price + project_id: Project ID + + region_id: Region ID + + include_prices: Show price. private: Any value to show private images - tag_key: Filter by tag keys. + tag_key: Optional. Filter by tag keys. ?`tag_key`=key1&`tag_key`=key2 - tag_key_value: Filter by tag key-value pairs. Must be a valid JSON string. + tag_key_value: Optional. Filter by tag key-value pairs. visibility: Image visibility. Globally visible images are public @@ -316,6 +320,10 @@ def create_from_volume( an image from it. Args: + project_id: Project ID + + region_id: Region ID + name: Image name volume_id: Required if source is volume. Volume id @@ -785,13 +793,17 @@ async def list( by the project or are public/shared with the client. Args: - include_prices: Show price + project_id: Project ID + + region_id: Region ID + + include_prices: Show price. private: Any value to show private images - tag_key: Filter by tag keys. + tag_key: Optional. Filter by tag keys. ?`tag_key`=key1&`tag_key`=key2 - tag_key_value: Filter by tag key-value pairs. Must be a valid JSON string. + tag_key_value: Optional. Filter by tag key-value pairs. visibility: Image visibility. Globally visible images are public @@ -938,6 +950,10 @@ async def create_from_volume( an image from it. Args: + project_id: Project ID + + region_id: Region ID + name: Image name volume_id: Required if source is volume. Volume id diff --git a/src/gcore/resources/cloud/load_balancers/flavors.py b/src/gcore/resources/cloud/load_balancers/flavors.py index 27e43c148..4f1c4f043 100644 --- a/src/gcore/resources/cloud/load_balancers/flavors.py +++ b/src/gcore/resources/cloud/load_balancers/flavors.py @@ -47,6 +47,8 @@ def list( project_id: int | None = None, region_id: int | None = None, include_prices: bool | Omit = omit, + 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, @@ -67,6 +69,11 @@ def list( include_prices: Set to true if the response should include flavor prices + limit: Optional. Limit the number of returned items + + offset: Optional. Offset value is used to exclude the first set of records from the + result + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -86,7 +93,14 @@ def list( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=maybe_transform({"include_prices": include_prices}, flavor_list_params.FlavorListParams), + query=maybe_transform( + { + "include_prices": include_prices, + "limit": limit, + "offset": offset, + }, + flavor_list_params.FlavorListParams, + ), ), cast_to=LoadBalancerFlavorList, ) @@ -118,6 +132,8 @@ async def list( project_id: int | None = None, region_id: int | None = None, include_prices: bool | Omit = omit, + 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, @@ -138,6 +154,11 @@ async def list( include_prices: Set to true if the response should include flavor prices + limit: Optional. Limit the number of returned items + + offset: Optional. Offset value is used to exclude the first set of records from the + result + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -158,7 +179,12 @@ async def list( extra_body=extra_body, timeout=timeout, query=await async_maybe_transform( - {"include_prices": include_prices}, flavor_list_params.FlavorListParams + { + "include_prices": include_prices, + "limit": limit, + "offset": offset, + }, + flavor_list_params.FlavorListParams, ), ), cast_to=LoadBalancerFlavorList, 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 b9243fe36..b9674fad2 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 @@ -26,7 +26,7 @@ ) from ....._base_client import make_request_options from .....types.cloud.task_id_list import TaskIDList -from .....types.cloud.load_balancers import l7_policy_create_params, l7_policy_update_params +from .....types.cloud.load_balancers import l7_policy_list_params, l7_policy_create_params, l7_policy_update_params from .....types.cloud.load_balancer_l7_policy import LoadBalancerL7Policy from .....types.cloud.load_balancer_l7_policy_list import LoadBalancerL7PolicyList @@ -584,6 +584,8 @@ def list( *, 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, @@ -599,6 +601,11 @@ def list( region_id: Region ID + limit: Optional. Limit the number of returned items + + offset: Optional. Offset value is used to exclude the first set of records from the + result + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -614,7 +621,17 @@ def list( return self._get( path_template("/cloud/v1/l7policies/{project_id}/{region_id}", project_id=project_id, region_id=region_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( + { + "limit": limit, + "offset": offset, + }, + l7_policy_list_params.L7PolicyListParams, + ), ), cast_to=LoadBalancerL7PolicyList, ) @@ -1613,6 +1630,8 @@ async def list( *, 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, @@ -1628,6 +1647,11 @@ async def list( region_id: Region ID + limit: Optional. Limit the number of returned items + + offset: Optional. Offset value is used to exclude the first set of records from the + result + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -1643,7 +1667,17 @@ async def list( return await self._get( path_template("/cloud/v1/l7policies/{project_id}/{region_id}", project_id=project_id, region_id=region_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( + { + "limit": limit, + "offset": offset, + }, + l7_policy_list_params.L7PolicyListParams, + ), ), cast_to=LoadBalancerL7PolicyList, ) 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 901baf039..1267a937d 100644 --- a/src/gcore/resources/cloud/load_balancers/l7_policies/rules.py +++ b/src/gcore/resources/cloud/load_balancers/l7_policies/rules.py @@ -20,7 +20,7 @@ from .....types.cloud.task_id_list import TaskIDList from .....types.cloud.load_balancer_l7_rule import LoadBalancerL7Rule from .....types.cloud.load_balancer_l7_rule_list import LoadBalancerL7RuleList -from .....types.cloud.load_balancers.l7_policies import rule_create_params, rule_replace_params +from .....types.cloud.load_balancers.l7_policies import rule_list_params, rule_create_params, rule_replace_params __all__ = ["RulesResource", "AsyncRulesResource"] @@ -139,6 +139,8 @@ def list( *, 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, @@ -156,6 +158,11 @@ def list( l7policy_id: L7 policy ID + limit: Optional. Limit the number of returned items + + offset: Optional. Offset value is used to exclude the first set of records from the + result + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -178,7 +185,17 @@ def list( l7policy_id=l7policy_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( + { + "limit": limit, + "offset": offset, + }, + rule_list_params.RuleListParams, + ), ), cast_to=LoadBalancerL7RuleList, ) @@ -674,6 +691,8 @@ async def list( *, 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, @@ -691,6 +710,11 @@ async def list( l7policy_id: L7 policy ID + limit: Optional. Limit the number of returned items + + offset: Optional. Offset value is used to exclude the first set of records from the + result + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -713,7 +737,17 @@ async def list( l7policy_id=l7policy_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( + { + "limit": limit, + "offset": offset, + }, + rule_list_params.RuleListParams, + ), ), cast_to=LoadBalancerL7RuleList, ) diff --git a/src/gcore/resources/cloud/load_balancers/listeners.py b/src/gcore/resources/cloud/load_balancers/listeners.py index cd6c6dcc4..be4aecd1c 100644 --- a/src/gcore/resources/cloud/load_balancers/listeners.py +++ b/src/gcore/resources/cloud/load_balancers/listeners.py @@ -272,7 +272,10 @@ def list( *, project_id: int | None = None, region_id: int | None = None, + limit: int | Omit = omit, load_balancer_id: str | Omit = omit, + name: str | Omit = omit, + offset: int | Omit = omit, show_stats: 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. @@ -289,8 +292,15 @@ def list( region_id: Region ID + limit: Optional. Limit the number of returned items + load_balancer_id: Load Balancer ID + name: Filter by name + + offset: Optional. Offset value is used to exclude the first set of records from the + result + show_stats: Show stats extra_headers: Send extra headers @@ -314,7 +324,10 @@ def list( timeout=timeout, query=maybe_transform( { + "limit": limit, "load_balancer_id": load_balancer_id, + "name": name, + "offset": offset, "show_stats": show_stats, }, listener_list_params.ListenerListParams, @@ -845,7 +858,10 @@ async def list( *, project_id: int | None = None, region_id: int | None = None, + limit: int | Omit = omit, load_balancer_id: str | Omit = omit, + name: str | Omit = omit, + offset: int | Omit = omit, show_stats: 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. @@ -862,8 +878,15 @@ async def list( region_id: Region ID + limit: Optional. Limit the number of returned items + load_balancer_id: Load Balancer ID + name: Filter by name + + offset: Optional. Offset value is used to exclude the first set of records from the + result + show_stats: Show stats extra_headers: Send extra headers @@ -887,7 +910,10 @@ async def list( timeout=timeout, query=await async_maybe_transform( { + "limit": limit, "load_balancer_id": load_balancer_id, + "name": name, + "offset": offset, "show_stats": show_stats, }, listener_list_params.ListenerListParams, diff --git a/src/gcore/resources/cloud/load_balancers/load_balancers.py b/src/gcore/resources/cloud/load_balancers/load_balancers.py index c9dd19bec..7ca62e451 100644 --- a/src/gcore/resources/cloud/load_balancers/load_balancers.py +++ b/src/gcore/resources/cloud/load_balancers/load_balancers.py @@ -146,12 +146,11 @@ def create( *, project_id: int | None = None, region_id: int | None = None, + name: str, flavor: str | Omit = omit, floating_ip: load_balancer_create_params.FloatingIP | Omit = omit, listeners: Iterable[load_balancer_create_params.Listener] | Omit = omit, logging: load_balancer_create_params.Logging | Omit = omit, - name: str | Omit = omit, - name_template: str | Omit = omit, preferred_connectivity: LoadBalancerMemberConnectivity | Omit = omit, tags: Dict[str, str] | Omit = omit, vip_ip_family: InterfaceIPFamily | Omit = omit, @@ -173,6 +172,8 @@ def create( region_id: Region ID + name: Load balancer name. + flavor: Load balancer flavor name floating_ip: Floating IP configuration for assignment @@ -182,11 +183,6 @@ def create( logging: Logging configuration - name: Load balancer name. Either `name` or `name_template` should be specified. - - name_template: Load balancer name which will be changed by template. Either `name` or - `name_template` should be specified. - preferred_connectivity: Preferred option to establish connectivity between load balancer and its pools members. L2 provides best performance, L3 provides less IPs usage. It is taking effect only if `instance_id` + `ip_address` is provided, not `subnet_id` + @@ -230,12 +226,11 @@ def create( ), body=maybe_transform( { + "name": name, "flavor": flavor, "floating_ip": floating_ip, "listeners": listeners, "logging": logging, - "name": name, - "name_template": name_template, "preferred_connectivity": preferred_connectivity, "tags": tags, "vip_ip_family": vip_ip_family, @@ -468,8 +463,7 @@ def create_and_poll( floating_ip: load_balancer_create_params.FloatingIP | Omit = omit, listeners: Iterable[load_balancer_create_params.Listener] | Omit = omit, logging: load_balancer_create_params.Logging | Omit = omit, - name: str | Omit = omit, - name_template: str | Omit = omit, + name: str, preferred_connectivity: LoadBalancerMemberConnectivity | Omit = omit, tags: Dict[str, str] | Omit = omit, vip_ip_family: InterfaceIPFamily | Omit = omit, @@ -493,7 +487,6 @@ def create_and_poll( listeners=listeners, logging=logging, name=name, - name_template=name_template, preferred_connectivity=preferred_connectivity, tags=tags, vip_ip_family=vip_ip_family, @@ -937,12 +930,11 @@ async def create( *, project_id: int | None = None, region_id: int | None = None, + name: str, flavor: str | Omit = omit, floating_ip: load_balancer_create_params.FloatingIP | Omit = omit, listeners: Iterable[load_balancer_create_params.Listener] | Omit = omit, logging: load_balancer_create_params.Logging | Omit = omit, - name: str | Omit = omit, - name_template: str | Omit = omit, preferred_connectivity: LoadBalancerMemberConnectivity | Omit = omit, tags: Dict[str, str] | Omit = omit, vip_ip_family: InterfaceIPFamily | Omit = omit, @@ -964,6 +956,8 @@ async def create( region_id: Region ID + name: Load balancer name. + flavor: Load balancer flavor name floating_ip: Floating IP configuration for assignment @@ -973,11 +967,6 @@ async def create( logging: Logging configuration - name: Load balancer name. Either `name` or `name_template` should be specified. - - name_template: Load balancer name which will be changed by template. Either `name` or - `name_template` should be specified. - preferred_connectivity: Preferred option to establish connectivity between load balancer and its pools members. L2 provides best performance, L3 provides less IPs usage. It is taking effect only if `instance_id` + `ip_address` is provided, not `subnet_id` + @@ -1021,12 +1010,11 @@ async def create( ), body=await async_maybe_transform( { + "name": name, "flavor": flavor, "floating_ip": floating_ip, "listeners": listeners, "logging": logging, - "name": name, - "name_template": name_template, "preferred_connectivity": preferred_connectivity, "tags": tags, "vip_ip_family": vip_ip_family, @@ -1259,8 +1247,7 @@ async def create_and_poll( floating_ip: load_balancer_create_params.FloatingIP | Omit = omit, listeners: Iterable[load_balancer_create_params.Listener] | Omit = omit, logging: load_balancer_create_params.Logging | Omit = omit, - name: str | Omit = omit, - name_template: str | Omit = omit, + name: str, preferred_connectivity: LoadBalancerMemberConnectivity | Omit = omit, tags: Dict[str, str] | Omit = omit, vip_ip_family: InterfaceIPFamily | Omit = omit, @@ -1284,7 +1271,6 @@ async def create_and_poll( listeners=listeners, logging=logging, name=name, - name_template=name_template, preferred_connectivity=preferred_connectivity, tags=tags, vip_ip_family=vip_ip_family, diff --git a/src/gcore/resources/cloud/load_balancers/pools/pools.py b/src/gcore/resources/cloud/load_balancers/pools/pools.py index ea10ebba5..330079daf 100644 --- a/src/gcore/resources/cloud/load_balancers/pools/pools.py +++ b/src/gcore/resources/cloud/load_balancers/pools/pools.py @@ -315,8 +315,10 @@ def list( project_id: int | None = None, region_id: int | None = None, details: bool | Omit = omit, + limit: int | Omit = omit, listener_id: str | Omit = omit, load_balancer_id: str | 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, @@ -334,10 +336,15 @@ def list( details: Show members and Health Monitor details + limit: Optional. Limit the number of returned items + listener_id: Listener ID load_balancer_id: Load Balancer ID + offset: Optional. Offset value is used to exclude the first set of records from the + result + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -360,8 +367,10 @@ def list( query=maybe_transform( { "details": details, + "limit": limit, "listener_id": listener_id, "load_balancer_id": load_balancer_id, + "offset": offset, }, pool_list_params.PoolListParams, ), @@ -912,8 +921,10 @@ async def list( project_id: int | None = None, region_id: int | None = None, details: bool | Omit = omit, + limit: int | Omit = omit, listener_id: str | Omit = omit, load_balancer_id: str | 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, @@ -931,10 +942,15 @@ async def list( details: Show members and Health Monitor details + limit: Optional. Limit the number of returned items + listener_id: Listener ID load_balancer_id: Load Balancer ID + offset: Optional. Offset value is used to exclude the first set of records from the + result + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -957,8 +973,10 @@ async def list( query=await async_maybe_transform( { "details": details, + "limit": limit, "listener_id": listener_id, "load_balancer_id": load_balancer_id, + "offset": offset, }, pool_list_params.PoolListParams, ), diff --git a/src/gcore/resources/cloud/networks/routers.py b/src/gcore/resources/cloud/networks/routers.py index 56931a61e..8946358b7 100644 --- a/src/gcore/resources/cloud/networks/routers.py +++ b/src/gcore/resources/cloud/networks/routers.py @@ -76,6 +76,10 @@ def create( Create a new router with the specified configuration. Args: + project_id: Project ID + + region_id: Region ID + name: name of router external_gateway_info: External gateway configuration. Use type 'default' to let the platform @@ -188,6 +192,7 @@ def list( project_id: int | None = None, region_id: int | None = None, limit: int | Omit = omit, + name: str | 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. @@ -200,9 +205,15 @@ def list( List all routers in the specified project and region. Args: - limit: Limit the number of returned routers + project_id: Project ID + + region_id: Region ID + + limit: Limit of items on a single page + + name: Optional. Filter routers by name - offset: Offset value is used to exclude the first set of records from the result + offset: Offset in results list extra_headers: Send extra headers @@ -227,6 +238,7 @@ def list( query=maybe_transform( { "limit": limit, + "name": name, "offset": offset, }, router_list_params.RouterListParams, @@ -480,6 +492,10 @@ async def create( Create a new router with the specified configuration. Args: + project_id: Project ID + + region_id: Region ID + name: name of router external_gateway_info: External gateway configuration. Use type 'default' to let the platform @@ -592,6 +608,7 @@ def list( project_id: int | None = None, region_id: int | None = None, limit: int | Omit = omit, + name: str | 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. @@ -604,9 +621,15 @@ def list( List all routers in the specified project and region. Args: - limit: Limit the number of returned routers + project_id: Project ID + + region_id: Region ID + + limit: Limit of items on a single page + + name: Optional. Filter routers by name - offset: Offset value is used to exclude the first set of records from the result + offset: Offset in results list extra_headers: Send extra headers @@ -631,6 +654,7 @@ def list( query=maybe_transform( { "limit": limit, + "name": name, "offset": offset, }, router_list_params.RouterListParams, diff --git a/src/gcore/resources/cloud/security_groups/rules.py b/src/gcore/resources/cloud/security_groups/rules.py index 9fba7c36b..061c42743 100644 --- a/src/gcore/resources/cloud/security_groups/rules.py +++ b/src/gcore/resources/cloud/security_groups/rules.py @@ -61,31 +61,32 @@ def create( ethertype: Literal["IPv4", "IPv6"] | Omit = omit, port_range_max: Optional[int] | Omit = omit, port_range_min: Optional[int] | Omit = omit, - protocol: Literal[ - "ah", - "any", - "dccp", - "egp", - "esp", - "gre", - "icmp", - "igmp", - "ipencap", - "ipip", - "ipv6-encap", - "ipv6-frag", - "ipv6-icmp", - "ipv6-nonxt", - "ipv6-opts", - "ipv6-route", - "ospf", - "pgm", - "rsvp", - "sctp", - "tcp", - "udp", - "udplite", - "vrrp", + protocol: Optional[ + Literal[ + "ah", + "dccp", + "egp", + "esp", + "gre", + "icmp", + "igmp", + "ipencap", + "ipip", + "ipv6-encap", + "ipv6-frag", + "ipv6-icmp", + "ipv6-nonxt", + "ipv6-opts", + "ipv6-route", + "ospf", + "pgm", + "rsvp", + "sctp", + "tcp", + "udp", + "udplite", + "vrrp", + ] ] | Omit = omit, remote_group_id: str | Omit = omit, @@ -119,7 +120,7 @@ def create( port_range_min: The minimum port number in the range that is matched by the security group rule - protocol: Protocol + protocol: V2 protocol enum without 'any'. Use null for all protocols instead. remote_group_id: The remote group UUID to associate with this security group @@ -361,7 +362,6 @@ def create_and_poll( port_range_min: Optional[int] | Omit = omit, protocol: Literal[ "ah", - "any", "dccp", "egp", "esp", @@ -522,31 +522,32 @@ async def create( ethertype: Literal["IPv4", "IPv6"] | Omit = omit, port_range_max: Optional[int] | Omit = omit, port_range_min: Optional[int] | Omit = omit, - protocol: Literal[ - "ah", - "any", - "dccp", - "egp", - "esp", - "gre", - "icmp", - "igmp", - "ipencap", - "ipip", - "ipv6-encap", - "ipv6-frag", - "ipv6-icmp", - "ipv6-nonxt", - "ipv6-opts", - "ipv6-route", - "ospf", - "pgm", - "rsvp", - "sctp", - "tcp", - "udp", - "udplite", - "vrrp", + protocol: Optional[ + Literal[ + "ah", + "dccp", + "egp", + "esp", + "gre", + "icmp", + "igmp", + "ipencap", + "ipip", + "ipv6-encap", + "ipv6-frag", + "ipv6-icmp", + "ipv6-nonxt", + "ipv6-opts", + "ipv6-route", + "ospf", + "pgm", + "rsvp", + "sctp", + "tcp", + "udp", + "udplite", + "vrrp", + ] ] | Omit = omit, remote_group_id: str | Omit = omit, @@ -580,7 +581,7 @@ async def create( port_range_min: The minimum port number in the range that is matched by the security group rule - protocol: Protocol + protocol: V2 protocol enum without 'any'. Use null for all protocols instead. remote_group_id: The remote group UUID to associate with this security group @@ -822,7 +823,6 @@ async def create_and_poll( port_range_min: Optional[int] | Omit = omit, protocol: Literal[ "ah", - "any", "dccp", "egp", "esp", diff --git a/src/gcore/resources/dns/api.md b/src/gcore/resources/dns/api.md index ff89a8bc2..86f3648e9 100644 --- a/src/gcore/resources/dns/api.md +++ b/src/gcore/resources/dns/api.md @@ -154,6 +154,6 @@ Methods: - client.dns.network_mappings.list(\*\*params) -> NetworkMappingListResponse - client.dns.network_mappings.delete(id) -> object - client.dns.network_mappings.get(id) -> DNSNetworkMapping -- client.dns.network_mappings.get_by_name(name) -> DNSNetworkMapping +- client.dns.network_mappings.get_by_name(name) -> DNSNetworkMapping - client.dns.network*mappings.import*() -> NetworkMappingImportResponse - client.dns.network_mappings.replace(id, \*\*params) -> object diff --git a/src/gcore/resources/dns/network_mappings.py b/src/gcore/resources/dns/network_mappings.py index 567435c68..f7a0bd11d 100644 --- a/src/gcore/resources/dns/network_mappings.py +++ b/src/gcore/resources/dns/network_mappings.py @@ -282,7 +282,7 @@ def get_by_name( Example of request: ``` - curl --location --request GET 'https://api.gcore.com/dns/v2/network-mappings/test-mapping' \\ + curl --location --request GET 'https://api.gcore.com/dns/v2/network-mappings/by-name/test-mapping' \\ --header 'Authorization: Bearer ...' ``` @@ -298,7 +298,7 @@ def get_by_name( if not name: raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") return self._get( - path_template("/dns/v2/network-mappings/{name}", name=name), + path_template("/dns/v2/network-mappings/by-name/{name}", name=name), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -716,7 +716,7 @@ async def get_by_name( Example of request: ``` - curl --location --request GET 'https://api.gcore.com/dns/v2/network-mappings/test-mapping' \\ + curl --location --request GET 'https://api.gcore.com/dns/v2/network-mappings/by-name/test-mapping' \\ --header 'Authorization: Bearer ...' ``` @@ -732,7 +732,7 @@ async def get_by_name( if not name: raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") return await self._get( - path_template("/dns/v2/network-mappings/{name}", name=name), + path_template("/dns/v2/network-mappings/by-name/{name}", name=name), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/gcore/types/cdn/origin_group_create_params.py b/src/gcore/types/cdn/origin_group_create_params.py index 10e256e54..8efbd7d26 100644 --- a/src/gcore/types/cdn/origin_group_create_params.py +++ b/src/gcore/types/cdn/origin_group_create_params.py @@ -26,7 +26,9 @@ class NoneAuth(TypedDict, total=False): sources: Required[Iterable[NoneAuthSource]] auth_type: str - """Origin authentication type. + """**Deprecated.** No longer necessary. Defaults to `none`. + + Origin authentication type. Possible values: @@ -204,10 +206,19 @@ class NoneAuthSourceChangeS3Source(TypedDict, total=False): class AwsSignatureV4(TypedDict, total=False): auth: Required[AwsSignatureV4Auth] - """Credentials to access the private bucket.""" + """ + **Deprecated.** To create S3 origins, configure them directly in sources with + `origin_type` and `config` instead. + + Credentials to access the private bucket. + """ auth_type: Required[str] - """Authentication type. + """ + **Deprecated.** To create S3 origins, configure them directly in sources with + `origin_type` and `config` instead. + + Authentication type. **awsSignatureV4** value is used for S3 storage. """ @@ -248,7 +259,11 @@ class AwsSignatureV4(TypedDict, total=False): class AwsSignatureV4Auth(TypedDict, total=False): - """Credentials to access the private bucket.""" + """ + **Deprecated.** To create S3 origins, configure them directly in sources with `origin_type` and `config` instead. + + Credentials to access the private bucket. + """ s3_access_key_id: Required[str] """Access key ID for the S3 account. diff --git a/src/gcore/types/cdn/origin_group_replace_params.py b/src/gcore/types/cdn/origin_group_replace_params.py index 4a93b73bf..a8694a660 100644 --- a/src/gcore/types/cdn/origin_group_replace_params.py +++ b/src/gcore/types/cdn/origin_group_replace_params.py @@ -20,21 +20,9 @@ class NoneAuth(TypedDict, total=False): - auth_type: Required[str] - """Origin authentication type. - - Possible values: - - - **none** - Used for public origins. - - **awsSignatureV4** - Used for S3 storage. - """ - name: Required[str] """Origin group name.""" - path: Required[str] - """Parameter is **deprecated**.""" - sources: Required[Iterable[NoneAuthSource]] use_next: Required[bool] @@ -49,6 +37,25 @@ class NoneAuth(TypedDict, total=False): - **false** - Option is disabled. """ + auth_type: str + """**Deprecated.** No longer necessary. Defaults to `none`. + + Origin authentication type. + + Possible values: + + - **none** - Used for public origins. + - **awsSignatureV4** - Used for S3 storage. + """ + + path: str + """**Deprecated.** No longer necessary. + + Omit this field and the default origin path behavior will be used. + + Origin path prefix. + """ + proxy_next_upstream: SequenceNotStr[str] """Defines cases when the request should be passed on to the next origin. @@ -207,10 +214,19 @@ class NoneAuthSourceChangeS3Source(TypedDict, total=False): class AwsSignatureV4(TypedDict, total=False): auth: Required[AwsSignatureV4Auth] - """Credentials to access the private bucket.""" + """ + **Deprecated.** To create S3 origins, configure them directly in sources with + `origin_type` and `config` instead. + + Credentials to access the private bucket. + """ auth_type: Required[str] - """Authentication type. + """ + **Deprecated.** To create S3 origins, configure them directly in sources with + `origin_type` and `config` instead. + + Authentication type. **awsSignatureV4** value is used for S3 storage. """ @@ -218,9 +234,6 @@ class AwsSignatureV4(TypedDict, total=False): name: Required[str] """Origin group name.""" - path: Required[str] - """Parameter is **deprecated**.""" - use_next: Required[bool] """ Defines whether to use the next origin from the origin group if origin responds @@ -233,6 +246,14 @@ class AwsSignatureV4(TypedDict, total=False): - **false** - Option is disabled. """ + path: str + """**Deprecated.** No longer necessary. + + Omit this field and the default origin path behavior will be used. + + Origin path prefix. + """ + proxy_next_upstream: SequenceNotStr[str] """Defines cases when the request should be passed on to the next origin. @@ -254,7 +275,11 @@ class AwsSignatureV4(TypedDict, total=False): class AwsSignatureV4Auth(TypedDict, total=False): - """Credentials to access the private bucket.""" + """ + **Deprecated.** To create S3 origins, configure them directly in sources with `origin_type` and `config` instead. + + Credentials to access the private bucket. + """ s3_access_key_id: Required[str] """Access key ID for the S3 account. diff --git a/src/gcore/types/cdn/origin_group_update_params.py b/src/gcore/types/cdn/origin_group_update_params.py index 39593b45b..63a0cb0fa 100644 --- a/src/gcore/types/cdn/origin_group_update_params.py +++ b/src/gcore/types/cdn/origin_group_update_params.py @@ -24,7 +24,9 @@ class NoneAuth(TypedDict, total=False): """Origin group name.""" auth_type: str - """Origin authentication type. + """**Deprecated.** No longer necessary. Defaults to `none`. + + Origin authentication type. Possible values: @@ -33,7 +35,12 @@ class NoneAuth(TypedDict, total=False): """ path: str - """Parameter is **deprecated**.""" + """**Deprecated.** No longer necessary. + + Omit this field and the default origin path behavior will be used. + + Origin path prefix. + """ proxy_next_upstream: SequenceNotStr[str] """Defines cases when the request should be passed on to the next origin. @@ -207,10 +214,19 @@ class NoneAuthSourceChangeS3Source(TypedDict, total=False): class AwsSignatureV4(TypedDict, total=False): auth: AwsSignatureV4Auth - """Credentials to access the private bucket.""" + """ + **Deprecated.** To create S3 origins, configure them directly in sources with + `origin_type` and `config` instead. + + Credentials to access the private bucket. + """ auth_type: str - """Authentication type. + """ + **Deprecated.** To create S3 origins, configure them directly in sources with + `origin_type` and `config` instead. + + Authentication type. **awsSignatureV4** value is used for S3 storage. """ @@ -219,7 +235,12 @@ class AwsSignatureV4(TypedDict, total=False): """Origin group name.""" path: str - """Parameter is **deprecated**.""" + """**Deprecated.** No longer necessary. + + Omit this field and the default origin path behavior will be used. + + Origin path prefix. + """ proxy_next_upstream: SequenceNotStr[str] """Defines cases when the request should be passed on to the next origin. @@ -254,7 +275,11 @@ class AwsSignatureV4(TypedDict, total=False): class AwsSignatureV4Auth(TypedDict, total=False): - """Credentials to access the private bucket.""" + """ + **Deprecated.** To create S3 origins, configure them directly in sources with `origin_type` and `config` instead. + + Credentials to access the private bucket. + """ s3_access_key_id: Required[str] """Access key ID for the S3 account. diff --git a/src/gcore/types/cdn/origin_groups.py b/src/gcore/types/cdn/origin_groups.py index 4bf02eb80..43a63d92e 100644 --- a/src/gcore/types/cdn/origin_groups.py +++ b/src/gcore/types/cdn/origin_groups.py @@ -179,7 +179,9 @@ class NoneAuth(BaseModel): """ auth_type: Optional[str] = None - """Origin authentication type. + """**Deprecated.** No longer necessary. Defaults to `none`. + + Origin authentication type. Possible values: @@ -197,7 +199,12 @@ class NoneAuth(BaseModel): """ path: Optional[str] = None - """Parameter is **deprecated**.""" + """**Deprecated.** No longer necessary. + + Omit this field and the default origin path behavior will be used. + + Origin path prefix. + """ proxy_next_upstream: Optional[List[str]] = None """Defines cases when the request should be passed on to the next origin. @@ -232,7 +239,11 @@ class NoneAuth(BaseModel): class AwsSignatureV4Auth(BaseModel): - """Credentials to access the private bucket.""" + """ + **Deprecated.** To create S3 origins, configure them directly in sources with `origin_type` and `config` instead. + + Credentials to access the private bucket. + """ s3_access_key_id: str """Access key ID for the S3 account. @@ -280,14 +291,27 @@ class AwsSignatureV4Auth(BaseModel): class AwsSignatureV4(BaseModel): + """ + **Deprecated.** To create S3 origins, configure them directly in sources with `origin_type` and `config` instead. + """ + id: int """Origin group ID.""" auth: AwsSignatureV4Auth - """Credentials to access the private bucket.""" + """ + **Deprecated.** To create S3 origins, configure them directly in sources with + `origin_type` and `config` instead. + + Credentials to access the private bucket. + """ auth_type: str - """Authentication type. + """ + **Deprecated.** To create S3 origins, configure them directly in sources with + `origin_type` and `config` instead. + + Authentication type. **awsSignatureV4** value is used for S3 storage. """ @@ -305,7 +329,12 @@ class AwsSignatureV4(BaseModel): """ path: Optional[str] = None - """Parameter is **deprecated**.""" + """**Deprecated.** No longer necessary. + + Omit this field and the default origin path behavior will be used. + + Origin path prefix. + """ proxy_next_upstream: Optional[List[str]] = None """Defines cases when the request should be passed on to the next origin. diff --git a/src/gcore/types/cdn/shield_list_response.py b/src/gcore/types/cdn/shield_list_response.py index 6956cf1ed..458a400cf 100644 --- a/src/gcore/types/cdn/shield_list_response.py +++ b/src/gcore/types/cdn/shield_list_response.py @@ -1,13 +1,14 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional +from typing_extensions import TypeAlias from ..._models import BaseModel -__all__ = ["ShieldListResponse"] +__all__ = ["ShieldListResponse", "PlainList", "PaginatedList", "PaginatedListResult"] -class ShieldListResponse(BaseModel): +class PlainList(BaseModel): id: Optional[int] = None """Origin shielding location ID.""" @@ -19,3 +20,33 @@ class ShieldListResponse(BaseModel): datacenter: Optional[str] = None """Name of origin shielding location datacenter.""" + + +class PaginatedListResult(BaseModel): + id: Optional[int] = None + """Origin shielding location ID.""" + + city: Optional[str] = None + """City of origin shielding location.""" + + country: Optional[str] = None + """Country of origin shielding location.""" + + datacenter: Optional[str] = None + """Name of origin shielding location datacenter.""" + + +class PaginatedList(BaseModel): + count: int + """Total number of items.""" + + next: Optional[str] = None + """URL to the next page of results. Null if current page is the last one.""" + + previous: Optional[str] = None + """URL to the previous page of results. Null if current page is the first one.""" + + results: List[PaginatedListResult] + + +ShieldListResponse: TypeAlias = Union[List[PlainList], PaginatedList] diff --git a/src/gcore/types/cloud/__init__.py b/src/gcore/types/cloud/__init__.py index 450b32e1d..bf9dea98b 100644 --- a/src/gcore/types/cloud/__init__.py +++ b/src/gcore/types/cloud/__init__.py @@ -4,7 +4,6 @@ from .tag import Tag as Tag from .task import Task as Task -from .image import Image as Image from .route import Route as Route from .member import Member as Member from .region import Region as Region @@ -22,7 +21,6 @@ from .gpu_image import GPUImage as GPUImage from .ip_ranges import IPRanges as IPRanges from .file_share import FileShare as FileShare -from .image_list import ImageList as ImageList from .ip_version import IPVersion as IPVersion from .floating_ip import FloatingIP as FloatingIP from .http_method import HTTPMethod as HTTPMethod diff --git a/src/gcore/types/cloud/baremetal/__init__.py b/src/gcore/types/cloud/baremetal/__init__.py index c96b54978..845e2578d 100644 --- a/src/gcore/types/cloud/baremetal/__init__.py +++ b/src/gcore/types/cloud/baremetal/__init__.py @@ -2,10 +2,12 @@ from __future__ import annotations +from .baremetal_image import BaremetalImage as BaremetalImage from .baremetal_server import BaremetalServer as BaremetalServer from .image_list_params import ImageListParams as ImageListParams from .flavor_list_params import FlavorListParams as FlavorListParams from .server_list_params import ServerListParams as ServerListParams +from .baremetal_image_list import BaremetalImageList as BaremetalImageList from .server_create_params import ServerCreateParams as ServerCreateParams from .server_delete_params import ServerDeleteParams as ServerDeleteParams from .server_update_params import ServerUpdateParams as ServerUpdateParams diff --git a/src/gcore/types/cloud/baremetal/baremetal_image.py b/src/gcore/types/cloud/baremetal/baremetal_image.py new file mode 100644 index 000000000..91a534d1f --- /dev/null +++ b/src/gcore/types/cloud/baremetal/baremetal_image.py @@ -0,0 +1,121 @@ +# 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 ..tag import Tag +from ...._models import BaseModel + +__all__ = ["BaremetalImage"] + + +class BaremetalImage(BaseModel): + id: str + """Image ID""" + + architecture: Literal["aarch64", "x86_64"] + """An image architecture type: aarch64, `x86_64`.""" + + created_at: datetime + """Datetime when the image was created""" + + creator_task_id: Optional[str] = None + """Task that created this entity""" + + currency_code: Optional[str] = None + """Currency code. Shown if the `include_prices` query parameter if set to true""" + + description: Optional[str] = None + """Image description""" + + disk_format: str + """Disk format""" + + display_order: Optional[int] = None + + gpu_driver: Optional[str] = None + """Name of the GPU driver vendor""" + + gpu_driver_type: Optional[str] = None + """Type of the GPU driver""" + + gpu_driver_version: Optional[str] = None + """Version of the installed GPU driver""" + + hw_firmware_type: Optional[Literal["bios", "uefi"]] = None + """Specifies the type of firmware with which to boot the guest.""" + + hw_machine_type: Optional[Literal["pc", "q35"]] = None + """A virtual chipset type.""" + + is_baremetal: Optional[bool] = None + """For bare metal servers this value is always set to true""" + + min_disk: int + """Minimal boot volume required""" + + min_ram: int + """Minimal VM RAM required""" + + name: str + """Image display name""" + + os_distro: str + """OS Distribution, i.e. Debian, CentOS, Ubuntu, CoreOS etc.""" + + os_type: Literal["linux", "windows"] + """The operating system installed on the image.""" + + os_version: str + """OS version, i.e. 19.04 (for Ubuntu) or 9.4 for Debian""" + + price_per_hour: Optional[float] = None + """Price per hour. Shown if the `include_prices` query parameter if set to true""" + + price_per_month: Optional[float] = None + """Price per month. Shown if the `include_prices` query parameter if set to true""" + + price_status: Optional[Literal["error", "hide", "show"]] = None + """Price status for the UI""" + + project_id: int + """Project ID""" + + region: str + """Region name""" + + region_id: int + """Region ID""" + + size: Optional[int] = None + """Image size in bytes""" + + ssh_key: Optional[Literal["allow", "deny", "required"]] = None + """Whether the image supports SSH key or not""" + + status: str + """Image status, i.e. active""" + + tags: List[Tag] + """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. + """ + + task_id: Optional[str] = None + """The UUID of the active task that currently holds a lock on the resource. + + This lock prevents concurrent modifications to ensure consistency. If `null`, + the resource is not locked. + """ + + updated_at: datetime + """Datetime when the image was updated""" + + visibility: str + """Image visibility. Globally visible images are public""" diff --git a/src/gcore/types/cloud/baremetal/baremetal_image_list.py b/src/gcore/types/cloud/baremetal/baremetal_image_list.py new file mode 100644 index 000000000..643c19415 --- /dev/null +++ b/src/gcore/types/cloud/baremetal/baremetal_image_list.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List + +from ...._models import BaseModel +from .baremetal_image import BaremetalImage + +__all__ = ["BaremetalImageList"] + + +class BaremetalImageList(BaseModel): + count: int + """Number of objects""" + + results: List[BaremetalImage] + """Objects""" diff --git a/src/gcore/types/cloud/baremetal/image_list_params.py b/src/gcore/types/cloud/baremetal/image_list_params.py index 1e1d29030..db3e88547 100644 --- a/src/gcore/types/cloud/baremetal/image_list_params.py +++ b/src/gcore/types/cloud/baremetal/image_list_params.py @@ -11,20 +11,22 @@ class ImageListParams(TypedDict, total=False): project_id: int + """Project ID""" region_id: int + """Region ID""" include_prices: bool - """Show price""" + """Show price.""" private: str """Any value to show private images""" tag_key: SequenceNotStr[str] - """Filter by tag keys.""" + """Optional. Filter by tag keys. ?`tag_key`=key1&`tag_key`=key2""" tag_key_value: str - """Filter by tag key-value pairs. Must be a valid JSON string.""" + """Optional. Filter by tag key-value pairs.""" visibility: Literal["private", "public", "shared"] """Image visibility. Globally visible images are public""" diff --git a/src/gcore/types/cloud/baremetal/server_create_params.py b/src/gcore/types/cloud/baremetal/server_create_params.py index ad257adf2..d406fbec8 100644 --- a/src/gcore/types/cloud/baremetal/server_create_params.py +++ b/src/gcore/types/cloud/baremetal/server_create_params.py @@ -353,14 +353,11 @@ class InterfaceCreateBareMetalReservedFixedIPInterfaceSerializer(TypedDict, tota class DDOSProfileField(TypedDict, total=False): - base_field: Optional[int] + base_field: Required[int] """Unique identifier of the DDoS protection field being configured""" field_value: object - value: Optional[str] - """Basic type value. Only one of 'value' or 'field_value' must be specified.""" - class DDOSProfile(TypedDict, total=False): """Enable advanced DDoS protection for the server""" diff --git a/src/gcore/types/cloud/billing_reservation.py b/src/gcore/types/cloud/billing_reservation.py index 9800c0298..6b56ff235 100644 --- a/src/gcore/types/cloud/billing_reservation.py +++ b/src/gcore/types/cloud/billing_reservation.py @@ -48,7 +48,7 @@ class Commit(BaseModel): price_total: str """Total price for the reservation period for the full reserved amount""" - subscription_id: int + subscription_id: Optional[int] = None """Billing subscription ID for commit""" diff --git a/src/gcore/types/cloud/cost_report_aggregated.py b/src/gcore/types/cloud/cost_report_aggregated.py index 4697169e1..a1fd1fb7b 100644 --- a/src/gcore/types/cloud/cost_report_aggregated.py +++ b/src/gcore/types/cloud/cost_report_aggregated.py @@ -253,7 +253,7 @@ class ResultTotalEgressTrafficWithCostSerializer(BaseModel): err: Optional[str] = None """Error message""" - instance_type: Literal["baremetal", "vm"] + instance_type: Literal["baremetal", "router", "vm"] """Type of the instance""" region: int diff --git a/src/gcore/types/cloud/cost_report_aggregated_monthly.py b/src/gcore/types/cloud/cost_report_aggregated_monthly.py index d62de86d9..4eb91aa44 100644 --- a/src/gcore/types/cloud/cost_report_aggregated_monthly.py +++ b/src/gcore/types/cloud/cost_report_aggregated_monthly.py @@ -253,7 +253,7 @@ class ResultTotalEgressTrafficWithCostSerializer(BaseModel): err: Optional[str] = None """Error message""" - instance_type: Literal["baremetal", "vm"] + instance_type: Literal["baremetal", "router", "vm"] """Type of the instance""" region: int diff --git a/src/gcore/types/cloud/cost_report_detailed.py b/src/gcore/types/cloud/cost_report_detailed.py index 348099aff..abec94014 100644 --- a/src/gcore/types/cloud/cost_report_detailed.py +++ b/src/gcore/types/cloud/cost_report_detailed.py @@ -368,7 +368,7 @@ class ResultResourceEgressTrafficWithCostSerializer(BaseModel): instance_name: Optional[str] = None """Name of the instance""" - instance_type: Literal["baremetal", "vm"] + instance_type: Literal["baremetal", "router", "vm"] """Type of the instance""" last_seen: datetime diff --git a/src/gcore/types/cloud/ddos_profile_field.py b/src/gcore/types/cloud/ddos_profile_field.py index 0bcfbca14..2e325199a 100644 --- a/src/gcore/types/cloud/ddos_profile_field.py +++ b/src/gcore/types/cloud/ddos_profile_field.py @@ -11,7 +11,7 @@ class DDOSProfileField(BaseModel): id: int """Unique identifier for the DDoS protection field""" - base_field: Optional[int] = None + base_field: int """ID of DDoS profile field""" default: Optional[str] = None @@ -20,14 +20,11 @@ class DDOSProfileField(BaseModel): description: Optional[str] = None """Detailed description explaining the field's purpose and usage guidelines""" - field_name: Optional[str] = None - """Name of DDoS profile field""" - field_type: Optional[str] = None """Data type classification of the field (e.g., string, integer, array)""" field_value: object - """Complex value. Only one of 'value' or 'field_value' must be specified.""" + """Complex value for the DDoS profile field""" name: str """Human-readable name of the protection field""" @@ -39,6 +36,3 @@ class DDOSProfileField(BaseModel): validation_schema: object """JSON schema defining validation rules and constraints for the field value""" - - value: Optional[str] = None - """Basic type value. Only one of 'value' or 'field_value' must be specified.""" diff --git a/src/gcore/types/cloud/gpu_baremetal/clusters/gpu_baremetal_cluster_server.py b/src/gcore/types/cloud/gpu_baremetal/clusters/gpu_baremetal_cluster_server.py index ff1e581fc..9e58b475b 100644 --- a/src/gcore/types/cloud/gpu_baremetal/clusters/gpu_baremetal_cluster_server.py +++ b/src/gcore/types/cloud/gpu_baremetal/clusters/gpu_baremetal_cluster_server.py @@ -28,6 +28,9 @@ class GPUBaremetalClusterServer(BaseModel): flavor: str """Unique flavor identifier""" + has_pending_changes: bool + """True if there are pending (not yet applied) server settings changes""" + image_id: Optional[str] = None """Server's image UUID""" diff --git a/src/gcore/types/cloud/gpu_baremetal/clusters/interface_attach_params.py b/src/gcore/types/cloud/gpu_baremetal/clusters/interface_attach_params.py index f3a3c26e8..9dd695aa3 100644 --- a/src/gcore/types/cloud/gpu_baremetal/clusters/interface_attach_params.py +++ b/src/gcore/types/cloud/gpu_baremetal/clusters/interface_attach_params.py @@ -51,14 +51,11 @@ class NewInterfaceExternalExtendSchemaWithDDOS(TypedDict, total=False): class NewInterfaceExternalExtendSchemaWithDdosddosProfileField(TypedDict, total=False): - base_field: Optional[int] + base_field: Required[int] """ID of DDoS profile field""" - field_name: Optional[str] - """Name of DDoS profile field""" - field_value: object - """Complex value. Only one of 'value' or 'field_value' must be specified.""" + """Complex value for the DDoS profile field""" value: Optional[str] """Basic type value. Only one of 'value' or 'field_value' must be specified.""" @@ -109,14 +106,11 @@ class NewInterfaceSpecificSubnetSchema(TypedDict, total=False): class NewInterfaceSpecificSubnetSchemaDDOSProfileField(TypedDict, total=False): - base_field: Optional[int] + base_field: Required[int] """ID of DDoS profile field""" - field_name: Optional[str] - """Name of DDoS profile field""" - field_value: object - """Complex value. Only one of 'value' or 'field_value' must be specified.""" + """Complex value for the DDoS profile field""" value: Optional[str] """Basic type value. Only one of 'value' or 'field_value' must be specified.""" @@ -170,14 +164,11 @@ class NewInterfaceAnySubnetSchema(TypedDict, total=False): class NewInterfaceAnySubnetSchemaDDOSProfileField(TypedDict, total=False): - base_field: Optional[int] + base_field: Required[int] """ID of DDoS profile field""" - field_name: Optional[str] - """Name of DDoS profile field""" - field_value: object - """Complex value. Only one of 'value' or 'field_value' must be specified.""" + """Complex value for the DDoS profile field""" value: Optional[str] """Basic type value. Only one of 'value' or 'field_value' must be specified.""" @@ -228,14 +219,11 @@ class NewInterfaceReservedFixedIPSchema(TypedDict, total=False): class NewInterfaceReservedFixedIPSchemaDDOSProfileField(TypedDict, total=False): - base_field: Optional[int] + base_field: Required[int] """ID of DDoS profile field""" - field_name: Optional[str] - """Name of DDoS profile field""" - field_value: object - """Complex value. Only one of 'value' or 'field_value' must be specified.""" + """Complex value for the DDoS profile field""" value: Optional[str] """Basic type value. Only one of 'value' or 'field_value' must be specified.""" diff --git a/src/gcore/types/cloud/gpu_baremetal/gpu_baremetal_cluster.py b/src/gcore/types/cloud/gpu_baremetal/gpu_baremetal_cluster.py index cba481304..ae01de520 100644 --- a/src/gcore/types/cloud/gpu_baremetal/gpu_baremetal_cluster.py +++ b/src/gcore/types/cloud/gpu_baremetal/gpu_baremetal_cluster.py @@ -131,6 +131,11 @@ class GPUBaremetalCluster(BaseModel): flavor: str """Cluster flavor name""" + has_pending_changes: bool + """ + True if any server in the cluster has pending (not yet applied) settings changes + """ + image_id: str """Image ID""" diff --git a/src/gcore/types/cloud/gpu_virtual/clusters/gpu_virtual_cluster_server.py b/src/gcore/types/cloud/gpu_virtual/clusters/gpu_virtual_cluster_server.py index d8126e53a..81b25a591 100644 --- a/src/gcore/types/cloud/gpu_virtual/clusters/gpu_virtual_cluster_server.py +++ b/src/gcore/types/cloud/gpu_virtual/clusters/gpu_virtual_cluster_server.py @@ -28,6 +28,9 @@ class GPUVirtualClusterServer(BaseModel): flavor: str """Unique flavor identifier""" + has_pending_changes: bool + """True if there are pending (not yet applied) server settings changes""" + image_id: Optional[str] = None """Server's image UUID""" diff --git a/src/gcore/types/cloud/gpu_virtual/gpu_virtual_cluster.py b/src/gcore/types/cloud/gpu_virtual/gpu_virtual_cluster.py index d31d1b36f..89333e0d8 100644 --- a/src/gcore/types/cloud/gpu_virtual/gpu_virtual_cluster.py +++ b/src/gcore/types/cloud/gpu_virtual/gpu_virtual_cluster.py @@ -165,6 +165,11 @@ class GPUVirtualCluster(BaseModel): flavor: str """Cluster flavor name""" + has_pending_changes: bool + """ + True if any server in the cluster has pending (not yet applied) settings changes + """ + name: str """Cluster name""" diff --git a/src/gcore/types/cloud/inference/__init__.py b/src/gcore/types/cloud/inference/__init__.py index 66a4d1985..194d24e15 100644 --- a/src/gcore/types/cloud/inference/__init__.py +++ b/src/gcore/types/cloud/inference/__init__.py @@ -22,7 +22,6 @@ from .deployment_create_params import DeploymentCreateParams as DeploymentCreateParams from .deployment_update_params import DeploymentUpdateParams as DeploymentUpdateParams from .inference_api_key_created import InferenceAPIKeyCreated as InferenceAPIKeyCreated -from .inference_deployment_api_key import InferenceDeploymentAPIKey as InferenceDeploymentAPIKey from .inference_registry_credentials import InferenceRegistryCredentials as InferenceRegistryCredentials from .registry_credential_list_params import RegistryCredentialListParams as RegistryCredentialListParams from .registry_credential_create_params import RegistryCredentialCreateParams as RegistryCredentialCreateParams diff --git a/src/gcore/types/cloud/inference/inference_deployment_api_key.py b/src/gcore/types/cloud/inference/inference_deployment_api_key.py deleted file mode 100644 index e6df4ffa5..000000000 --- a/src/gcore/types/cloud/inference/inference_deployment_api_key.py +++ /dev/null @@ -1,15 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing_extensions import Literal - -from ...._models import BaseModel - -__all__ = ["InferenceDeploymentAPIKey"] - - -class InferenceDeploymentAPIKey(BaseModel): - secret: str - """API key secret""" - - status: Literal["PENDING", "READY"] - """API key status""" diff --git a/src/gcore/types/cloud/instances/__init__.py b/src/gcore/types/cloud/instances/__init__.py index fb06e51e6..85c26ce70 100644 --- a/src/gcore/types/cloud/instances/__init__.py +++ b/src/gcore/types/cloud/instances/__init__.py @@ -2,7 +2,9 @@ from __future__ import annotations +from .image import Image as Image from .metrics import Metrics as Metrics +from .image_list import ImageList as ImageList from .metrics_list import MetricsList as MetricsList from .image_get_params import ImageGetParams as ImageGetParams from .image_list_params import ImageListParams as ImageListParams diff --git a/src/gcore/types/cloud/image.py b/src/gcore/types/cloud/instances/image.py similarity index 78% rename from src/gcore/types/cloud/image.py rename to src/gcore/types/cloud/instances/image.py index 901b04364..823b6ce50 100644 --- a/src/gcore/types/cloud/image.py +++ b/src/gcore/types/cloud/instances/image.py @@ -4,8 +4,8 @@ from datetime import datetime from typing_extensions import Literal -from .tag import Tag -from ..._models import BaseModel +from ..tag import Tag +from ...._models import BaseModel __all__ = ["Image"] @@ -14,12 +14,44 @@ class Image(BaseModel): id: str """Image ID""" + architecture: Literal["aarch64", "x86_64"] + """An image architecture type: aarch64, `x86_64`.""" + created_at: datetime """Datetime when the image was created""" + creator_task_id: Optional[str] = None + """Task that created this entity""" + + currency_code: Optional[str] = None + """Currency code. Shown if the `include_prices` query parameter if set to true""" + + description: Optional[str] = None + """Image description""" + disk_format: str """Disk format""" + display_order: Optional[int] = None + + gpu_driver: Optional[str] = None + """Name of the GPU driver vendor""" + + gpu_driver_type: Optional[str] = None + """Type of the GPU driver""" + + gpu_driver_version: Optional[str] = None + """Version of the installed GPU driver""" + + hw_firmware_type: Optional[Literal["bios", "uefi"]] = None + """Specifies the type of firmware with which to boot the guest.""" + + hw_machine_type: Optional[Literal["pc", "q35"]] = None + """A virtual chipset type.""" + + is_baremetal: bool + """Set to true if the image will be used by bare metal servers.""" + min_disk: int """Minimal boot volume required""" @@ -38,6 +70,15 @@ class Image(BaseModel): os_version: str """OS version, i.e. 19.04 (for Ubuntu) or 9.4 for Debian""" + price_per_hour: Optional[float] = None + """Price per hour. Shown if the `include_prices` query parameter if set to true""" + + price_per_month: Optional[float] = None + """Price per month. Shown if the `include_prices` query parameter if set to true""" + + price_status: Optional[Literal["error", "hide", "show"]] = None + """Price status for the UI""" + project_id: int """Project ID""" @@ -47,9 +88,12 @@ class Image(BaseModel): region_id: int """Region ID""" - size: int + size: Optional[int] = None """Image size in bytes""" + ssh_key: Optional[Literal["allow", "deny", "required"]] = None + """Whether the image supports SSH key or not""" + status: str """Image status, i.e. active""" @@ -63,47 +107,15 @@ class Image(BaseModel): values. """ - updated_at: datetime - """Datetime when the image was updated""" - - visibility: str - """Image visibility. Globally visible images are public""" - - architecture: Optional[Literal["aarch64", "x86_64"]] = None - """An image architecture type: aarch64, `x86_64`""" - - creator_task_id: Optional[str] = None - """Task that created this entity""" - - description: Optional[str] = None - """Image description""" - - display_order: Optional[int] = None - - gpu_driver: Optional[str] = None - """Name of the GPU driver vendor""" - - gpu_driver_type: Optional[str] = None - """Type of the GPU driver""" - - gpu_driver_version: Optional[str] = None - """Version of the installed GPU driver""" - - hw_firmware_type: Optional[Literal["bios", "uefi"]] = None - """Specifies the type of firmware with which to boot the guest.""" - - hw_machine_type: Optional[Literal["pc", "q35"]] = None - """A virtual chipset type.""" - - is_baremetal: Optional[bool] = None - """Set to true if the image will be used by bare metal servers. Defaults to false.""" - - ssh_key: Optional[Literal["allow", "deny", "required"]] = None - """Whether the image supports SSH key or not""" - task_id: Optional[str] = None """The UUID of the active task that currently holds a lock on the resource. This lock prevents concurrent modifications to ensure consistency. If `null`, the resource is not locked. """ + + updated_at: datetime + """Datetime when the image was updated""" + + visibility: str + """Image visibility. Globally visible images are public""" diff --git a/src/gcore/types/cloud/instances/image_create_from_volume_params.py b/src/gcore/types/cloud/instances/image_create_from_volume_params.py index d98e34ae5..beb3f64f4 100644 --- a/src/gcore/types/cloud/instances/image_create_from_volume_params.py +++ b/src/gcore/types/cloud/instances/image_create_from_volume_params.py @@ -10,8 +10,10 @@ class ImageCreateFromVolumeParams(TypedDict, total=False): project_id: int + """Project ID""" region_id: int + """Region ID""" name: Required[str] """Image name""" diff --git a/src/gcore/types/cloud/image_list.py b/src/gcore/types/cloud/instances/image_list.py similarity index 89% rename from src/gcore/types/cloud/image_list.py rename to src/gcore/types/cloud/instances/image_list.py index 4a4981fc4..07ea56875 100644 --- a/src/gcore/types/cloud/image_list.py +++ b/src/gcore/types/cloud/instances/image_list.py @@ -3,7 +3,7 @@ from typing import List from .image import Image -from ..._models import BaseModel +from ...._models import BaseModel __all__ = ["ImageList"] diff --git a/src/gcore/types/cloud/instances/image_list_params.py b/src/gcore/types/cloud/instances/image_list_params.py index 1e1d29030..db3e88547 100644 --- a/src/gcore/types/cloud/instances/image_list_params.py +++ b/src/gcore/types/cloud/instances/image_list_params.py @@ -11,20 +11,22 @@ class ImageListParams(TypedDict, total=False): project_id: int + """Project ID""" region_id: int + """Region ID""" include_prices: bool - """Show price""" + """Show price.""" private: str """Any value to show private images""" tag_key: SequenceNotStr[str] - """Filter by tag keys.""" + """Optional. Filter by tag keys. ?`tag_key`=key1&`tag_key`=key2""" tag_key_value: str - """Filter by tag key-value pairs. Must be a valid JSON string.""" + """Optional. Filter by tag key-value pairs.""" visibility: Literal["private", "public", "shared"] """Image visibility. Globally visible images are public""" diff --git a/src/gcore/types/cloud/instances/interface_attach_params.py b/src/gcore/types/cloud/instances/interface_attach_params.py index f3a3c26e8..9dd695aa3 100644 --- a/src/gcore/types/cloud/instances/interface_attach_params.py +++ b/src/gcore/types/cloud/instances/interface_attach_params.py @@ -51,14 +51,11 @@ class NewInterfaceExternalExtendSchemaWithDDOS(TypedDict, total=False): class NewInterfaceExternalExtendSchemaWithDdosddosProfileField(TypedDict, total=False): - base_field: Optional[int] + base_field: Required[int] """ID of DDoS profile field""" - field_name: Optional[str] - """Name of DDoS profile field""" - field_value: object - """Complex value. Only one of 'value' or 'field_value' must be specified.""" + """Complex value for the DDoS profile field""" value: Optional[str] """Basic type value. Only one of 'value' or 'field_value' must be specified.""" @@ -109,14 +106,11 @@ class NewInterfaceSpecificSubnetSchema(TypedDict, total=False): class NewInterfaceSpecificSubnetSchemaDDOSProfileField(TypedDict, total=False): - base_field: Optional[int] + base_field: Required[int] """ID of DDoS profile field""" - field_name: Optional[str] - """Name of DDoS profile field""" - field_value: object - """Complex value. Only one of 'value' or 'field_value' must be specified.""" + """Complex value for the DDoS profile field""" value: Optional[str] """Basic type value. Only one of 'value' or 'field_value' must be specified.""" @@ -170,14 +164,11 @@ class NewInterfaceAnySubnetSchema(TypedDict, total=False): class NewInterfaceAnySubnetSchemaDDOSProfileField(TypedDict, total=False): - base_field: Optional[int] + base_field: Required[int] """ID of DDoS profile field""" - field_name: Optional[str] - """Name of DDoS profile field""" - field_value: object - """Complex value. Only one of 'value' or 'field_value' must be specified.""" + """Complex value for the DDoS profile field""" value: Optional[str] """Basic type value. Only one of 'value' or 'field_value' must be specified.""" @@ -228,14 +219,11 @@ class NewInterfaceReservedFixedIPSchema(TypedDict, total=False): class NewInterfaceReservedFixedIPSchemaDDOSProfileField(TypedDict, total=False): - base_field: Optional[int] + base_field: Required[int] """ID of DDoS profile field""" - field_name: Optional[str] - """Name of DDoS profile field""" - field_value: object - """Complex value. Only one of 'value' or 'field_value' must be specified.""" + """Complex value for the DDoS profile field""" value: Optional[str] """Basic type value. Only one of 'value' or 'field_value' must be specified.""" diff --git a/src/gcore/types/cloud/k8s/cluster_create_params.py b/src/gcore/types/cloud/k8s/cluster_create_params.py index 6888e4412..380c73fc5 100644 --- a/src/gcore/types/cloud/k8s/cluster_create_params.py +++ b/src/gcore/types/cloud/k8s/cluster_create_params.py @@ -327,10 +327,7 @@ class DDOSProfileField(TypedDict, total=False): base_field: Required[int] field_value: object - """Complex value. Only one of 'value' or 'field_value' must be specified""" - - value: Optional[str] - """Basic value. Only one of 'value' or 'field_value' must be specified""" + """Complex value for the DDoS profile field""" class DDOSProfile(TypedDict, total=False): diff --git a/src/gcore/types/cloud/k8s/cluster_update_params.py b/src/gcore/types/cloud/k8s/cluster_update_params.py index 911a71e8d..52aaea13f 100644 --- a/src/gcore/types/cloud/k8s/cluster_update_params.py +++ b/src/gcore/types/cloud/k8s/cluster_update_params.py @@ -237,10 +237,7 @@ class DDOSProfileField(TypedDict, total=False): base_field: Required[int] field_value: object - """Complex value. Only one of 'value' or 'field_value' must be specified""" - - value: Optional[str] - """Basic value. Only one of 'value' or 'field_value' must be specified""" + """Complex value for the DDoS profile field""" class DDOSProfile(TypedDict, total=False): diff --git a/src/gcore/types/cloud/k8s/k8s_cluster.py b/src/gcore/types/cloud/k8s/k8s_cluster.py index 283626ba9..3780a73f9 100644 --- a/src/gcore/types/cloud/k8s/k8s_cluster.py +++ b/src/gcore/types/cloud/k8s/k8s_cluster.py @@ -162,10 +162,7 @@ class DDOSProfileField(BaseModel): base_field: int field_value: Optional[object] = None - """Complex value. Only one of 'value' or 'field_value' must be specified""" - - value: Optional[str] = None - """Basic value. Only one of 'value' or 'field_value' must be specified""" + """Complex value for the DDoS profile field""" class DDOSProfile(BaseModel): diff --git a/src/gcore/types/cloud/load_balancer_create_params.py b/src/gcore/types/cloud/load_balancer_create_params.py index b1fe2885e..24e0724bc 100644 --- a/src/gcore/types/cloud/load_balancer_create_params.py +++ b/src/gcore/types/cloud/load_balancer_create_params.py @@ -38,6 +38,9 @@ class LoadBalancerCreateParams(TypedDict, total=False): region_id: int """Region ID""" + name: Required[str] + """Load balancer name.""" + flavor: str """Load balancer flavor name""" @@ -53,15 +56,6 @@ class LoadBalancerCreateParams(TypedDict, total=False): logging: Logging """Logging configuration""" - name: str - """Load balancer name. Either `name` or `name_template` should be specified.""" - - name_template: str - """Load balancer name which will be changed by template. - - Either `name` or `name_template` should be specified. - """ - preferred_connectivity: LoadBalancerMemberConnectivity """ Preferred option to establish connectivity between load balancer and its pools diff --git a/src/gcore/types/cloud/load_balancers/__init__.py b/src/gcore/types/cloud/load_balancers/__init__.py index cfacdce75..7a7eddafd 100644 --- a/src/gcore/types/cloud/load_balancers/__init__.py +++ b/src/gcore/types/cloud/load_balancers/__init__.py @@ -9,6 +9,7 @@ from .pool_update_params import PoolUpdateParams as PoolUpdateParams from .listener_get_params import ListenerGetParams as ListenerGetParams from .listener_list_params import ListenerListParams as ListenerListParams +from .l7_policy_list_params import L7PolicyListParams as L7PolicyListParams from .listener_create_params import ListenerCreateParams as ListenerCreateParams from .listener_delete_params import ListenerDeleteParams as ListenerDeleteParams from .listener_update_params import ListenerUpdateParams as ListenerUpdateParams diff --git a/src/gcore/types/cloud/load_balancers/flavor_list_params.py b/src/gcore/types/cloud/load_balancers/flavor_list_params.py index af622cd6c..ef732d4e3 100644 --- a/src/gcore/types/cloud/load_balancers/flavor_list_params.py +++ b/src/gcore/types/cloud/load_balancers/flavor_list_params.py @@ -16,3 +16,12 @@ class FlavorListParams(TypedDict, total=False): include_prices: bool """Set to true if the response should include flavor prices""" + + limit: int + """Optional. Limit the number of returned items""" + + offset: int + """Optional. + + Offset value is used to exclude the first set of records from the result + """ diff --git a/src/gcore/types/cloud/load_balancers/l7_policies/__init__.py b/src/gcore/types/cloud/load_balancers/l7_policies/__init__.py index 832f1d779..91199151a 100644 --- a/src/gcore/types/cloud/load_balancers/l7_policies/__init__.py +++ b/src/gcore/types/cloud/load_balancers/l7_policies/__init__.py @@ -2,5 +2,6 @@ from __future__ import annotations +from .rule_list_params import RuleListParams as RuleListParams from .rule_create_params import RuleCreateParams as RuleCreateParams from .rule_replace_params import RuleReplaceParams as RuleReplaceParams diff --git a/src/gcore/types/cloud/load_balancers/l7_policies/rule_list_params.py b/src/gcore/types/cloud/load_balancers/l7_policies/rule_list_params.py new file mode 100644 index 000000000..f4ccd8e06 --- /dev/null +++ b/src/gcore/types/cloud/load_balancers/l7_policies/rule_list_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_extensions import TypedDict + +__all__ = ["RuleListParams"] + + +class RuleListParams(TypedDict, total=False): + project_id: int + """Project ID""" + + region_id: int + """Region ID""" + + limit: int + """Optional. Limit the number of returned items""" + + offset: int + """Optional. + + Offset value is used to exclude the first set of records from the result + """ diff --git a/src/gcore/types/cloud/load_balancers/l7_policy_list_params.py b/src/gcore/types/cloud/load_balancers/l7_policy_list_params.py new file mode 100644 index 000000000..2f63dec06 --- /dev/null +++ b/src/gcore/types/cloud/load_balancers/l7_policy_list_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_extensions import TypedDict + +__all__ = ["L7PolicyListParams"] + + +class L7PolicyListParams(TypedDict, total=False): + project_id: int + """Project ID""" + + region_id: int + """Region ID""" + + limit: int + """Optional. Limit the number of returned items""" + + offset: int + """Optional. + + Offset value is used to exclude the first set of records from the result + """ diff --git a/src/gcore/types/cloud/load_balancers/listener_list_params.py b/src/gcore/types/cloud/load_balancers/listener_list_params.py index c3e9925f5..cb277ce3c 100644 --- a/src/gcore/types/cloud/load_balancers/listener_list_params.py +++ b/src/gcore/types/cloud/load_balancers/listener_list_params.py @@ -14,8 +14,20 @@ class ListenerListParams(TypedDict, total=False): region_id: int """Region ID""" + limit: int + """Optional. Limit the number of returned items""" + load_balancer_id: str """Load Balancer ID""" + name: str + """Filter by name""" + + offset: int + """Optional. + + Offset value is used to exclude the first set of records from the result + """ + show_stats: bool """Show stats""" diff --git a/src/gcore/types/cloud/load_balancers/pool_list_params.py b/src/gcore/types/cloud/load_balancers/pool_list_params.py index 1cddb97b6..fe83828f1 100644 --- a/src/gcore/types/cloud/load_balancers/pool_list_params.py +++ b/src/gcore/types/cloud/load_balancers/pool_list_params.py @@ -17,8 +17,17 @@ class PoolListParams(TypedDict, total=False): details: bool """Show members and Health Monitor details""" + limit: int + """Optional. Limit the number of returned items""" + listener_id: str """Listener ID""" load_balancer_id: str """Load Balancer ID""" + + offset: int + """Optional. + + Offset value is used to exclude the first set of records from the result + """ diff --git a/src/gcore/types/cloud/networks/router_create_params.py b/src/gcore/types/cloud/networks/router_create_params.py index 89f0c379b..6d1be0e52 100644 --- a/src/gcore/types/cloud/networks/router_create_params.py +++ b/src/gcore/types/cloud/networks/router_create_params.py @@ -17,8 +17,10 @@ class RouterCreateParams(TypedDict, total=False): project_id: int + """Project ID""" region_id: int + """Region ID""" name: Required[str] """name of router""" diff --git a/src/gcore/types/cloud/networks/router_list_params.py b/src/gcore/types/cloud/networks/router_list_params.py index 4842c3115..b53732d43 100644 --- a/src/gcore/types/cloud/networks/router_list_params.py +++ b/src/gcore/types/cloud/networks/router_list_params.py @@ -9,11 +9,16 @@ class RouterListParams(TypedDict, total=False): project_id: int + """Project ID""" region_id: int + """Region ID""" limit: int - """Limit the number of returned routers""" + """Limit of items on a single page""" + + name: str + """Optional. Filter routers by name""" offset: int - """Offset value is used to exclude the first set of records from the result""" + """Offset in results list""" diff --git a/src/gcore/types/cloud/region.py b/src/gcore/types/cloud/region.py index b7b24fbe1..5b95eb78b 100644 --- a/src/gcore/types/cloud/region.py +++ b/src/gcore/types/cloud/region.py @@ -87,6 +87,9 @@ class Region(BaseModel): metrics_database_id: Optional[int] = None """Foreign key to Metrics database entity""" + slug: str + """Short, human-readable region identifier (e.g. luxembourg-2, santa-clara-1).""" + state: Literal["ACTIVE", "DELETED", "DELETING", "DELETION_FAILED", "INACTIVE", "MAINTENANCE", "NEW"] """Region state""" diff --git a/src/gcore/types/cloud/security_group_create_params.py b/src/gcore/types/cloud/security_group_create_params.py index e660dee36..c56ab8e25 100644 --- a/src/gcore/types/cloud/security_group_create_params.py +++ b/src/gcore/types/cloud/security_group_create_params.py @@ -53,33 +53,34 @@ class Rule(TypedDict, total=False): port_range_min: Optional[int] """The minimum port number in the range that is matched by the security group rule""" - protocol: Literal[ - "ah", - "any", - "dccp", - "egp", - "esp", - "gre", - "icmp", - "igmp", - "ipencap", - "ipip", - "ipv6-encap", - "ipv6-frag", - "ipv6-icmp", - "ipv6-nonxt", - "ipv6-opts", - "ipv6-route", - "ospf", - "pgm", - "rsvp", - "sctp", - "tcp", - "udp", - "udplite", - "vrrp", + protocol: Optional[ + Literal[ + "ah", + "dccp", + "egp", + "esp", + "gre", + "icmp", + "igmp", + "ipencap", + "ipip", + "ipv6-encap", + "ipv6-frag", + "ipv6-icmp", + "ipv6-nonxt", + "ipv6-opts", + "ipv6-route", + "ospf", + "pgm", + "rsvp", + "sctp", + "tcp", + "udp", + "udplite", + "vrrp", + ] ] - """Protocol""" + """V2 protocol enum without 'any'. Use null for all protocols instead.""" remote_group_id: str """The remote group UUID to associate with this security group""" diff --git a/src/gcore/types/cloud/security_group_update_params.py b/src/gcore/types/cloud/security_group_update_params.py index a5e34df0b..55f327aa0 100644 --- a/src/gcore/types/cloud/security_group_update_params.py +++ b/src/gcore/types/cloud/security_group_update_params.py @@ -74,33 +74,34 @@ class Rule(TypedDict, total=False): port_range_min: int """The minimum port number in the range that is matched by the security group rule""" - protocol: Literal[ - "ah", - "any", - "dccp", - "egp", - "esp", - "gre", - "icmp", - "igmp", - "ipencap", - "ipip", - "ipv6-encap", - "ipv6-frag", - "ipv6-icmp", - "ipv6-nonxt", - "ipv6-opts", - "ipv6-route", - "ospf", - "pgm", - "rsvp", - "sctp", - "tcp", - "udp", - "udplite", - "vrrp", + protocol: Optional[ + Literal[ + "ah", + "dccp", + "egp", + "esp", + "gre", + "icmp", + "igmp", + "ipencap", + "ipip", + "ipv6-encap", + "ipv6-frag", + "ipv6-icmp", + "ipv6-nonxt", + "ipv6-opts", + "ipv6-route", + "ospf", + "pgm", + "rsvp", + "sctp", + "tcp", + "udp", + "udplite", + "vrrp", + ] ] - """Protocol""" + """V2 protocol enum without 'any'. Use null for all protocols instead.""" remote_group_id: str """The remote group UUID to associate with this security group rule""" diff --git a/src/gcore/types/cloud/security_groups/rule_create_params.py b/src/gcore/types/cloud/security_groups/rule_create_params.py index 46fdd4112..29f1216ed 100644 --- a/src/gcore/types/cloud/security_groups/rule_create_params.py +++ b/src/gcore/types/cloud/security_groups/rule_create_params.py @@ -32,33 +32,34 @@ class RuleCreateParams(TypedDict, total=False): port_range_min: Optional[int] """The minimum port number in the range that is matched by the security group rule""" - protocol: Literal[ - "ah", - "any", - "dccp", - "egp", - "esp", - "gre", - "icmp", - "igmp", - "ipencap", - "ipip", - "ipv6-encap", - "ipv6-frag", - "ipv6-icmp", - "ipv6-nonxt", - "ipv6-opts", - "ipv6-route", - "ospf", - "pgm", - "rsvp", - "sctp", - "tcp", - "udp", - "udplite", - "vrrp", + protocol: Optional[ + Literal[ + "ah", + "dccp", + "egp", + "esp", + "gre", + "icmp", + "igmp", + "ipencap", + "ipip", + "ipv6-encap", + "ipv6-frag", + "ipv6-icmp", + "ipv6-nonxt", + "ipv6-opts", + "ipv6-route", + "ospf", + "pgm", + "rsvp", + "sctp", + "tcp", + "udp", + "udplite", + "vrrp", + ] ] - """Protocol""" + """V2 protocol enum without 'any'. Use null for all protocols instead.""" remote_group_id: str """The remote group UUID to associate with this security group""" diff --git a/src/gcore/types/cloud/usage_report.py b/src/gcore/types/cloud/usage_report.py index 659a5421f..a99546dd8 100644 --- a/src/gcore/types/cloud/usage_report.py +++ b/src/gcore/types/cloud/usage_report.py @@ -346,7 +346,7 @@ class ResourceResourceEgressTrafficSerializer(BaseModel): instance_name: Optional[str] = None """Name of the instance""" - instance_type: Literal["baremetal", "vm"] + instance_type: Literal["baremetal", "router", "vm"] """Type of the instance""" last_seen: datetime @@ -1290,7 +1290,7 @@ class TotalTotalEgressTrafficReportItemSerializer(BaseModel): billing_value_unit: Literal["bytes"] """Unit of billing value""" - instance_type: Literal["baremetal", "vm"] + instance_type: Literal["baremetal", "router", "vm"] """Type of the instance""" region: int diff --git a/src/gcore/types/dns/zones/dns_output_rrset.py b/src/gcore/types/dns/zones/dns_output_rrset.py index 67b794d6a..169ecc4c1 100644 --- a/src/gcore/types/dns/zones/dns_output_rrset.py +++ b/src/gcore/types/dns/zones/dns_output_rrset.py @@ -14,15 +14,11 @@ class ResourceRecord(BaseModel): """ Content of resource record The exact length of the array depends on the type of rrset, each individual record parameter must be a separate element of the array. - For example - - - SRV-record: `[100, 1, 5061, "example.com"]` - - CNAME-record: `[ "the.target.domain" ]` - - A-record: `[ "1.2.3.4", "5.6.7.8" ]` - - AAAA-record: `[ "2001:db8::1", "2001:db8::2" ]` - - MX-record: `[ "mail1.example.com", "mail2.example.com" ]` - - SVCB/HTTPS-record: - `[ 1, ".", ["alpn", "h3", "h2"], [ "port", 1443 ], [ "ipv4hint", "10.0.0.1" ], [ "ech", "AEn+DQBFKwAgACABWIHUGj4u+PIggYXcR5JF0gYk3dCRioBW8uJq9H4mKAAIAAEAAQABAANAEnB1YmxpYy50bHMtZWNoLmRldgAA" ] ]` + For example SRV-record: `[100, 1, 5061, "example.com"]` CNAME-record: + `[ "the.target.domain" ]` A-record: `[ "1.2.3.4", "5.6.7.8" ]` AAAA-record: + `[ "2001:db8::1", "2001:db8::2" ]` MX-record: + `[ "mail1.example.com", "mail2.example.com" ]` SVCB/HTTPS-record: + `[ 1, ".", ["alpn", "h3", "h2"], [ "port", 1443 ], [ "ipv4hint", "10.0.0.1" ], [ "ech", "AEn+DQBFKwAgACABWIHUGj4u+PIggYXcR5JF0gYk3dCRioBW8uJq9H4mKAAIAAEAAQABAANAEnB1YmxpYy50bHMtZWNoLmRldgAA" ] ]` """ id: Optional[int] = None diff --git a/src/gcore/types/dns/zones/rrset_create_params.py b/src/gcore/types/dns/zones/rrset_create_params.py index e4b2f876b..a5bfdef1e 100644 --- a/src/gcore/types/dns/zones/rrset_create_params.py +++ b/src/gcore/types/dns/zones/rrset_create_params.py @@ -34,15 +34,11 @@ class ResourceRecord(TypedDict, total=False): """ Content of resource record The exact length of the array depends on the type of rrset, each individual record parameter must be a separate element of the array. - For example - - - SRV-record: `[100, 1, 5061, "example.com"]` - - CNAME-record: `[ "the.target.domain" ]` - - A-record: `[ "1.2.3.4", "5.6.7.8" ]` - - AAAA-record: `[ "2001:db8::1", "2001:db8::2" ]` - - MX-record: `[ "mail1.example.com", "mail2.example.com" ]` - - SVCB/HTTPS-record: - `[ 1, ".", ["alpn", "h3", "h2"], [ "port", 1443 ], [ "ipv4hint", "10.0.0.1" ], [ "ech", "AEn+DQBFKwAgACABWIHUGj4u+PIggYXcR5JF0gYk3dCRioBW8uJq9H4mKAAIAAEAAQABAANAEnB1YmxpYy50bHMtZWNoLmRldgAA" ] ]` + For example SRV-record: `[100, 1, 5061, "example.com"]` CNAME-record: + `[ "the.target.domain" ]` A-record: `[ "1.2.3.4", "5.6.7.8" ]` AAAA-record: + `[ "2001:db8::1", "2001:db8::2" ]` MX-record: + `[ "mail1.example.com", "mail2.example.com" ]` SVCB/HTTPS-record: + `[ 1, ".", ["alpn", "h3", "h2"], [ "port", 1443 ], [ "ipv4hint", "10.0.0.1" ], [ "ech", "AEn+DQBFKwAgACABWIHUGj4u+PIggYXcR5JF0gYk3dCRioBW8uJq9H4mKAAIAAEAAQABAANAEnB1YmxpYy50bHMtZWNoLmRldgAA" ] ]` """ enabled: bool diff --git a/src/gcore/types/dns/zones/rrset_replace_params.py b/src/gcore/types/dns/zones/rrset_replace_params.py index 46f6274c5..b2d155ec2 100644 --- a/src/gcore/types/dns/zones/rrset_replace_params.py +++ b/src/gcore/types/dns/zones/rrset_replace_params.py @@ -34,15 +34,11 @@ class ResourceRecord(TypedDict, total=False): """ Content of resource record The exact length of the array depends on the type of rrset, each individual record parameter must be a separate element of the array. - For example - - - SRV-record: `[100, 1, 5061, "example.com"]` - - CNAME-record: `[ "the.target.domain" ]` - - A-record: `[ "1.2.3.4", "5.6.7.8" ]` - - AAAA-record: `[ "2001:db8::1", "2001:db8::2" ]` - - MX-record: `[ "mail1.example.com", "mail2.example.com" ]` - - SVCB/HTTPS-record: - `[ 1, ".", ["alpn", "h3", "h2"], [ "port", 1443 ], [ "ipv4hint", "10.0.0.1" ], [ "ech", "AEn+DQBFKwAgACABWIHUGj4u+PIggYXcR5JF0gYk3dCRioBW8uJq9H4mKAAIAAEAAQABAANAEnB1YmxpYy50bHMtZWNoLmRldgAA" ] ]` + For example SRV-record: `[100, 1, 5061, "example.com"]` CNAME-record: + `[ "the.target.domain" ]` A-record: `[ "1.2.3.4", "5.6.7.8" ]` AAAA-record: + `[ "2001:db8::1", "2001:db8::2" ]` MX-record: + `[ "mail1.example.com", "mail2.example.com" ]` SVCB/HTTPS-record: + `[ 1, ".", ["alpn", "h3", "h2"], [ "port", 1443 ], [ "ipv4hint", "10.0.0.1" ], [ "ech", "AEn+DQBFKwAgACABWIHUGj4u+PIggYXcR5JF0gYk3dCRioBW8uJq9H4mKAAIAAEAAQABAANAEnB1YmxpYy50bHMtZWNoLmRldgAA" ] ]` """ enabled: bool diff --git a/src/gcore/types/waap/domains/waap_request_details.py b/src/gcore/types/waap/domains/waap_request_details.py index 0eae8cfcd..16475cd97 100644 --- a/src/gcore/types/waap/domains/waap_request_details.py +++ b/src/gcore/types/waap/domains/waap_request_details.py @@ -186,7 +186,7 @@ class WaapRequestDetails(BaseModel): """Name of the triggered rule""" scheme: str - """The HTTP scheme of the request that generated an event""" + """The URI scheme of the request that generated an event""" session_id: str """The session ID associated with the request.""" diff --git a/src/gcore/types/waap/waap_request_summary.py b/src/gcore/types/waap/waap_request_summary.py index 3e3926ab9..22be6abaa 100644 --- a/src/gcore/types/waap/waap_request_summary.py +++ b/src/gcore/types/waap/waap_request_summary.py @@ -70,5 +70,11 @@ class WaapRequestSummary(BaseModel): user_agent_client: str """Client from parsed User agent header""" + http_version: Optional[str] = None + """HTTP version of request""" + + scheme: Optional[str] = None + """The URI scheme of the request that generated an event""" + session_id: Optional[str] = None """The session ID associated with the request.""" diff --git a/tests/api_resources/cdn/cdn_resources/test_rules.py b/tests/api_resources/cdn/cdn_resources/test_rules.py index 0fb4027da..e7a410e07 100644 --- a/tests/api_resources/cdn/cdn_resources/test_rules.py +++ b/tests/api_resources/cdn/cdn_resources/test_rules.py @@ -9,9 +9,9 @@ from gcore import Gcore, AsyncGcore from tests.utils import assert_matches_type -from gcore.pagination import SyncOffsetPage, AsyncOffsetPage from gcore.types.cdn.cdn_resources import ( CDNResourceRule, + CDNResourceRuleList, ) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -658,7 +658,7 @@ def test_method_list(self, client: Gcore) -> None: rule = client.cdn.cdn_resources.rules.list( resource_id=0, ) - assert_matches_type(SyncOffsetPage[CDNResourceRule], rule, path=["response"]) + assert_matches_type(CDNResourceRuleList, rule, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Gcore) -> None: @@ -667,7 +667,7 @@ def test_method_list_with_all_params(self, client: Gcore) -> None: limit=1, offset=0, ) - assert_matches_type(SyncOffsetPage[CDNResourceRule], rule, path=["response"]) + assert_matches_type(CDNResourceRuleList, rule, path=["response"]) @parametrize def test_raw_response_list(self, client: Gcore) -> None: @@ -678,7 +678,7 @@ def test_raw_response_list(self, client: Gcore) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" rule = response.parse() - assert_matches_type(SyncOffsetPage[CDNResourceRule], rule, path=["response"]) + assert_matches_type(CDNResourceRuleList, rule, path=["response"]) @parametrize def test_streaming_response_list(self, client: Gcore) -> None: @@ -689,7 +689,7 @@ def test_streaming_response_list(self, client: Gcore) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" rule = response.parse() - assert_matches_type(SyncOffsetPage[CDNResourceRule], rule, path=["response"]) + assert_matches_type(CDNResourceRuleList, rule, path=["response"]) assert cast(Any, response.is_closed) is True @@ -1725,7 +1725,7 @@ async def test_method_list(self, async_client: AsyncGcore) -> None: rule = await async_client.cdn.cdn_resources.rules.list( resource_id=0, ) - assert_matches_type(AsyncOffsetPage[CDNResourceRule], rule, path=["response"]) + assert_matches_type(CDNResourceRuleList, rule, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> None: @@ -1734,7 +1734,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> No limit=1, offset=0, ) - assert_matches_type(AsyncOffsetPage[CDNResourceRule], rule, path=["response"]) + assert_matches_type(CDNResourceRuleList, rule, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncGcore) -> None: @@ -1745,7 +1745,7 @@ async def test_raw_response_list(self, async_client: AsyncGcore) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" rule = await response.parse() - assert_matches_type(AsyncOffsetPage[CDNResourceRule], rule, path=["response"]) + assert_matches_type(CDNResourceRuleList, rule, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncGcore) -> None: @@ -1756,7 +1756,7 @@ async def test_streaming_response_list(self, async_client: AsyncGcore) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" rule = await response.parse() - assert_matches_type(AsyncOffsetPage[CDNResourceRule], rule, path=["response"]) + assert_matches_type(CDNResourceRuleList, rule, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/cdn/test_origin_groups.py b/tests/api_resources/cdn/test_origin_groups.py index 58a1b94f3..cc9e84b78 100644 --- a/tests/api_resources/cdn/test_origin_groups.py +++ b/tests/api_resources/cdn/test_origin_groups.py @@ -351,9 +351,7 @@ def test_streaming_response_get(self, client: Gcore) -> None: def test_method_replace_overload_1(self, client: Gcore) -> None: origin_group = client.cdn.origin_groups.replace( origin_group_id=0, - auth_type="none", name="YourOriginGroup", - path="", sources=[{"source": "yourdomain.com"}], use_next=True, ) @@ -363,9 +361,7 @@ def test_method_replace_overload_1(self, client: Gcore) -> None: def test_method_replace_with_all_params_overload_1(self, client: Gcore) -> None: origin_group = client.cdn.origin_groups.replace( origin_group_id=0, - auth_type="none", name="YourOriginGroup", - path="", sources=[ { "source": "yourdomain.com", @@ -376,6 +372,8 @@ def test_method_replace_with_all_params_overload_1(self, client: Gcore) -> None: } ], use_next=True, + auth_type="none", + path="", proxy_next_upstream=["error", "timeout", "invalid_header", "http_500", "http_502", "http_503", "http_504"], ) assert_matches_type(OriginGroups, origin_group, path=["response"]) @@ -384,9 +382,7 @@ def test_method_replace_with_all_params_overload_1(self, client: Gcore) -> None: def test_raw_response_replace_overload_1(self, client: Gcore) -> None: response = client.cdn.origin_groups.with_raw_response.replace( origin_group_id=0, - auth_type="none", name="YourOriginGroup", - path="", sources=[{"source": "yourdomain.com"}], use_next=True, ) @@ -400,9 +396,7 @@ def test_raw_response_replace_overload_1(self, client: Gcore) -> None: def test_streaming_response_replace_overload_1(self, client: Gcore) -> None: with client.cdn.origin_groups.with_streaming_response.replace( origin_group_id=0, - auth_type="none", name="YourOriginGroup", - path="", sources=[{"source": "yourdomain.com"}], use_next=True, ) as response: @@ -426,7 +420,6 @@ def test_method_replace_overload_2(self, client: Gcore) -> None: }, auth_type="awsSignatureV4", name="YourOriginGroup", - path="", use_next=True, ) assert_matches_type(OriginGroups, origin_group, path=["response"]) @@ -445,8 +438,8 @@ def test_method_replace_with_all_params_overload_2(self, client: Gcore) -> None: }, auth_type="awsSignatureV4", name="YourOriginGroup", - path="", use_next=True, + path="", proxy_next_upstream=["error", "timeout", "invalid_header", "http_500", "http_502", "http_503", "http_504"], ) assert_matches_type(OriginGroups, origin_group, path=["response"]) @@ -463,7 +456,6 @@ def test_raw_response_replace_overload_2(self, client: Gcore) -> None: }, auth_type="awsSignatureV4", name="YourOriginGroup", - path="", use_next=True, ) @@ -484,7 +476,6 @@ def test_streaming_response_replace_overload_2(self, client: Gcore) -> None: }, auth_type="awsSignatureV4", name="YourOriginGroup", - path="", use_next=True, ) as response: assert not response.is_closed @@ -832,9 +823,7 @@ async def test_streaming_response_get(self, async_client: AsyncGcore) -> None: async def test_method_replace_overload_1(self, async_client: AsyncGcore) -> None: origin_group = await async_client.cdn.origin_groups.replace( origin_group_id=0, - auth_type="none", name="YourOriginGroup", - path="", sources=[{"source": "yourdomain.com"}], use_next=True, ) @@ -844,9 +833,7 @@ async def test_method_replace_overload_1(self, async_client: AsyncGcore) -> None async def test_method_replace_with_all_params_overload_1(self, async_client: AsyncGcore) -> None: origin_group = await async_client.cdn.origin_groups.replace( origin_group_id=0, - auth_type="none", name="YourOriginGroup", - path="", sources=[ { "source": "yourdomain.com", @@ -857,6 +844,8 @@ async def test_method_replace_with_all_params_overload_1(self, async_client: Asy } ], use_next=True, + auth_type="none", + path="", proxy_next_upstream=["error", "timeout", "invalid_header", "http_500", "http_502", "http_503", "http_504"], ) assert_matches_type(OriginGroups, origin_group, path=["response"]) @@ -865,9 +854,7 @@ async def test_method_replace_with_all_params_overload_1(self, async_client: Asy async def test_raw_response_replace_overload_1(self, async_client: AsyncGcore) -> None: response = await async_client.cdn.origin_groups.with_raw_response.replace( origin_group_id=0, - auth_type="none", name="YourOriginGroup", - path="", sources=[{"source": "yourdomain.com"}], use_next=True, ) @@ -881,9 +868,7 @@ async def test_raw_response_replace_overload_1(self, async_client: AsyncGcore) - async def test_streaming_response_replace_overload_1(self, async_client: AsyncGcore) -> None: async with async_client.cdn.origin_groups.with_streaming_response.replace( origin_group_id=0, - auth_type="none", name="YourOriginGroup", - path="", sources=[{"source": "yourdomain.com"}], use_next=True, ) as response: @@ -907,7 +892,6 @@ async def test_method_replace_overload_2(self, async_client: AsyncGcore) -> None }, auth_type="awsSignatureV4", name="YourOriginGroup", - path="", use_next=True, ) assert_matches_type(OriginGroups, origin_group, path=["response"]) @@ -926,8 +910,8 @@ async def test_method_replace_with_all_params_overload_2(self, async_client: Asy }, auth_type="awsSignatureV4", name="YourOriginGroup", - path="", use_next=True, + path="", proxy_next_upstream=["error", "timeout", "invalid_header", "http_500", "http_502", "http_503", "http_504"], ) assert_matches_type(OriginGroups, origin_group, path=["response"]) @@ -944,7 +928,6 @@ async def test_raw_response_replace_overload_2(self, async_client: AsyncGcore) - }, auth_type="awsSignatureV4", name="YourOriginGroup", - path="", use_next=True, ) @@ -965,7 +948,6 @@ async def test_streaming_response_replace_overload_2(self, async_client: AsyncGc }, auth_type="awsSignatureV4", name="YourOriginGroup", - path="", use_next=True, ) as response: assert not response.is_closed diff --git a/tests/api_resources/cdn/test_rule_templates.py b/tests/api_resources/cdn/test_rule_templates.py index 0457f5654..b81bbb02b 100644 --- a/tests/api_resources/cdn/test_rule_templates.py +++ b/tests/api_resources/cdn/test_rule_templates.py @@ -11,8 +11,8 @@ from tests.utils import assert_matches_type from gcore.types.cdn import ( RuleTemplate, + RuleTemplateList, ) -from gcore.pagination import SyncOffsetPage, AsyncOffsetPage base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -641,7 +641,7 @@ def test_streaming_response_update(self, client: Gcore) -> None: @parametrize def test_method_list(self, client: Gcore) -> None: rule_template = client.cdn.rule_templates.list() - assert_matches_type(SyncOffsetPage[RuleTemplate], rule_template, path=["response"]) + assert_matches_type(RuleTemplateList, rule_template, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Gcore) -> None: @@ -649,7 +649,7 @@ def test_method_list_with_all_params(self, client: Gcore) -> None: limit=1, offset=0, ) - assert_matches_type(SyncOffsetPage[RuleTemplate], rule_template, path=["response"]) + assert_matches_type(RuleTemplateList, rule_template, path=["response"]) @parametrize def test_raw_response_list(self, client: Gcore) -> None: @@ -658,7 +658,7 @@ def test_raw_response_list(self, client: Gcore) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" rule_template = response.parse() - assert_matches_type(SyncOffsetPage[RuleTemplate], rule_template, path=["response"]) + assert_matches_type(RuleTemplateList, rule_template, path=["response"]) @parametrize def test_streaming_response_list(self, client: Gcore) -> None: @@ -667,7 +667,7 @@ def test_streaming_response_list(self, client: Gcore) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" rule_template = response.parse() - assert_matches_type(SyncOffsetPage[RuleTemplate], rule_template, path=["response"]) + assert_matches_type(RuleTemplateList, rule_template, path=["response"]) assert cast(Any, response.is_closed) is True @@ -1674,7 +1674,7 @@ async def test_streaming_response_update(self, async_client: AsyncGcore) -> None @parametrize async def test_method_list(self, async_client: AsyncGcore) -> None: rule_template = await async_client.cdn.rule_templates.list() - assert_matches_type(AsyncOffsetPage[RuleTemplate], rule_template, path=["response"]) + assert_matches_type(RuleTemplateList, rule_template, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> None: @@ -1682,7 +1682,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> No limit=1, offset=0, ) - assert_matches_type(AsyncOffsetPage[RuleTemplate], rule_template, path=["response"]) + assert_matches_type(RuleTemplateList, rule_template, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncGcore) -> None: @@ -1691,7 +1691,7 @@ async def test_raw_response_list(self, async_client: AsyncGcore) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" rule_template = await response.parse() - assert_matches_type(AsyncOffsetPage[RuleTemplate], rule_template, path=["response"]) + assert_matches_type(RuleTemplateList, rule_template, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncGcore) -> None: @@ -1700,7 +1700,7 @@ async def test_streaming_response_list(self, async_client: AsyncGcore) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" rule_template = await response.parse() - assert_matches_type(AsyncOffsetPage[RuleTemplate], rule_template, path=["response"]) + assert_matches_type(RuleTemplateList, rule_template, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/cdn/test_shields.py b/tests/api_resources/cdn/test_shields.py index f175c08a1..5444a0f1f 100644 --- a/tests/api_resources/cdn/test_shields.py +++ b/tests/api_resources/cdn/test_shields.py @@ -10,7 +10,6 @@ from gcore import Gcore, AsyncGcore from tests.utils import assert_matches_type from gcore.types.cdn import ShieldListResponse -from gcore.pagination import SyncOffsetPage, AsyncOffsetPage base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -21,7 +20,7 @@ class TestShields: @parametrize def test_method_list(self, client: Gcore) -> None: shield = client.cdn.shields.list() - assert_matches_type(SyncOffsetPage[ShieldListResponse], shield, path=["response"]) + assert_matches_type(ShieldListResponse, shield, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Gcore) -> None: @@ -29,7 +28,7 @@ def test_method_list_with_all_params(self, client: Gcore) -> None: limit=1, offset=0, ) - assert_matches_type(SyncOffsetPage[ShieldListResponse], shield, path=["response"]) + assert_matches_type(ShieldListResponse, shield, path=["response"]) @parametrize def test_raw_response_list(self, client: Gcore) -> None: @@ -38,7 +37,7 @@ def test_raw_response_list(self, client: Gcore) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" shield = response.parse() - assert_matches_type(SyncOffsetPage[ShieldListResponse], shield, path=["response"]) + assert_matches_type(ShieldListResponse, shield, path=["response"]) @parametrize def test_streaming_response_list(self, client: Gcore) -> None: @@ -47,7 +46,7 @@ def test_streaming_response_list(self, client: Gcore) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" shield = response.parse() - assert_matches_type(SyncOffsetPage[ShieldListResponse], shield, path=["response"]) + assert_matches_type(ShieldListResponse, shield, path=["response"]) assert cast(Any, response.is_closed) is True @@ -60,7 +59,7 @@ class TestAsyncShields: @parametrize async def test_method_list(self, async_client: AsyncGcore) -> None: shield = await async_client.cdn.shields.list() - assert_matches_type(AsyncOffsetPage[ShieldListResponse], shield, path=["response"]) + assert_matches_type(ShieldListResponse, shield, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> None: @@ -68,7 +67,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> No limit=1, offset=0, ) - assert_matches_type(AsyncOffsetPage[ShieldListResponse], shield, path=["response"]) + assert_matches_type(ShieldListResponse, shield, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncGcore) -> None: @@ -77,7 +76,7 @@ async def test_raw_response_list(self, async_client: AsyncGcore) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" shield = await response.parse() - assert_matches_type(AsyncOffsetPage[ShieldListResponse], shield, path=["response"]) + assert_matches_type(ShieldListResponse, shield, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncGcore) -> None: @@ -86,6 +85,6 @@ async def test_streaming_response_list(self, async_client: AsyncGcore) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" shield = await response.parse() - assert_matches_type(AsyncOffsetPage[ShieldListResponse], shield, path=["response"]) + assert_matches_type(ShieldListResponse, shield, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/cloud/baremetal/test_images.py b/tests/api_resources/cloud/baremetal/test_images.py index 235f970b4..0d047bbdc 100644 --- a/tests/api_resources/cloud/baremetal/test_images.py +++ b/tests/api_resources/cloud/baremetal/test_images.py @@ -9,7 +9,7 @@ from gcore import Gcore, AsyncGcore from tests.utils import assert_matches_type -from gcore.types.cloud import ImageList +from gcore.types.cloud.baremetal import BaremetalImageList base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -20,47 +20,47 @@ class TestImages: @parametrize def test_method_list(self, client: Gcore) -> None: image = client.cloud.baremetal.images.list( - project_id=0, - region_id=0, + project_id=1, + region_id=7, ) - assert_matches_type(ImageList, image, path=["response"]) + assert_matches_type(BaremetalImageList, image, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Gcore) -> None: image = client.cloud.baremetal.images.list( - project_id=0, - region_id=0, + project_id=1, + region_id=7, include_prices=True, private="private", - tag_key=["string"], + tag_key=["key1", "key2"], tag_key_value="tag_key_value", visibility="private", ) - assert_matches_type(ImageList, image, path=["response"]) + assert_matches_type(BaremetalImageList, image, path=["response"]) @parametrize def test_raw_response_list(self, client: Gcore) -> None: response = client.cloud.baremetal.images.with_raw_response.list( - project_id=0, - region_id=0, + project_id=1, + region_id=7, ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" image = response.parse() - assert_matches_type(ImageList, image, path=["response"]) + assert_matches_type(BaremetalImageList, image, path=["response"]) @parametrize def test_streaming_response_list(self, client: Gcore) -> None: with client.cloud.baremetal.images.with_streaming_response.list( - project_id=0, - region_id=0, + project_id=1, + region_id=7, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" image = response.parse() - assert_matches_type(ImageList, image, path=["response"]) + assert_matches_type(BaremetalImageList, image, path=["response"]) assert cast(Any, response.is_closed) is True @@ -73,46 +73,46 @@ class TestAsyncImages: @parametrize async def test_method_list(self, async_client: AsyncGcore) -> None: image = await async_client.cloud.baremetal.images.list( - project_id=0, - region_id=0, + project_id=1, + region_id=7, ) - assert_matches_type(ImageList, image, path=["response"]) + assert_matches_type(BaremetalImageList, image, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> None: image = await async_client.cloud.baremetal.images.list( - project_id=0, - region_id=0, + project_id=1, + region_id=7, include_prices=True, private="private", - tag_key=["string"], + tag_key=["key1", "key2"], tag_key_value="tag_key_value", visibility="private", ) - assert_matches_type(ImageList, image, path=["response"]) + assert_matches_type(BaremetalImageList, image, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncGcore) -> None: response = await async_client.cloud.baremetal.images.with_raw_response.list( - project_id=0, - region_id=0, + project_id=1, + region_id=7, ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" image = await response.parse() - assert_matches_type(ImageList, image, path=["response"]) + assert_matches_type(BaremetalImageList, image, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncGcore) -> None: async with async_client.cloud.baremetal.images.with_streaming_response.list( - project_id=0, - region_id=0, + project_id=1, + region_id=7, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" image = await response.parse() - assert_matches_type(ImageList, image, path=["response"]) + assert_matches_type(BaremetalImageList, image, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/cloud/baremetal/test_servers.py b/tests/api_resources/cloud/baremetal/test_servers.py index a165f7950..2380807e3 100644 --- a/tests/api_resources/cloud/baremetal/test_servers.py +++ b/tests/api_resources/cloud/baremetal/test_servers.py @@ -54,7 +54,6 @@ def test_method_create_with_all_params(self, client: Gcore) -> None: { "base_field": 10, "field_value": [45046, 45047], - "value": None, } ], }, @@ -115,7 +114,10 @@ def test_method_update_with_all_params(self, client: Gcore) -> None: project_id=1, region_id=1, name="server_name", - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(BaremetalServer, server, path=["response"]) @@ -418,7 +420,6 @@ async def test_method_create_with_all_params(self, async_client: AsyncGcore) -> { "base_field": 10, "field_value": [45046, 45047], - "value": None, } ], }, @@ -479,7 +480,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncGcore) -> project_id=1, region_id=1, name="server_name", - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(BaremetalServer, server, path=["response"]) diff --git a/tests/api_resources/cloud/gpu_baremetal/clusters/test_interfaces.py b/tests/api_resources/cloud/gpu_baremetal/clusters/test_interfaces.py index de330f4dc..650f21754 100644 --- a/tests/api_resources/cloud/gpu_baremetal/clusters/test_interfaces.py +++ b/tests/api_resources/cloud/gpu_baremetal/clusters/test_interfaces.py @@ -83,9 +83,8 @@ def test_method_attach_with_all_params_overload_1(self, client: Gcore) -> None: "fields": [ { "base_field": 10, - "field_name": "field_name", "field_value": [45046, 45047], - "value": None, + "value": "value", } ], "profile_template_name": "profile_template_name", @@ -160,9 +159,8 @@ def test_method_attach_with_all_params_overload_2(self, client: Gcore) -> None: "fields": [ { "base_field": 10, - "field_name": "field_name", "field_value": [45046, 45047], - "value": None, + "value": "value", } ], "profile_template_name": "profile_template_name", @@ -239,9 +237,8 @@ def test_method_attach_with_all_params_overload_3(self, client: Gcore) -> None: "fields": [ { "base_field": 10, - "field_name": "field_name", "field_value": [45046, 45047], - "value": None, + "value": "value", } ], "profile_template_name": "profile_template_name", @@ -319,9 +316,8 @@ def test_method_attach_with_all_params_overload_4(self, client: Gcore) -> None: "fields": [ { "base_field": 10, - "field_name": "field_name", "field_value": [45046, 45047], - "value": None, + "value": "value", } ], "profile_template_name": "profile_template_name", @@ -502,9 +498,8 @@ async def test_method_attach_with_all_params_overload_1(self, async_client: Asyn "fields": [ { "base_field": 10, - "field_name": "field_name", "field_value": [45046, 45047], - "value": None, + "value": "value", } ], "profile_template_name": "profile_template_name", @@ -579,9 +574,8 @@ async def test_method_attach_with_all_params_overload_2(self, async_client: Asyn "fields": [ { "base_field": 10, - "field_name": "field_name", "field_value": [45046, 45047], - "value": None, + "value": "value", } ], "profile_template_name": "profile_template_name", @@ -658,9 +652,8 @@ async def test_method_attach_with_all_params_overload_3(self, async_client: Asyn "fields": [ { "base_field": 10, - "field_name": "field_name", "field_value": [45046, 45047], - "value": None, + "value": "value", } ], "profile_template_name": "profile_template_name", @@ -738,9 +731,8 @@ async def test_method_attach_with_all_params_overload_4(self, async_client: Asyn "fields": [ { "base_field": 10, - "field_name": "field_name", "field_value": [45046, 45047], - "value": None, + "value": "value", } ], "profile_template_name": "profile_template_name", diff --git a/tests/api_resources/cloud/gpu_baremetal/test_clusters.py b/tests/api_resources/cloud/gpu_baremetal/test_clusters.py index e6b030a60..2771230f0 100644 --- a/tests/api_resources/cloud/gpu_baremetal/test_clusters.py +++ b/tests/api_resources/cloud/gpu_baremetal/test_clusters.py @@ -124,7 +124,10 @@ def test_method_update_with_all_params(self, client: Gcore) -> None: project_id=1, region_id=7, name="gpu-cluster-1", - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(GPUBaremetalCluster, cluster, path=["response"]) @@ -679,7 +682,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncGcore) -> project_id=1, region_id=7, name="gpu-cluster-1", - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(GPUBaremetalCluster, cluster, path=["response"]) diff --git a/tests/api_resources/cloud/gpu_virtual/test_clusters.py b/tests/api_resources/cloud/gpu_virtual/test_clusters.py index 05bdb6516..9c748c542 100644 --- a/tests/api_resources/cloud/gpu_virtual/test_clusters.py +++ b/tests/api_resources/cloud/gpu_virtual/test_clusters.py @@ -161,7 +161,10 @@ def test_method_update_with_all_params(self, client: Gcore) -> None: project_id=1, region_id=7, name="gpu-cluster-1", - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(GPUVirtualCluster, cluster, path=["response"]) @@ -753,7 +756,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncGcore) -> project_id=1, region_id=7, name="gpu-cluster-1", - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(GPUVirtualCluster, cluster, path=["response"]) diff --git a/tests/api_resources/cloud/inference/test_deployments.py b/tests/api_resources/cloud/inference/test_deployments.py index a9e40264e..481841b50 100644 --- a/tests/api_resources/cloud/inference/test_deployments.py +++ b/tests/api_resources/cloud/inference/test_deployments.py @@ -13,11 +13,8 @@ from gcore.types.cloud import TaskIDList from gcore.types.cloud.inference import ( InferenceDeployment, - InferenceDeploymentAPIKey, ) -# pyright: reportDeprecated=false - base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -496,53 +493,6 @@ def test_path_params_get(self, client: Gcore) -> None: project_id=1, ) - @parametrize - def test_method_get_api_key(self, client: Gcore) -> None: - with pytest.warns(DeprecationWarning): - deployment = client.cloud.inference.deployments.get_api_key( - deployment_name="my-instance", - project_id=1, - ) - - assert_matches_type(InferenceDeploymentAPIKey, deployment, path=["response"]) - - @parametrize - def test_raw_response_get_api_key(self, client: Gcore) -> None: - with pytest.warns(DeprecationWarning): - response = client.cloud.inference.deployments.with_raw_response.get_api_key( - deployment_name="my-instance", - project_id=1, - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - deployment = response.parse() - assert_matches_type(InferenceDeploymentAPIKey, deployment, path=["response"]) - - @parametrize - def test_streaming_response_get_api_key(self, client: Gcore) -> None: - with pytest.warns(DeprecationWarning): - with client.cloud.inference.deployments.with_streaming_response.get_api_key( - deployment_name="my-instance", - project_id=1, - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - deployment = response.parse() - assert_matches_type(InferenceDeploymentAPIKey, deployment, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_get_api_key(self, client: Gcore) -> None: - with pytest.warns(DeprecationWarning): - with pytest.raises(ValueError, match=r"Expected a non-empty value for `deployment_name` but received ''"): - client.cloud.inference.deployments.with_raw_response.get_api_key( - deployment_name="", - project_id=1, - ) - @parametrize def test_method_start(self, client: Gcore) -> None: deployment = client.cloud.inference.deployments.start( @@ -1105,53 +1055,6 @@ async def test_path_params_get(self, async_client: AsyncGcore) -> None: project_id=1, ) - @parametrize - async def test_method_get_api_key(self, async_client: AsyncGcore) -> None: - with pytest.warns(DeprecationWarning): - deployment = await async_client.cloud.inference.deployments.get_api_key( - deployment_name="my-instance", - project_id=1, - ) - - assert_matches_type(InferenceDeploymentAPIKey, deployment, path=["response"]) - - @parametrize - async def test_raw_response_get_api_key(self, async_client: AsyncGcore) -> None: - with pytest.warns(DeprecationWarning): - response = await async_client.cloud.inference.deployments.with_raw_response.get_api_key( - deployment_name="my-instance", - project_id=1, - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - deployment = await response.parse() - assert_matches_type(InferenceDeploymentAPIKey, deployment, path=["response"]) - - @parametrize - async def test_streaming_response_get_api_key(self, async_client: AsyncGcore) -> None: - with pytest.warns(DeprecationWarning): - async with async_client.cloud.inference.deployments.with_streaming_response.get_api_key( - deployment_name="my-instance", - project_id=1, - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - deployment = await response.parse() - assert_matches_type(InferenceDeploymentAPIKey, deployment, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_get_api_key(self, async_client: AsyncGcore) -> None: - with pytest.warns(DeprecationWarning): - with pytest.raises(ValueError, match=r"Expected a non-empty value for `deployment_name` but received ''"): - await async_client.cloud.inference.deployments.with_raw_response.get_api_key( - deployment_name="", - project_id=1, - ) - @parametrize async def test_method_start(self, async_client: AsyncGcore) -> None: deployment = await async_client.cloud.inference.deployments.start( diff --git a/tests/api_resources/cloud/instances/test_images.py b/tests/api_resources/cloud/instances/test_images.py index 45679a8f8..ca1c50115 100644 --- a/tests/api_resources/cloud/instances/test_images.py +++ b/tests/api_resources/cloud/instances/test_images.py @@ -9,7 +9,11 @@ from gcore import Gcore, AsyncGcore from tests.utils import assert_matches_type -from gcore.types.cloud import Image, ImageList, TaskIDList +from gcore.types.cloud import TaskIDList +from gcore.types.cloud.instances import ( + Image, + ImageList, +) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -38,7 +42,7 @@ def test_method_update_with_all_params(self, client: Gcore) -> None: name="my-image", os_type="linux", ssh_key="allow", - tags={"foo": "string"}, + tags={"my-tag": "my-tag-value"}, ) assert_matches_type(Image, image, path=["response"]) @@ -82,19 +86,19 @@ def test_path_params_update(self, client: Gcore) -> None: @parametrize def test_method_list(self, client: Gcore) -> None: image = client.cloud.instances.images.list( - project_id=0, - region_id=0, + project_id=1, + region_id=7, ) assert_matches_type(ImageList, image, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Gcore) -> None: image = client.cloud.instances.images.list( - project_id=0, - region_id=0, + project_id=1, + region_id=7, include_prices=True, private="private", - tag_key=["string"], + tag_key=["key1", "key2"], tag_key_value="tag_key_value", visibility="private", ) @@ -103,8 +107,8 @@ def test_method_list_with_all_params(self, client: Gcore) -> None: @parametrize def test_raw_response_list(self, client: Gcore) -> None: response = client.cloud.instances.images.with_raw_response.list( - project_id=0, - region_id=0, + project_id=1, + region_id=7, ) assert response.is_closed is True @@ -115,8 +119,8 @@ def test_raw_response_list(self, client: Gcore) -> None: @parametrize def test_streaming_response_list(self, client: Gcore) -> None: with client.cloud.instances.images.with_streaming_response.list( - project_id=0, - region_id=0, + project_id=1, + region_id=7, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -175,8 +179,8 @@ def test_path_params_delete(self, client: Gcore) -> None: @parametrize def test_method_create_from_volume(self, client: Gcore) -> None: image = client.cloud.instances.images.create_from_volume( - project_id=0, - region_id=0, + project_id=1, + region_id=7, name="my-image", volume_id="d478ae29-dedc-4869-82f0-96104425f565", ) @@ -185,8 +189,8 @@ def test_method_create_from_volume(self, client: Gcore) -> None: @parametrize def test_method_create_from_volume_with_all_params(self, client: Gcore) -> None: image = client.cloud.instances.images.create_from_volume( - project_id=0, - region_id=0, + project_id=1, + region_id=7, name="my-image", volume_id="d478ae29-dedc-4869-82f0-96104425f565", architecture="x86_64", @@ -203,8 +207,8 @@ def test_method_create_from_volume_with_all_params(self, client: Gcore) -> None: @parametrize def test_raw_response_create_from_volume(self, client: Gcore) -> None: response = client.cloud.instances.images.with_raw_response.create_from_volume( - project_id=0, - region_id=0, + project_id=1, + region_id=7, name="my-image", volume_id="d478ae29-dedc-4869-82f0-96104425f565", ) @@ -217,8 +221,8 @@ def test_raw_response_create_from_volume(self, client: Gcore) -> None: @parametrize def test_streaming_response_create_from_volume(self, client: Gcore) -> None: with client.cloud.instances.images.with_streaming_response.create_from_volume( - project_id=0, - region_id=0, + project_id=1, + region_id=7, name="my-image", volume_id="d478ae29-dedc-4869-82f0-96104425f565", ) as response: @@ -373,7 +377,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncGcore) -> name="my-image", os_type="linux", ssh_key="allow", - tags={"foo": "string"}, + tags={"my-tag": "my-tag-value"}, ) assert_matches_type(Image, image, path=["response"]) @@ -417,19 +421,19 @@ async def test_path_params_update(self, async_client: AsyncGcore) -> None: @parametrize async def test_method_list(self, async_client: AsyncGcore) -> None: image = await async_client.cloud.instances.images.list( - project_id=0, - region_id=0, + project_id=1, + region_id=7, ) assert_matches_type(ImageList, image, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> None: image = await async_client.cloud.instances.images.list( - project_id=0, - region_id=0, + project_id=1, + region_id=7, include_prices=True, private="private", - tag_key=["string"], + tag_key=["key1", "key2"], tag_key_value="tag_key_value", visibility="private", ) @@ -438,8 +442,8 @@ async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> No @parametrize async def test_raw_response_list(self, async_client: AsyncGcore) -> None: response = await async_client.cloud.instances.images.with_raw_response.list( - project_id=0, - region_id=0, + project_id=1, + region_id=7, ) assert response.is_closed is True @@ -450,8 +454,8 @@ async def test_raw_response_list(self, async_client: AsyncGcore) -> None: @parametrize async def test_streaming_response_list(self, async_client: AsyncGcore) -> None: async with async_client.cloud.instances.images.with_streaming_response.list( - project_id=0, - region_id=0, + project_id=1, + region_id=7, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -510,8 +514,8 @@ async def test_path_params_delete(self, async_client: AsyncGcore) -> None: @parametrize async def test_method_create_from_volume(self, async_client: AsyncGcore) -> None: image = await async_client.cloud.instances.images.create_from_volume( - project_id=0, - region_id=0, + project_id=1, + region_id=7, name="my-image", volume_id="d478ae29-dedc-4869-82f0-96104425f565", ) @@ -520,8 +524,8 @@ async def test_method_create_from_volume(self, async_client: AsyncGcore) -> None @parametrize async def test_method_create_from_volume_with_all_params(self, async_client: AsyncGcore) -> None: image = await async_client.cloud.instances.images.create_from_volume( - project_id=0, - region_id=0, + project_id=1, + region_id=7, name="my-image", volume_id="d478ae29-dedc-4869-82f0-96104425f565", architecture="x86_64", @@ -538,8 +542,8 @@ async def test_method_create_from_volume_with_all_params(self, async_client: Asy @parametrize async def test_raw_response_create_from_volume(self, async_client: AsyncGcore) -> None: response = await async_client.cloud.instances.images.with_raw_response.create_from_volume( - project_id=0, - region_id=0, + project_id=1, + region_id=7, name="my-image", volume_id="d478ae29-dedc-4869-82f0-96104425f565", ) @@ -552,8 +556,8 @@ async def test_raw_response_create_from_volume(self, async_client: AsyncGcore) - @parametrize async def test_streaming_response_create_from_volume(self, async_client: AsyncGcore) -> None: async with async_client.cloud.instances.images.with_streaming_response.create_from_volume( - project_id=0, - region_id=0, + project_id=1, + region_id=7, name="my-image", volume_id="d478ae29-dedc-4869-82f0-96104425f565", ) as response: diff --git a/tests/api_resources/cloud/instances/test_interfaces.py b/tests/api_resources/cloud/instances/test_interfaces.py index 348e946de..6d2c82523 100644 --- a/tests/api_resources/cloud/instances/test_interfaces.py +++ b/tests/api_resources/cloud/instances/test_interfaces.py @@ -83,9 +83,8 @@ def test_method_attach_with_all_params_overload_1(self, client: Gcore) -> None: "fields": [ { "base_field": 10, - "field_name": "field_name", "field_value": [45046, 45047], - "value": None, + "value": "value", } ], "profile_template_name": "profile_template_name", @@ -160,9 +159,8 @@ def test_method_attach_with_all_params_overload_2(self, client: Gcore) -> None: "fields": [ { "base_field": 10, - "field_name": "field_name", "field_value": [45046, 45047], - "value": None, + "value": "value", } ], "profile_template_name": "profile_template_name", @@ -239,9 +237,8 @@ def test_method_attach_with_all_params_overload_3(self, client: Gcore) -> None: "fields": [ { "base_field": 10, - "field_name": "field_name", "field_value": [45046, 45047], - "value": None, + "value": "value", } ], "profile_template_name": "profile_template_name", @@ -319,9 +316,8 @@ def test_method_attach_with_all_params_overload_4(self, client: Gcore) -> None: "fields": [ { "base_field": 10, - "field_name": "field_name", "field_value": [45046, 45047], - "value": None, + "value": "value", } ], "profile_template_name": "profile_template_name", @@ -502,9 +498,8 @@ async def test_method_attach_with_all_params_overload_1(self, async_client: Asyn "fields": [ { "base_field": 10, - "field_name": "field_name", "field_value": [45046, 45047], - "value": None, + "value": "value", } ], "profile_template_name": "profile_template_name", @@ -579,9 +574,8 @@ async def test_method_attach_with_all_params_overload_2(self, async_client: Asyn "fields": [ { "base_field": 10, - "field_name": "field_name", "field_value": [45046, 45047], - "value": None, + "value": "value", } ], "profile_template_name": "profile_template_name", @@ -658,9 +652,8 @@ async def test_method_attach_with_all_params_overload_3(self, async_client: Asyn "fields": [ { "base_field": 10, - "field_name": "field_name", "field_value": [45046, 45047], - "value": None, + "value": "value", } ], "profile_template_name": "profile_template_name", @@ -738,9 +731,8 @@ async def test_method_attach_with_all_params_overload_4(self, async_client: Asyn "fields": [ { "base_field": 10, - "field_name": "field_name", "field_value": [45046, 45047], - "value": None, + "value": "value", } ], "profile_template_name": "profile_template_name", diff --git a/tests/api_resources/cloud/instances/test_metrics.py b/tests/api_resources/cloud/instances/test_metrics.py index afa615203..3d0ecc42f 100644 --- a/tests/api_resources/cloud/instances/test_metrics.py +++ b/tests/api_resources/cloud/instances/test_metrics.py @@ -24,7 +24,7 @@ def test_method_list(self, client: Gcore) -> None: project_id=0, region_id=0, time_interval=6, - time_unit="day", + time_unit="hour", ) assert_matches_type(MetricsList, metric, path=["response"]) @@ -35,7 +35,7 @@ def test_raw_response_list(self, client: Gcore) -> None: project_id=0, region_id=0, time_interval=6, - time_unit="day", + time_unit="hour", ) assert response.is_closed is True @@ -50,7 +50,7 @@ def test_streaming_response_list(self, client: Gcore) -> None: project_id=0, region_id=0, time_interval=6, - time_unit="day", + time_unit="hour", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -68,7 +68,7 @@ def test_path_params_list(self, client: Gcore) -> None: project_id=0, region_id=0, time_interval=6, - time_unit="day", + time_unit="hour", ) @@ -84,7 +84,7 @@ async def test_method_list(self, async_client: AsyncGcore) -> None: project_id=0, region_id=0, time_interval=6, - time_unit="day", + time_unit="hour", ) assert_matches_type(MetricsList, metric, path=["response"]) @@ -95,7 +95,7 @@ async def test_raw_response_list(self, async_client: AsyncGcore) -> None: project_id=0, region_id=0, time_interval=6, - time_unit="day", + time_unit="hour", ) assert response.is_closed is True @@ -110,7 +110,7 @@ async def test_streaming_response_list(self, async_client: AsyncGcore) -> None: project_id=0, region_id=0, time_interval=6, - time_unit="day", + time_unit="hour", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -128,5 +128,5 @@ async def test_path_params_list(self, async_client: AsyncGcore) -> None: project_id=0, region_id=0, time_interval=6, - time_unit="day", + time_unit="hour", ) diff --git a/tests/api_resources/cloud/k8s/test_clusters.py b/tests/api_resources/cloud/k8s/test_clusters.py index eb78a0b2b..353b26ab0 100644 --- a/tests/api_resources/cloud/k8s/test_clusters.py +++ b/tests/api_resources/cloud/k8s/test_clusters.py @@ -107,7 +107,6 @@ def test_method_create_with_all_params(self, client: Gcore) -> None: { "base_field": 10, "field_value": [45046, 45047], - "value": None, } ], "profile_template": 29, @@ -231,7 +230,6 @@ def test_method_update_with_all_params(self, client: Gcore) -> None: { "base_field": 10, "field_value": [45046, 45047], - "value": None, } ], "profile_template": 29, @@ -652,7 +650,6 @@ async def test_method_create_with_all_params(self, async_client: AsyncGcore) -> { "base_field": 10, "field_value": [45046, 45047], - "value": None, } ], "profile_template": 29, @@ -776,7 +773,6 @@ async def test_method_update_with_all_params(self, async_client: AsyncGcore) -> { "base_field": 10, "field_value": [45046, 45047], - "value": None, } ], "profile_template": 29, diff --git a/tests/api_resources/cloud/load_balancers/l7_policies/test_rules.py b/tests/api_resources/cloud/load_balancers/l7_policies/test_rules.py index 93b6eaf5b..c46496899 100644 --- a/tests/api_resources/cloud/load_balancers/l7_policies/test_rules.py +++ b/tests/api_resources/cloud/load_balancers/l7_policies/test_rules.py @@ -99,6 +99,17 @@ def test_method_list(self, client: Gcore) -> None: ) assert_matches_type(LoadBalancerL7RuleList, rule, path=["response"]) + @parametrize + def test_method_list_with_all_params(self, client: Gcore) -> None: + rule = client.cloud.load_balancers.l7_policies.rules.list( + l7policy_id="023f2e34-7806-443b-bfae-16c324569a3d", + project_id=1, + region_id=1, + limit=1000, + offset=0, + ) + assert_matches_type(LoadBalancerL7RuleList, rule, path=["response"]) + @parametrize def test_raw_response_list(self, client: Gcore) -> None: response = client.cloud.load_balancers.l7_policies.rules.with_raw_response.list( @@ -414,6 +425,17 @@ async def test_method_list(self, async_client: AsyncGcore) -> None: ) assert_matches_type(LoadBalancerL7RuleList, rule, path=["response"]) + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> None: + rule = await async_client.cloud.load_balancers.l7_policies.rules.list( + l7policy_id="023f2e34-7806-443b-bfae-16c324569a3d", + project_id=1, + region_id=1, + limit=1000, + offset=0, + ) + assert_matches_type(LoadBalancerL7RuleList, rule, path=["response"]) + @parametrize async def test_raw_response_list(self, async_client: AsyncGcore) -> None: response = await async_client.cloud.load_balancers.l7_policies.rules.with_raw_response.list( diff --git a/tests/api_resources/cloud/load_balancers/test_flavors.py b/tests/api_resources/cloud/load_balancers/test_flavors.py index 49f14df1a..43ddefddd 100644 --- a/tests/api_resources/cloud/load_balancers/test_flavors.py +++ b/tests/api_resources/cloud/load_balancers/test_flavors.py @@ -31,6 +31,8 @@ def test_method_list_with_all_params(self, client: Gcore) -> None: project_id=1, region_id=7, include_prices=True, + limit=1000, + offset=0, ) assert_matches_type(LoadBalancerFlavorList, flavor, path=["response"]) @@ -80,6 +82,8 @@ async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> No project_id=1, region_id=7, include_prices=True, + limit=1000, + offset=0, ) assert_matches_type(LoadBalancerFlavorList, flavor, path=["response"]) diff --git a/tests/api_resources/cloud/load_balancers/test_l7_policies.py b/tests/api_resources/cloud/load_balancers/test_l7_policies.py index aae512186..88520e012 100644 --- a/tests/api_resources/cloud/load_balancers/test_l7_policies.py +++ b/tests/api_resources/cloud/load_balancers/test_l7_policies.py @@ -520,6 +520,16 @@ def test_method_list(self, client: Gcore) -> None: ) assert_matches_type(LoadBalancerL7PolicyList, l7_policy, path=["response"]) + @parametrize + def test_method_list_with_all_params(self, client: Gcore) -> None: + l7_policy = client.cloud.load_balancers.l7_policies.list( + project_id=1, + region_id=1, + limit=1000, + offset=0, + ) + assert_matches_type(LoadBalancerL7PolicyList, l7_policy, path=["response"]) + @parametrize def test_raw_response_list(self, client: Gcore) -> None: response = client.cloud.load_balancers.l7_policies.with_raw_response.list( @@ -1147,6 +1157,16 @@ async def test_method_list(self, async_client: AsyncGcore) -> None: ) assert_matches_type(LoadBalancerL7PolicyList, l7_policy, path=["response"]) + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> None: + l7_policy = await async_client.cloud.load_balancers.l7_policies.list( + project_id=1, + region_id=1, + limit=1000, + offset=0, + ) + assert_matches_type(LoadBalancerL7PolicyList, l7_policy, path=["response"]) + @parametrize async def test_raw_response_list(self, async_client: AsyncGcore) -> None: response = await async_client.cloud.load_balancers.l7_policies.with_raw_response.list( diff --git a/tests/api_resources/cloud/load_balancers/test_listeners.py b/tests/api_resources/cloud/load_balancers/test_listeners.py index 81c7a2b2b..212dc211a 100644 --- a/tests/api_resources/cloud/load_balancers/test_listeners.py +++ b/tests/api_resources/cloud/load_balancers/test_listeners.py @@ -173,7 +173,10 @@ def test_method_list_with_all_params(self, client: Gcore) -> None: listener = client.cloud.load_balancers.listeners.list( project_id=1, region_id=1, + limit=1000, load_balancer_id="00000000-0000-4000-8000-000000000000", + name="listener-name", + offset=0, show_stats=True, ) assert_matches_type(LoadBalancerListenerList, listener, path=["response"]) @@ -478,7 +481,10 @@ async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> No listener = await async_client.cloud.load_balancers.listeners.list( project_id=1, region_id=1, + limit=1000, load_balancer_id="00000000-0000-4000-8000-000000000000", + name="listener-name", + offset=0, show_stats=True, ) assert_matches_type(LoadBalancerListenerList, listener, path=["response"]) diff --git a/tests/api_resources/cloud/load_balancers/test_metrics.py b/tests/api_resources/cloud/load_balancers/test_metrics.py index 3ab21ffd6..0a1014674 100644 --- a/tests/api_resources/cloud/load_balancers/test_metrics.py +++ b/tests/api_resources/cloud/load_balancers/test_metrics.py @@ -24,7 +24,7 @@ def test_method_list(self, client: Gcore) -> None: project_id=1, region_id=7, time_interval=6, - time_unit="day", + time_unit="hour", ) assert_matches_type(LoadBalancerMetricsList, metric, path=["response"]) @@ -35,7 +35,7 @@ def test_raw_response_list(self, client: Gcore) -> None: project_id=1, region_id=7, time_interval=6, - time_unit="day", + time_unit="hour", ) assert response.is_closed is True @@ -50,7 +50,7 @@ def test_streaming_response_list(self, client: Gcore) -> None: project_id=1, region_id=7, time_interval=6, - time_unit="day", + time_unit="hour", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -68,7 +68,7 @@ def test_path_params_list(self, client: Gcore) -> None: project_id=1, region_id=7, time_interval=6, - time_unit="day", + time_unit="hour", ) @@ -84,7 +84,7 @@ async def test_method_list(self, async_client: AsyncGcore) -> None: project_id=1, region_id=7, time_interval=6, - time_unit="day", + time_unit="hour", ) assert_matches_type(LoadBalancerMetricsList, metric, path=["response"]) @@ -95,7 +95,7 @@ async def test_raw_response_list(self, async_client: AsyncGcore) -> None: project_id=1, region_id=7, time_interval=6, - time_unit="day", + time_unit="hour", ) assert response.is_closed is True @@ -110,7 +110,7 @@ async def test_streaming_response_list(self, async_client: AsyncGcore) -> None: project_id=1, region_id=7, time_interval=6, - time_unit="day", + time_unit="hour", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -128,5 +128,5 @@ async def test_path_params_list(self, async_client: AsyncGcore) -> None: project_id=1, region_id=7, time_interval=6, - time_unit="day", + time_unit="hour", ) diff --git a/tests/api_resources/cloud/load_balancers/test_pools.py b/tests/api_resources/cloud/load_balancers/test_pools.py index 9905e435f..6a1819999 100644 --- a/tests/api_resources/cloud/load_balancers/test_pools.py +++ b/tests/api_resources/cloud/load_balancers/test_pools.py @@ -22,7 +22,7 @@ def test_method_create(self, client: Gcore) -> None: pool = client.cloud.load_balancers.pools.create( project_id=1, region_id=1, - lb_algorithm="LEAST_CONNECTIONS", + lb_algorithm="ROUND_ROBIN", name="pool_name", protocol="HTTP", ) @@ -33,7 +33,7 @@ def test_method_create_with_all_params(self, client: Gcore) -> None: pool = client.cloud.load_balancers.pools.create( project_id=1, region_id=1, - lb_algorithm="LEAST_CONNECTIONS", + lb_algorithm="ROUND_ROBIN", name="pool_name", protocol="HTTP", ca_secret_id="ca_secret_id", @@ -95,7 +95,7 @@ def test_raw_response_create(self, client: Gcore) -> None: response = client.cloud.load_balancers.pools.with_raw_response.create( project_id=1, region_id=1, - lb_algorithm="LEAST_CONNECTIONS", + lb_algorithm="ROUND_ROBIN", name="pool_name", protocol="HTTP", ) @@ -110,7 +110,7 @@ def test_streaming_response_create(self, client: Gcore) -> None: with client.cloud.load_balancers.pools.with_streaming_response.create( project_id=1, region_id=1, - lb_algorithm="LEAST_CONNECTIONS", + lb_algorithm="ROUND_ROBIN", name="pool_name", protocol="HTTP", ) as response: @@ -153,7 +153,7 @@ def test_method_update_with_all_params(self, client: Gcore) -> None: "type": "HTTP", "url_path": "/", }, - lb_algorithm="LEAST_CONNECTIONS", + lb_algorithm="ROUND_ROBIN", members=[ { "address": "192.168.40.33", @@ -233,8 +233,10 @@ def test_method_list_with_all_params(self, client: Gcore) -> None: project_id=1, region_id=1, details=True, + limit=1000, listener_id="00000000-0000-4000-8000-000000000000", load_balancer_id="00000000-0000-4000-8000-000000000000", + offset=0, ) assert_matches_type(LoadBalancerPoolList, pool, path=["response"]) @@ -367,7 +369,7 @@ async def test_method_create(self, async_client: AsyncGcore) -> None: pool = await async_client.cloud.load_balancers.pools.create( project_id=1, region_id=1, - lb_algorithm="LEAST_CONNECTIONS", + lb_algorithm="ROUND_ROBIN", name="pool_name", protocol="HTTP", ) @@ -378,7 +380,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncGcore) -> pool = await async_client.cloud.load_balancers.pools.create( project_id=1, region_id=1, - lb_algorithm="LEAST_CONNECTIONS", + lb_algorithm="ROUND_ROBIN", name="pool_name", protocol="HTTP", ca_secret_id="ca_secret_id", @@ -440,7 +442,7 @@ async def test_raw_response_create(self, async_client: AsyncGcore) -> None: response = await async_client.cloud.load_balancers.pools.with_raw_response.create( project_id=1, region_id=1, - lb_algorithm="LEAST_CONNECTIONS", + lb_algorithm="ROUND_ROBIN", name="pool_name", protocol="HTTP", ) @@ -455,7 +457,7 @@ async def test_streaming_response_create(self, async_client: AsyncGcore) -> None async with async_client.cloud.load_balancers.pools.with_streaming_response.create( project_id=1, region_id=1, - lb_algorithm="LEAST_CONNECTIONS", + lb_algorithm="ROUND_ROBIN", name="pool_name", protocol="HTTP", ) as response: @@ -498,7 +500,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncGcore) -> "type": "HTTP", "url_path": "/", }, - lb_algorithm="LEAST_CONNECTIONS", + lb_algorithm="ROUND_ROBIN", members=[ { "address": "192.168.40.33", @@ -578,8 +580,10 @@ async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> No project_id=1, region_id=1, details=True, + limit=1000, listener_id="00000000-0000-4000-8000-000000000000", load_balancer_id="00000000-0000-4000-8000-000000000000", + offset=0, ) assert_matches_type(LoadBalancerPoolList, pool, path=["response"]) diff --git a/tests/api_resources/cloud/networks/test_routers.py b/tests/api_resources/cloud/networks/test_routers.py index 968607af3..942646ca7 100644 --- a/tests/api_resources/cloud/networks/test_routers.py +++ b/tests/api_resources/cloud/networks/test_routers.py @@ -26,8 +26,8 @@ class TestRouters: @parametrize def test_method_create(self, client: Gcore) -> None: router = client.cloud.networks.routers.create( - project_id=0, - region_id=0, + project_id=1, + region_id=1, name="my_wonderful_router", ) assert_matches_type(TaskIDList, router, path=["response"]) @@ -35,8 +35,8 @@ def test_method_create(self, client: Gcore) -> None: @parametrize def test_method_create_with_all_params(self, client: Gcore) -> None: router = client.cloud.networks.routers.create( - project_id=0, - region_id=0, + project_id=1, + region_id=1, name="my_wonderful_router", external_gateway_info={ "enable_snat": True, @@ -60,8 +60,8 @@ def test_method_create_with_all_params(self, client: Gcore) -> None: @parametrize def test_raw_response_create(self, client: Gcore) -> None: response = client.cloud.networks.routers.with_raw_response.create( - project_id=0, - region_id=0, + project_id=1, + region_id=1, name="my_wonderful_router", ) @@ -73,8 +73,8 @@ def test_raw_response_create(self, client: Gcore) -> None: @parametrize def test_streaming_response_create(self, client: Gcore) -> None: with client.cloud.networks.routers.with_streaming_response.create( - project_id=0, - region_id=0, + project_id=1, + region_id=1, name="my_wonderful_router", ) as response: assert not response.is_closed @@ -162,17 +162,18 @@ def test_path_params_update(self, client: Gcore) -> None: @parametrize def test_method_list(self, client: Gcore) -> None: router = client.cloud.networks.routers.list( - project_id=0, - region_id=0, + project_id=1, + region_id=1, ) assert_matches_type(SyncOffsetPage[Router], router, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Gcore) -> None: router = client.cloud.networks.routers.list( - project_id=0, - region_id=0, - limit=0, + project_id=1, + region_id=1, + limit=10, + name="router-name", offset=0, ) assert_matches_type(SyncOffsetPage[Router], router, path=["response"]) @@ -180,8 +181,8 @@ def test_method_list_with_all_params(self, client: Gcore) -> None: @parametrize def test_raw_response_list(self, client: Gcore) -> None: response = client.cloud.networks.routers.with_raw_response.list( - project_id=0, - region_id=0, + project_id=1, + region_id=1, ) assert response.is_closed is True @@ -192,8 +193,8 @@ def test_raw_response_list(self, client: Gcore) -> None: @parametrize def test_streaming_response_list(self, client: Gcore) -> None: with client.cloud.networks.routers.with_streaming_response.list( - project_id=0, - region_id=0, + project_id=1, + region_id=1, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -415,8 +416,8 @@ class TestAsyncRouters: @parametrize async def test_method_create(self, async_client: AsyncGcore) -> None: router = await async_client.cloud.networks.routers.create( - project_id=0, - region_id=0, + project_id=1, + region_id=1, name="my_wonderful_router", ) assert_matches_type(TaskIDList, router, path=["response"]) @@ -424,8 +425,8 @@ async def test_method_create(self, async_client: AsyncGcore) -> None: @parametrize async def test_method_create_with_all_params(self, async_client: AsyncGcore) -> None: router = await async_client.cloud.networks.routers.create( - project_id=0, - region_id=0, + project_id=1, + region_id=1, name="my_wonderful_router", external_gateway_info={ "enable_snat": True, @@ -449,8 +450,8 @@ async def test_method_create_with_all_params(self, async_client: AsyncGcore) -> @parametrize async def test_raw_response_create(self, async_client: AsyncGcore) -> None: response = await async_client.cloud.networks.routers.with_raw_response.create( - project_id=0, - region_id=0, + project_id=1, + region_id=1, name="my_wonderful_router", ) @@ -462,8 +463,8 @@ 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.networks.routers.with_streaming_response.create( - project_id=0, - region_id=0, + project_id=1, + region_id=1, name="my_wonderful_router", ) as response: assert not response.is_closed @@ -551,17 +552,18 @@ async def test_path_params_update(self, async_client: AsyncGcore) -> None: @parametrize async def test_method_list(self, async_client: AsyncGcore) -> None: router = await async_client.cloud.networks.routers.list( - project_id=0, - region_id=0, + project_id=1, + region_id=1, ) assert_matches_type(AsyncOffsetPage[Router], router, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> None: router = await async_client.cloud.networks.routers.list( - project_id=0, - region_id=0, - limit=0, + project_id=1, + region_id=1, + limit=10, + name="router-name", offset=0, ) assert_matches_type(AsyncOffsetPage[Router], router, path=["response"]) @@ -569,8 +571,8 @@ async def test_method_list_with_all_params(self, async_client: AsyncGcore) -> No @parametrize async def test_raw_response_list(self, async_client: AsyncGcore) -> None: response = await async_client.cloud.networks.routers.with_raw_response.list( - project_id=0, - region_id=0, + project_id=1, + region_id=1, ) assert response.is_closed is True @@ -581,8 +583,8 @@ async def test_raw_response_list(self, async_client: AsyncGcore) -> None: @parametrize async def test_streaming_response_list(self, async_client: AsyncGcore) -> None: async with async_client.cloud.networks.routers.with_streaming_response.list( - project_id=0, - region_id=0, + project_id=1, + region_id=1, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" diff --git a/tests/api_resources/cloud/networks/test_subnets.py b/tests/api_resources/cloud/networks/test_subnets.py index 58f950c6f..6049bcc16 100644 --- a/tests/api_resources/cloud/networks/test_subnets.py +++ b/tests/api_resources/cloud/networks/test_subnets.py @@ -110,7 +110,10 @@ def test_method_update_with_all_params(self, client: Gcore) -> None: } ], name="some_name", - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(Subnet, subnet, path=["response"]) @@ -390,7 +393,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncGcore) -> } ], name="some_name", - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(Subnet, subnet, path=["response"]) diff --git a/tests/api_resources/cloud/test_file_shares.py b/tests/api_resources/cloud/test_file_shares.py index 3d015d546..1348551b2 100644 --- a/tests/api_resources/cloud/test_file_shares.py +++ b/tests/api_resources/cloud/test_file_shares.py @@ -174,7 +174,10 @@ def test_method_update_with_all_params(self, client: Gcore) -> None: "path_length": "LCD", "root_squash": True, }, - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(TaskIDList, file_share, path=["response"]) @@ -562,7 +565,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncGcore) -> "path_length": "LCD", "root_squash": True, }, - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(TaskIDList, file_share, path=["response"]) diff --git a/tests/api_resources/cloud/test_floating_ips.py b/tests/api_resources/cloud/test_floating_ips.py index 55ac79046..4416197fe 100644 --- a/tests/api_resources/cloud/test_floating_ips.py +++ b/tests/api_resources/cloud/test_floating_ips.py @@ -86,7 +86,10 @@ def test_method_update_with_all_params(self, client: Gcore) -> None: region_id=1, fixed_ip_address="192.168.10.15", port_id="ee2402d0-f0cd-4503-9b75-69be1d11c5f1", - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(TaskIDList, floating_ip, path=["response"]) @@ -453,7 +456,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncGcore) -> region_id=1, fixed_ip_address="192.168.10.15", port_id="ee2402d0-f0cd-4503-9b75-69be1d11c5f1", - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(TaskIDList, floating_ip, path=["response"]) diff --git a/tests/api_resources/cloud/test_instances.py b/tests/api_resources/cloud/test_instances.py index dd5d7f453..49f04ef33 100644 --- a/tests/api_resources/cloud/test_instances.py +++ b/tests/api_resources/cloud/test_instances.py @@ -139,7 +139,10 @@ def test_method_update_with_all_params(self, client: Gcore) -> None: project_id=0, region_id=0, name="instance_name", - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(Instance, instance, path=["response"]) @@ -1011,7 +1014,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncGcore) -> project_id=0, region_id=0, name="instance_name", - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(Instance, instance, path=["response"]) diff --git a/tests/api_resources/cloud/test_load_balancers.py b/tests/api_resources/cloud/test_load_balancers.py index 2c5764ef1..f760dc3e1 100644 --- a/tests/api_resources/cloud/test_load_balancers.py +++ b/tests/api_resources/cloud/test_load_balancers.py @@ -28,6 +28,7 @@ def test_method_create(self, client: Gcore) -> None: load_balancer = client.cloud.load_balancers.create( project_id=1, region_id=7, + name="new_load_balancer", ) assert_matches_type(TaskIDList, load_balancer, path=["response"]) @@ -36,6 +37,7 @@ def test_method_create_with_all_params(self, client: Gcore) -> None: load_balancer = client.cloud.load_balancers.create( project_id=1, region_id=7, + name="new_load_balancer", flavor="lb1-1-2", floating_ip={ "existing_floating_id": "c64e5db1-5f1f-43ec-a8d9-5090df85b82d", @@ -124,11 +126,9 @@ def test_method_create_with_all_params(self, client: Gcore) -> None: "retention_policy": {"period": 45}, "topic_name": "my-log-name", }, - name="new_load_balancer", - name_template="lb_name_template", preferred_connectivity="L2", tags={"my-tag": "my-tag-value"}, - vip_ip_family="dual", + vip_ip_family="ipv4", vip_network_id="ac307687-31a4-4a11-a949-6bea1b2878f5", vip_port_id="ff83e13a-b256-4be2-ba5d-028d3f0ab450", vip_subnet_id="4e7802d3-5023-44b8-b298-7726558fddf4", @@ -140,6 +140,7 @@ def test_raw_response_create(self, client: Gcore) -> None: response = client.cloud.load_balancers.with_raw_response.create( project_id=1, region_id=7, + name="new_load_balancer", ) assert response.is_closed is True @@ -152,6 +153,7 @@ def test_streaming_response_create(self, client: Gcore) -> None: with client.cloud.load_balancers.with_streaming_response.create( project_id=1, region_id=7, + name="new_load_balancer", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -187,7 +189,10 @@ def test_method_update_with_all_params(self, client: Gcore) -> None: }, name="some_name", preferred_connectivity="L2", - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(LoadBalancer, load_balancer, path=["response"]) @@ -504,6 +509,7 @@ async def test_method_create(self, async_client: AsyncGcore) -> None: load_balancer = await async_client.cloud.load_balancers.create( project_id=1, region_id=7, + name="new_load_balancer", ) assert_matches_type(TaskIDList, load_balancer, path=["response"]) @@ -512,6 +518,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncGcore) -> load_balancer = await async_client.cloud.load_balancers.create( project_id=1, region_id=7, + name="new_load_balancer", flavor="lb1-1-2", floating_ip={ "existing_floating_id": "c64e5db1-5f1f-43ec-a8d9-5090df85b82d", @@ -600,11 +607,9 @@ async def test_method_create_with_all_params(self, async_client: AsyncGcore) -> "retention_policy": {"period": 45}, "topic_name": "my-log-name", }, - name="new_load_balancer", - name_template="lb_name_template", preferred_connectivity="L2", tags={"my-tag": "my-tag-value"}, - vip_ip_family="dual", + vip_ip_family="ipv4", vip_network_id="ac307687-31a4-4a11-a949-6bea1b2878f5", vip_port_id="ff83e13a-b256-4be2-ba5d-028d3f0ab450", vip_subnet_id="4e7802d3-5023-44b8-b298-7726558fddf4", @@ -616,6 +621,7 @@ async def test_raw_response_create(self, async_client: AsyncGcore) -> None: response = await async_client.cloud.load_balancers.with_raw_response.create( project_id=1, region_id=7, + name="new_load_balancer", ) assert response.is_closed is True @@ -628,6 +634,7 @@ async def test_streaming_response_create(self, async_client: AsyncGcore) -> None async with async_client.cloud.load_balancers.with_streaming_response.create( project_id=1, region_id=7, + name="new_load_balancer", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -663,7 +670,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncGcore) -> }, name="some_name", preferred_connectivity="L2", - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(LoadBalancer, load_balancer, path=["response"]) diff --git a/tests/api_resources/cloud/test_networks.py b/tests/api_resources/cloud/test_networks.py index 7a46a77b7..57d1d6ea3 100644 --- a/tests/api_resources/cloud/test_networks.py +++ b/tests/api_resources/cloud/test_networks.py @@ -86,7 +86,10 @@ def test_method_update_with_all_params(self, client: Gcore) -> None: project_id=1, region_id=1, name="some_name", - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(Network, network, path=["response"]) @@ -341,7 +344,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncGcore) -> project_id=1, region_id=1, name="some_name", - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(Network, network, path=["response"]) diff --git a/tests/api_resources/cloud/test_reserved_fixed_ips.py b/tests/api_resources/cloud/test_reserved_fixed_ips.py index 21a89074f..536cbd650 100644 --- a/tests/api_resources/cloud/test_reserved_fixed_ips.py +++ b/tests/api_resources/cloud/test_reserved_fixed_ips.py @@ -36,7 +36,7 @@ def test_method_create_with_all_params_overload_1(self, client: Gcore) -> None: project_id=0, region_id=0, type="external", - ip_family="dual", + ip_family="ipv4", is_vip=False, ) assert_matches_type(TaskIDList, reserved_fixed_ip, path=["response"]) @@ -137,7 +137,7 @@ def test_method_create_with_all_params_overload_3(self, client: Gcore) -> None: region_id=0, network_id="e3c6ee77-48cb-416b-b204-11b492cc776e3", type="any_subnet", - ip_family="dual", + ip_family="ipv4", is_vip=False, ) assert_matches_type(TaskIDList, reserved_fixed_ip, path=["response"]) @@ -481,7 +481,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn project_id=0, region_id=0, type="external", - ip_family="dual", + ip_family="ipv4", is_vip=False, ) assert_matches_type(TaskIDList, reserved_fixed_ip, path=["response"]) @@ -582,7 +582,7 @@ async def test_method_create_with_all_params_overload_3(self, async_client: Asyn region_id=0, network_id="e3c6ee77-48cb-416b-b204-11b492cc776e3", type="any_subnet", - ip_family="dual", + ip_family="ipv4", is_vip=False, ) assert_matches_type(TaskIDList, reserved_fixed_ip, path=["response"]) diff --git a/tests/api_resources/cloud/test_security_groups.py b/tests/api_resources/cloud/test_security_groups.py index b97cd2654..8e06bd06e 100644 --- a/tests/api_resources/cloud/test_security_groups.py +++ b/tests/api_resources/cloud/test_security_groups.py @@ -110,7 +110,10 @@ def test_method_update_with_all_params(self, client: Gcore) -> None: "remote_ip_prefix": "10.0.0.0/8", } ], - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(TaskIDList, security_group, path=["response"]) @@ -481,7 +484,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncGcore) -> "remote_ip_prefix": "10.0.0.0/8", } ], - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(TaskIDList, security_group, path=["response"]) diff --git a/tests/api_resources/cloud/test_volume_snapshots.py b/tests/api_resources/cloud/test_volume_snapshots.py index 04ae487df..02ed69d4c 100644 --- a/tests/api_resources/cloud/test_volume_snapshots.py +++ b/tests/api_resources/cloud/test_volume_snapshots.py @@ -88,7 +88,10 @@ def test_method_update_with_all_params(self, client: Gcore) -> None: project_id=1, region_id=1, name="my-backup-snapshot", - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(Snapshot, volume_snapshot, path=["response"]) @@ -295,7 +298,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncGcore) -> project_id=1, region_id=1, name="my-backup-snapshot", - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(Snapshot, volume_snapshot, path=["response"]) diff --git a/tests/api_resources/cloud/test_volumes.py b/tests/api_resources/cloud/test_volumes.py index 1b58422a0..0ea8f5a3d 100644 --- a/tests/api_resources/cloud/test_volumes.py +++ b/tests/api_resources/cloud/test_volumes.py @@ -219,7 +219,10 @@ def test_method_update_with_all_params(self, client: Gcore) -> None: project_id=1, region_id=1, name="some_name", - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(Volume, volume, path=["response"]) @@ -875,7 +878,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncGcore) -> project_id=1, region_id=1, name="some_name", - tags={"foo": "string"}, + tags={ + "my-tag": "my-tag-value", + "my-tag-to-remove": None, + }, ) assert_matches_type(Volume, volume, path=["response"]) diff --git a/tests/api_resources/dns/test_network_mappings.py b/tests/api_resources/dns/test_network_mappings.py index 2211c8fe2..158a3f7bd 100644 --- a/tests/api_resources/dns/test_network_mappings.py +++ b/tests/api_resources/dns/test_network_mappings.py @@ -158,7 +158,6 @@ def test_streaming_response_get(self, client: Gcore) -> None: assert cast(Any, response.is_closed) is True - @pytest.mark.skip(reason="DNS-2948: OpenAPI spec has ambiguous overlapping path templates {id} vs {name}") @parametrize def test_method_get_by_name(self, client: Gcore) -> None: network_mapping = client.dns.network_mappings.get_by_name( @@ -166,7 +165,6 @@ def test_method_get_by_name(self, client: Gcore) -> None: ) assert_matches_type(DNSNetworkMapping, network_mapping, path=["response"]) - @pytest.mark.skip(reason="DNS-2948: OpenAPI spec has ambiguous overlapping path templates {id} vs {name}") @parametrize def test_raw_response_get_by_name(self, client: Gcore) -> None: response = client.dns.network_mappings.with_raw_response.get_by_name( @@ -178,7 +176,6 @@ def test_raw_response_get_by_name(self, client: Gcore) -> None: network_mapping = response.parse() assert_matches_type(DNSNetworkMapping, network_mapping, path=["response"]) - @pytest.mark.skip(reason="DNS-2948: OpenAPI spec has ambiguous overlapping path templates {id} vs {name}") @parametrize def test_streaming_response_get_by_name(self, client: Gcore) -> None: with client.dns.network_mappings.with_streaming_response.get_by_name( @@ -412,7 +409,6 @@ async def test_streaming_response_get(self, async_client: AsyncGcore) -> None: assert cast(Any, response.is_closed) is True - @pytest.mark.skip(reason="DNS-2948: OpenAPI spec has ambiguous overlapping path templates {id} vs {name}") @parametrize async def test_method_get_by_name(self, async_client: AsyncGcore) -> None: network_mapping = await async_client.dns.network_mappings.get_by_name( @@ -420,7 +416,6 @@ async def test_method_get_by_name(self, async_client: AsyncGcore) -> None: ) assert_matches_type(DNSNetworkMapping, network_mapping, path=["response"]) - @pytest.mark.skip(reason="DNS-2948: OpenAPI spec has ambiguous overlapping path templates {id} vs {name}") @parametrize async def test_raw_response_get_by_name(self, async_client: AsyncGcore) -> None: response = await async_client.dns.network_mappings.with_raw_response.get_by_name( @@ -432,7 +427,6 @@ async def test_raw_response_get_by_name(self, async_client: AsyncGcore) -> None: network_mapping = await response.parse() assert_matches_type(DNSNetworkMapping, network_mapping, path=["response"]) - @pytest.mark.skip(reason="DNS-2948: OpenAPI spec has ambiguous overlapping path templates {id} vs {name}") @parametrize async def test_streaming_response_get_by_name(self, async_client: AsyncGcore) -> None: async with async_client.dns.network_mappings.with_streaming_response.get_by_name( diff --git a/tests/test_client.py b/tests/test_client.py index 9a14904e2..b27528a88 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -427,6 +427,30 @@ def test_default_query_option(self) -> None: client.close() + def test_hardcoded_query_params_in_url(self, client: Gcore) -> None: + request = client._build_request(FinalRequestOptions(method="get", url="/foo?beta=true")) + url = httpx.URL(request.url) + assert dict(url.params) == {"beta": "true"} + + request = client._build_request( + FinalRequestOptions( + method="get", + url="/foo?beta=true", + params={"limit": "10", "page": "abc"}, + ) + ) + url = httpx.URL(request.url) + assert dict(url.params) == {"beta": "true", "limit": "10", "page": "abc"} + + request = client._build_request( + FinalRequestOptions( + method="get", + url="/files/a%2Fb?beta=true", + params={"limit": "10"}, + ) + ) + assert request.url.raw_path == b"/files/a%2Fb?beta=true&limit=10" + def test_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;"): @@ -1338,6 +1362,30 @@ async def test_default_query_option(self) -> None: await client.close() + async def test_hardcoded_query_params_in_url(self, async_client: AsyncGcore) -> None: + request = async_client._build_request(FinalRequestOptions(method="get", url="/foo?beta=true")) + url = httpx.URL(request.url) + assert dict(url.params) == {"beta": "true"} + + request = async_client._build_request( + FinalRequestOptions( + method="get", + url="/foo?beta=true", + params={"limit": "10", "page": "abc"}, + ) + ) + url = httpx.URL(request.url) + assert dict(url.params) == {"beta": "true", "limit": "10", "page": "abc"} + + request = async_client._build_request( + FinalRequestOptions( + method="get", + url="/files/a%2Fb?beta=true", + params={"limit": "10"}, + ) + ) + assert request.url.raw_path == b"/files/a%2Fb?beta=true&limit=10" + 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;"): diff --git a/tests/test_extract_files.py b/tests/test_extract_files.py index d67473bc4..e05e48bdc 100644 --- a/tests/test_extract_files.py +++ b/tests/test_extract_files.py @@ -35,6 +35,15 @@ def test_multiple_files() -> None: assert query == {"documents": [{}, {}]} +def test_top_level_file_array() -> None: + query = {"files": [b"file one", b"file two"], "title": "hello"} + assert extract_files(query, paths=[["files", ""]]) == [ + ("files[]", b"file one"), + ("files[]", b"file two"), + ] + assert query == {"title": "hello"} + + @pytest.mark.parametrize( "query,paths,expected", [