anyscale 0.26.29__py3-none-any.whl → 0.26.30__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,13 +1,11 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import asyncio
4
- from collections import defaultdict
5
- from enum import Enum
6
4
  import os
7
5
  import random
8
6
  import string
9
7
  import time
10
- from typing import Any, Callable, cast, Dict, Iterable, List, Optional
8
+ from typing import Any, cast, Dict, List, Optional
11
9
 
12
10
  import click
13
11
  import tabulate
@@ -27,21 +25,10 @@ from anyscale.client.openapi_client.models.create_internal_production_job import
27
25
  from anyscale.client.openapi_client.models.create_job_queue_config import (
28
26
  CreateJobQueueConfig,
29
27
  )
30
- from anyscale.client.openapi_client.models.decorated_job_queue import DecoratedJobQueue
31
28
  from anyscale.client.openapi_client.models.decorated_production_job import (
32
29
  DecoratedProductionJob,
33
30
  )
34
- from anyscale.client.openapi_client.models.decoratedjobqueue_response import (
35
- DecoratedjobqueueResponse,
36
- )
37
31
  from anyscale.client.openapi_client.models.ha_job_states import HaJobStates
38
- from anyscale.client.openapi_client.models.job_queue_sort_directive import (
39
- JobQueueSortDirective,
40
- )
41
- from anyscale.client.openapi_client.models.job_queues_query import JobQueuesQuery
42
- from anyscale.client.openapi_client.models.update_job_queue_request import (
43
- UpdateJobQueueRequest,
44
- )
45
32
  from anyscale.controllers.base_controller import BaseController
46
33
  from anyscale.models.job_model import JobConfig
47
34
  from anyscale.project_utils import infer_project_id
@@ -60,7 +47,7 @@ from anyscale.util import (
60
47
  populate_unspecified_cluster_configs_from_current_workspace,
61
48
  validate_job_config_dict,
62
49
  )
63
- from anyscale.utils.connect_helpers import paginate, search_entities
50
+ from anyscale.utils.connect_helpers import search_entities
64
51
  from anyscale.utils.runtime_env import override_runtime_env_config
65
52
  from anyscale.utils.workload_types import Workload
66
53
 
@@ -664,198 +651,6 @@ class JobController(BaseController):
664
651
  )
665
652
  return job_runs
666
653
 
