|
| 1 | +import requests |
1 | 2 | from dataclasses import dataclass |
2 | 3 | from dataclasses_json import dataclass_json, Undefined # type: ignore |
3 | | -from typing import List, Optional, Dict |
| 4 | +from typing import List, Optional, Dict, Any |
4 | 5 | from enum import Enum |
5 | 6 |
|
| 7 | +from datacrunch.http_client.http_client import HTTPClient |
| 8 | + |
6 | 9 |
|
7 | 10 | # API endpoints |
8 | 11 | CONTAINER_DEPLOYMENTS_ENDPOINT = '/container-deployments' |
@@ -256,39 +259,44 @@ class Deployment: |
256 | 259 | :param is_spot: Whether is spot deployment |
257 | 260 | :param endpoint_base_url: Optional base URL for the deployment endpoint |
258 | 261 | :param scaling: Optional scaling configuration |
| 262 | + :param created_at: Optional timestamp when the deployment was created |
| 263 | + :param inference_key: Optional inference key for the deployment |
259 | 264 | """ |
260 | 265 | name: str |
261 | 266 | container_registry_settings: ContainerRegistrySettings |
262 | | - containers: List[Container] |
| 267 | + containers: List[Container] | List[ContainerInfo] |
263 | 268 | compute: ComputeResource |
264 | 269 | is_spot: bool = False |
265 | 270 | endpoint_base_url: Optional[str] = None |
266 | 271 | scaling: Optional[ScalingOptions] = None |
| 272 | + created_at: Optional[str] = None |
267 | 273 |
|
| 274 | + inference_key: Optional[str] = None |
268 | 275 |
|
269 | | -@dataclass_json(undefined=Undefined.EXCLUDE) |
270 | | -@dataclass |
271 | | -class DeploymentInfo: |
272 | | - """Configuration for a container deployment. |
273 | | - This class is read-only and includes system-managed fields. |
| 276 | + @classmethod |
| 277 | + def from_dict_with_inference_key(cls, data: Dict[str, Any], inference_key: str = None, **kwargs) -> 'Deployment': |
| 278 | + """Create a Deployment instance from a dictionary with an inference key. |
274 | 279 |
|
275 | | - :param name: Name of the deployment |
276 | | - :param container_registry_settings: Settings for accessing container registry |
277 | | - :param containers: List of containers in the deployment |
278 | | - :param compute: Compute resource configuration |
279 | | - :param is_spot: Whether is spot deployment |
280 | | - :param endpoint_base_url: Optional base URL for the deployment endpoint |
281 | | - :param scaling: Optional scaling configuration |
282 | | - :param created_at: Timestamp when the deployment was created |
283 | | - """ |
284 | | - name: str |
285 | | - container_registry_settings: ContainerRegistrySettings |
286 | | - containers: List[ContainerInfo] |
287 | | - compute: ComputeResource |
288 | | - is_spot: bool = False |
289 | | - endpoint_base_url: Optional[str] = None |
290 | | - scaling: Optional[ScalingOptions] = None |
291 | | - created_at: Optional[str] = None |
| 280 | + :param data: Dictionary containing deployment data |
| 281 | + :param inference_key: inference key to set on the deployment |
| 282 | + :param **kwargs: Additional arguments to pass to from_dict |
| 283 | + :return: Deployment instance |
| 284 | + """ |
| 285 | + deployment = cls.from_dict(data, **kwargs) |
| 286 | + deployment._inference_key = inference_key |
| 287 | + return deployment |
| 288 | + |
| 289 | + def run_sync(self, data: Dict[str, Any], path: str = "", timeout_seconds: int = 60 * 5): |
| 290 | + if self._inference_key is None: |
| 291 | + raise ValueError("Inference key is not set") # TODO: review this |
| 292 | + |
| 293 | + # TODO: create a request object |
| 294 | + return requests.post( |
| 295 | + url=f"{self.endpoint_base_url}{path}", |
| 296 | + json=data, |
| 297 | + headers={"Authorization": f"Bearer {self._inference_key}"}, |
| 298 | + timeout=timeout_seconds |
| 299 | + ) |
292 | 300 |
|
293 | 301 |
|
294 | 302 | @dataclass_json |
@@ -397,67 +405,71 @@ def __init__(self, name: str, docker_config_json: str): |
397 | 405 | class ContainersService: |
398 | 406 | """Service for managing container deployments""" |
399 | 407 |
|
400 | | - def __init__(self, http_client) -> None: |
| 408 | + def __init__(self, http_client: HTTPClient, inference_key: str = None) -> None: |
401 | 409 | """Initialize the containers service |
402 | 410 |
|
403 | 411 | :param http_client: HTTP client for making API requests |
404 | 412 | :type http_client: Any |
405 | 413 | """ |
406 | 414 | self.client = http_client |
| 415 | + self._inference_key = inference_key |
407 | 416 |
|
408 | | - def get_deployments(self) -> List[DeploymentInfo]: |
| 417 | + def get_deployments(self) -> List[Deployment]: |
409 | 418 | """Get all deployments |
410 | 419 |
|
411 | 420 | :return: list of deployments |
412 | | - :rtype: List[DeploymentInfo] |
| 421 | + :rtype: List[Deployment] |
413 | 422 | """ |
414 | 423 | response = self.client.get(CONTAINER_DEPLOYMENTS_ENDPOINT) |
415 | | - return [DeploymentInfo.from_dict(deployment, infer_missing=True) for deployment in response.json()] |
| 424 | + return [Deployment.from_dict(deployment, infer_missing=True) for deployment in response.json()] |
416 | 425 |
|
417 | | - def get_deployment_by_name(self, deployment_name: str) -> DeploymentInfo: |
| 426 | + def get_deployment_by_name(self, deployment_name: str) -> Deployment: |
418 | 427 | """Get a deployment by name |
419 | 428 |
|
420 | 429 | :param deployment_name: name of the deployment |
421 | 430 | :type deployment_name: str |
422 | 431 | :return: deployment |
423 | | - :rtype: DeploymentInfo |
| 432 | + :rtype: Deployment |
424 | 433 | """ |
425 | 434 | response = self.client.get( |
426 | 435 | f"{CONTAINER_DEPLOYMENTS_ENDPOINT}/{deployment_name}") |
427 | | - return DeploymentInfo.from_dict(response.json(), infer_missing=True) |
| 436 | + return Deployment.from_dict_with_inference_key(response.json(), self._inference_key) |
| 437 | + |
| 438 | + # Function alias |
| 439 | + get_deployment = get_deployment_by_name |
428 | 440 |
|
429 | 441 | def create_deployment( |
430 | 442 | self, |
431 | 443 | deployment: Deployment |
432 | | - ) -> DeploymentInfo: |
| 444 | + ) -> Deployment: |
433 | 445 | """Create a new deployment |
434 | 446 |
|
435 | 447 | :param deployment: deployment configuration |
436 | 448 | :type deployment: Deployment |
437 | 449 | :return: created deployment |
438 | | - :rtype: DeploymentInfo |
| 450 | + :rtype: Deployment |
439 | 451 | """ |
440 | 452 | response = self.client.post( |
441 | 453 | CONTAINER_DEPLOYMENTS_ENDPOINT, |
442 | 454 | deployment.to_dict() |
443 | 455 | ) |
444 | | - return DeploymentInfo.from_dict(response.json(), infer_missing=True) |
| 456 | + return Deployment.from_dict(response.json(), infer_missing=True) |
445 | 457 |
|
446 | | - def update_deployment(self, deployment_name: str, deployment: DeploymentInfo) -> DeploymentInfo: |
| 458 | + def update_deployment(self, deployment_name: str, deployment: Deployment) -> Deployment: |
447 | 459 | """Update an existing deployment |
448 | 460 |
|
449 | 461 | :param deployment_name: name of the deployment to update |
450 | 462 | :type deployment_name: str |
451 | 463 | :param deployment: updated deployment |
452 | | - :type deployment: DeploymentInfo |
| 464 | + :type deployment: Deployment |
453 | 465 | :return: updated deployment |
454 | | - :rtype: DeploymentInfo |
| 466 | + :rtype: Deployment |
455 | 467 | """ |
456 | 468 | response = self.client.patch( |
457 | 469 | f"{CONTAINER_DEPLOYMENTS_ENDPOINT}/{deployment_name}", |
458 | 470 | deployment.to_dict() |
459 | 471 | ) |
460 | | - return DeploymentInfo.from_dict(response.json(), infer_missing=True) |
| 472 | + return Deployment.from_dict(response.json(), infer_missing=True) |
461 | 473 |
|
462 | 474 | def delete_deployment(self, deployment_name: str) -> None: |
463 | 475 | """Delete a deployment |
@@ -661,6 +673,9 @@ def get_compute_resources(self) -> List[ComputeResource]: |
661 | 673 | resources.append(ComputeResource.from_dict(resource)) |
662 | 674 | return resources |
663 | 675 |
|
| 676 | + # Function alias |
| 677 | + get_gpus = get_compute_resources |
| 678 | + |
664 | 679 | def get_secrets(self) -> List[Secret]: |
665 | 680 | """Get all secrets |
666 | 681 |
|
|
0 commit comments