diracx-client 0.0.1a15__tar.gz → 0.0.1a17__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/PKG-INFO +1 -1
  2. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx/client/__init__.py +1 -1
  3. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx/client/_client.py +1 -1
  4. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx/client/_configuration.py +1 -1
  5. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx/client/_patch.py +24 -7
  6. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx/client/_serialization.py +1 -1
  7. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx/client/_vendor.py +1 -1
  8. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx/client/aio/__init__.py +1 -1
  9. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx/client/aio/_client.py +1 -1
  10. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx/client/aio/_configuration.py +1 -1
  11. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx/client/aio/_patch.py +13 -4
  12. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx/client/aio/_vendor.py +1 -1
  13. {diracx_client-0.0.1a15/src/diracx/client → diracx_client-0.0.1a17/src/diracx/client/aio}/operations/__init__.py +1 -1
  14. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx/client/aio/operations/_operations.py +124 -115
  15. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx/client/models/__init__.py +3 -7
  16. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx/client/models/_enums.py +13 -18
  17. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx/client/models/_models.py +57 -42
  18. {diracx_client-0.0.1a15/src/diracx/client/aio → diracx_client-0.0.1a17/src/diracx/client}/operations/__init__.py +1 -1
  19. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx/client/operations/_operations.py +157 -148
  20. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx_client.egg-info/PKG-INFO +1 -1
  21. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/README.md +0 -0
  22. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/pyproject.toml +0 -0
  23. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/setup.cfg +0 -0
  24. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx/client/aio/operations/_patch.py +0 -0
  25. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx/client/models/_patch.py +0 -0
  26. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx/client/operations/_patch.py +0 -0
  27. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx/client/py.typed +0 -0
  28. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx_client.egg-info/SOURCES.txt +0 -0
  29. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx_client.egg-info/dependency_links.txt +0 -0
  30. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx_client.egg-info/requires.txt +0 -0
  31. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/src/diracx_client.egg-info/top_level.txt +0 -0
  32. {diracx_client-0.0.1a15 → diracx_client-0.0.1a17}/tests/test_regenerate.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: diracx-client
3
- Version: 0.0.1a15
3
+ Version: 0.0.1a17
4
4
  Summary: TODO
5
5
  License: GPL-3.0-only
6
6
  Classifier: Intended Audience :: Science/Research
@@ -1,6 +1,6 @@
1
1
  # coding=utf-8
2
2
  # --------------------------------------------------------------------------
3
- # Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.13.9)
3
+ # Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.13.19)
4
4
  # Changes may cause incorrect behavior and will be lost if the code is regenerated.
5
5
  # --------------------------------------------------------------------------
6
6
 
@@ -1,6 +1,6 @@
1
1
  # coding=utf-8
2
2
  # --------------------------------------------------------------------------
3
- # Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.13.9)
3
+ # Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.13.19)
4
4
  # Changes may cause incorrect behavior and will be lost if the code is regenerated.
5
5
  # --------------------------------------------------------------------------
6
6
 
@@ -1,6 +1,6 @@
1
1
  # coding=utf-8
2
2
  # --------------------------------------------------------------------------
3
- # Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.13.9)
3
+ # Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.13.19)
4
4
  # Changes may cause incorrect behavior and will be lost if the code is regenerated.
5
5
  # --------------------------------------------------------------------------
6
6
 