667
- def update_job_queue(
668
- self,
669
- job_queue_id: str,
670
- job_queue_name: str,
671
- max_concurrency: Optional[int] = None,
672
- idle_timeout_s: Optional[int] = None,
673
- ):
674
- job_queue: DecoratedJobQueue = _resolve_object(
675
- fetch_by_id=cast(
676
- Callable[[str], DecoratedjobqueueResponse],
677
- self.api_client.get_job_queue_api_v2_job_queues_job_queue_id_get,
678
- ),
679
- fetch_by_id_param=job_queue_id,
680
- fetch_by_name=cast(
681
- Callable[[str], DecoratedjobqueueResponse],
682
- self.api_client.list_job_queues_api_v2_job_queues_post,
683
- ),
684
- fetch_by_name_query={
685
- "job_queues_query": {"name": {"equals": job_queue_name,}}
686
- },
687
- object_type_description="job queue",
688
- )
689
-
690
- queue: DecoratedJobQueue = self.api_client.update_job_queue_api_v2_job_queues_job_queue_id_put(
691
- job_queue_id=job_queue.id,
692
- update_job_queue_request=UpdateJobQueueRequest(
693
- max_concurrency=max_concurrency, idle_timeout_sec=idle_timeout_s,
694
- ),
695
- ).result
696
-
697
- _print_job_queue_vertical(queue, JobQueueView.ALL)
698
-
699
- def get_job_queue(self, job_queue_id: str):
700
- queue: DecoratedJobQueue = self.api_client.get_job_queue_api_v2_job_queues_job_queue_id_get(
701
- job_queue_id=job_queue_id
702
- ).result
703
-
704
- _print_job_queue_vertical(queue, JobQueueView.ALL)
705
-
706
- def list_job_queues(
707
- self,
708
- include_all_users: bool,
709
- view: JobQueueView,
710
- page_size: int,
711
- max_items: Optional[int],
712
- sorting_directives: List[JobQueueSortDirective],
713
- interactive: bool,
714
- ):
715
- creator_id = (
716
- None
717
- if include_all_users
718
- else self.api_client.get_user_info_api_v2_userinfo_get().result.id
719
- )
720
-
721
- def build_query(paging_token: Optional[str], count: int) -> Dict:
722
- return {
723
- "job_queues_query": JobQueuesQuery(
724
- creator_id=creator_id,
725
- paging=PageQuery(paging_token=paging_token, count=count),
726
- sorting_directives=sorting_directives,
727
- )
728
- }
729
-
730
- for batch in paginate(
731
- search_function=self.api_client.list_job_queues_api_v2_job_queues_post,
732
- query_builder=build_query,
733
- interactive=interactive,
734
- page_size=page_size,
735
- max_items=max_items,
736
- ):
737
- _render_job_queues(batch, view)
738
-
739
-
740
- def _render_jobs(jobs):
741
- jobs_table = [
742
- [
743
- job.name,
744
- job.id,
745
- job.project.name,
746
- job.last_job_run.cluster.name
747
- if job.last_job_run and job.last_job_run.cluster
748
- else None,
749
- job.state.current_state,
750
- job.creator.email,
751
- job.config.entrypoint
752
- if len(job.config.entrypoint) < 50
753
- else job.config.entrypoint[:50] + " ...",
754
- ]
755
- for job in jobs
756
- ]
757
-
758
- table = tabulate.tabulate(
759
- jobs_table,
760
- headers=[
761
- "NAME",
762
- "ID",
763
- "PROJECT NAME",
764
- "CLUSTER NAME",
765
- "CURRENT STATE",
766
- "CREATOR",
767
- "ENTRYPOINT",
768
- ],
769
- tablefmt="plain",
770
- )
771
- click.echo(f"{table}")
772
-
773
-
774
- class JobQueueView(Enum):
775
- ALL = DecoratedJobQueue.attribute_map.keys()
776
- STATS = [
777
- "id",
778
- "name",
779
- "total_jobs",
780
- "active_jobs",
781
- "successful_jobs",
782
- "failed_jobs",
783
- ]
784
- DEFAULT = [
785
- "id",
786
- "name",
787
- "cluster_id",
788
- "creator_id",
789
- "max_concurrency",
790
- "idle_timeout_sec",
791
- "current_cluster_state",
792
- "created_at",
793
- ]
794
-
795
-
796
- def _format_job_queue(queue: DecoratedJobQueue, view: JobQueueView) -> List[str]:
797
- formatters: Dict[str, Callable[[Any], Any]] = defaultdict(lambda: (lambda v: v))
798
- formatters["created_at"] = lambda k: k.strftime("%Y-%m-%d %H:%M:%S")
799
-
800
- return [formatters[field](getattr(queue, field, "")) or "" for field in view.value]
801
-
802
-
803
- def _render_job_queues(queues: Iterable[DecoratedJobQueue], view: JobQueueView):
804
- if not queues:
805
- click.echo("No job queues found!")
806
- return
807
- table = tabulate.tabulate(
808
- [
809
- _format_job_queue(queue, view)
810
- for queue in cast(Iterable[DecoratedJobQueue], queues)
811
- ],
812
- headers=[field.replace("_", " ").upper() for field in view.value],
813
- tablefmt="plain",
814
- maxcolwidths=30, # type: ignore
815
- numalign="center",
816
- stralign="center",
817
- )
818
- click.echo(table)
819
-
820
-
821
- def _print_job_queue_vertical(queue: DecoratedJobQueue, job_queue_view: JobQueueView):
822
- """
823
- Print single job queue with headers as a vertical table
824
- """
825
- for header, value in zip(
826
- [field.replace("_", " ").upper() for field in job_queue_view.value],
827
- _format_job_queue(queue, job_queue_view),
828
- ):
829
- print(f"{header:<{30}}: {value}")
830
-
831
-
832
- def _resolve_object(
833
- fetch_by_id: Optional[Callable[[str], object]],
834
- fetch_by_id_param: Optional[str],
835
- fetch_by_name,
836
- fetch_by_name_query,
837
- object_type_description: str,
838
- ) -> Any:
839
- """Given job_id or job_name, retrieve decorated ha job spec"""
840
- if fetch_by_id_param is None and fetch_by_name_query is None:
841
- raise click.ClickException(
842
- "Either `--id` or `--name` must be passed in for object."
843
- )
844
- if fetch_by_id_param:
845
- try:
846
- return fetch_by_id(fetch_by_id_param).result # type: ignore
847
- except Exception as e: # noqa: BLE001
848
- raise click.ClickException(
849
- f"Could not fetch {object_type_description} by id: {e}"
850
- )
851
-
852
- object_list_resp: List[Any] = fetch_by_name(**fetch_by_name_query).results
853
- if len(object_list_resp) == 0:
854
- raise click.ClickException(
855
- f"No {object_type_description} found with the provided name"
856
- )
857
- if len(object_list_resp) > 1:
858
- raise click.ClickException(
859
- f"Multiple {object_type_description}s found with the provided name"
860
- )
861
- return object_list_resp[0]
654
+ def get_authenticated_user_id(self) -> str:
655
+ user_info_response = self.api_client.get_user_info_api_v2_userinfo_get()
656
+ return user_info_response.result.id
@@ -0,0 +1,89 @@
1
+ from typing import List, Optional
2
+
3
+ from anyscale._private.anyscale_client import AnyscaleClient
4
+ from anyscale._private.models.model_base import ResultIterator
5
+ from anyscale._private.sdk import sdk_command, sdk_docs
6
+ from anyscale._private.sdk.base_sdk import Timer
7
+ from anyscale.cli_logger import BlockLogger
8
+ from anyscale.client.openapi_client.models.job_queue_sort_directive import (
9
+ JobQueueSortDirective,
10
+ )
11
+ from anyscale.client.openapi_client.models.session_state import SessionState
12
+ from anyscale.job_queue._private.job_queue_sdk import PrivateJobQueueSDK
13
+ from anyscale.job_queue.commands import (
14
+ _JOB_QUEUE_SDK_SINGLETON_KEY,
15
+ _LIST_ARG_DOCSTRINGS,
16
+ _LIST_EXAMPLE,
17
+ _STATUS_ARG_DOCSTRINGS,
18
+ _STATUS_EXAMPLE,
19
+ _UPDATE_ARG_DOCSTRINGS,
20
+ _UPDATE_EXAMPLE,
21
+ list,
22
+ status,
23
+ update,
24
+ )
25
+ from anyscale.job_queue.models import JobQueueSortField, JobQueueState, JobQueueStatus
26
+
27
+
28
+ class JobQueueSDK:
29
+ """Public SDK for interacting with Anyscale Job Queues."""
30
+
31
+ def __init__(
32
+ self,
33
+ *,
34
+ client: Optional[AnyscaleClient] = None,
35
+ logger: Optional[BlockLogger] = None,
36
+ timer: Optional[Timer] = None,
37
+ ):
38
+ self._private_sdk = PrivateJobQueueSDK(
39
+ client=client, logger=logger, timer=timer
40
+ )
41
+
42
+ @sdk_docs(doc_py_example=_LIST_EXAMPLE, arg_docstrings=_LIST_ARG_DOCSTRINGS)
43
+ def list( # noqa: F811
44
+ self,
45
+ *,
46
+ job_queue_id: Optional[str] = None,
47
+ name: Optional[str] = None,
48
+ creator_id: Optional[str] = None,
49
+ cloud: Optional[str] = None,
50
+ project: Optional[str] = None,
51
+ cluster_status: Optional[SessionState] = None,
52
+ page_size: Optional[int] = None,
53
+ max_items: Optional[int] = None,
54
+ sorting_directives: Optional[List[JobQueueSortDirective]] = None,
55
+ ) -> ResultIterator[JobQueueStatus]:
56
+ """List job queues or fetch a single job queue by ID."""
57
+ return self._private_sdk.list(
58
+ job_queue_id=job_queue_id,
59
+ name=name,
60
+ creator_id=creator_id,
61
+ cloud=cloud,
62
+ project=project,
63
+ cluster_status=cluster_status,
64
+ page_size=page_size,
65
+ max_items=max_items,
66
+ sorting_directives=sorting_directives,
67
+ )
68
+
69
+ @sdk_docs(doc_py_example=_STATUS_EXAMPLE, arg_docstrings=_STATUS_ARG_DOCSTRINGS)
70
+ def status(self, job_queue_id: str) -> JobQueueStatus: # noqa: F811
71
+ """Get the status and details for a specific job queue."""
72
+ return self._private_sdk.status(job_queue_id=job_queue_id)
73
+
74
+ @sdk_docs(doc_py_example=_UPDATE_EXAMPLE, arg_docstrings=_UPDATE_ARG_DOCSTRINGS)
75
+ def update( # noqa: F811
76
+ self,
77
+ *,
78
+ job_queue_id: Optional[str] = None,
79
+ job_queue_name: Optional[str] = None,
80
+ max_concurrency: Optional[int] = None,
81
+ idle_timeout_s: Optional[int] = None,
82
+ ) -> JobQueueStatus:
83
+ """Update a job queue."""
84
+ return self._private_sdk.update(
85
+ job_queue_id=job_queue_id,
86
+ job_queue_name=job_queue_name,
87
+ max_concurrency=max_concurrency,
88
+ idle_timeout_s=idle_timeout_s,
89
+ )
@@ -0,0 +1,158 @@
1
+ from typing import List, Optional
2
+
3
+ from anyscale._private.models.model_base import ResultIterator
4
+ from anyscale._private.workload import WorkloadSDK
5
+ from anyscale.client.openapi_client.models.decorated_job_queue import DecoratedJobQueue
6
+ from anyscale.client.openapi_client.models.decoratedjobqueue_list_response import (
7
+ DecoratedjobqueueListResponse,
8
+ )
9
+ from anyscale.client.openapi_client.models.job_queue_sort_directive import (
10
+ JobQueueSortDirective,
11
+ )
12
+ from anyscale.client.openapi_client.models.list_response_metadata import (
13
+ ListResponseMetadata,
14
+ )
15
+ from anyscale.client.openapi_client.models.session_state import SessionState
16
+ from anyscale.job_queue.models import JobQueueStatus
17
+
18
+
19
+ class PrivateJobQueueSDK(WorkloadSDK):
20
+ """Internal SDK logic for Job Queue operations."""
21
+
22
+ def list(
23
+ self,
24
+ *,
25
+ job_queue_id: Optional[str] = None,
26
+ name: Optional[str] = None,
27
+ creator_id: Optional[str] = None,
28
+ cloud: Optional[str] = None,
29
+ project: Optional[str] = None,
30
+ cluster_status: Optional[SessionState] = None,
31
+ page_size: Optional[int] = None,
32
+ max_items: Optional[int] = None,
33
+ sorting_directives: Optional[List[JobQueueSortDirective]] = None,
34
+ ) -> ResultIterator[JobQueueStatus]:
35
+ """List job queues based on specified filters and pagination.
36
+
37
+ If job_queue_id is provided, fetches only that specific job queue.
38
+ """
39
+
40
+ if job_queue_id is not None:
41
+ raw = self._resolve_to_job_queue_model(job_queue_id=job_queue_id)
42
+
43
+ def _fetch_single_page(
44
+ _token: Optional[str],
45
+ ) -> DecoratedjobqueueListResponse:
46
+ # Only return data on the first call (token=None), simulate single-item page
47
+ if _token is None and raw is not None:
48
+ results = [raw]
49
+ metadata = ListResponseMetadata(total=1, next_paging_token=None)
50
+ else:
51
+ results = []
52
+ metadata = ListResponseMetadata(total=0, next_paging_token=None)
53
+
54
+ return DecoratedjobqueueListResponse(
55
+ results=results, metadata=metadata,
56
+ )
57
+
58
+ return ResultIterator(
59
+ page_token=None,
60
+ max_items=0,
61
+ fetch_page=_fetch_single_page,
62
+ parse_fn=_parse_decorated_jq_to_status,
63
+ )
64
+
65
+ def _fetch_page(token: Optional[str]) -> DecoratedjobqueueListResponse:
66
+ return self.client.list_job_queues(
67
+ name=name,
68
+ creator_id=creator_id,
69
+ cloud=cloud,
70
+ project=project,
71
+ cluster_status=cluster_status,
72
+ count=page_size,
73
+ paging_token=token,
74
+ sorting_directives=sorting_directives,
75
+ )
76
+
77
+ return ResultIterator(
78
+ page_token=None,
79
+ max_items=max_items,
80
+ fetch_page=_fetch_page,
81
+ parse_fn=_parse_decorated_jq_to_status,
82
+ )
83
+
84
+ def status(self, job_queue_id: str) -> JobQueueStatus:
85
+ """Get the status and details for a specific job queue."""
86
+ raw = self._resolve_to_job_queue_model(job_queue_id=job_queue_id)
87
+ return _parse_decorated_jq_to_status(raw)
88
+
89
+ def update(
90
+ self,
91
+ *,
92
+ job_queue_id: Optional[str] = None,
93
+ job_queue_name: Optional[str] = None,
94
+ max_concurrency: Optional[int] = None,
95
+ idle_timeout_s: Optional[int] = None,
96
+ ) -> JobQueueStatus:
97
+ """Update a job queue."""
98
+
99
+ if max_concurrency is None and idle_timeout_s is None:
100
+ raise ValueError("No fields to update")
101
+
102
+ jq = self._resolve_to_job_queue_model(
103
+ job_queue_id=job_queue_id, name=job_queue_name
104
+ )
105
+
106
+ assert jq.id is not None
107
+ updated_jq = self.client.update_job_queue(
108
+ job_queue_id=jq.id,
109
+ max_concurrency=max_concurrency,
110
+ idle_timeout_s=idle_timeout_s,
111
+ )
112
+
113
+ return _parse_decorated_jq_to_status(updated_jq)
114
+
115
+ def _resolve_to_job_queue_model(
116
+ self, *, job_queue_id: Optional[str] = None, name: Optional[str] = None,
117
+ ) -> DecoratedJobQueue:
118
+ """Finds the specific Job Queue API model by ID or name.
119
+ """
120
+ if job_queue_id is None and name is None:
121
+ raise ValueError("Either 'job_queue_id' or 'name' must be provided.")
122
+
123
+ if job_queue_id:
124
+ job_queue = self.client.get_job_queue(job_queue_id)
125
+ if job_queue is None:
126
+ raise ValueError(f"Job Queue with ID '{job_queue_id}' not found.")
127
+ return job_queue
128
+ else:
129
+ job_queues = self.client.list_job_queues(name=name, count=1)
130
+ if len(job_queues) == 0:
131
+ raise ValueError(f"Job Queue with name '{name}' not found.")
132
+ return job_queues[0]
133
+
134
+
135
+ def _parse_decorated_jq_to_status(decorated_jq: DecoratedJobQueue) -> JobQueueStatus:
136
+ """Helper to convert API model to SDK model."""
137
+
138
+ if decorated_jq.id is None or decorated_jq.current_job_queue_state is None:
139
+ raise ValueError("Job Queue ID or state is missing.")
140
+
141
+ return JobQueueStatus(
142
+ id=decorated_jq.id,
143
+ name=decorated_jq.name,
144
+ state=decorated_jq.current_job_queue_state,
145
+ creator_email=decorated_jq.creator_email,
146
+ project_id=decorated_jq.project_id,
147
+ created_at=decorated_jq.created_at,
148
+ max_concurrency=decorated_jq.max_concurrency,
149
+ idle_timeout_s=decorated_jq.idle_timeout_sec,
150
+ creator_id=decorated_jq.creator_id,
151
+ cloud_id=decorated_jq.cloud_id,
152
+ user_provided_id=decorated_jq.user_provided_id,
153
+ execution_mode=decorated_jq.execution_mode,
154
+ total_jobs=decorated_jq.total_jobs,
155
+ active_jobs=decorated_jq.active_jobs,
156
+ successful_jobs=decorated_jq.successful_jobs,
157
+ failed_jobs=decorated_jq.failed_jobs,
158
+ )
@@ -0,0 +1,130 @@
1
+ from typing import List, Optional
2
+
3
+ from anyscale._private.models.model_base import ResultIterator
4
+ from anyscale._private.sdk import sdk_command
5
+ from anyscale.client.openapi_client.models.job_queue_sort_directive import (
6
+ JobQueueSortDirective,
7
+ )
8
+ from anyscale.client.openapi_client.models.session_state import SessionState
9
+ from anyscale.job_queue._private.job_queue_sdk import PrivateJobQueueSDK
10
+ from anyscale.job_queue.models import JobQueueStatus
11
+
12
+
13
+ _JOB_QUEUE_SDK_SINGLETON_KEY = "job_queue_sdk"
14
+
15
+
16
+ _LIST_EXAMPLE = """
17
+ import anyscale
18
+
19
+ # Example: List the first 50 job queues
20
+ for jq in anyscale.job_queue.list(max_items=50):
21
+ print(jq.id, jq.name, jq.state)
22
+ """
23
+
24
+ _LIST_ARG_DOCSTRINGS = {
25
+ "job_queue_id": "If provided, fetches only the job queue with this ID.",
26
+ "name": "Filter by job queue name.",
27
+ "creator_id": "Filter by the user ID of the creator.",
28
+ "cloud": "Filter by cloud name.",
29
+ "project": "Filter by project name.",
30
+ "cluster_status": "Filter by the state of the associated cluster.",
31
+ "page_size": "Number of items per API request page.",
32
+ "max_items": "Maximum total number of items to return.",
33
+ "sorting_directives": "List of directives to sort the results.",
34
+ }
35
+
36
+ _STATUS_EXAMPLE = """
37
+ import anyscale
38
+
39
+ status = anyscale.job_queue.status(job_queue_id=\"jobq_abc123\")
40
+ print(status)
41
+ """
42
+
43
+ _STATUS_ARG_DOCSTRINGS = {
44
+ "job_queue_id": "The unique ID of the job queue.",
45
+ }
46
+
47
+ _UPDATE_EXAMPLE = """
48
+ import anyscale
49
+
50
+ updated_jq = anyscale.job_queue.update(job_queue_id=\"jobq_abc123\", max_concurrency=5)
51
+ print(updated_jq)
52
+ """
53
+
54
+ _UPDATE_ARG_DOCSTRINGS = {
55
+ "job_queue_id": "ID of the job queue to update.",
56
+ "job_queue_name": "Name of the job queue to update (alternative to ID).",
57
+ "max_concurrency": "New maximum concurrency value.",
58
+ "idle_timeout_s": "New idle timeout in seconds.",
59
+ }
60
+
61
+
62
+ @sdk_command(
63
+ _JOB_QUEUE_SDK_SINGLETON_KEY,
64
+ PrivateJobQueueSDK,
65
+ doc_py_example=_LIST_EXAMPLE,
66
+ arg_docstrings=_LIST_ARG_DOCSTRINGS,
67
+ )
68
+ def list( # noqa: A001
69
+ *,
70
+ job_queue_id: Optional[str] = None,
71
+ name: Optional[str] = None,
72
+ creator_id: Optional[str] = None,
73
+ cloud: Optional[str] = None,
74
+ project: Optional[str] = None,
75
+ cluster_status: Optional[SessionState] = None,
76
+ page_size: Optional[int] = None,
77
+ max_items: Optional[int] = None,
78
+ sorting_directives: Optional[List[JobQueueSortDirective]] = None,
79
+ _private_sdk: Optional[PrivateJobQueueSDK] = None,
80
+ ) -> ResultIterator[JobQueueStatus]:
81
+ """List job queues or fetch a single job queue by ID."""
82
+ return _private_sdk.list( # type: ignore
83
+ job_queue_id=job_queue_id,
84
+ name=name,
85
+ creator_id=creator_id,
86
+ cloud=cloud,
87
+ project=project,
88
+ cluster_status=cluster_status,
89
+ page_size=page_size,
90
+ max_items=max_items,
91
+ sorting_directives=sorting_directives,
92
+ )
93
+
94
+
95
+ @sdk_command(
96
+ _JOB_QUEUE_SDK_SINGLETON_KEY,
97
+ PrivateJobQueueSDK,
98
+ doc_py_example=_STATUS_EXAMPLE,
99
+ arg_docstrings=_STATUS_ARG_DOCSTRINGS,
100
+ )
101
+ def status(
102
+ job_queue_id: str, _private_sdk: Optional[PrivateJobQueueSDK] = None
103
+ ) -> JobQueueStatus:
104
+ """Get the status and details for a specific job queue."""
105
+ return _private_sdk.status( # type: ignore
106
+ job_queue_id=job_queue_id
107
+ )
108
+
109
+
110
+ @sdk_command(
111
+ _JOB_QUEUE_SDK_SINGLETON_KEY,
112
+ PrivateJobQueueSDK,
113
+ doc_py_example=_UPDATE_EXAMPLE,
114
+ arg_docstrings=_UPDATE_ARG_DOCSTRINGS,
115
+ )
116
+ def update(
117
+ *,
118
+ job_queue_id: Optional[str] = None,
119
+ job_queue_name: Optional[str] = None,
120
+ max_concurrency: Optional[int] = None,
121
+ idle_timeout_s: Optional[int] = None,
122
+ _private_sdk: Optional[PrivateJobQueueSDK] = None,
123
+ ) -> JobQueueStatus:
124
+ """Update a job queue."""
125
+ return _private_sdk.update( # type: ignore
126
+ job_queue_id=job_queue_id,
127
+ job_queue_name=job_queue_name,
128
+ max_concurrency=max_concurrency,
129
+ idle_timeout_s=idle_timeout_s,
130
+ )