diff --git a/scaleway-async/scaleway_async/qaas/v1alpha1/__init__.py b/scaleway-async/scaleway_async/qaas/v1alpha1/__init__.py index 6e7c77ed7..53c554e19 100644 --- a/scaleway-async/scaleway_async/qaas/v1alpha1/__init__.py +++ b/scaleway-async/scaleway_async/qaas/v1alpha1/__init__.py @@ -9,6 +9,7 @@ from .types import ListBookingsRequestOrderBy from .types import ListJobResultsRequestOrderBy from .types import ListJobsRequestOrderBy +from .types import ListModelsRequestOrderBy from .types import ListPlatformsRequestOrderBy from .types import ListProcessResultsRequestOrderBy from .types import ListProcessesRequestOrderBy @@ -31,6 +32,7 @@ from .types import Booking from .types import JobResult from .types import Job +from .types import Model from .types import Platform from .types import ProcessResult from .types import Process @@ -38,6 +40,7 @@ from .types import CancelJobRequest from .types import CancelProcessRequest from .types import CreateJobRequest +from .types import CreateModelRequest from .types import CreateProcessRequest from .types import CreateSessionRequest from .types import DeleteJobRequest @@ -47,6 +50,7 @@ from .types import GetBookingRequest from .types import GetJobCircuitRequest from .types import GetJobRequest +from .types import GetModelRequest from .types import GetPlatformRequest from .types import GetProcessRequest from .types import GetSessionRequest @@ -58,6 +62,8 @@ from .types import ListJobResultsResponse from .types import ListJobsRequest from .types import ListJobsResponse +from .types import ListModelsRequest +from .types import ListModelsResponse from .types import ListPlatformsRequest from .types import ListPlatformsResponse from .types import ListProcessResultsRequest @@ -85,6 +91,7 @@ "ListBookingsRequestOrderBy", "ListJobResultsRequestOrderBy", "ListJobsRequestOrderBy", + "ListModelsRequestOrderBy", "ListPlatformsRequestOrderBy", "ListProcessResultsRequestOrderBy", "ListProcessesRequestOrderBy", @@ -107,6 +114,7 @@ "Booking", "JobResult", "Job", + "Model", "Platform", "ProcessResult", "Process", @@ -114,6 +122,7 @@ "CancelJobRequest", "CancelProcessRequest", "CreateJobRequest", + "CreateModelRequest", "CreateProcessRequest", "CreateSessionRequest", "DeleteJobRequest", @@ -123,6 +132,7 @@ "GetBookingRequest", "GetJobCircuitRequest", "GetJobRequest", + "GetModelRequest", "GetPlatformRequest", "GetProcessRequest", "GetSessionRequest", @@ -134,6 +144,8 @@ "ListJobResultsResponse", "ListJobsRequest", "ListJobsResponse", + "ListModelsRequest", + "ListModelsResponse", "ListPlatformsRequest", "ListPlatformsResponse", "ListProcessResultsRequest", diff --git a/scaleway-async/scaleway_async/qaas/v1alpha1/api.py b/scaleway-async/scaleway_async/qaas/v1alpha1/api.py index 6d8b70138..8a7d2e409 100644 --- a/scaleway-async/scaleway_async/qaas/v1alpha1/api.py +++ b/scaleway-async/scaleway_async/qaas/v1alpha1/api.py @@ -18,6 +18,7 @@ ListBookingsRequestOrderBy, ListJobResultsRequestOrderBy, ListJobsRequestOrderBy, + ListModelsRequestOrderBy, ListPlatformsRequestOrderBy, ListProcessResultsRequestOrderBy, ListProcessesRequestOrderBy, @@ -29,6 +30,7 @@ Application, Booking, CreateJobRequest, + CreateModelRequest, CreateProcessRequest, CreateSessionRequest, CreateSessionRequestBookingDemand, @@ -39,11 +41,13 @@ ListBookingsResponse, ListJobResultsResponse, ListJobsResponse, + ListModelsResponse, ListPlatformsResponse, ListProcessResultsResponse, ListProcessesResponse, ListSessionACLsResponse, ListSessionsResponse, + Model, Platform, Process, ProcessResult, @@ -64,6 +68,7 @@ unmarshal_Application, unmarshal_Booking, unmarshal_Job, + unmarshal_Model, unmarshal_Platform, unmarshal_Process, unmarshal_Session, @@ -71,12 +76,14 @@ unmarshal_ListBookingsResponse, unmarshal_ListJobResultsResponse, unmarshal_ListJobsResponse, + unmarshal_ListModelsResponse, unmarshal_ListPlatformsResponse, unmarshal_ListProcessResultsResponse, unmarshal_ListProcessesResponse, unmarshal_ListSessionACLsResponse, unmarshal_ListSessionsResponse, marshal_CreateJobRequest, + marshal_CreateModelRequest, marshal_CreateProcessRequest, marshal_CreateSessionRequest, marshal_UpdateBookingRequest, @@ -331,6 +338,8 @@ async def create_job( circuit: JobCircuit, tags: Optional[List[str]] = None, max_duration: Optional[str] = None, + model_id: Optional[str] = None, + parameters: Optional[str] = None, ) -> Job: """ Create a job. @@ -340,6 +349,8 @@ async def create_job( :param circuit: Quantum circuit that should be executed. :param tags: Tags of the job. :param max_duration: Maximum duration of the job. + :param model_id: Computation model ID to be executed by the job. + :param parameters: Execution parameters for this job. :return: :class:`Job ` Usage: @@ -362,6 +373,8 @@ async def create_job( circuit=circuit, tags=tags, max_duration=max_duration, + model_id=model_id, + parameters=parameters, ), self.client, ), @@ -780,6 +793,7 @@ async def create_session( tags: Optional[List[str]] = None, deduplication_id: Optional[str] = None, booking_demand: Optional[CreateSessionRequestBookingDemand] = None, + model_id: Optional[str] = None, ) -> Session: """ Create a session. @@ -792,6 +806,7 @@ async def create_session( :param tags: Tags of the session. :param deduplication_id: Deduplication ID of the session. :param booking_demand: A booking demand to schedule the session, only applicable if the platform is bookable. + :param model_id: Default computation model ID to be executed by job assigned to this session. :return: :class:`Session ` Usage: @@ -815,6 +830,7 @@ async def create_session( tags=tags, deduplication_id=deduplication_id, booking_demand=booking_demand, + model_id=model_id, ), self.client, ), @@ -1655,3 +1671,138 @@ async def update_booking( self._throw_on_error(res) return unmarshal_Booking(res.json()) + + async def create_model( + self, + *, + project_id: Optional[str] = None, + payload: Optional[str] = None, + ) -> Model: + """ + Create a new model. + Create and register a new model that can be executed through next jobs. A model can also be assigned to a Session. + :param project_id: Project ID to attach this model. + :param payload: The serialized model data. + :return: :class:`Model ` + + Usage: + :: + + result = await api.create_model() + """ + + res = self._request( + "POST", + "/qaas/v1alpha1/models", + body=marshal_CreateModelRequest( + CreateModelRequest( + project_id=project_id, + payload=payload, + ), + self.client, + ), + ) + + self._throw_on_error(res) + return unmarshal_Model(res.json()) + + async def get_model( + self, + *, + model_id: str, + ) -> Model: + """ + Get model information. + Retrieve information about of the provided **model ID**. + :param model_id: Unique ID of the model. + :return: :class:`Model ` + + Usage: + :: + + result = await api.get_model( + model_id="example", + ) + """ + + param_model_id = validate_path_param("model_id", model_id) + + res = self._request( + "GET", + f"/qaas/v1alpha1/models/{param_model_id}", + ) + + self._throw_on_error(res) + return unmarshal_Model(res.json()) + + async def list_models( + self, + *, + project_id: Optional[str] = None, + page: Optional[int] = None, + page_size: Optional[int] = None, + order_by: Optional[ListModelsRequestOrderBy] = None, + ) -> ListModelsResponse: + """ + List all models attached to the **project ID**. + Retrieve information about all models of the provided **project ID**. + :param project_id: List models belonging to this project ID. + :param page: Page number. + :param page_size: Maximum number of results to return per page. + :param order_by: Sort order of the returned results. + :return: :class:`ListModelsResponse ` + + Usage: + :: + + result = await api.list_models() + """ + + res = self._request( + "GET", + "/qaas/v1alpha1/models", + params={ + "order_by": order_by, + "page": page, + "page_size": page_size or self.client.default_page_size, + "project_id": project_id or self.client.default_project_id, + }, + ) + + self._throw_on_error(res) + return unmarshal_ListModelsResponse(res.json()) + + async def list_models_all( + self, + *, + project_id: Optional[str] = None, + page: Optional[int] = None, + page_size: Optional[int] = None, + order_by: Optional[ListModelsRequestOrderBy] = None, + ) -> List[Model]: + """ + List all models attached to the **project ID**. + Retrieve information about all models of the provided **project ID**. + :param project_id: List models belonging to this project ID. + :param page: Page number. + :param page_size: Maximum number of results to return per page. + :param order_by: Sort order of the returned results. + :return: :class:`List[Model] ` + + Usage: + :: + + result = await api.list_models_all() + """ + + return await fetch_all_pages_async( + type=ListModelsResponse, + key="models", + fetcher=self.list_models, + args={ + "project_id": project_id, + "page": page, + "page_size": page_size, + "order_by": order_by, + }, + ) diff --git a/scaleway-async/scaleway_async/qaas/v1alpha1/marshalling.py b/scaleway-async/scaleway_async/qaas/v1alpha1/marshalling.py index 35fd793a4..7ca965ab9 100644 --- a/scaleway-async/scaleway_async/qaas/v1alpha1/marshalling.py +++ b/scaleway-async/scaleway_async/qaas/v1alpha1/marshalling.py @@ -18,6 +18,7 @@ Application, Booking, Job, + Model, PlatformBookingRequirement, PlatformHardware, Platform, @@ -28,6 +29,7 @@ JobResult, ListJobResultsResponse, ListJobsResponse, + ListModelsResponse, ListPlatformsResponse, ProcessResult, ListProcessResultsResponse, @@ -35,6 +37,7 @@ ListSessionACLsResponse, ListSessionsResponse, CreateJobRequest, + CreateModelRequest, CreateProcessRequest, CreateSessionRequestBookingDemand, CreateSessionRequest, @@ -172,10 +175,6 @@ def unmarshal_Job(data: Any) -> Job: if field is not None: args["session_id"] = field - field = data.get("status", None) - if field is not None: - args["status"] = field - field = data.get("tags", None) if field is not None: args["tags"] = field @@ -194,6 +193,10 @@ def unmarshal_Job(data: Any) -> Job: else: args["started_at"] = None + field = data.get("status", None) + if field is not None: + args["status"] = field + field = data.get("updated_at", None) if field is not None: args["updated_at"] = parser.isoparse(field) if isinstance(field, str) else field @@ -218,9 +221,52 @@ def unmarshal_Job(data: Any) -> Job: else: args["result_distribution"] = None + field = data.get("model_id", None) + if field is not None: + args["model_id"] = field + else: + args["model_id"] = None + + field = data.get("parameters", None) + if field is not None: + args["parameters"] = field + else: + args["parameters"] = None + return Job(**args) +def unmarshal_Model(data: Any) -> Model: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'Model' failed as data isn't a dictionary." + ) + + args: Dict[str, Any] = {} + + field = data.get("id", None) + if field is not None: + args["id"] = field + + field = data.get("project_id", None) + if field is not None: + args["project_id"] = field + + field = data.get("created_at", None) + if field is not None: + args["created_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["created_at"] = None + + field = data.get("url", None) + if field is not None: + args["url"] = field + else: + args["url"] = None + + return Model(**args) + + def unmarshal_PlatformBookingRequirement(data: Any) -> PlatformBookingRequirement: if not isinstance(data, dict): raise TypeError( @@ -507,12 +553,6 @@ def unmarshal_Session(data: Any) -> Session: if field is not None: args["waiting_job_count"] = field - field = data.get("created_at", None) - if field is not None: - args["created_at"] = parser.isoparse(field) if isinstance(field, str) else field - else: - args["created_at"] = None - field = data.get("finished_job_count", None) if field is not None: args["finished_job_count"] = field @@ -529,9 +569,11 @@ def unmarshal_Session(data: Any) -> Session: if field is not None: args["deduplication_id"] = field - field = data.get("origin_type", None) + field = data.get("created_at", None) if field is not None: - args["origin_type"] = field + args["created_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["created_at"] = None field = data.get("started_at", None) if field is not None: @@ -571,6 +613,10 @@ def unmarshal_Session(data: Any) -> Session: else: args["tags"] = None + field = data.get("origin_type", None) + if field is not None: + args["origin_type"] = field + field = data.get("origin_id", None) if field is not None: args["origin_id"] = field @@ -589,6 +635,12 @@ def unmarshal_Session(data: Any) -> Session: else: args["booking_id"] = None + field = data.get("model_id", None) + if field is not None: + args["model_id"] = field + else: + args["model_id"] = None + return Session(**args) @@ -707,6 +759,27 @@ def unmarshal_ListJobsResponse(data: Any) -> ListJobsResponse: return ListJobsResponse(**args) +def unmarshal_ListModelsResponse(data: Any) -> ListModelsResponse: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'ListModelsResponse' failed as data isn't a dictionary." + ) + + args: Dict[str, Any] = {} + + field = data.get("total_count", None) + if field is not None: + args["total_count"] = field + + field = data.get("models", None) + if field is not None: + args["models"] = ( + [unmarshal_Model(v) for v in field] if field is not None else None + ) + + return ListModelsResponse(**args) + + def unmarshal_ListPlatformsResponse(data: Any) -> ListPlatformsResponse: if not isinstance(data, dict): raise TypeError( @@ -881,6 +954,27 @@ def marshal_CreateJobRequest( if request.max_duration is not None: output["max_duration"] = request.max_duration + if request.model_id is not None: + output["model_id"] = request.model_id + + if request.parameters is not None: + output["parameters"] = request.parameters + + return output + + +def marshal_CreateModelRequest( + request: CreateModelRequest, + defaults: ProfileDefaults, +) -> Dict[str, Any]: + output: Dict[str, Any] = {} + + if request.project_id is not None: + output["project_id"] = request.project_id or defaults.default_project_id + + if request.payload is not None: + output["payload"] = request.payload + return output @@ -961,6 +1055,9 @@ def marshal_CreateSessionRequest( request.booking_demand, defaults ) + if request.model_id is not None: + output["model_id"] = request.model_id + return output diff --git a/scaleway-async/scaleway_async/qaas/v1alpha1/types.py b/scaleway-async/scaleway_async/qaas/v1alpha1/types.py index f0157bba2..ca55f12db 100644 --- a/scaleway-async/scaleway_async/qaas/v1alpha1/types.py +++ b/scaleway-async/scaleway_async/qaas/v1alpha1/types.py @@ -93,6 +93,14 @@ def __str__(self) -> str: return str(self.value) +class ListModelsRequestOrderBy(str, Enum, metaclass=StrEnumMeta): + CREATED_AT_DESC = "created_at_desc" + CREATED_AT_ASC = "created_at_asc" + + def __str__(self) -> str: + return str(self.value) + + class ListPlatformsRequestOrderBy(str, Enum, metaclass=StrEnumMeta): NAME_ASC = "name_asc" NAME_DESC = "name_desc" @@ -415,11 +423,6 @@ class Job: Session ID in which the job is executed. """ - status: JobStatus - """ - Job status. - """ - tags: Optional[List[str]] """ Tags of the job. @@ -435,6 +438,11 @@ class Job: Time at which the job was started. """ + status: JobStatus + """ + Job status. + """ + updated_at: Optional[datetime] """ Time at which the job was updated. @@ -455,6 +463,39 @@ class Job: Result of the job, if the job is finished. """ + model_id: Optional[str] + """ + Computation model ID executed by the job. + """ + + parameters: Optional[str] + """ + Execution parameters for this job. + """ + + +@dataclass +class Model: + id: str + """ + Unique ID of the model. + """ + + project_id: str + """ + Project ID in which the model has been created. + """ + + created_at: Optional[datetime] + """ + Time at which the model was created. + """ + + url: Optional[str] + """ + Storage URL of the model. + """ + @dataclass class Platform: @@ -677,11 +718,6 @@ class Session: Number of waiting jobs linked to the session. """ - created_at: Optional[datetime] - """ - The time at which the session was created. - """ - finished_job_count: int """ Number of finished jobs linked to the session. @@ -702,9 +738,9 @@ class Session: Deduplication ID of the session. """ - origin_type: SessionOriginType + created_at: Optional[datetime] """ - Resource type that creates the session. + The time at which the session was created. """ started_at: Optional[datetime] @@ -737,6 +773,11 @@ class Session: Tags of the session. """ + origin_type: SessionOriginType + """ + Resource type that creates the session. + """ + origin_id: Optional[str] """ Unique ID of the session's origin resource (if exists). @@ -752,6 +793,11 @@ class Session: An optional booking unique ID of an attached booking. """ + model_id: Optional[str] + """ + Default computation model ID to be executed by job assigned to this session. + """ + @dataclass class CancelJobRequest: @@ -796,6 +842,29 @@ class CreateJobRequest: Maximum duration of the job. """ + model_id: Optional[str] + """ + Computation model ID to be executed by the job. + """ + + parameters: Optional[str] + """ + Execution parameters for this job. + """ + + +@dataclass +class CreateModelRequest: + project_id: Optional[str] + """ + Project ID to attach this model. + """ + + payload: Optional[str] + """ + The serialized model data. + """ + @dataclass class CreateProcessRequest: @@ -872,6 +941,11 @@ class CreateSessionRequest: A booking demand to schedule the session, only applicable if the platform is bookable. """ + model_id: Optional[str] + """ + Default computation model ID to be executed by job assigned to this session. + """ + @dataclass class DeleteJobRequest: @@ -929,6 +1003,14 @@ class GetJobRequest: """ +@dataclass +class GetModelRequest: + model_id: str + """ + Unique ID of the model. + """ + + @dataclass class GetPlatformRequest: platform_id: str @@ -1111,6 +1193,42 @@ class ListJobsResponse: """ +@dataclass +class ListModelsRequest: + project_id: Optional[str] + """ + List models belonging to this project ID. + """ + + page: Optional[int] + """ + Page number. + """ + + page_size: Optional[int] + """ + Maximum number of results to return per page. + """ + + order_by: Optional[ListModelsRequestOrderBy] + """ + Sort order of the returned results. + """ + + +@dataclass +class ListModelsResponse: + total_count: int + """ + Total number of models. + """ + + models: List[Model] + """ + List of models. + """ + + @dataclass class ListPlatformsRequest: provider_name: Optional[str] diff --git a/scaleway/scaleway/qaas/v1alpha1/__init__.py b/scaleway/scaleway/qaas/v1alpha1/__init__.py index 6e7c77ed7..53c554e19 100644 --- a/scaleway/scaleway/qaas/v1alpha1/__init__.py +++ b/scaleway/scaleway/qaas/v1alpha1/__init__.py @@ -9,6 +9,7 @@ from .types import ListBookingsRequestOrderBy from .types import ListJobResultsRequestOrderBy from .types import ListJobsRequestOrderBy +from .types import ListModelsRequestOrderBy from .types import ListPlatformsRequestOrderBy from .types import ListProcessResultsRequestOrderBy from .types import ListProcessesRequestOrderBy @@ -31,6 +32,7 @@ from .types import Booking from .types import JobResult from .types import Job +from .types import Model from .types import Platform from .types import ProcessResult from .types import Process @@ -38,6 +40,7 @@ from .types import CancelJobRequest from .types import CancelProcessRequest from .types import CreateJobRequest +from .types import CreateModelRequest from .types import CreateProcessRequest from .types import CreateSessionRequest from .types import DeleteJobRequest @@ -47,6 +50,7 @@ from .types import GetBookingRequest from .types import GetJobCircuitRequest from .types import GetJobRequest +from .types import GetModelRequest from .types import GetPlatformRequest from .types import GetProcessRequest from .types import GetSessionRequest @@ -58,6 +62,8 @@ from .types import ListJobResultsResponse from .types import ListJobsRequest from .types import ListJobsResponse +from .types import ListModelsRequest +from .types import ListModelsResponse from .types import ListPlatformsRequest from .types import ListPlatformsResponse from .types import ListProcessResultsRequest @@ -85,6 +91,7 @@ "ListBookingsRequestOrderBy", "ListJobResultsRequestOrderBy", "ListJobsRequestOrderBy", + "ListModelsRequestOrderBy", "ListPlatformsRequestOrderBy", "ListProcessResultsRequestOrderBy", "ListProcessesRequestOrderBy", @@ -107,6 +114,7 @@ "Booking", "JobResult", "Job", + "Model", "Platform", "ProcessResult", "Process", @@ -114,6 +122,7 @@ "CancelJobRequest", "CancelProcessRequest", "CreateJobRequest", + "CreateModelRequest", "CreateProcessRequest", "CreateSessionRequest", "DeleteJobRequest", @@ -123,6 +132,7 @@ "GetBookingRequest", "GetJobCircuitRequest", "GetJobRequest", + "GetModelRequest", "GetPlatformRequest", "GetProcessRequest", "GetSessionRequest", @@ -134,6 +144,8 @@ "ListJobResultsResponse", "ListJobsRequest", "ListJobsResponse", + "ListModelsRequest", + "ListModelsResponse", "ListPlatformsRequest", "ListPlatformsResponse", "ListProcessResultsRequest", diff --git a/scaleway/scaleway/qaas/v1alpha1/api.py b/scaleway/scaleway/qaas/v1alpha1/api.py index f750854c7..5508f7c03 100644 --- a/scaleway/scaleway/qaas/v1alpha1/api.py +++ b/scaleway/scaleway/qaas/v1alpha1/api.py @@ -18,6 +18,7 @@ ListBookingsRequestOrderBy, ListJobResultsRequestOrderBy, ListJobsRequestOrderBy, + ListModelsRequestOrderBy, ListPlatformsRequestOrderBy, ListProcessResultsRequestOrderBy, ListProcessesRequestOrderBy, @@ -29,6 +30,7 @@ Application, Booking, CreateJobRequest, + CreateModelRequest, CreateProcessRequest, CreateSessionRequest, CreateSessionRequestBookingDemand, @@ -39,11 +41,13 @@ ListBookingsResponse, ListJobResultsResponse, ListJobsResponse, + ListModelsResponse, ListPlatformsResponse, ListProcessResultsResponse, ListProcessesResponse, ListSessionACLsResponse, ListSessionsResponse, + Model, Platform, Process, ProcessResult, @@ -64,6 +68,7 @@ unmarshal_Application, unmarshal_Booking, unmarshal_Job, + unmarshal_Model, unmarshal_Platform, unmarshal_Process, unmarshal_Session, @@ -71,12 +76,14 @@ unmarshal_ListBookingsResponse, unmarshal_ListJobResultsResponse, unmarshal_ListJobsResponse, + unmarshal_ListModelsResponse, unmarshal_ListPlatformsResponse, unmarshal_ListProcessResultsResponse, unmarshal_ListProcessesResponse, unmarshal_ListSessionACLsResponse, unmarshal_ListSessionsResponse, marshal_CreateJobRequest, + marshal_CreateModelRequest, marshal_CreateProcessRequest, marshal_CreateSessionRequest, marshal_UpdateBookingRequest, @@ -331,6 +338,8 @@ def create_job( circuit: JobCircuit, tags: Optional[List[str]] = None, max_duration: Optional[str] = None, + model_id: Optional[str] = None, + parameters: Optional[str] = None, ) -> Job: """ Create a job. @@ -340,6 +349,8 @@ def create_job( :param circuit: Quantum circuit that should be executed. :param tags: Tags of the job. :param max_duration: Maximum duration of the job. + :param model_id: Computation model ID to be executed by the job. + :param parameters: Execution parameters for this job. :return: :class:`Job ` Usage: @@ -362,6 +373,8 @@ def create_job( circuit=circuit, tags=tags, max_duration=max_duration, + model_id=model_id, + parameters=parameters, ), self.client, ), @@ -780,6 +793,7 @@ def create_session( tags: Optional[List[str]] = None, deduplication_id: Optional[str] = None, booking_demand: Optional[CreateSessionRequestBookingDemand] = None, + model_id: Optional[str] = None, ) -> Session: """ Create a session. @@ -792,6 +806,7 @@ def create_session( :param tags: Tags of the session. :param deduplication_id: Deduplication ID of the session. :param booking_demand: A booking demand to schedule the session, only applicable if the platform is bookable. + :param model_id: Default computation model ID to be executed by job assigned to this session. :return: :class:`Session ` Usage: @@ -815,6 +830,7 @@ def create_session( tags=tags, deduplication_id=deduplication_id, booking_demand=booking_demand, + model_id=model_id, ), self.client, ), @@ -1655,3 +1671,138 @@ def update_booking( self._throw_on_error(res) return unmarshal_Booking(res.json()) + + def create_model( + self, + *, + project_id: Optional[str] = None, + payload: Optional[str] = None, + ) -> Model: + """ + Create a new model. + Create and register a new model that can be executed through next jobs. A model can also be assigned to a Session. + :param project_id: Project ID to attach this model. + :param payload: The serialized model data. + :return: :class:`Model ` + + Usage: + :: + + result = api.create_model() + """ + + res = self._request( + "POST", + "/qaas/v1alpha1/models", + body=marshal_CreateModelRequest( + CreateModelRequest( + project_id=project_id, + payload=payload, + ), + self.client, + ), + ) + + self._throw_on_error(res) + return unmarshal_Model(res.json()) + + def get_model( + self, + *, + model_id: str, + ) -> Model: + """ + Get model information. + Retrieve information about of the provided **model ID**. + :param model_id: Unique ID of the model. + :return: :class:`Model ` + + Usage: + :: + + result = api.get_model( + model_id="example", + ) + """ + + param_model_id = validate_path_param("model_id", model_id) + + res = self._request( + "GET", + f"/qaas/v1alpha1/models/{param_model_id}", + ) + + self._throw_on_error(res) + return unmarshal_Model(res.json()) + + def list_models( + self, + *, + project_id: Optional[str] = None, + page: Optional[int] = None, + page_size: Optional[int] = None, + order_by: Optional[ListModelsRequestOrderBy] = None, + ) -> ListModelsResponse: + """ + List all models attached to the **project ID**. + Retrieve information about all models of the provided **project ID**. + :param project_id: List models belonging to this project ID. + :param page: Page number. + :param page_size: Maximum number of results to return per page. + :param order_by: Sort order of the returned results. + :return: :class:`ListModelsResponse ` + + Usage: + :: + + result = api.list_models() + """ + + res = self._request( + "GET", + "/qaas/v1alpha1/models", + params={ + "order_by": order_by, + "page": page, + "page_size": page_size or self.client.default_page_size, + "project_id": project_id or self.client.default_project_id, + }, + ) + + self._throw_on_error(res) + return unmarshal_ListModelsResponse(res.json()) + + def list_models_all( + self, + *, + project_id: Optional[str] = None, + page: Optional[int] = None, + page_size: Optional[int] = None, + order_by: Optional[ListModelsRequestOrderBy] = None, + ) -> List[Model]: + """ + List all models attached to the **project ID**. + Retrieve information about all models of the provided **project ID**. + :param project_id: List models belonging to this project ID. + :param page: Page number. + :param page_size: Maximum number of results to return per page. + :param order_by: Sort order of the returned results. + :return: :class:`List[Model] ` + + Usage: + :: + + result = api.list_models_all() + """ + + return fetch_all_pages( + type=ListModelsResponse, + key="models", + fetcher=self.list_models, + args={ + "project_id": project_id, + "page": page, + "page_size": page_size, + "order_by": order_by, + }, + ) diff --git a/scaleway/scaleway/qaas/v1alpha1/marshalling.py b/scaleway/scaleway/qaas/v1alpha1/marshalling.py index 35fd793a4..7ca965ab9 100644 --- a/scaleway/scaleway/qaas/v1alpha1/marshalling.py +++ b/scaleway/scaleway/qaas/v1alpha1/marshalling.py @@ -18,6 +18,7 @@ Application, Booking, Job, + Model, PlatformBookingRequirement, PlatformHardware, Platform, @@ -28,6 +29,7 @@ JobResult, ListJobResultsResponse, ListJobsResponse, + ListModelsResponse, ListPlatformsResponse, ProcessResult, ListProcessResultsResponse, @@ -35,6 +37,7 @@ ListSessionACLsResponse, ListSessionsResponse, CreateJobRequest, + CreateModelRequest, CreateProcessRequest, CreateSessionRequestBookingDemand, CreateSessionRequest, @@ -172,10 +175,6 @@ def unmarshal_Job(data: Any) -> Job: if field is not None: args["session_id"] = field - field = data.get("status", None) - if field is not None: - args["status"] = field - field = data.get("tags", None) if field is not None: args["tags"] = field @@ -194,6 +193,10 @@ def unmarshal_Job(data: Any) -> Job: else: args["started_at"] = None + field = data.get("status", None) + if field is not None: + args["status"] = field + field = data.get("updated_at", None) if field is not None: args["updated_at"] = parser.isoparse(field) if isinstance(field, str) else field @@ -218,9 +221,52 @@ def unmarshal_Job(data: Any) -> Job: else: args["result_distribution"] = None + field = data.get("model_id", None) + if field is not None: + args["model_id"] = field + else: + args["model_id"] = None + + field = data.get("parameters", None) + if field is not None: + args["parameters"] = field + else: + args["parameters"] = None + return Job(**args) +def unmarshal_Model(data: Any) -> Model: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'Model' failed as data isn't a dictionary." + ) + + args: Dict[str, Any] = {} + + field = data.get("id", None) + if field is not None: + args["id"] = field + + field = data.get("project_id", None) + if field is not None: + args["project_id"] = field + + field = data.get("created_at", None) + if field is not None: + args["created_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["created_at"] = None + + field = data.get("url", None) + if field is not None: + args["url"] = field + else: + args["url"] = None + + return Model(**args) + + def unmarshal_PlatformBookingRequirement(data: Any) -> PlatformBookingRequirement: if not isinstance(data, dict): raise TypeError( @@ -507,12 +553,6 @@ def unmarshal_Session(data: Any) -> Session: if field is not None: args["waiting_job_count"] = field - field = data.get("created_at", None) - if field is not None: - args["created_at"] = parser.isoparse(field) if isinstance(field, str) else field - else: - args["created_at"] = None - field = data.get("finished_job_count", None) if field is not None: args["finished_job_count"] = field @@ -529,9 +569,11 @@ def unmarshal_Session(data: Any) -> Session: if field is not None: args["deduplication_id"] = field - field = data.get("origin_type", None) + field = data.get("created_at", None) if field is not None: - args["origin_type"] = field + args["created_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["created_at"] = None field = data.get("started_at", None) if field is not None: @@ -571,6 +613,10 @@ def unmarshal_Session(data: Any) -> Session: else: args["tags"] = None + field = data.get("origin_type", None) + if field is not None: + args["origin_type"] = field + field = data.get("origin_id", None) if field is not None: args["origin_id"] = field @@ -589,6 +635,12 @@ def unmarshal_Session(data: Any) -> Session: else: args["booking_id"] = None + field = data.get("model_id", None) + if field is not None: + args["model_id"] = field + else: + args["model_id"] = None + return Session(**args) @@ -707,6 +759,27 @@ def unmarshal_ListJobsResponse(data: Any) -> ListJobsResponse: return ListJobsResponse(**args) +def unmarshal_ListModelsResponse(data: Any) -> ListModelsResponse: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'ListModelsResponse' failed as data isn't a dictionary." + ) + + args: Dict[str, Any] = {} + + field = data.get("total_count", None) + if field is not None: + args["total_count"] = field + + field = data.get("models", None) + if field is not None: + args["models"] = ( + [unmarshal_Model(v) for v in field] if field is not None else None + ) + + return ListModelsResponse(**args) + + def unmarshal_ListPlatformsResponse(data: Any) -> ListPlatformsResponse: if not isinstance(data, dict): raise TypeError( @@ -881,6 +954,27 @@ def marshal_CreateJobRequest( if request.max_duration is not None: output["max_duration"] = request.max_duration + if request.model_id is not None: + output["model_id"] = request.model_id + + if request.parameters is not None: + output["parameters"] = request.parameters + + return output + + +def marshal_CreateModelRequest( + request: CreateModelRequest, + defaults: ProfileDefaults, +) -> Dict[str, Any]: + output: Dict[str, Any] = {} + + if request.project_id is not None: + output["project_id"] = request.project_id or defaults.default_project_id + + if request.payload is not None: + output["payload"] = request.payload + return output @@ -961,6 +1055,9 @@ def marshal_CreateSessionRequest( request.booking_demand, defaults ) + if request.model_id is not None: + output["model_id"] = request.model_id + return output diff --git a/scaleway/scaleway/qaas/v1alpha1/types.py b/scaleway/scaleway/qaas/v1alpha1/types.py index f0157bba2..ca55f12db 100644 --- a/scaleway/scaleway/qaas/v1alpha1/types.py +++ b/scaleway/scaleway/qaas/v1alpha1/types.py @@ -93,6 +93,14 @@ def __str__(self) -> str: return str(self.value) +class ListModelsRequestOrderBy(str, Enum, metaclass=StrEnumMeta): + CREATED_AT_DESC = "created_at_desc" + CREATED_AT_ASC = "created_at_asc" + + def __str__(self) -> str: + return str(self.value) + + class ListPlatformsRequestOrderBy(str, Enum, metaclass=StrEnumMeta): NAME_ASC = "name_asc" NAME_DESC = "name_desc" @@ -415,11 +423,6 @@ class Job: Session ID in which the job is executed. """ - status: JobStatus - """ - Job status. - """ - tags: Optional[List[str]] """ Tags of the job. @@ -435,6 +438,11 @@ class Job: Time at which the job was started. """ + status: JobStatus + """ + Job status. + """ + updated_at: Optional[datetime] """ Time at which the job was updated. @@ -455,6 +463,39 @@ class Job: Result of the job, if the job is finished. """ + model_id: Optional[str] + """ + Computation model ID executed by the job. + """ + + parameters: Optional[str] + """ + Execution parameters for this job. + """ + + +@dataclass +class Model: + id: str + """ + Unique ID of the model. + """ + + project_id: str + """ + Project ID in which the model has been created. + """ + + created_at: Optional[datetime] + """ + Time at which the model was created. + """ + + url: Optional[str] + """ + Storage URL of the model. + """ + @dataclass class Platform: @@ -677,11 +718,6 @@ class Session: Number of waiting jobs linked to the session. """ - created_at: Optional[datetime] - """ - The time at which the session was created. - """ - finished_job_count: int """ Number of finished jobs linked to the session. @@ -702,9 +738,9 @@ class Session: Deduplication ID of the session. """ - origin_type: SessionOriginType + created_at: Optional[datetime] """ - Resource type that creates the session. + The time at which the session was created. """ started_at: Optional[datetime] @@ -737,6 +773,11 @@ class Session: Tags of the session. """ + origin_type: SessionOriginType + """ + Resource type that creates the session. + """ + origin_id: Optional[str] """ Unique ID of the session's origin resource (if exists). @@ -752,6 +793,11 @@ class Session: An optional booking unique ID of an attached booking. """ + model_id: Optional[str] + """ + Default computation model ID to be executed by job assigned to this session. + """ + @dataclass class CancelJobRequest: @@ -796,6 +842,29 @@ class CreateJobRequest: Maximum duration of the job. """ + model_id: Optional[str] + """ + Computation model ID to be executed by the job. + """ + + parameters: Optional[str] + """ + Execution parameters for this job. + """ + + +@dataclass +class CreateModelRequest: + project_id: Optional[str] + """ + Project ID to attach this model. + """ + + payload: Optional[str] + """ + The serialized model data. + """ + @dataclass class CreateProcessRequest: @@ -872,6 +941,11 @@ class CreateSessionRequest: A booking demand to schedule the session, only applicable if the platform is bookable. """ + model_id: Optional[str] + """ + Default computation model ID to be executed by job assigned to this session. + """ + @dataclass class DeleteJobRequest: @@ -929,6 +1003,14 @@ class GetJobRequest: """ +@dataclass +class GetModelRequest: + model_id: str + """ + Unique ID of the model. + """ + + @dataclass class GetPlatformRequest: platform_id: str @@ -1111,6 +1193,42 @@ class ListJobsResponse: """ +@dataclass +class ListModelsRequest: + project_id: Optional[str] + """ + List models belonging to this project ID. + """ + + page: Optional[int] + """ + Page number. + """ + + page_size: Optional[int] + """ + Maximum number of results to return per page. + """ + + order_by: Optional[ListModelsRequestOrderBy] + """ + Sort order of the returned results. + """ + + +@dataclass +class ListModelsResponse: + total_count: int + """ + Total number of models. + """ + + models: List[Model] + """ + List of models. + """ + + @dataclass class ListPlatformsRequest: provider_name: Optional[str]