@@ -8,12 +8,14 @@ Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python
8
8
  """
9
9
  from __future__ import annotations
10
10
 
11
- from datetime import datetime
11
+ from datetime import datetime, timezone
12
12
  import json
13
+ import jwt
13
14
  import requests
14
15
 
15
16
  from pathlib import Path
16
17
  from typing import Any, Dict, List, Optional, cast
18
+ from urllib import parse
17
19
  from azure.core.credentials import AccessToken
18
20
  from azure.core.credentials import TokenCredential
19
21
  from azure.core.pipeline import PipelineRequest
@@ -113,9 +115,12 @@ class DiracBearerTokenCredentialPolicy(BearerTokenCredentialPolicy):
113
115
 
114
116
  if not self._token:
115
117
  credentials = json.loads(self._credential.location.read_text())
116
- self._token = self._credential.get_token(
117
- "", refresh_token=credentials["refresh_token"]
118
- )
118
+ refresh_token = credentials["refresh_token"]
119
+ if not is_refresh_token_valid(refresh_token):
120
+ # If we are here, it means the refresh token is not valid anymore
121
+ # we suppose it is not needed to perform the request
122
+ return
123
+ self._token = self._credential.get_token("", refresh_token=refresh_token)
119
124
 
120
125
  request.http_request.headers["Authorization"] = f"Bearer {self._token.token}"
121
126
 
@@ -134,7 +139,7 @@ class DiracClient(DiracGenerated):
134
139
  **kwargs: Any,
135
140
  ) -> None:
136
141
  diracx_preferences = diracx_preferences or get_diracx_preferences()
137
- self._endpoint = endpoint or diracx_preferences.url
142
+ self._endpoint = str(endpoint or diracx_preferences.url)
138
143
  if verify is True and diracx_preferences.ca_path:
139
144
  verify = str(diracx_preferences.ca_path)
140
145
  kwargs["connection_verify"] = verify
@@ -211,7 +216,7 @@ def get_openid_configuration(
211
216
  ) -> Dict[str, str]:
212
217
  """Get the openid configuration from the .well-known endpoint"""
213
218
  response = requests.get(
214
- url=f"{endpoint}/.well-known/openid-configuration",
219
+ url=parse.urljoin(endpoint, ".well-known/openid-configuration"),
215
220
  verify=verify,
216
221
  )
217
222
  if not response.ok:
@@ -242,8 +247,20 @@ def get_token(location: Path, token: AccessToken | None) -> AccessToken | None:
242
247
  return token
243
248
 
244
249
 
250
+ def is_refresh_token_valid(refresh_token: str) -> bool:
251
+ """Check if the refresh token is still valid."""
252
+ # Decode the refresh token
253
+ refresh_payload = jwt.decode(refresh_token, options={"verify_signature": False})
254
+ if not refresh_payload or "exp" not in refresh_payload:
255
+ return False
256
+
257
+ # Check the expiration time
258
+ return refresh_payload["exp"] > datetime.now(tz=timezone.utc).timestamp()
259
+
260
+
245
261
  def is_token_valid(token: AccessToken) -> bool:
246
262
  """Condition to get a new token"""
247
263
  return (
248
- datetime.utcfromtimestamp(token.expires_on) - datetime.utcnow()
264
+ datetime.fromtimestamp(token.expires_on, tz=timezone.utc)
265
+ - datetime.now(tz=timezone.utc)
249
266
  ).total_seconds() > 300
@@ -1525,7 +1525,7 @@ class Deserializer(object):
1525
1525
  elif isinstance(response, type) and issubclass(response, Enum):
1526
1526
  return self.deserialize_enum(data, response)
1527
1527
 
1528
- if data is None:
1528
+ if data is None or data is CoreNull:
1529
1529
  return data
1530
1530
  try:
1531
1531
  attributes = response._attribute_map # type: ignore
@@ -1,5 +1,5 @@
1
1
  # --------------------------------------------------------------------------
2
- # Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.13.9)
2
+ # Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.13.19)
3
3
  # Changes may cause incorrect behavior and will be lost if the code is regenerated.
4
4
  # --------------------------------------------------------------------------
5
5
 
@@ -1,6 +1,6 @@
1
1
  # coding=utf-8
2
2
  # --------------------------------------------------------------------------
3
- # Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.13.9)
3
+ # Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.13.19)
4
4
  # Changes may cause incorrect behavior and will be lost if the code is regenerated.
5
5
  # --------------------------------------------------------------------------
6
6
 
@@ -1,6 +1,6 @@
1
1
  # coding=utf-8
2
2
  # --------------------------------------------------------------------------
3
- # Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.13.9)
3
+ # Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.13.19)
4
4
  # Changes may cause incorrect behavior and will be lost if the code is regenerated.
5
5
  # --------------------------------------------------------------------------
6
6
 
@@ -1,6 +1,6 @@
1
1
  # coding=utf-8
2
2
  # --------------------------------------------------------------------------
3
- # Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.13.9)
3
+ # Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.13.19)
4
4
  # Changes may cause incorrect behavior and will be lost if the code is regenerated.
5
5
  # --------------------------------------------------------------------------
6
6
 
@@ -18,7 +18,12 @@ from azure.core.pipeline.policies import AsyncBearerTokenCredentialPolicy
18
18
  from diracx.core.preferences import get_diracx_preferences, DiracxPreferences
19
19
 
20
20
  from ._client import Dirac as DiracGenerated
21
- from .._patch import get_openid_configuration, get_token, refresh_token
21
+ from .._patch import (
22
+ get_openid_configuration,
23
+ get_token,
24
+ refresh_token,
25
+ is_refresh_token_valid,
26
+ )
22
27
 
23
28
  __all__: List[str] = [
24
29
  "DiracClient",
@@ -114,7 +119,6 @@ class DiracBearerTokenCredentialPolicy(AsyncBearerTokenCredentialPolicy):
114
119
  self._token: AccessToken | None
115
120
  self._credential: DiracTokenCredential
116
121
  credentials: dict[str, Any]
117
-
118
122
  try:
119
123
  self._token = get_token(self._credential.location, self._token)
120
124
  except RuntimeError:
@@ -124,8 +128,13 @@ class DiracBearerTokenCredentialPolicy(AsyncBearerTokenCredentialPolicy):
124
128
 
125
129
  if not self._token:
126
130
  credentials = json.loads(self._credential.location.read_text())
131
+ refresh_token = credentials["refresh_token"]
132
+ if not is_refresh_token_valid(refresh_token):
133
+ # If we are here, it means the refresh token is not valid anymore
134
+ # we suppose it is not needed to perform the request
135
+ return
127
136
  self._token = await self._credential.get_token(
128
- "", refresh_token=credentials["refresh_token"]
137
+ "", refresh_token=refresh_token
129
138
  )
130
139
 
131
140
  request.http_request.headers["Authorization"] = f"Bearer {self._token.token}"
@@ -148,7 +157,7 @@ class DiracClient(DiracGenerated):
148
157
  if verify is True and diracx_preferences.ca_path:
149
158
  verify = str(diracx_preferences.ca_path)
150
159
  kwargs["connection_verify"] = verify
151
- self._endpoint = endpoint or diracx_preferences.url
160
+ self._endpoint = str(endpoint or diracx_preferences.url)
152
161
  self._client_id = client_id or "myDIRACClientID"
153
162
 
154
163
  # Get .well-known configuration
@@ -1,5 +1,5 @@
1
1
  # --------------------------------------------------------------------------
2
- # Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.13.9)
2
+ # Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.13.19)
3
3
  # Changes may cause incorrect behavior and will be lost if the code is regenerated.
4
4
  # --------------------------------------------------------------------------
5
5
 
@@ -1,6 +1,6 @@
1
1
  # coding=utf-8
2
2
  # --------------------------------------------------------------------------
3
- # Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.13.9)
3
+ # Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.13.19)
4
4
  # Changes may cause incorrect behavior and will be lost if the code is regenerated.
5
5
  # --------------------------------------------------------------------------
6
6
 
@@ -1,7 +1,7 @@
1
1
  # pylint: disable=too-many-lines,too-many-statements
2
2
  # coding=utf-8
3
3
  # --------------------------------------------------------------------------
4
- # Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.13.9)
4
+ # Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.13.19)
5
5
  # Changes may cause incorrect behavior and will be lost if the code is regenerated.
6
6
  # --------------------------------------------------------------------------
7
7
  from io import IOBase
@@ -245,22 +245,25 @@ class AuthOperations: # pylint: disable=abstract-class-instantiated
245
245
  )
246
246
 
247
247
  @distributed_trace_async
248
- async def do_device_flow(self, *, user_code: str, **kwargs: Any) -> Any:
249
- """Do Device Flow.
248
+ async def initiate_device_flow(
249
+ self, *, client_id: str, scope: str, **kwargs: Any
250
+ ) -> _models.InitiateDeviceFlowResponse:
251
+ """Initiate Device Flow.
250
252
 
251
- This is called as the verification URI for the device flow.
252
- It will redirect to the actual OpenID server (IAM, CheckIn) to
253
- perform a authorization code flow.
253
+ Initiate the device flow against DIRAC authorization Server.
254
+ Scope must have exactly up to one ``group`` (otherwise default) and
255
+ one or more ``property`` scope.
256
+ If no property, then get default one
254
257
 
255
- We set the user_code obtained from the device flow in a cookie
256
- to be able to map the authorization flow with the corresponding
257
- device flow.
258
- (note: it can't be put as parameter or in the URL).
258
+ Offers the user to go with the browser to
259
+ ``auth/<vo>/device?user_code=XYZ``.
259
260
 
260
- :keyword user_code: Required.
261
- :paramtype user_code: str
262
- :return: any
263
- :rtype: any
261
+ :keyword client_id: Required.
262
+ :paramtype client_id: str
263
+ :keyword scope: Required.
264
+ :paramtype scope: str
265
+ :return: InitiateDeviceFlowResponse
266
+ :rtype: ~client.models.InitiateDeviceFlowResponse
264
267
  :raises ~azure.core.exceptions.HttpResponseError:
265
268
  """
