diff --git a/.github/workflows/code_style.yml b/.github/workflows/code_style.yml index f383856..f0995ff 100644 --- a/.github/workflows/code_style.yml +++ b/.github/workflows/code_style.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - python-version: [3.6, 3.7, 3.8, 3.9, '3.10', 3.11] + python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 1197577..e5205ae 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - python-version: [3.6, 3.7, 3.8, 3.9, '3.10', 3.11] + python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] steps: - uses: actions/checkout@v2 diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 7a3aa3c..ba9a4d9 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,16 @@ Changelog ========= +v1.7.3 (2025-03-07) +------------------- + +* Fix type for contract and pricing parameters + +v1.7.1 (2025-03-06) +------------------- + +* Add contract and pricing parameters in datacrunch.instances.create() + v1.7.0 (2024-11-21) ------------------- diff --git a/datacrunch/__version__.py b/datacrunch/__version__.py index 81af483..7250282 100644 --- a/datacrunch/__version__.py +++ b/datacrunch/__version__.py @@ -1 +1 @@ -VERSION = '1.7.0' +VERSION = '1.7.3' diff --git a/datacrunch/instances/instances.py b/datacrunch/instances/instances.py index 2b65b1c..4539abb 100644 --- a/datacrunch/instances/instances.py +++ b/datacrunch/instances/instances.py @@ -1,9 +1,11 @@ -from typing import List, Union, Optional, Dict +from typing import List, Union, Optional, Dict, Literal from datacrunch.helpers import stringify_class_object_properties from datacrunch.constants import Locations INSTANCES_ENDPOINT = '/instances' +Contract = Literal['LONG_TERM', 'PAY_AS_YOU_GO', 'SPOT'] +Pricing = Literal['DYNAMIC_PRICE', 'FIXED_PRICE'] class Instance: """An instance model class""" @@ -27,7 +29,9 @@ def __init__(self, gpu_memory: dict, location: str = Locations.FIN_01, startup_script_id: str = None, - is_spot: bool = False + is_spot: bool = False, + contract: Contract = None, + pricing: Pricing = None, ) -> None: """Initialize the instance object @@ -89,6 +93,8 @@ def __init__(self, self._os_volume_id = os_volume_id self._gpu_memory = gpu_memory self._is_spot = is_spot + self._contract = contract + self._pricing = pricing @property def id(self) -> str: @@ -261,6 +267,24 @@ def is_spot(self) -> bool: """ return self._is_spot + @property + def contract(self) -> bool: + """Get contract type + + :return: contract type + :rtype: str + """ + return self._contract + + @property + def pricing(self) -> bool: + """Get pricing type + + :return: pricing type + :rtype: str + """ + return self._pricing + def __str__(self) -> str: """Returns a string of the json representation of the instance @@ -306,7 +330,9 @@ def get(self, status: str = None) -> List[Instance]: storage=instance_dict['storage'], os_volume_id=instance_dict['os_volume_id'] if 'os_volume_id' in instance_dict else None, gpu_memory=instance_dict['gpu_memory'] if 'gpu_memory' in instance_dict else None, - is_spot=instance_dict['is_spot'] if 'is_spot' in instance_dict else False + is_spot=instance_dict['is_spot'] if 'is_spot' in instance_dict else False, + contract=instance_dict['contract'] if 'contract' in instance_dict else False, + pricing=instance_dict['pricing'] if 'pricing' in instance_dict else False, ), instances_dict)) return instances @@ -340,7 +366,9 @@ def get_by_id(self, id: str) -> Instance: storage=instance_dict['storage'], os_volume_id=instance_dict['os_volume_id'] if 'os_volume_id' in instance_dict else None, gpu_memory=instance_dict['gpu_memory'] if 'gpu_memory' in instance_dict else None, - is_spot=instance_dict['is_spot'] if 'is_spot' in instance_dict else False + is_spot=instance_dict['is_spot'] if 'is_spot' in instance_dict else False, + contract=instance_dict['contract'] if 'contract' in instance_dict else False, + pricing=instance_dict['pricing'] if 'pricing' in instance_dict else False, ) return instance @@ -356,6 +384,8 @@ def create(self, existing_volumes: List[str] = None, os_volume: Dict = None, is_spot: bool = False, + contract: Contract = None, + pricing: Pricing = None, coupon: str = None) -> Instance: """Creates (deploys) a new instance @@ -381,6 +411,10 @@ def create(self, :type os_volume: Dict, optional :param is_spot: Is spot instance :type is_spot: bool, optional + :param pricing: Pricing type + :type pricing: str, optional + :param contract: Contract type + :type contract: str, optional :param coupon: coupon code :type coupon: str, optional :return: the new instance object @@ -398,8 +432,12 @@ def create(self, "volumes": volumes, "existing_volumes": existing_volumes, "is_spot": is_spot, - "coupon": coupon + "coupon": coupon, } + if contract: + payload['contract'] = contract + if pricing: + payload['pricing'] = pricing id = self._http_client.post(INSTANCES_ENDPOINT, json=payload).text instance = self.get_by_id(id) return instance