qi-compute-api-client 0.39.0__py3-none-any.whl → 0.43.0__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.

Potentially problematic release.


This version of qi-compute-api-client might be problematic. Click here for more details.

@@ -18,6 +18,7 @@ __version__ = "1.0.0"
18
18
 
19
19
  # import apis into sdk package
20
20
  from compute_api_client.api.algorithms_api import AlgorithmsApi
21
+ from compute_api_client.api.auth_config_api import AuthConfigApi
21
22
  from compute_api_client.api.backend_api import BackendApi
22
23
  from compute_api_client.api.backend_types_api import BackendTypesApi
23
24
  from compute_api_client.api.batch_jobs_api import BatchJobsApi
@@ -52,6 +53,7 @@ from compute_api_client.exceptions import ApiException
52
53
  from compute_api_client.models.algorithm import Algorithm
53
54
  from compute_api_client.models.algorithm_in import AlgorithmIn
54
55
  from compute_api_client.models.algorithm_type import AlgorithmType
56
+ from compute_api_client.models.auth_config import AuthConfig
55
57
  from compute_api_client.models.backend import Backend
56
58
  from compute_api_client.models.backend_in import BackendIn
57
59
  from compute_api_client.models.backend_patch import BackendPatch
@@ -70,6 +72,7 @@ from compute_api_client.models.file import File
70
72
  from compute_api_client.models.file_in import FileIn
71
73
  from compute_api_client.models.final_result import FinalResult
72
74
  from compute_api_client.models.final_result_in import FinalResultIn
75
+ from compute_api_client.models.http_bad_request_error import HTTPBadRequestError
73
76
  from compute_api_client.models.http_not_found_error import HTTPNotFoundError
74
77
  from compute_api_client.models.http_validation_error import HTTPValidationError
75
78
  from compute_api_client.models.job import Job
@@ -2,6 +2,7 @@
2
2
 
3
3
  # import apis into api package
4
4
  from compute_api_client.api.algorithms_api import AlgorithmsApi
5
+ from compute_api_client.api.auth_config_api import AuthConfigApi
5
6
  from compute_api_client.api.backend_api import BackendApi
6
7
  from compute_api_client.api.backend_types_api import BackendTypesApi
7
8
  from compute_api_client.api.batch_jobs_api import BatchJobsApi