266
269
  error_map: MutableMapping[int, Type[HttpResponseError]] = {
@@ -274,10 +277,11 @@ class AuthOperations: # pylint: disable=abstract-class-instantiated
274
277
  _headers = kwargs.pop("headers", {}) or {}
275
278
  _params = kwargs.pop("params", {}) or {}
276
279
 
277
- cls: ClsType[Any] = kwargs.pop("cls", None)
280
+ cls: ClsType[_models.InitiateDeviceFlowResponse] = kwargs.pop("cls", None)
278
281
 
279
- _request = build_auth_do_device_flow_request(
280
- user_code=user_code,
282
+ _request = build_auth_initiate_device_flow_request(
283
+ client_id=client_id,
284
+ scope=scope,
281
285
  headers=_headers,
282
286
  params=_params,
283
287
  )
@@ -300,7 +304,9 @@ class AuthOperations: # pylint: disable=abstract-class-instantiated
300
304
  )
301
305
  raise HttpResponseError(response=response)
302
306
 
303
- deserialized = self._deserialize("object", pipeline_response)
307
+ deserialized = self._deserialize(
308
+ "InitiateDeviceFlowResponse", pipeline_response
309
+ )
304
310
 
305
311
  if cls:
306
312
  return cls(pipeline_response, deserialized, {}) # type: ignore
@@ -308,25 +314,22 @@ class AuthOperations: # pylint: disable=abstract-class-instantiated
308
314
  return deserialized # type: ignore
309
315
 
310
316
  @distributed_trace_async
311
- async def initiate_device_flow(
312
- self, *, client_id: str, scope: str, **kwargs: Any
313
- ) -> _models.InitiateDeviceFlowResponse:
314
- """Initiate Device Flow.
317
+ async def do_device_flow(self, *, user_code: str, **kwargs: Any) -> Any:
318
+ """Do Device Flow.
315
319
 
316
- Initiate the device flow against DIRAC authorization Server.
317
- Scope must have exactly up to one ``group`` (otherwise default) and
318
- one or more ``property`` scope.
319
- If no property, then get default one
320
+ This is called as the verification URI for the device flow.
321
+ It will redirect to the actual OpenID server (IAM, CheckIn) to
322
+ perform a authorization code flow.
320
323
 
321
- Offers the user to go with the browser to
322
- ``auth/<vo>/device?user_code=XYZ``.
324
+ We set the user_code obtained from the device flow in a cookie
325
+ to be able to map the authorization flow with the corresponding
326
+ device flow.
327
+ (note: it can't be put as parameter or in the URL).
323
328
 
324
- :keyword client_id: Required.
325
- :paramtype client_id: str
326
- :keyword scope: Required.
327
- :paramtype scope: str
328
- :return: InitiateDeviceFlowResponse
329
- :rtype: ~client.models.InitiateDeviceFlowResponse
329
+ :keyword user_code: Required.
330
+ :paramtype user_code: str
331
+ :return: any
332
+ :rtype: any
330
333
  :raises ~azure.core.exceptions.HttpResponseError:
331
334
  """
332
335
  error_map: MutableMapping[int, Type[HttpResponseError]] = {
@@ -340,11 +343,10 @@ class AuthOperations: # pylint: disable=abstract-class-instantiated
340
343
  _headers = kwargs.pop("headers", {}) or {}
341
344
  _params = kwargs.pop("params", {}) or {}
342
345
 
343
- cls: ClsType[_models.InitiateDeviceFlowResponse] = kwargs.pop("cls", None)
346
+ cls: ClsType[Any] = kwargs.pop("cls", None)
344
347
 
345
- _request = build_auth_initiate_device_flow_request(
346
- client_id=client_id,
347
- scope=scope,
348
+ _request = build_auth_do_device_flow_request(
349
+ user_code=user_code,
348
350
  headers=_headers,
349
351
  params=_params,
350
352
  )
@@ -367,9 +369,7 @@ class AuthOperations: # pylint: disable=abstract-class-instantiated
367
369
  )
368
370
  raise HttpResponseError(response=response)
369
371
 
370
- deserialized = self._deserialize(
371
- "InitiateDeviceFlowResponse", pipeline_response
372
- )
372
+ deserialized = self._deserialize("object", pipeline_response)
373
373
 
374
374
  if cls:
375
375
  return cls(pipeline_response, deserialized, {}) # type: ignore
@@ -939,70 +939,6 @@ class JobsOperations: # pylint: disable=too-many-public-methods
939
939
  input_args.pop(0) if input_args else kwargs.pop("deserializer")
940
940
  )
941
941
 
942
- @distributed_trace_async
943
- async def get_sandbox_file(
944
- self, *, pfn: str, **kwargs: Any
945
- ) -> _models.SandboxDownloadResponse:
946
- """Get Sandbox File.
947
-
948
- Get a presigned URL to download a sandbox file
949
-
950
- This route cannot use a redirect response most clients will also send the
951
- authorization header when following a redirect. This is not desirable as
952
- it would leak the authorization token to the storage backend. Additionally,
953
- most storage backends return an error when they receive an authorization
954
- header for a presigned URL.
955
-
956
- :keyword pfn: Required.
957
- :paramtype pfn: str
958
- :return: SandboxDownloadResponse
959
- :rtype: ~client.models.SandboxDownloadResponse
960
- :raises ~azure.core.exceptions.HttpResponseError:
961
- """
962
- error_map: MutableMapping[int, Type[HttpResponseError]] = {
963
- 401: ClientAuthenticationError,
964
- 404: ResourceNotFoundError,
965
- 409: ResourceExistsError,
966
- 304: ResourceNotModifiedError,
967
- }
968
- error_map.update(kwargs.pop("error_map", {}) or {})
969
-
970
- _headers = kwargs.pop("headers", {}) or {}
971
- _params = kwargs.pop("params", {}) or {}
972
-
973
- cls: ClsType[_models.SandboxDownloadResponse] = kwargs.pop("cls", None)
974
-
975
- _request = build_jobs_get_sandbox_file_request(
976
- pfn=pfn,
977
- headers=_headers,
978
- params=_params,
979
- )
980
- _request.url = self._client.format_url(_request.url)
981
-
982
- _stream = False
983
- pipeline_response: PipelineResponse = (
984
- await self._client._pipeline.run( # pylint: disable=protected-access
985
- _request, stream=_stream, **kwargs
986
- )
987
- )
988
-
989
- response = pipeline_response.http_response
990
-
991
- if response.status_code not in [200]:
992
- if _stream:
993
- await response.read() # Load the body in memory and close the socket
994
- map_error(
995
- status_code=response.status_code, response=response, error_map=error_map
996
- )
997
- raise HttpResponseError(response=response)
998
-
999
- deserialized = self._deserialize("SandboxDownloadResponse", pipeline_response)
1000
-
1001
- if cls:
1002
- return cls(pipeline_response, deserialized, {}) # type: ignore
1003
-
1004
- return deserialized # type: ignore
1005
-
1006
942
  @overload
1007
943
  async def initiate_sandbox_upload(
1008
944
  self,
@@ -1132,6 +1068,70 @@ class JobsOperations: # pylint: disable=too-many-public-methods
1132
1068
 
1133
1069
  return deserialized # type: ignore
1134
1070
 
1071
+ @distributed_trace_async
1072
+ async def get_sandbox_file(
1073
+ self, *, pfn: str, **kwargs: Any
1074
+ ) -> _models.SandboxDownloadResponse:
1075
+ """Get Sandbox File.
1076
+
1077
+ Get a presigned URL to download a sandbox file
1078
+
1079
+ This route cannot use a redirect response most clients will also send the
1080
+ authorization header when following a redirect. This is not desirable as
1081
+ it would leak the authorization token to the storage backend. Additionally,
1082
+ most storage backends return an error when they receive an authorization
1083
+ header for a presigned URL.
1084
+
1085
+ :keyword pfn: Required.
1086
+ :paramtype pfn: str
1087
+ :return: SandboxDownloadResponse
1088
+ :rtype: ~client.models.SandboxDownloadResponse
1089
+ :raises ~azure.core.exceptions.HttpResponseError:
1090
+ """
1091
+ error_map: MutableMapping[int, Type[HttpResponseError]] = {
1092
+ 401: ClientAuthenticationError,
1093
+ 404: ResourceNotFoundError,
1094
+ 409: ResourceExistsError,
1095
+ 304: ResourceNotModifiedError,
1096
+ }
1097
+ error_map.update(kwargs.pop("error_map", {}) or {})
1098
+
1099
+ _headers = kwargs.pop("headers", {}) or {}
1100
+ _params = kwargs.pop("params", {}) or {}
1101
+
1102
+ cls: ClsType[_models.SandboxDownloadResponse] = kwargs.pop("cls", None)
1103
+
1104
+ _request = build_jobs_get_sandbox_file_request(
1105
+ pfn=pfn,
1106
+ headers=_headers,
1107
+ params=_params,
1108
+ )
1109
+ _request.url = self._client.format_url(_request.url)
1110
+
1111
+ _stream = False
1112
+ pipeline_response: PipelineResponse = (
1113
+ await self._client._pipeline.run( # pylint: disable=protected-access
1114
+ _request, stream=_stream, **kwargs
1115
+ )
1116
+ )
1117
+
1118
+ response = pipeline_response.http_response
1119
+
1120
+ if response.status_code not in [200]:
1121
+ if _stream:
1122
+ await response.read() # Load the body in memory and close the socket
1123
+ map_error(
1124
+ status_code=response.status_code, response=response, error_map=error_map
1125
+ )
1126
+ raise HttpResponseError(response=response)
1127
+
1128
+ deserialized = self._deserialize("SandboxDownloadResponse", pipeline_response)
1129
+
1130
+ if cls:
1131
+ return cls(pipeline_response, deserialized, {}) # type: ignore
1132
+
1133
+ return deserialized # type: ignore
1134
+
1135
1135
  @distributed_trace_async
1136
1136
  async def unassign_bulk_jobs_sandboxes(
1137
1137
  self, *, jobs_ids: List[int], **kwargs: Any
@@ -1369,7 +1369,7 @@ class JobsOperations: # pylint: disable=too-many-public-methods
1369
1369
  async def assign_sandbox_to_job(self, job_id: int, body: str, **kwargs: Any) -> Any:
1370
1370
  """Assign Sandbox To Job.
1371
1371
 
1372
- Mapp the pfn as output sandbox to job.
1372
+ Map the pfn as output sandbox to job.
1373
1373
 
1374
1374
  :param job_id: Required.
1375
1375
  :type job_id: int
@@ -2072,7 +2072,7 @@ class JobsOperations: # pylint: disable=too-many-public-methods
2072
2072
  self,
2073
2073
  body: Optional[_models.JobSearchParams] = None,
2074
2074
  *,
2075
- page: int = 0,
2075
+ page: int = 1,
2076
2076
  per_page: int = 100,
2077
2077
  content_type: str = "application/json",
2078
2078
  **kwargs: Any,
@@ -2085,7 +2085,7 @@ class JobsOperations: # pylint: disable=too-many-public-methods
2085
2085
 
2086
2086
  :param body: Default value is None.
2087
2087
  :type body: ~client.models.JobSearchParams
2088
- :keyword page: Default value is 0.
2088
+ :keyword page: Default value is 1.
2089
2089
  :paramtype page: int
2090
2090
  :keyword per_page: Default value is 100.
2091
2091
  :paramtype per_page: int
@@ -2102,7 +2102,7 @@ class JobsOperations: # pylint: disable=too-many-public-methods
2102
2102
  self,
2103
2103
  body: Optional[IO[bytes]] = None,
2104
2104
  *,
2105
- page: int = 0,
2105
+ page: int = 1,
2106
2106
  per_page: int = 100,
2107
2107
  content_type: str = "application/json",
2108
2108
  **kwargs: Any,
@@ -2115,7 +2115,7 @@ class JobsOperations: # pylint: disable=too-many-public-methods
2115
2115
 
2116
2116
  :param body: Default value is None.
2117
2117
  :type body: IO[bytes]
2118
- :keyword page: Default value is 0.
2118
+ :keyword page: Default value is 1.
2119
2119
  :paramtype page: int
2120
2120
  :keyword per_page: Default value is 100.
2121
2121
  :paramtype per_page: int
@@ -2132,7 +2132,7 @@ class JobsOperations: # pylint: disable=too-many-public-methods
2132
2132
  self,
2133
2133
  body: Optional[Union[_models.JobSearchParams, IO[bytes]]] = None,
2134
2134
  *,
2135
- page: int = 0,
2135
+ page: int = 1,
2136
2136
  per_page: int = 100,
2137
2137
  **kwargs: Any,
2138
2138
  ) -> List[JSON]:
@@ -2144,7 +2144,7 @@ class JobsOperations: # pylint: disable=too-many-public-methods
2144
2144
 
2145
2145
  :param body: Is either a JobSearchParams type or a IO[bytes] type. Default value is None.
2146
2146
  :type body: ~client.models.JobSearchParams or IO[bytes]
2147
- :keyword page: Default value is 0.
2147
+ :keyword page: Default value is 1.
2148
2148
  :paramtype page: int
2149
2149
  :keyword per_page: Default value is 100.
2150
2150
  :paramtype per_page: int
@@ -2199,7 +2199,7 @@ class JobsOperations: # pylint: disable=too-many-public-methods
2199
2199
 
2200
2200
  response = pipeline_response.http_response
2201
2201
 
2202
- if response.status_code not in [200]:
2202
+ if response.status_code not in [200, 206]:
2203
2203
  if _stream:
2204
2204
  await response.read() # Load the body in memory and close the socket
2205
2205
  map_error(
@@ -2207,10 +2207,19 @@ class JobsOperations: # pylint: disable=too-many-public-methods
2207
2207
  )
2208
2208
  raise HttpResponseError(response=response)
2209
2209
 
2210
- deserialized = self._deserialize("[object]", pipeline_response)
2210
+ response_headers = {}
2211
+ if response.status_code == 200:
2212
+ deserialized = self._deserialize("[object]", pipeline_response)
2213
+
2214
+ if response.status_code == 206:
2215
+ response_headers["Content-Range"] = self._deserialize(
2216
+ "str", response.headers.get("Content-Range")
2217
+ )
2218
+
2219
+ deserialized = self._deserialize("[object]", pipeline_response)
2211
2220
 
2212
2221
  if cls:
2213
- return cls(pipeline_response, deserialized, {}) # type: ignore
2222
+ return cls(pipeline_response, deserialized, response_headers) # type: ignore
2214
2223
 
2215
2224
  return deserialized # type: ignore
2216
2225
 
@@ -1,6 +1,6 @@
1
1
  # coding=utf-8
2
2
  # --------------------------------------------------------------------------
3
- # Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.13.9)
3
+ # Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.13.19)
4
4
  # Changes may cause incorrect behavior and will be lost if the code is regenerated.
5
5
  # --------------------------------------------------------------------------
6
6
 
@@ -25,7 +25,6 @@ from ._models import ScalarSearchSpec
25
25
  from ._models import ScalarSearchSpecValue
26
26
  from ._models import SetJobStatusReturn
27
27
  from ._models import SortSpec
28
- from ._models import SortSpecDirection
29
28
  from ._models import SupportInfo
30
29
  from ._models import TokenResponse
31
30
  from ._models import UserInfoResponse
@@ -38,8 +37,6 @@ from ._models import VectorSearchSpecValues
38
37
  from ._enums import ChecksumAlgorithm
39
38
  from ._enums import Enum0
40
39
  from ._enums import Enum1
41
- from ._enums import Enum11
42
- from ._enums import Enum12
43
40
  from ._enums import Enum2
44
41
  from ._enums import Enum3
45
42
  from ._enums import Enum4
@@ -47,6 +44,7 @@ from ._enums import JobStatus
47
44
  from ._enums import SandboxFormat
48
45
  from ._enums import SandboxType
49
46
  from ._enums import ScalarSearchOperator
47
+ from ._enums import SortDirection
50
48
  from ._enums import VectorSearchOperator
51
49
  from ._patch import __all__ as _patch_all
52
50
  from ._patch import * # pylint: disable=unused-wildcard-import
@@ -74,7 +72,6 @@ __all__ = [
74
72
  "ScalarSearchSpecValue",
75
73
  "SetJobStatusReturn",
76
74
  "SortSpec",
77
- "SortSpecDirection",
78
75
  "SupportInfo",
79
76
  "TokenResponse",
80
77
  "UserInfoResponse",
@@ -86,8 +83,6 @@ __all__ = [
86
83
  "ChecksumAlgorithm",
87
84
  "Enum0",
88
85
  "Enum1",
89
- "Enum11",
90
- "Enum12",
91
86
  "Enum2",
92
87
  "Enum3",
93
88
  "Enum4",
@@ -95,6 +90,7 @@ __all__ = [
95
90
  "SandboxFormat",
96
91
  "SandboxType",
97
92
  "ScalarSearchOperator",
93
+ "SortDirection",
98
94
  "VectorSearchOperator",
99
95
  ]
100
96
  __all__.extend([p for p in _patch_all if p not in __all__])