@@ -0,0 +1,286 @@
1
+ # coding: utf-8
2
+
3
+ """
4
+ Quantum Inspire 2
5
+
6
+ No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
7
+
8
+ The version of the OpenAPI document: 0.1.0
9
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
10
+
11
+ Do not edit the class manually.
12
+ """ # noqa: E501
13
+
14
+
15
+ import io
16
+ import warnings
17
+
18
+ from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt
19
+ from typing import Dict, List, Optional, Tuple, Union, Any
20
+
21
+ try:
22
+ from typing import Annotated
23
+ except ImportError:
24
+ from typing_extensions import Annotated
25
+
26
+ from compute_api_client.models.auth_config import AuthConfig
27
+
28
+ from compute_api_client.api_client import ApiClient
29
+ from compute_api_client.api_response import ApiResponse
30
+ from compute_api_client.rest import RESTResponseType
31
+
32
+
33
+ class AuthConfigApi:
34
+ """NOTE: This class is auto generated by OpenAPI Generator
35
+ Ref: https://openapi-generator.tech
36
+
37
+ Do not edit the class manually.
38
+ """
39
+
40
+ def __init__(self, api_client=None) -> None:
41
+ if api_client is None:
42
+ api_client = ApiClient.get_default()
43
+ self.api_client = api_client
44
+
45
+
46
+ @validate_call
47
+ async def auth_config_auth_config_get(
48
+ self,
49
+ _request_timeout: Union[
50
+ None,
51
+ Annotated[StrictFloat, Field(gt=0)],
52
+ Tuple[
53
+ Annotated[StrictFloat, Field(gt=0)],
54
+ Annotated[StrictFloat, Field(gt=0)]
55
+ ]
56
+ ] = None,
57
+ _request_auth: Optional[Dict[StrictStr, Any]] = None,
58
+ _content_type: Optional[StrictStr] = None,
59
+ _headers: Optional[Dict[StrictStr, Any]] = None,
60
+ _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
61
+ ) -> AuthConfig:
62
+ """Get suggested authentication configuration
63
+
64
+
65
+ :param _request_timeout: timeout setting for this request. If one
66
+ number provided, it will be total request
67
+ timeout. It can also be a pair (tuple) of
68
+ (connection, read) timeouts.
69
+ :type _request_timeout: int, tuple(int, int), optional
70
+ :param _request_auth: set to override the auth_settings for an a single
71
+ request; this effectively ignores the
72
+ authentication in the spec for a single request.
73
+ :type _request_auth: dict, optional
74
+ :param _content_type: force content-type for the request.
75
+ :type _content_type: str, Optional
76
+ :param _headers: set to override the headers for a single
77
+ request; this effectively ignores the headers
78
+ in the spec for a single request.
79
+ :type _headers: dict, optional
80
+ :param _host_index: set to override the host_index for a single
81
+ request; this effectively ignores the host_index
82
+ in the spec for a single request.
83
+ :type _host_index: int, optional
84
+ :return: Returns the result object.
85
+ """ # noqa: E501
86
+
87
+ _param = self._auth_config_auth_config_get_serialize(
88
+ _request_auth=_request_auth,
89
+ _content_type=_content_type,
90
+ _headers=_headers,
91
+ _host_index=_host_index
92
+ )
93
+
94
+ _response_types_map: Dict[str, Optional[str]] = {
95
+ '200': "AuthConfig"
96
+
97
+ }
98
+ response_data = await self.api_client.call_api(
99
+ *_param,
100
+ _request_timeout=_request_timeout
101
+ )
102
+ await response_data.read()
103
+ return self.api_client.response_deserialize(
104
+ response_data=response_data,
105
+ response_types_map=_response_types_map,
106
+ ).data
107
+
108
+
109
+ @validate_call
110
+ async def auth_config_auth_config_get_with_http_info(
111
+ self,
112
+ _request_timeout: Union[
113
+ None,
114
+ Annotated[StrictFloat, Field(gt=0)],
115
+ Tuple[
116
+ Annotated[StrictFloat, Field(gt=0)],
117
+ Annotated[StrictFloat, Field(gt=0)]
118
+ ]
119
+ ] = None,
120
+ _request_auth: Optional[Dict[StrictStr, Any]] = None,
121
+ _content_type: Optional[StrictStr] = None,
122
+ _headers: Optional[Dict[StrictStr, Any]] = None,
123
+ _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
124
+ ) -> ApiResponse[AuthConfig]:
125
+ """Get suggested authentication configuration
126
+
127
+
128
+ :param _request_timeout: timeout setting for this request. If one
129
+ number provided, it will be total request
130
+ timeout. It can also be a pair (tuple) of
131
+ (connection, read) timeouts.
132
+ :type _request_timeout: int, tuple(int, int), optional
133
+ :param _request_auth: set to override the auth_settings for an a single
134
+ request; this effectively ignores the
135
+ authentication in the spec for a single request.
136
+ :type _request_auth: dict, optional
137
+ :param _content_type: force content-type for the request.
138
+ :type _content_type: str, Optional
139
+ :param _headers: set to override the headers for a single
140
+ request; this effectively ignores the headers
141
+ in the spec for a single request.
142
+ :type _headers: dict, optional
143
+ :param _host_index: set to override the host_index for a single
144
+ request; this effectively ignores the host_index
145
+ in the spec for a single request.
146
+ :type _host_index: int, optional
147
+ :return: Returns the result object.
148
+ """ # noqa: E501
149
+
150
+ _param = self._auth_config_auth_config_get_serialize(
151
+ _request_auth=_request_auth,
152
+ _content_type=_content_type,
153
+ _headers=_headers,
154
+ _host_index=_host_index
155
+ )
156
+
157
+ _response_types_map: Dict[str, Optional[str]] = {
158
+ '200': "AuthConfig"
159
+
160
+ }
161
+ response_data = await self.api_client.call_api(
162
+ *_param,
163
+ _request_timeout=_request_timeout
164
+ )
165
+ await response_data.read()
166
+ return self.api_client.response_deserialize(
167
+ response_data=response_data,
168
+ response_types_map=_response_types_map,
169
+ )
170
+
171
+
172
+ @validate_call
173
+ async def auth_config_auth_config_get_without_preload_content(
174
+ self,
175
+ _request_timeout: Union[
176
+ None,
177
+ Annotated[StrictFloat, Field(gt=0)],
178
+ Tuple[
179
+ Annotated[StrictFloat, Field(gt=0)],
180
+ Annotated[StrictFloat, Field(gt=0)]
181
+ ]
182
+ ] = None,
183
+ _request_auth: Optional[Dict[StrictStr, Any]] = None,
184
+ _content_type: Optional[StrictStr] = None,
185
+ _headers: Optional[Dict[StrictStr, Any]] = None,
186
+ _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
187
+ ) -> RESTResponseType:
188
+ """Get suggested authentication configuration
189
+
190
+
191
+ :param _request_timeout: timeout setting for this request. If one
192
+ number provided, it will be total request
193
+ timeout. It can also be a pair (tuple) of
194
+ (connection, read) timeouts.
195
+ :type _request_timeout: int, tuple(int, int), optional
196
+ :param _request_auth: set to override the auth_settings for an a single
197
+ request; this effectively ignores the
198
+ authentication in the spec for a single request.
199
+ :type _request_auth: dict, optional
200
+ :param _content_type: force content-type for the request.
201
+ :type _content_type: str, Optional
202
+ :param _headers: set to override the headers for a single
203
+ request; this effectively ignores the headers
204
+ in the spec for a single request.
205
+ :type _headers: dict, optional
206
+ :param _host_index: set to override the host_index for a single
207
+ request; this effectively ignores the host_index
208
+ in the spec for a single request.
209
+ :type _host_index: int, optional
210
+ :return: Returns the result object.
211
+ """ # noqa: E501
212
+
213
+ _param = self._auth_config_auth_config_get_serialize(
214
+ _request_auth=_request_auth,
215
+ _content_type=_content_type,
216
+ _headers=_headers,
217
+ _host_index=_host_index
218
+ )
219
+
220
+ _response_types_map: Dict[str, Optional[str]] = {
221
+ '200': "AuthConfig"
222
+
223
+ }
224
+ response_data = await self.api_client.call_api(
225
+ *_param,
226
+ _request_timeout=_request_timeout
227
+ )
228
+ return response_data.response
229
+
230
+
231
+ def _auth_config_auth_config_get_serialize(
232
+ self,
233
+ _request_auth,
234
+ _content_type,
235
+ _headers,
236
+ _host_index,
237
+ ) -> Tuple:
238
+
239
+ _host = None
240
+
241
+ _collection_formats: Dict[str, str] = {
242
+
243
+ }
244
+
245
+ _path_params: Dict[str, str] = {}
246
+ _query_params: List[Tuple[str, str]] = []
247
+ _header_params: Dict[str, Optional[str]] = _headers or {}
248
+ _form_params: List[Tuple[str, str]] = []
249
+ _files: Dict[str, str] = {}
250
+ _body_params: Optional[bytes] = None
251
+
252
+ # process the path parameters
253
+ # process the query parameters
254
+ # process the header parameters
255
+ # process the form parameters
256
+ # process the body parameter
257
+
258
+
259
+ # set the HTTP header `Accept`
260
+ _header_params['Accept'] = self.api_client.select_header_accept(
261
+ [
262
+ 'application/json'
263
+ ]
264
+ )
265
+
266
+
267
+ # authentication setting
268
+ _auth_settings: List[str] = [
269
+ ]
270
+
271
+ return self.api_client.param_serialize(
272
+ method='GET',
273
+ resource_path='/auth_config',
274
+ path_params=_path_params,
275
+ query_params=_query_params,
276
+ header_params=_header_params,
277
+ body=_body_params,
278
+ post_params=_form_params,
279
+ files=_files,
280
+ auth_settings=_auth_settings,
281
+ collection_formats=_collection_formats,
282
+ _host=_host,
283
+ _request_auth=_request_auth
284
+ )
285
+
286
+
@@ -298,7 +298,8 @@ class BackendTypesApi:
298
298
 
299
299
  # authentication setting
300
300
  _auth_settings: List[str] = [
301
- 'user_bearer'
301
+ 'user_bearer',
302
+ 'backend'
302
303
  ]
303
304
 
304
305
  return self.api_client.param_serialize(
@@ -0,0 +1,30 @@
1
+ # AuthConfig
2
+
3
+
4
+ ## Properties
5
+ Name | Type | Description | Notes
6
+ ------------ | ------------- | ------------- | -------------
7
+ **client_id** | **str** | |
8
+ **audience** | **str** | |
9
+ **well_known_endpoint** | **str** | |
10
+
11
+ ## Example
12
+
13
+ ```python
14
+ from compute_api_client.models.auth_config import AuthConfig
15
+
16
+ # TODO update the JSON string below
17
+ json = "{}"
18
+ # create an instance of AuthConfig from a JSON string
19
+ auth_config_instance = AuthConfig.from_json(json)
20
+ # print the JSON string representation of the object
21
+ print AuthConfig.to_json()
22
+
23
+ # convert the object into a dict
24
+ auth_config_dict = auth_config_instance.to_dict()
25
+ # create an instance of AuthConfig from a dict
26
+ auth_config_form_dict = auth_config.from_dict(auth_config_dict)
27
+ ```
28
+ [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
29
+
30
+
@@ -0,0 +1,70 @@
1
+ # compute_api_client.AuthConfigApi
2
+
3
+ All URIs are relative to *http://localhost*
4
+
5
+ Method | HTTP request | Description
6
+ ------------- | ------------- | -------------
7
+ [**auth_config_auth_config_get**](AuthConfigApi.md#auth_config_auth_config_get) | **GET** /auth_config | Get suggested authentication configuration
8
+
9
+
10
+ # **auth_config_auth_config_get**
11
+ > AuthConfig auth_config_auth_config_get()
12
+
13
+ Get suggested authentication configuration
14
+
15
+ ### Example
16
+
17
+ ```python
18
+ import time
19
+ import os
20
+ import compute_api_client
21
+ from compute_api_client.models.auth_config import AuthConfig
22
+ from compute_api_client.rest import ApiException
23
+ from pprint import pprint
24
+
25
+ # Defining the host is optional and defaults to http://localhost
26
+ # See configuration.py for a list of all supported configuration parameters.
27
+ configuration = compute_api_client.Configuration(
28
+ host = "http://localhost"
29
+ )
30
+
31
+
32
+ # Enter a context with an instance of the API client
33
+ async with compute_api_client.ApiClient(configuration) as api_client:
34
+ # Create an instance of the API class
35
+ api_instance = compute_api_client.AuthConfigApi(api_client)
36
+
37
+ try:
38
+ # Get suggested authentication configuration
39
+ api_response = await api_instance.auth_config_auth_config_get()
40
+ print("The response of AuthConfigApi->auth_config_auth_config_get:\n")
41
+ pprint(api_response)
42
+ except Exception as e:
43
+ print("Exception when calling AuthConfigApi->auth_config_auth_config_get: %s\n" % e)
44
+ ```
45
+
46
+
47
+
48
+ ### Parameters
49
+ This endpoint does not need any parameter.
50
+
51
+ ### Return type
52
+
53
+ [**AuthConfig**](AuthConfig.md)
54
+
55
+ ### Authorization
56
+
57
+ No authorization required
58
+
59
+ ### HTTP request headers
60
+
61
+ - **Content-Type**: Not defined
62
+ - **Accept**: application/json
63
+
64
+ ### HTTP response details
65
+ | Status code | Description | Response headers |
66
+ |-------------|-------------|------------------|
67
+ **200** | Successful Response | - |
68
+
69
+ [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
70
+
@@ -18,6 +18,7 @@ Get backend type by ID.
18
18
  ### Example
19
19
 
20
20
  * OAuth Authentication (user_bearer):
21
+ * Api Key Authentication (backend):
21
22
  ```python
22
23
  import time
23
24
  import os
@@ -39,6 +40,12 @@ configuration = compute_api_client.Configuration(
39
40
 
40
41
  configuration.access_token = os.environ["ACCESS_TOKEN"]
41
42
 
43
+ # Configure API key authorization: backend
44
+ configuration.api_key['backend'] = os.environ["API_KEY"]
45
+
46
+ # Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
47
+ # configuration.api_key_prefix['backend'] = 'Bearer'
48
+
42
49
  # Enter a context with an instance of the API client
43
50
  async with compute_api_client.ApiClient(configuration) as api_client:
44
51
  # Create an instance of the API class
@@ -68,7 +75,7 @@ Name | Type | Description | Notes
68
75
 
69
76
  ### Authorization
70
77
 
71
- [user_bearer](../README.md#user_bearer)
78
+ [user_bearer](../README.md#user_bearer), [backend](../README.md#backend)
72
79
 
73
80
  ### HTTP request headers
74
81
 
@@ -90,6 +90,7 @@ void (empty response body)
90
90
  |-------------|-------------|------------------|
91
91
  **204** | Compiled | - |
92
92
  **404** | Not Found | - |
93
+ **400** | Bad Request | - |
93
94
  **422** | Validation Error | - |
94
95
 
95
96
  [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
@@ -0,0 +1,28 @@
1
+ # HTTPBadRequestError
2
+
3
+
4
+ ## Properties
5
+ Name | Type | Description | Notes
6
+ ------------ | ------------- | ------------- | -------------
7
+ **detail** | **str** | |
8
+
9
+ ## Example
10
+
11
+ ```python
12
+ from compute_api_client.models.http_bad_request_error import HTTPBadRequestError
13
+
14
+ # TODO update the JSON string below
15
+ json = "{}"
16
+ # create an instance of HTTPBadRequestError from a JSON string
17
+ http_bad_request_error_instance = HTTPBadRequestError.from_json(json)
18
+ # print the JSON string representation of the object
19
+ print HTTPBadRequestError.to_json()
20
+
21
+ # convert the object into a dict
22
+ http_bad_request_error_dict = http_bad_request_error_instance.to_dict()
23
+ # create an instance of HTTPBadRequestError from a dict
24
+ http_bad_request_error_form_dict = http_bad_request_error.from_dict(http_bad_request_error_dict)
25
+ ```
26
+ [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
27
+
28
+
@@ -17,6 +17,7 @@
17
17
  from compute_api_client.models.algorithm import Algorithm
18
18
  from compute_api_client.models.algorithm_in import AlgorithmIn
19
19
  from compute_api_client.models.algorithm_type import AlgorithmType
20
+ from compute_api_client.models.auth_config import AuthConfig
20
21
  from compute_api_client.models.backend import Backend
21
22
  from compute_api_client.models.backend_in import BackendIn
22
23
  from compute_api_client.models.backend_patch import BackendPatch
@@ -35,6 +36,7 @@ from compute_api_client.models.file import File
35
36
  from compute_api_client.models.file_in import FileIn
36
37
  from compute_api_client.models.final_result import FinalResult
37
38
  from compute_api_client.models.final_result_in import FinalResultIn
39
+ from compute_api_client.models.http_bad_request_error import HTTPBadRequestError
38
40
  from compute_api_client.models.http_not_found_error import HTTPNotFoundError
39
41
  from compute_api_client.models.http_validation_error import HTTPValidationError
40
42
  from compute_api_client.models.job import Job
@@ -0,0 +1,91 @@
1
+ # coding: utf-8
2
+
3
+ """
4
+ Quantum Inspire 2
5
+
6
+ No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
7
+
8
+ The version of the OpenAPI document: 0.1.0
9
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
10
+
11
+ Do not edit the class manually.
12
+ """ # noqa: E501
13
+
14
+
15
+ from __future__ import annotations
16
+ import pprint
17
+ import re # noqa: F401
18
+ import json
19
+
20
+
21
+ from typing import Any, ClassVar, Dict, List
22
+ from pydantic import BaseModel, StrictStr
23
+ try:
24
+ from typing import Self
25
+ except ImportError:
26
+ from typing_extensions import Self
27
+
28
+ class AuthConfig(BaseModel):
29
+ """
30
+ AuthConfig
31
+ """ # noqa: E501
32
+ client_id: StrictStr
33
+ audience: StrictStr
34
+ well_known_endpoint: StrictStr
35
+ __properties: ClassVar[List[str]] = ["client_id", "audience", "well_known_endpoint"]
36
+
37
+ model_config = {
38
+ "populate_by_name": True,
39
+ "validate_assignment": True
40
+ }
41
+
42
+
43
+ def to_str(self) -> str:
44
+ """Returns the string representation of the model using alias"""
45
+ return pprint.pformat(self.model_dump(by_alias=True))
46
+
47
+ def to_json(self) -> str:
48
+ """Returns the JSON representation of the model using alias"""
49
+ # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
50
+ return json.dumps(self.to_dict())
51
+
52
+ @classmethod
53
+ def from_json(cls, json_str: str) -> Self:
54
+ """Create an instance of AuthConfig from a JSON string"""
55
+ return cls.from_dict(json.loads(json_str))
56
+
57
+ def to_dict(self) -> Dict[str, Any]:
58
+ """Return the dictionary representation of the model using alias.
59
+
60
+ This has the following differences from calling pydantic's
61
+ `self.model_dump(by_alias=True)`:
62
+
63
+ * `None` is only added to the output dict for nullable fields that
64
+ were set at model initialization. Other fields with value `None`
65
+ are ignored.
66
+ """
67
+ _dict = self.model_dump(
68
+ by_alias=True,
69
+ exclude={
70
+ },
71
+ exclude_none=True,
72
+ )
73
+ return _dict
74
+
75
+ @classmethod
76
+ def from_dict(cls, obj: Dict) -> Self:
77
+ """Create an instance of AuthConfig from a dict"""
78
+ if obj is None:
79
+ return None
80
+
81
+ if not isinstance(obj, dict):
82
+ return cls.model_validate(obj)
83
+
84
+ _obj = cls.model_validate({
85
+ "client_id": obj.get("client_id"),
86
+ "audience": obj.get("audience"),
87
+ "well_known_endpoint": obj.get("well_known_endpoint")
88
+ })
89
+ return _obj
90
+
91
+
@@ -0,0 +1,87 @@
1
+ # coding: utf-8
2
+
3
+ """
4
+ Quantum Inspire 2
5
+
6
+ No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
7
+
8
+ The version of the OpenAPI document: 0.1.0
9
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
10
+
11
+ Do not edit the class manually.
12
+ """ # noqa: E501
13
+
14
+
15
+ from __future__ import annotations
16
+ import pprint
17
+ import re # noqa: F401
18
+ import json
19
+
20
+
21
+ from typing import Any, ClassVar, Dict, List
22
+ from pydantic import BaseModel, StrictStr
23
+ try:
24
+ from typing import Self
25
+ except ImportError:
26
+ from typing_extensions import Self
27
+
28
+ class HTTPBadRequestError(BaseModel):
29
+ """
30
+ HTTPBadRequestError
31
+ """ # noqa: E501
32
+ detail: StrictStr
33
+ __properties: ClassVar[List[str]] = ["detail"]
34
+
35
+ model_config = {
36
+ "populate_by_name": True,
37
+ "validate_assignment": True
38
+ }
39
+
40
+
41
+ def to_str(self) -> str:
42
+ """Returns the string representation of the model using alias"""
43
+ return pprint.pformat(self.model_dump(by_alias=True))
44
+
45
+ def to_json(self) -> str:
46
+ """Returns the JSON representation of the model using alias"""
47
+ # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
48
+ return json.dumps(self.to_dict())
49
+
50
+ @classmethod
51
+ def from_json(cls, json_str: str) -> Self:
52
+ """Create an instance of HTTPBadRequestError from a JSON string"""
53
+ return cls.from_dict(json.loads(json_str))
54
+
55
+ def to_dict(self) -> Dict[str, Any]:
56
+ """Return the dictionary representation of the model using alias.
57
+
58
+ This has the following differences from calling pydantic's
59
+ `self.model_dump(by_alias=True)`:
60
+
61
+ * `None` is only added to the output dict for nullable fields that
62
+ were set at model initialization. Other fields with value `None`
63
+ are ignored.
64
+ """
65
+ _dict = self.model_dump(
66
+ by_alias=True,
67
+ exclude={
68
+ },
69
+ exclude_none=True,
70
+ )
71
+ return _dict
72
+
73
+ @classmethod
74
+ def from_dict(cls, obj: Dict) -> Self:
75
+ """Create an instance of HTTPBadRequestError from a dict"""
76
+ if obj is None:
77
+ return None
78
+
79
+ if not isinstance(obj, dict):
80
+ return cls.model_validate(obj)
81
+
82
+ _obj = cls.model_validate({
83
+ "detail": obj.get("detail")
84
+ })
85
+ return _obj
86
+
87
+
qi2_shared/__init__.py ADDED
File without changes
@@ -0,0 +1,65 @@
1
+ import time
2
+ from typing import Any, Tuple, cast
3
+
4
+ import requests
5
+
6
+ from qi2_shared.settings import ApiSettings, TokenInfo, Url
7
+
8
+
9
+ class AuthorisationError(Exception):
10
+ """Indicates that the authorisation permanently went wrong."""
11
+ pass
12
+
13
+
14
+ class IdentityProvider:
15
+ """Class for interfacing with the IdentityProvider."""
16
+
17
+ def __init__(self, well_known_endpoint: str):
18
+ self._well_known_endpoint = well_known_endpoint
19
+ self._token_endpoint, self._device_endpoint = self._get_endpoints()
20
+ self._headers = {"Content-Type": "application/x-www-form-urlencoded"}
21
+
22
+ def _get_endpoints(self) -> Tuple[str, str]:
23
+ response = requests.get(self._well_known_endpoint)
24
+ response.raise_for_status()
25
+ config = response.json()
26
+ return config["token_endpoint"], config["device_authorization_endpoint"]
27
+
28
+ def refresh_access_token(self, client_id: str, refresh_token: str) -> dict[str, Any]:
29
+ data = {
30
+ "grant_type": "refresh_token",
31
+ "client_id": client_id,
32
+ "refresh_token": refresh_token,
33
+ }
34
+ response = requests.post(self._token_endpoint, headers=self._headers, data=data)
35
+ response.raise_for_status()
36
+ return cast(dict[str, Any], response.json())
37
+
38
+
39
+ class OauthDeviceSession:
40
+ """Class for storing OAuth session information and refreshing tokens when needed."""
41
+
42
+ def __init__(self, host: Url, settings: ApiSettings, identity_provider: IdentityProvider):
43
+ self._api_settings = settings
44
+ _auth_settings = settings.auths[host]
45
+ self._host = host
46
+ self._client_id = _auth_settings.client_id
47
+ self._token_info = _auth_settings.tokens
48
+ self._refresh_time_reduction = 5 # the number of seconds to refresh the expiration time
49
+ self._identity_provider = identity_provider
50
+
51
+ def refresh(self) -> TokenInfo:
52
+ if self._token_info is None:
53
+ raise AuthorisationError("You should authenticate first before you can refresh")
54
+
55
+ if self._token_info.access_expires_at > time.time() + self._refresh_time_reduction:
56
+ return self._token_info
57
+
58
+ try:
59
+ self._token_info = TokenInfo(
60
+ **self._identity_provider.refresh_access_token(self._client_id, self._token_info.refresh_token)
61
+ )
62
+ self._api_settings.store_tokens(self._host, self._token_info)
63
+ return self._token_info
64
+ except requests.HTTPError as e:
65
+ raise AuthorisationError(f"An error occurred during token refresh: {e}")
qi2_shared/client.py ADDED
@@ -0,0 +1,52 @@
1
+ from typing import Any, Optional
2
+
3
+ import compute_api_client
4
+
5
+ from qi2_shared.authentication import IdentityProvider, OauthDeviceSession
6
+ from qi2_shared.settings import ApiSettings
7
+
8
+
9
+ class Configuration(compute_api_client.Configuration): # type: ignore[misc]
10
+ """Original Configuration class in compute_api_client does not handle refreshing bearer tokens, so we need to add
11
+ some functionality."""
12
+
13
+ def __init__(self, host: str, oauth_session: OauthDeviceSession, **kwargs: Any):
14
+ self._oauth_session = oauth_session
15
+ super().__init__(host=host, **kwargs)
16
+
17
+ def auth_settings(self) -> Any:
18
+ token_info = self._oauth_session.refresh()
19
+ self.access_token = token_info.access_token
20
+ return super().auth_settings()
21
+
22
+
23
+ _config: Optional[Configuration] = None
24
+
25
+
26
+ def connect() -> None:
27
+ """Set connection configuration for the Quantum Inspire API.
28
+
29
+ Call after logging in with the CLI. Will remove old configuration.
30
+ """
31
+ global _config
32
+ settings = ApiSettings.from_config_file()
33
+
34
+ tokens = settings.auths[settings.default_host].tokens
35
+
36
+ if tokens is None:
37
+ raise ValueError("No access token found for the default host. Please connect to Quantum Inspire using the CLI.")
38
+
39
+ host = settings.default_host
40
+ _config = Configuration(
41
+ host=host,
42
+ oauth_session=OauthDeviceSession(host, settings, IdentityProvider(settings.auths[host].well_known_endpoint)),
43
+ )
44
+
45
+
46
+ def config() -> Configuration:
47
+ global _config
48
+ if _config is None:
49
+ connect()
50
+
51
+ assert _config is not None
52
+ return _config
@@ -0,0 +1,44 @@
1
+ from typing import Any, Awaitable, Callable, Generic, List, Optional, TypeVar, Union, cast
2
+
3
+ from pydantic import BaseModel, Field
4
+ from typing_extensions import Annotated
5
+
6
+ PageType = TypeVar("PageType")
7
+ ItemType = TypeVar("ItemType")
8
+
9
+
10
+ class PageInterface(BaseModel, Generic[ItemType]):
11
+ """The page models in the generated API client don't inherit from a common base class, so we have to trick the
12
+ typing system a bit with this fake base class."""
13
+
14
+ items: List[ItemType]
15
+ total: Optional[Annotated[int, Field(strict=True, ge=0)]]
16
+ page: Optional[Annotated[int, Field(strict=True, ge=1)]]
17
+ size: Optional[Annotated[int, Field(strict=True, ge=1)]]
18
+ pages: Optional[Annotated[int, Field(strict=True, ge=0)]] = None
19
+
20
+
21
+ class PageReader(Generic[PageType, ItemType]):
22
+ """Helper class for reading fastapi-pagination style pages returned by the compute_api_client."""
23
+
24
+ async def get_all(self, api_call: Callable[..., Awaitable[PageType]], **kwargs: Any) -> List[ItemType]:
25
+ """Get all items from an API call that supports paging."""
26
+ items: List[ItemType] = []
27
+ page = 1
28
+
29
+ while True:
30
+ response = cast(PageInterface[ItemType], await api_call(page=page, **kwargs))
31
+
32
+ items.extend(response.items)
33
+ page += 1
34
+ if response.pages is None or page > response.pages:
35
+ break
36
+ return items
37
+
38
+ async def get_single(self, api_call: Callable[..., Awaitable[PageType]], **kwargs: Any) -> Union[ItemType, None]:
39
+ """Get a single item from an API call that supports paging."""
40
+ response = cast(PageInterface[ItemType], await api_call(**kwargs))
41
+ if len(response.items) > 1:
42
+ raise RuntimeError(f"Response contains more than one item -> {kwargs}.")
43
+
44
+ return response.items[0] if response.items else None
qi2_shared/settings.py ADDED
@@ -0,0 +1,68 @@
1
+ """Module containing the handler for the Quantum Inspire persistent configuration."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import time
6
+ from pathlib import Path
7
+ from typing import Dict, Optional
8
+
9
+ from pydantic import BaseModel, BeforeValidator, Field, HttpUrl
10
+ from typing_extensions import Annotated
11
+
12
+ Url = Annotated[str, BeforeValidator(lambda value: str(HttpUrl(value)).rstrip("/"))]
13
+ API_SETTINGS_FILE = Path.joinpath(Path.home(), ".quantuminspire", "config.json")
14
+
15
+
16
+ class TokenInfo(BaseModel):
17
+ """A pydantic model for storing all information regarding oauth access and refresh tokens."""
18
+
19
+ access_token: str
20
+ expires_in: int # [s]
21
+ refresh_token: str
22
+ refresh_expires_in: Optional[int] = None # [s]
23
+ generated_at: float = Field(default_factory=time.time)
24
+
25
+ @property
26
+ def access_expires_at(self) -> float:
27
+ """Unix timestamp containing the time when the access token will expire."""
28
+ return self.generated_at + self.expires_in
29
+
30
+
31
+ class AuthSettings(BaseModel):
32
+ """Pydantic model for storing all auth related settings for a given host."""
33
+
34
+ client_id: str
35
+ code_challenge_method: str
36
+ code_verifyer_length: int
37
+ well_known_endpoint: Url
38
+ tokens: Optional[TokenInfo]
39
+ team_member_id: Optional[int]
40
+
41
+
42
+ class ApiSettings(BaseModel):
43
+ """The settings class for the Quantum Inspire persistent configuration."""
44
+
45
+ auths: Dict[Url, AuthSettings]
46
+ default_host: Url
47
+
48
+ def store_tokens(self, host: Url, tokens: TokenInfo, path: Path = API_SETTINGS_FILE) -> None:
49
+ """Stores the team_member_id, access and refresh tokens in the config.json file.
50
+
51
+ Args:
52
+ host: The hostname of the API for which the tokens are intended.
53
+ tokens: OAuth access and refresh tokens.
54
+ path: The path to the config.json file. Defaults to API_SETTINGS_FILE.
55
+ Returns:
56
+ None
57
+ """
58
+ self.auths[host].tokens = tokens
59
+ path.write_text(self.model_dump_json(indent=2))
60
+
61
+ @classmethod
62
+ def from_config_file(cls, path: Path = API_SETTINGS_FILE) -> ApiSettings:
63
+ """Load the configuration from a file."""
64
+ if not path.is_file():
65
+ raise FileNotFoundError("No configuration file found. Please connect to Quantum Inspire using the CLI.")
66
+
67
+ api_settings = path.read_text()
68
+ return ApiSettings.model_validate_json(api_settings)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: qi-compute-api-client
3
- Version: 0.39.0
3
+ Version: 0.43.0
4
4
  Summary: An API client for the Compute Job Manager of Quantum Inspire.
5
5
  Home-page: https://github.com/QuTech-Delft/compute-api-client
6
6
  License: Apache-2.0
@@ -17,7 +17,9 @@ Classifier: Programming Language :: Python :: 3.11
17
17
  Classifier: Programming Language :: Python :: 3.12
18
18
  Classifier: Programming Language :: Python :: 3.13
19
19
  Requires-Dist: aiohttp (>=3.10.5,<4.0.0)
20
+ Requires-Dist: pydantic (>=2.10.4,<3.0.0)
20
21
  Requires-Dist: python-dateutil (>=2.8.2,<3.0.0)
22
+ Requires-Dist: requests (>=2.32.3,<3.0.0)
21
23
  Requires-Dist: urllib3 (>=2.0.0,<3.0.0)
22
24
  Project-URL: Repository, https://github.com/QuTech-Delft/compute-api-client
23
25
  Description-Content-Type: text/markdown
@@ -99,6 +101,7 @@ Class | Method | HTTP request | Description
99
101
  *AlgorithmsApi* | [**read_algorithm_algorithms_id_get**](compute_api_client/docs/AlgorithmsApi.md#read_algorithm_algorithms_id_get) | **GET** /algorithms/{id} | Retrieve algorithm
100
102
  *AlgorithmsApi* | [**read_algorithms_algorithms_get**](compute_api_client/docs/AlgorithmsApi.md#read_algorithms_algorithms_get) | **GET** /algorithms | List algorithms
101
103
  *AlgorithmsApi* | [**update_algorithm_algorithms_id_put**](compute_api_client/docs/AlgorithmsApi.md#update_algorithm_algorithms_id_put) | **PUT** /algorithms/{id} | Update algorithm
104
+ *AuthConfigApi* | [**auth_config_auth_config_get**](compute_api_client/docs/AuthConfigApi.md#auth_config_auth_config_get) | **GET** /auth_config | Get suggested authentication configuration
102
105
  *BackendApi* | [**create_backend_backends_post**](compute_api_client/docs/BackendApi.md#create_backend_backends_post) | **POST** /backends | Create backend
103
106
  *BackendApi* | [**read_backend_backends_id_get**](compute_api_client/docs/BackendApi.md#read_backend_backends_id_get) | **GET** /backends/{id} | Retrieve backend
104
107
  *BackendApi* | [**read_backend_self_backends_me_get**](compute_api_client/docs/BackendApi.md#read_backend_self_backends_me_get) | **GET** /backends/me | Retrieve backend
@@ -174,6 +177,7 @@ Class | Method | HTTP request | Description
174
177
  - [Algorithm](compute_api_client/docs/Algorithm.md)
175
178
  - [AlgorithmIn](compute_api_client/docs/AlgorithmIn.md)
176
179
  - [AlgorithmType](compute_api_client/docs/AlgorithmType.md)
180
+ - [AuthConfig](compute_api_client/docs/AuthConfig.md)
177
181
  - [Backend](compute_api_client/docs/Backend.md)
178
182
  - [BackendIn](compute_api_client/docs/BackendIn.md)
179
183
  - [BackendPatch](compute_api_client/docs/BackendPatch.md)
@@ -192,6 +196,7 @@ Class | Method | HTTP request | Description
192
196
  - [FileIn](compute_api_client/docs/FileIn.md)
193
197
  - [FinalResult](compute_api_client/docs/FinalResult.md)
194
198
  - [FinalResultIn](compute_api_client/docs/FinalResultIn.md)
199
+ - [HTTPBadRequestError](compute_api_client/docs/HTTPBadRequestError.md)
195
200
  - [HTTPNotFoundError](compute_api_client/docs/HTTPNotFoundError.md)
196
201
  - [HTTPValidationError](compute_api_client/docs/HTTPValidationError.md)
197
202
  - [Job](compute_api_client/docs/Job.md)
@@ -1,8 +1,9 @@
1
- compute_api_client/__init__.py,sha256=KzYZR60xot6tcs9C3UEJXLx3Zn-6O3AWarbY8qyBvMc,6229
2
- compute_api_client/api/__init__.py,sha256=r1XAqXSWdvgMGLPSoqbjUEHsf6p2tYHMg7Aejad7u24,1199
1
+ compute_api_client/__init__.py,sha256=6uTw7shPw1cSMPpZ9Oi-b8WMBdfem8HXp6MCjaFPh7Y,6436
2
+ compute_api_client/api/__init__.py,sha256=nRY1G_pFDiKdCGFNpTIu91NbSjcomkC-g0loObSiF94,1264
3
3
  compute_api_client/api/algorithms_api.py,sha256=Iq3X7347R8ZsF3hDoIlEA8girl0ww_k1orMPMc6ygDE,59489
4
+ compute_api_client/api/auth_config_api.py,sha256=O7XDoKk6-bWyUJkfiiOZRbb8OuDv_H0xvcs_XFfAGG8,10356
4
5
  compute_api_client/api/backend_api.py,sha256=zNX_CYAm-6IrCuR7hlgHOCTwOkR1YQXn-3Ck9VUsCK8,57958
5
- compute_api_client/api/backend_types_api.py,sha256=Dq00VucVeV_6QvWSan-TBhih6XYoQDWPURRtci9vmi4,30729
6
+ compute_api_client/api/backend_types_api.py,sha256=NL8pscTuqUfTKoqC_HJ55clfpBgXQ6ZdFZjYEowlRuE,30753
6
7
  compute_api_client/api/batch_jobs_api.py,sha256=OB9EsaNpLvr80Tq3CUkNoJlwrO4CnDnVBeHne3FVJa8,83892
7
8
  compute_api_client/api/commits_api.py,sha256=ETcosKPwE8EYr_wd3rZItlmJqLtuSu8E2CpJt0t5y_0,57560
8
9
  compute_api_client/api/files_api.py,sha256=eItVegQVnni7AK2yyT_6Paj4WB01vUwM8fIwxwJEZuk,47862
@@ -26,13 +27,15 @@ compute_api_client/docs/Algorithm.md,sha256=LThexsNa9FuuIyP9Hs2yjP2L-04VszC7AdfO
26
27
  compute_api_client/docs/AlgorithmIn.md,sha256=ikR6b3TyLjXyWxqlUDcS25ZCwyion5VCQ5D6RNWpuz4,1013
27
28
  compute_api_client/docs/AlgorithmType.md,sha256=056KK2zjtdGqqTXkDsxg8mCzxr2sM8C37YmrR3txGVA,292
28
29
  compute_api_client/docs/AlgorithmsApi.md,sha256=86LvDgo-LpfLBI8E8hgEn3BMymEmIqNpfk_Q5v2U3hw,14474
30
+ compute_api_client/docs/AuthConfig.md,sha256=aAw9GUKZpP92FKndD-V2tv3fb538a4w5CnyIJtOig1c,903
31
+ compute_api_client/docs/AuthConfigApi.md,sha256=i5YETvw2H8RrO5JGp7DlwAzGRZSG85OwwHKzm7JbmEo,2060
29
32
  compute_api_client/docs/Backend.md,sha256=7xbvLaCTqqFzwcA2QONhY-QXa_Ts1fWiuBQBJegW50g,968
30
33
  compute_api_client/docs/BackendApi.md,sha256=KWld3mvfxlP_ZiYNSHxNNCkMSwuSnbKy9aFsrFvuHMg,13986
31
34
  compute_api_client/docs/BackendIn.md,sha256=7_drRygOUPHFWjrvAJGo7WwmcyK6EeRnlSnA6WtTCu0,978
32
35
  compute_api_client/docs/BackendPatch.md,sha256=xET1pnI8JStGhtHm7qT-1zv7RCuKl2CUIKtYueWq72U,927
33
36
  compute_api_client/docs/BackendStatus.md,sha256=ofnS843IHCIxoywjJJ01GP90Gn1XedAm5xR8TONmUbk,292
34
37
  compute_api_client/docs/BackendType.md,sha256=8NORl7QEvRr1lHOyHqdv8rnAiGWXaErw5kc1Kn74JfQ,1359
35
- compute_api_client/docs/BackendTypesApi.md,sha256=17u9tnQ5_A_bKjFICYB79T5xRhLP8wFEd65owopCIug,7137
38
+ compute_api_client/docs/BackendTypesApi.md,sha256=c2WK6rKdNoTWh24yQz8NnLDR3ux5_9morfLnJtYPAL0,7432
36
39
  compute_api_client/docs/BackendWithAuthentication.md,sha256=u9lZh4FusMtOuV53yc0QXHdnTas-4HNC06NyDh8E1Go,1256
37
40
  compute_api_client/docs/BatchJob.md,sha256=IozaJI2zAL1zo_zmuI-RIKvLGK68KkyW53AH4jbIaIs,1210
38
41
  compute_api_client/docs/BatchJobIn.md,sha256=9-nP1Xgnzd5tfvo8WmandUWR8IY-2pMeZyW0HveKZEU,847
@@ -40,7 +43,7 @@ compute_api_client/docs/BatchJobStatus.md,sha256=UQift_l9A3L0azzYjQtr7UnmYk6X36U
40
43
  compute_api_client/docs/BatchJobsApi.md,sha256=h7MhwjOcDwfSuDOK44XrwYw30oUN4vOw4LrM12L2JtI,20832
41
44
  compute_api_client/docs/Commit.md,sha256=WI3TcSFBdLWRjvJ9OBKiAKSN5AX7gXHs7EZm-Zs77FE,894
42
45
  compute_api_client/docs/CommitIn.md,sha256=tnd4OQ1brIRnNGAGkH3x_HRIQIg68CZTuAEJ2JDKK9w,843
43
- compute_api_client/docs/CommitsApi.md,sha256=47BwU64D-s9OByJxEc-q7xzhvfF-Tc5u3wrOL4DIIOA,13756
46
+ compute_api_client/docs/CommitsApi.md,sha256=FcRxDjqBQqI_1tqDBkF-cB06euahEhWl_choBd4aRCE,13786
44
47
  compute_api_client/docs/CompilePayload.md,sha256=W9x3x0CodJPGgiEbyKiaNm7rl0FzayVS8jv-3SiT8PI,954
45
48
  compute_api_client/docs/CompileStage.md,sha256=-U9wb4fyD8b_cjV1-GBIBJfbquFulRlHFm3C0GFnGik,291
46
49
  compute_api_client/docs/Domain.md,sha256=HONTAt17CX2vFhnkHOFqMpJEIJjPM8GTBBQriWA71UY,285
@@ -50,6 +53,7 @@ compute_api_client/docs/FilesApi.md,sha256=GC4e2AiIb0IVxw5e2pEHulw0bnYVexBRxdR1o
50
53
  compute_api_client/docs/FinalResult.md,sha256=sRCvqIH3TXruJvgaHp4s6zyfCEkuBReVoaqr2iHVkJU,939
51
54
  compute_api_client/docs/FinalResultIn.md,sha256=9RSstFSQ08-we_4TtoEAP1_KIq6FBdftRyc-DDkAGLQ,913
52
55
  compute_api_client/docs/FinalResultsApi.md,sha256=V7X34yAWXZMlUBhPgC7EKhW_TXenIlhYR84PiH3kG9A,8167
56
+ compute_api_client/docs/HTTPBadRequestError.md,sha256=TtmChwzainHvcapRwqTjmZghUFfvG3LZvYlDvs2dYjw,962
53
57
  compute_api_client/docs/HTTPNotFoundError.md,sha256=1GluS5OAVTk1qNrQwBOb29eQiNMJnCXyJk-0oKf-Rlc,936
54
58
  compute_api_client/docs/HTTPValidationError.md,sha256=MRdybtO0HOeFCN3Zk221Q6XH6fw1Qyg8J9KLPn38tI4,1006
55
59
  compute_api_client/docs/HealthApi.md,sha256=K1eWpfCF0AIbMsi0mAvFnIW-xjnnJvoQoyDQf7vyKEE,1825
@@ -109,10 +113,11 @@ compute_api_client/docs/UserIn.md,sha256=xAPeVO5WTaNcbI151w0j_g6BEM-xYquMV5Nx6sr
109
113
  compute_api_client/docs/UsersApi.md,sha256=_i1dIB7AW349xb8JcFtGohvK4l6iovAEYUYKaY5DZYc,10802
110
114
  compute_api_client/docs/ValidationError.md,sha256=NZSCUyM9u2fx4CFZfPF9cl_e6zDxQ9siBX-WtNHJyeA,978
111
115
  compute_api_client/exceptions.py,sha256=SxnwGBUmd989OJ9knsPWbZ3v59nn3_kipRYzOQZztXE,5451
112
- compute_api_client/models/__init__.py,sha256=ZowuC1OJQuy88rfDPgWejU3XpTV30KEJKBA8expO5ME,4498
116
+ compute_api_client/models/__init__.py,sha256=KsynU7092TuftNP1zO7_8F99IgG26FL7V4QWd9TcC6k,4640
113
117
  compute_api_client/models/algorithm.py,sha256=eA77q4e5gi8VStOJplR0UF-E9gBr6VFkxsqt8Ohx1Yo,3190
114
118
  compute_api_client/models/algorithm_in.py,sha256=-U2CoNZZSpAGBe6O7KFMJ9yIJAaOGEbPBdCTMIB3s2g,3148
115
119
  compute_api_client/models/algorithm_type.py,sha256=yKefgGvi-f_O6OReG1Tu8Me_u2YZrvx5CFOSlTk8-6M,862
120
+ compute_api_client/models/auth_config.py,sha256=J37ORfetcs5S3sqma-cra08Vry9qhdBpjjAMJYkhRrE,2573
116
121
  compute_api_client/models/backend.py,sha256=cZ_q1zzW6t9hDF-Llu2Zm8bgVQLvef0qFWLIENmp1Bg,3006
117
122
  compute_api_client/models/backend_in.py,sha256=9XK17112GvDxH2jAJpedX7z4kQ4oNr14EsCQ5dmGsEk,2957
118
123
  compute_api_client/models/backend_patch.py,sha256=QMKRJkxMIRiIc4dFQscqIJFe5zgCU11cm_6d_rnKOaE,2556
@@ -131,6 +136,7 @@ compute_api_client/models/file.py,sha256=PBxeUINDtmevly7zqwWTbg_1gKq21c5__HlGSfD
131
136
  compute_api_client/models/file_in.py,sha256=MWC-9renc5TKWJ5C-xSEWa7jmtm8xlL0YmcWOa0axRo,3397
132
137
  compute_api_client/models/final_result.py,sha256=nikP4R6CF4otZ3kPmw1_VlrS51-y-2c1UdDhiVFmi28,2643
133
138
  compute_api_client/models/final_result_in.py,sha256=0a3BDpM21XdfMp-kdr7DQ3peU4IDa_Pe-2z6v_D1s_8,2477
139
+ compute_api_client/models/http_bad_request_error.py,sha256=3Bqvic3dc-xeClqdEgClwRIvIFzkScpwbNEvw34paQU,2391
134
140
  compute_api_client/models/http_not_found_error.py,sha256=ZxTsaEc2MX_Sb6pyoqt-sEhnQ6uwzpd8uRTEklcfaSY,2383
135
141
  compute_api_client/models/http_validation_error.py,sha256=x7kRxeYeaVlQ-ckHPfkeFlsWsxZPDMKcvfOCR7jOlao,2882
136
142
  compute_api_client/models/job.py,sha256=XFjB2GqK40Wkp-mGHF5nxTXzB_3qJYhbu2-kLbl_3y4,4050
@@ -178,7 +184,12 @@ compute_api_client/models/user.py,sha256=WD1QyiqRlyObnK61QRE2NUCyY5Oc9ejeNcOGopm
178
184
  compute_api_client/models/user_in.py,sha256=gMWrBylb3ihoc-bm-K7AG9w3iWGn_ROV14wZnGlJU30,3330
179
185
  compute_api_client/models/validation_error.py,sha256=HWliEU5aNn3CkND3c0MxJf0D8bUJmE3HKncfUCKDk5o,2941
180
186
  compute_api_client/rest.py,sha256=-N7fantOYHH5Ot97NOHm2ouAUuw4kdqbnOvCtf25H7g,5836
181
- qi_compute_api_client-0.39.0.dist-info/LICENSE.md,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
182
- qi_compute_api_client-0.39.0.dist-info/METADATA,sha256=WZhBR6I9JQVTfu9ZR9RqhxERuCc_kyWHT35cnef9ZwQ,20255
183
- qi_compute_api_client-0.39.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
184
- qi_compute_api_client-0.39.0.dist-info/RECORD,,
187
+ qi2_shared/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
188
+ qi2_shared/authentication.py,sha256=zTnbB9SIGowSZgetlyXj8NNM3p2beQ3fQo4R0lTrjk8,2550
189
+ qi2_shared/client.py,sha256=vK_VC5V9p2cy02GeVXh0lKxqhMrM3lzUSRtts1CvF-A,1591
190
+ qi2_shared/pagination.py,sha256=sypb9tSsi_7A1D9WoaUEuo7Xyfci8gG2QCX8XSIb7rI,1844
191
+ qi2_shared/settings.py,sha256=x2wNv8nzftMFb-5K7wKvhfJVxQn0YYlZ_Guu6DHm_qU,2384
192
+ qi_compute_api_client-0.43.0.dist-info/LICENSE.md,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
193
+ qi_compute_api_client-0.43.0.dist-info/METADATA,sha256=W9XGJv0kL7P1swJ-gw3TqBa8JT0WXP-x3Xe9Si0XaJ8,20657
194
+ qi_compute_api_client-0.43.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
195
+ qi_compute_api_client-0.43.0.dist-info/RECORD,,