cyberdesk 1.9.0__py3-none-any.whl → 1.10.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 cyberdesk might be problematic. Click here for more details.

cyberdesk/__init__.py CHANGED
@@ -23,10 +23,11 @@ from .client import (
23
23
  RunAttachmentCreate,
24
24
  RunAttachmentUpdate,
25
25
  RunAttachmentResponse,
26
+ RunAttachmentDownloadUrlResponse,
26
27
  AttachmentType,
27
28
  )
28
29
 
29
- __version__ = "1.9.0"
30
+ __version__ = "1.10.0"
30
31
 
31
32
  __all__ = [
32
33
  "CyberdeskClient",
@@ -51,5 +52,6 @@ __all__ = [
51
52
  "RunAttachmentCreate",
52
53
  "RunAttachmentUpdate",
53
54
  "RunAttachmentResponse",
55
+ "RunAttachmentDownloadUrlResponse",
54
56
  "AttachmentType",
55
57
  ]
cyberdesk/client.py CHANGED
@@ -1,6 +1,7 @@
1
1
  """Cyberdesk Python SDK Client."""
2
2
  from typing import Optional, Dict, Any, Union
3
3
  from uuid import UUID
4
+ from pathlib import Path
4
5
  import httpx
5
6
  from dataclasses import dataclass
6
7
 
@@ -45,6 +46,7 @@ from openapi_client.cyberdesk_cloud_client.api.run_attachments import (
45
46
  create_run_attachment_v1_run_attachments_post,
46
47
  get_run_attachment_v1_run_attachments_attachment_id_get,
47
48
  download_run_attachment_v1_run_attachments_attachment_id_download_get,
49
+ get_run_attachment_download_url_v1_run_attachments_attachment_id_download_url_get,
48
50
  update_run_attachment_v1_run_attachments_attachment_id_put,
49
51
  delete_run_attachment_v1_run_attachments_attachment_id_delete,
50
52
  )
@@ -72,6 +74,7 @@ from openapi_client.cyberdesk_cloud_client.models import (
72
74
  RunAttachmentCreate,
73
75
  RunAttachmentUpdate,
74
76
  RunAttachmentResponse,
77
+ RunAttachmentDownloadUrlResponse,
75
78
  AttachmentType,
76
79
  PaginatedResponseMachineResponse,
77
80
  PaginatedResponseWorkflowResponse,
@@ -105,6 +108,7 @@ __all__ = [
105
108
  "RunAttachmentCreate",
106
109
  "RunAttachmentUpdate",
107
110
  "RunAttachmentResponse",
111
+ "RunAttachmentDownloadUrlResponse",
108
112
  "AttachmentType",
109
113
  ]
110
114
 
@@ -847,14 +851,75 @@ class RunAttachmentsAPI:
847
851
  except Exception as e:
848
852
  return ApiResponse(error=e)
849
853
 
854
+ async def get_download_url(
855
+ self,
856
+ attachment_id: str,
857
+ expires_in: Optional[int] = None
858
+ ) -> ApiResponse:
859
+ """Get a signed download URL for a run attachment.
860
+
861
+ The returned URL will trigger an automatic download when accessed in a browser.
862
+
863
+ Args:
864
+ attachment_id: The ID of the attachment
865
+ expires_in: URL expiration time in seconds (10-3600). Default: 300 (5 minutes)
866
+
867
+ Returns:
868
+ ApiResponse with RunAttachmentDownloadUrlResponse containing:
869
+ - url: The signed download URL
870
+ - expires_in: The expiration time in seconds
871
+ """
872
+ try:
873
+ response = await get_run_attachment_download_url_v1_run_attachments_attachment_id_download_url_get.asyncio(
874
+ client=self.client,
875
+ attachment_id=_to_uuid(attachment_id),
876
+ expires_in=_to_unset_or_value(expires_in)
877
+ )
878
+ return ApiResponse(data=response)
879
+ except Exception as e:
880
+ return ApiResponse(error=e)
881
+
882
+ def get_download_url_sync(
883
+ self,
884
+ attachment_id: str,
885
+ expires_in: Optional[int] = None
886
+ ) -> ApiResponse:
887
+ """Get a signed download URL for a run attachment (synchronous).
888
+
889
+ The returned URL will trigger an automatic download when accessed in a browser.
890
+
891
+ Args:
892
+ attachment_id: The ID of the attachment
893
+ expires_in: URL expiration time in seconds (10-3600). Default: 300 (5 minutes)
894
+
895
+ Returns:
896
+ ApiResponse with RunAttachmentDownloadUrlResponse containing:
897
+ - url: The signed download URL
898
+ - expires_in: The expiration time in seconds
899
+ """
900
+ try:
901
+ response = get_run_attachment_download_url_v1_run_attachments_attachment_id_download_url_get.sync(
902
+ client=self.client,
903
+ attachment_id=_to_uuid(attachment_id),
904
+ expires_in=_to_unset_or_value(expires_in)
905
+ )
906
+ return ApiResponse(data=response)
907
+ except Exception as e:
908
+ return ApiResponse(error=e)
909
+
850
910
  async def download(self, attachment_id: str) -> ApiResponse:
851
- """Download a run attachment file.
911
+ """Download a run attachment file directly.
912
+
913
+ This method returns the raw file content as bytes. For a download URL instead,
914
+ use get_download_url().
915
+
916
+ Args:
917
+ attachment_id: The ID of the attachment to download
852
918
 
853
919
  Returns:
854
- ApiResponse with data containing the file bytes or a download URL
920
+ ApiResponse with data containing the raw file bytes
855
921
  """
856
922
  try:
857
- # The download endpoint typically returns binary data or a redirect URL
858
923
  response = await download_run_attachment_v1_run_attachments_attachment_id_download_get.asyncio(
859
924
  client=self.client,
860
925
  attachment_id=_to_uuid(attachment_id)
@@ -864,10 +929,16 @@ class RunAttachmentsAPI:
864
929
  return ApiResponse(error=e)
865
930
 
866
931
  def download_sync(self, attachment_id: str) -> ApiResponse:
867
- """Download a run attachment file (synchronous).
932
+ """Download a run attachment file directly (synchronous).
933
+
934
+ This method returns the raw file content as bytes. For a download URL instead,
935
+ use get_download_url_sync().
936
+
937
+ Args:
938
+ attachment_id: The ID of the attachment to download
868
939
 
869
940
  Returns:
870
- ApiResponse with data containing the file bytes or a download URL
941
+ ApiResponse with data containing the raw file bytes
871
942
  """
872
943
  try:
873
944
  response = download_run_attachment_v1_run_attachments_attachment_id_download_get.sync(
@@ -923,6 +994,104 @@ class RunAttachmentsAPI:
923
994
  return ApiResponse(data={"success": True})
924
995
  except Exception as e:
925
996
  return ApiResponse(error=e)
997
+
998
+ async def save_to_file(
999
+ self,
1000
+ attachment_id: str,
1001
+ output_path: Optional[Union[str, Path]] = None,
1002
+ use_original_filename: bool = True
1003
+ ) -> ApiResponse:
1004
+ """Download and save a run attachment to a file.
1005
+
1006
+ This is a convenience method that combines getting attachment info
1007
+ and downloading the file content.
1008
+
1009
+ Args:
1010
+ attachment_id: The ID of the attachment to download
1011
+ output_path: Path where to save the file. If None and use_original_filename
1012
+ is True, saves to current directory with original filename.
1013
+ use_original_filename: If True and output_path is a directory, uses the
1014
+ attachment's original filename.
1015
+
1016
+ Returns:
1017
+ ApiResponse with data containing the saved file path
1018
+ """
1019
+ try:
1020
+ # Get attachment info for filename
1021
+ info_response = await self.get(attachment_id)
1022
+ if info_response.error:
1023
+ return info_response
1024
+
1025
+ attachment_info = info_response.data
1026
+
1027
+ # Download the file content
1028
+ download_response = await self.download(attachment_id)
1029
+ if download_response.error:
1030
+ return download_response
1031
+
1032
+ # Determine output path
1033
+ if output_path is None:
1034
+ output_path = Path(attachment_info.filename)
1035
+ else:
1036
+ output_path = Path(output_path)
1037
+ if output_path.is_dir() and use_original_filename:
1038
+ output_path = output_path / attachment_info.filename
1039
+
1040
+ # Save to file
1041
+ output_path.write_bytes(download_response.data)
1042
+
1043
+ return ApiResponse(data={"path": str(output_path), "size": len(download_response.data)})
1044
+ except Exception as e:
1045
+ return ApiResponse(error=e)
1046
+
1047
+ def save_to_file_sync(
1048
+ self,
1049
+ attachment_id: str,
1050
+ output_path: Optional[Union[str, Path]] = None,
1051
+ use_original_filename: bool = True
1052
+ ) -> ApiResponse:
1053
+ """Download and save a run attachment to a file (synchronous).
1054
+
1055
+ This is a convenience method that combines getting attachment info
1056
+ and downloading the file content.
1057
+
1058
+ Args:
1059
+ attachment_id: The ID of the attachment to download
1060
+ output_path: Path where to save the file. If None and use_original_filename
1061
+ is True, saves to current directory with original filename.
1062
+ use_original_filename: If True and output_path is a directory, uses the
1063
+ attachment's original filename.
1064
+
1065
+ Returns:
1066
+ ApiResponse with data containing the saved file path
1067
+ """
1068
+ try:
1069
+ # Get attachment info for filename
1070
+ info_response = self.get_sync(attachment_id)
1071
+ if info_response.error:
1072
+ return info_response
1073
+
1074
+ attachment_info = info_response.data
1075
+
1076
+ # Download the file content
1077
+ download_response = self.download_sync(attachment_id)
1078
+ if download_response.error:
1079
+ return download_response
1080
+
1081
+ # Determine output path
1082
+ if output_path is None:
1083
+ output_path = Path(attachment_info.filename)
1084
+ else:
1085
+ output_path = Path(output_path)
1086
+ if output_path.is_dir() and use_original_filename:
1087
+ output_path = output_path / attachment_info.filename
1088
+
1089
+ # Save to file
1090
+ output_path.write_bytes(download_response.data)
1091
+
1092
+ return ApiResponse(data={"path": str(output_path), "size": len(download_response.data)})
1093
+ except Exception as e:
1094
+ return ApiResponse(error=e)
926
1095
 
927
1096
 
928
1097
  class CyberdeskClient:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cyberdesk
3
- Version: 1.9.0
3
+ Version: 1.10.0
4
4
  Summary: The official Python SDK for Cyberdesk
5
5
  Author-email: Cyberdesk Team <dev@cyberdesk.io>
6
6
  License-Expression: MIT
@@ -1,6 +1,6 @@
1
- cyberdesk/__init__.py,sha256=ZjS5ouIl0k25SujyFhyiuN6Z8YP0qGO7cYvDmAYoT3A,1079
2
- cyberdesk/client.py,sha256=qmPJ7J1fzZaYWDGZ_xrFojLQSjMWWu_NsmRfZROZXAU,35026
3
- cyberdesk-1.9.0.dist-info/licenses/LICENSE,sha256=06Op63FCwGhuUOz__M8IZW5sxd29WxyGC4X5-Uih7IQ,1071
1
+ cyberdesk/__init__.py,sha256=fEL8e-_YJA8OxkB9SfeJoKcBWH6EIJofGRQMGObdB_A,1158
2
+ cyberdesk/client.py,sha256=hb6SwdYuV7wyGSwLjmiUfg31O3TXkqYkbSPPtZAprS8,41730
3
+ cyberdesk-1.10.0.dist-info/licenses/LICENSE,sha256=06Op63FCwGhuUOz__M8IZW5sxd29WxyGC4X5-Uih7IQ,1071
4
4
  openapi_client/cyberdesk_cloud_client/__init__.py,sha256=r_uVkNUL-SOK8j7-KiGMIKdinES5X8K1Q250ySX2F-A,158
5
5
  openapi_client/cyberdesk_cloud_client/client.py,sha256=o_mdLqyBCQstu5tS1WZFwqIEbGwkvWQ7eQjuCJw_5VY,12419
6
6
  openapi_client/cyberdesk_cloud_client/errors.py,sha256=gO8GBmKqmSNgAg-E5oT-oOyxztvp7V_6XG7OUTT15q0,546
@@ -46,7 +46,8 @@ openapi_client/cyberdesk_cloud_client/api/request_logs/update_request_log_v1_req
46
46
  openapi_client/cyberdesk_cloud_client/api/run_attachments/__init__.py,sha256=5vd9uJWAjRqa9xzxzYkLD1yoZ12Ld_bAaNB5WX4fbE8,56
47
47
  openapi_client/cyberdesk_cloud_client/api/run_attachments/create_run_attachment_v1_run_attachments_post.py,sha256=DTcoKhj8uflj1FUJAIKrVhbCXaQIjjWH3ZpijDJZdJI,5216
48
48
  openapi_client/cyberdesk_cloud_client/api/run_attachments/delete_run_attachment_v1_run_attachments_attachment_id_delete.py,sha256=BUamhNNCzRL_irucvhvlOxkqnOxNv0wUUDUrHvmnDc0,4465
49
- openapi_client/cyberdesk_cloud_client/api/run_attachments/download_run_attachment_v1_run_attachments_attachment_id_download_get.py,sha256=boplCuACwpIfPQt32CL-OxII1xKiVbFLWLlGg0WrlZM,4389
49
+ openapi_client/cyberdesk_cloud_client/api/run_attachments/download_run_attachment_v1_run_attachments_attachment_id_download_get.py,sha256=CGqC2lCQK1AbGCsIq2sA5PS8b1oA0VV5ysYvORuF8FY,4405
50
+ openapi_client/cyberdesk_cloud_client/api/run_attachments/get_run_attachment_download_url_v1_run_attachments_attachment_id_download_url_get.py,sha256=99FZWvi6f0Wlwd2SxFoudbH5t9H57lw1LMWFhf4J408,6560
50
51
  openapi_client/cyberdesk_cloud_client/api/run_attachments/get_run_attachment_v1_run_attachments_attachment_id_get.py,sha256=9Rkn4y-3mh-SMEnmvPLeo34Hhp9Bsk_Wb7sWw1xeDhA,4786
51
52
  openapi_client/cyberdesk_cloud_client/api/run_attachments/list_run_attachments_v1_run_attachments_get.py,sha256=LGcoHCLkujfTHgwzapuYV8Ve8y4yw_VZ3jkSK5Rt91o,7783
52
53
  openapi_client/cyberdesk_cloud_client/api/run_attachments/update_run_attachment_v1_run_attachments_attachment_id_put.py,sha256=4jsIek-Z4U5hbKHRMBsnJr0DgfOoY5B2sC22d5Af-UU,5395
@@ -72,7 +73,7 @@ openapi_client/cyberdesk_cloud_client/api/workflows/get_workflow_v1_workflows_wo
72
73
  openapi_client/cyberdesk_cloud_client/api/workflows/get_workflow_versions_v1_workflows_workflow_id_versions_get.py,sha256=jBJJwJQfKBBYTX1FhSe7qWFxK0ZvYD_QKcrxTgo361U,5857
73
74
  openapi_client/cyberdesk_cloud_client/api/workflows/list_workflows_v1_workflows_get.py,sha256=xM1Ex78PdeJK2IrQ10ghKqk93FwNGOnVOPt666hUhwE,5626
74
75
  openapi_client/cyberdesk_cloud_client/api/workflows/update_workflow_v1_workflows_workflow_id_patch.py,sha256=G6l9aClbapqjCmDsjK01447iqRKhRFp9CnJDLHV8OBc,5705
75
- openapi_client/cyberdesk_cloud_client/models/__init__.py,sha256=jchhYiVrBiL2nnpIBY9Zvfhz4D5_NyHKMqq7Bgw747M,7981
76
+ openapi_client/cyberdesk_cloud_client/models/__init__.py,sha256=SRvxZix5iwyWa-eVhB0FcjhWgkRexP_YMP1KGH2vQDc,8104
76
77
  openapi_client/cyberdesk_cloud_client/models/attachment_type.py,sha256=zqPOsSd2AmxGNqb5HQ6ZYBAYL8k-0UbWHhfAJYNHoro,161
77
78
  openapi_client/cyberdesk_cloud_client/models/connection_create.py,sha256=gCI36DmjJDZxzGFPbykyYw9k4QEf_4dVNz9b-xZfLo4,3288
78
79
  openapi_client/cyberdesk_cloud_client/models/connection_response.py,sha256=aFxqJX75wSEw5dZ-kvh3Wgv_haJ6xYJ7o72vSAbEtHY,5247
@@ -112,6 +113,7 @@ openapi_client/cyberdesk_cloud_client/models/request_log_create.py,sha256=6CNnBv
112
113
  openapi_client/cyberdesk_cloud_client/models/request_log_response.py,sha256=mU3lUdbLRFg9XppHnO-GjKcvt4M_BCG5CynWwU7ivZE,7445
113
114
  openapi_client/cyberdesk_cloud_client/models/request_log_update.py,sha256=VcXBNffDOoEYYBjwvdkuSWPz04BW3c8YTcqzlZRb0ns,5677
114
115
  openapi_client/cyberdesk_cloud_client/models/run_attachment_create.py,sha256=w58KmB9lLnE2N2EQJz_DP1PQj5OEL__t9ufdQFryp0A,4965
116
+ openapi_client/cyberdesk_cloud_client/models/run_attachment_download_url_response.py,sha256=CUeh3Zas29uwfpH5oMbQ_hhkpsZ_RH7ZA_RyfRsf8mY,1864
115
117
  openapi_client/cyberdesk_cloud_client/models/run_attachment_response.py,sha256=LZEFltiyC_bBVNlz3LM1H5MXFoBkVzk-CzNuvlTumJ4,5769
116
118
  openapi_client/cyberdesk_cloud_client/models/run_attachment_update.py,sha256=rGXcB21waSTXG0-mt0XhNcwoJI1PhBpBDUkLfp8mM-0,2573
117
119
  openapi_client/cyberdesk_cloud_client/models/run_create.py,sha256=hUMuozdNHMQwndTl-mCfQ8hGwPeJ_EkPeZEmAUQWMHc,6083
@@ -140,7 +142,7 @@ openapi_client/cyberdesk_cloud_client/models/workflow_create.py,sha256=Z7XG8k1js
140
142
  openapi_client/cyberdesk_cloud_client/models/workflow_response.py,sha256=kC_ZGUweaiogKqyRS1yjByHuYqZW0jzxuEyM9CIfFsc,6937
141
143
  openapi_client/cyberdesk_cloud_client/models/workflow_response_old_versions_type_0_item.py,sha256=W9AxxlBlN3rUwLDcoUx5H7MUiYA9UztfX9iEpNGlgAs,1340
142
144
  openapi_client/cyberdesk_cloud_client/models/workflow_update.py,sha256=_zMo2mJbYdKILygBXwebAD37SJJCUZOTkJkMOCzeNTA,4439
143
- cyberdesk-1.9.0.dist-info/METADATA,sha256=SrCf6y1nUAjvB1t2-I9DQF01Qyd0uiYHyixa2azjDE8,6791
144
- cyberdesk-1.9.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
145
- cyberdesk-1.9.0.dist-info/top_level.txt,sha256=qTYHZHVHh3VClNPQsiFFA8p8tmJgFGhq9G1COd-pX_A,25
146
- cyberdesk-1.9.0.dist-info/RECORD,,
145
+ cyberdesk-1.10.0.dist-info/METADATA,sha256=mcSaRs06cVkhE_-SVJ1kWkVfXWzog4r6eTkxKNxDgg4,6792
146
+ cyberdesk-1.10.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
147
+ cyberdesk-1.10.0.dist-info/top_level.txt,sha256=qTYHZHVHh3VClNPQsiFFA8p8tmJgFGhq9G1COd-pX_A,25
148
+ cyberdesk-1.10.0.dist-info/RECORD,,
@@ -57,7 +57,7 @@ def sync_detailed(
57
57
 
58
58
  Download a run attachment file.
59
59
 
60
- Returns the file content as a streaming response.
60
+ Returns the raw file content as a streaming response.
61
61
 
62
62
  Args:
63
63
  attachment_id (UUID):
@@ -90,7 +90,7 @@ def sync(
90
90
 
91
91
  Download a run attachment file.
92
92
 
93
- Returns the file content as a streaming response.
93
+ Returns the raw file content as a streaming response.
94
94
 
95
95
  Args:
96
96
  attachment_id (UUID):
@@ -118,7 +118,7 @@ async def asyncio_detailed(
118
118
 
119
119
  Download a run attachment file.
120
120
 
121
- Returns the file content as a streaming response.
121
+ Returns the raw file content as a streaming response.
122
122
 
123
123
  Args:
124
124
  attachment_id (UUID):
@@ -149,7 +149,7 @@ async def asyncio(
149
149
 
150
150
  Download a run attachment file.
151
151
 
152
- Returns the file content as a streaming response.
152
+ Returns the raw file content as a streaming response.
153
153
 
154
154
  Args:
155
155
  attachment_id (UUID):
@@ -0,0 +1,209 @@
1
+ from http import HTTPStatus
2
+ from typing import Any, Optional, Union
3
+ from uuid import UUID
4
+
5
+ import httpx
6
+
7
+ from ... import errors
8
+ from ...client import AuthenticatedClient, Client
9
+ from ...models.http_validation_error import HTTPValidationError
10
+ from ...models.run_attachment_download_url_response import RunAttachmentDownloadUrlResponse
11
+ from ...types import UNSET, Response, Unset
12
+
13
+
14
+ def _get_kwargs(
15
+ attachment_id: UUID,
16
+ *,
17
+ expires_in: Union[Unset, int] = 300,
18
+ ) -> dict[str, Any]:
19
+ params: dict[str, Any] = {}
20
+
21
+ params["expires_in"] = expires_in
22
+
23
+ params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
24
+
25
+ _kwargs: dict[str, Any] = {
26
+ "method": "get",
27
+ "url": f"/v1/run-attachments/{attachment_id}/download-url",
28
+ "params": params,
29
+ }
30
+
31
+ return _kwargs
32
+
33
+
34
+ def _parse_response(
35
+ *, client: Union[AuthenticatedClient, Client], response: httpx.Response
36
+ ) -> Optional[Union[HTTPValidationError, RunAttachmentDownloadUrlResponse]]:
37
+ if response.status_code == 200:
38
+ response_200 = RunAttachmentDownloadUrlResponse.from_dict(response.json())
39
+
40
+ return response_200
41
+ if response.status_code == 422:
42
+ response_422 = HTTPValidationError.from_dict(response.json())
43
+
44
+ return response_422
45
+ if client.raise_on_unexpected_status:
46
+ raise errors.UnexpectedStatus(response.status_code, response.content)
47
+ else:
48
+ return None
49
+
50
+
51
+ def _build_response(
52
+ *, client: Union[AuthenticatedClient, Client], response: httpx.Response
53
+ ) -> Response[Union[HTTPValidationError, RunAttachmentDownloadUrlResponse]]:
54
+ return Response(
55
+ status_code=HTTPStatus(response.status_code),
56
+ content=response.content,
57
+ headers=response.headers,
58
+ parsed=_parse_response(client=client, response=response),
59
+ )
60
+
61
+
62
+ def sync_detailed(
63
+ attachment_id: UUID,
64
+ *,
65
+ client: AuthenticatedClient,
66
+ expires_in: Union[Unset, int] = 300,
67
+ ) -> Response[Union[HTTPValidationError, RunAttachmentDownloadUrlResponse]]:
68
+ """Get Run Attachment Download Url
69
+
70
+ Get a signed download URL for a run attachment file.
71
+
72
+ Returns a signed URL that triggers automatic download when accessed.
73
+
74
+ Args:
75
+ attachment_id: The ID of the attachment to download
76
+ expires_in: URL expiration time in seconds (10-3600). Default: 300 (5 minutes)
77
+
78
+ Args:
79
+ attachment_id (UUID):
80
+ expires_in (Union[Unset, int]): URL expiration time in seconds (10-3600) Default: 300.
81
+
82
+ Raises:
83
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
84
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
85
+
86
+ Returns:
87
+ Response[Union[HTTPValidationError, RunAttachmentDownloadUrlResponse]]
88
+ """
89
+
90
+ kwargs = _get_kwargs(
91
+ attachment_id=attachment_id,
92
+ expires_in=expires_in,
93
+ )
94
+
95
+ response = client.get_httpx_client().request(
96
+ **kwargs,
97
+ )
98
+
99
+ return _build_response(client=client, response=response)
100
+
101
+
102
+ def sync(
103
+ attachment_id: UUID,
104
+ *,
105
+ client: AuthenticatedClient,
106
+ expires_in: Union[Unset, int] = 300,
107
+ ) -> Optional[Union[HTTPValidationError, RunAttachmentDownloadUrlResponse]]:
108
+ """Get Run Attachment Download Url
109
+
110
+ Get a signed download URL for a run attachment file.
111
+
112
+ Returns a signed URL that triggers automatic download when accessed.
113
+
114
+ Args:
115
+ attachment_id: The ID of the attachment to download
116
+ expires_in: URL expiration time in seconds (10-3600). Default: 300 (5 minutes)
117
+
118
+ Args:
119
+ attachment_id (UUID):
120
+ expires_in (Union[Unset, int]): URL expiration time in seconds (10-3600) Default: 300.
121
+
122
+ Raises:
123
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
124
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
125
+
126
+ Returns:
127
+ Union[HTTPValidationError, RunAttachmentDownloadUrlResponse]
128
+ """
129
+
130
+ return sync_detailed(
131
+ attachment_id=attachment_id,
132
+ client=client,
133
+ expires_in=expires_in,
134
+ ).parsed
135
+
136
+
137
+ async def asyncio_detailed(
138
+ attachment_id: UUID,
139
+ *,
140
+ client: AuthenticatedClient,
141
+ expires_in: Union[Unset, int] = 300,
142
+ ) -> Response[Union[HTTPValidationError, RunAttachmentDownloadUrlResponse]]:
143
+ """Get Run Attachment Download Url
144
+
145
+ Get a signed download URL for a run attachment file.
146
+
147
+ Returns a signed URL that triggers automatic download when accessed.
148
+
149
+ Args:
150
+ attachment_id: The ID of the attachment to download
151
+ expires_in: URL expiration time in seconds (10-3600). Default: 300 (5 minutes)
152
+
153
+ Args:
154
+ attachment_id (UUID):
155
+ expires_in (Union[Unset, int]): URL expiration time in seconds (10-3600) Default: 300.
156
+
157
+ Raises:
158
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
159
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
160
+
161
+ Returns:
162
+ Response[Union[HTTPValidationError, RunAttachmentDownloadUrlResponse]]
163
+ """
164
+
165
+ kwargs = _get_kwargs(
166
+ attachment_id=attachment_id,
167
+ expires_in=expires_in,
168
+ )
169
+
170
+ response = await client.get_async_httpx_client().request(**kwargs)
171
+
172
+ return _build_response(client=client, response=response)
173
+
174
+
175
+ async def asyncio(
176
+ attachment_id: UUID,
177
+ *,
178
+ client: AuthenticatedClient,
179
+ expires_in: Union[Unset, int] = 300,
180
+ ) -> Optional[Union[HTTPValidationError, RunAttachmentDownloadUrlResponse]]:
181
+ """Get Run Attachment Download Url
182
+
183
+ Get a signed download URL for a run attachment file.
184
+
185
+ Returns a signed URL that triggers automatic download when accessed.
186
+
187
+ Args:
188
+ attachment_id: The ID of the attachment to download
189
+ expires_in: URL expiration time in seconds (10-3600). Default: 300 (5 minutes)
190
+
191
+ Args:
192
+ attachment_id (UUID):
193
+ expires_in (Union[Unset, int]): URL expiration time in seconds (10-3600) Default: 300.
194
+
195
+ Raises:
196
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
197
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
198
+
199
+ Returns:
200
+ Union[HTTPValidationError, RunAttachmentDownloadUrlResponse]
201
+ """
202
+
203
+ return (
204
+ await asyncio_detailed(
205
+ attachment_id=attachment_id,
206
+ client=client,
207
+ expires_in=expires_in,
208
+ )
209
+ ).parsed
@@ -57,6 +57,7 @@ from .request_log_create import RequestLogCreate
57
57
  from .request_log_response import RequestLogResponse
58
58
  from .request_log_update import RequestLogUpdate
59
59
  from .run_attachment_create import RunAttachmentCreate
60
+ from .run_attachment_download_url_response import RunAttachmentDownloadUrlResponse
60
61
  from .run_attachment_response import RunAttachmentResponse
61
62
  from .run_attachment_update import RunAttachmentUpdate
62
63
  from .run_create import RunCreate
@@ -126,6 +127,7 @@ __all__ = (
126
127
  "RequestLogResponse",
127
128
  "RequestLogUpdate",
128
129
  "RunAttachmentCreate",
130
+ "RunAttachmentDownloadUrlResponse",
129
131
  "RunAttachmentResponse",
130
132
  "RunAttachmentUpdate",
131
133
  "RunCreate",
@@ -0,0 +1,68 @@
1
+ from collections.abc import Mapping
2
+ from typing import Any, TypeVar
3
+
4
+ from attrs import define as _attrs_define
5
+ from attrs import field as _attrs_field
6
+
7
+ T = TypeVar("T", bound="RunAttachmentDownloadUrlResponse")
8
+
9
+
10
+ @_attrs_define
11
+ class RunAttachmentDownloadUrlResponse:
12
+ """Response schema for run attachment download URL
13
+
14
+ Attributes:
15
+ url (str): Signed URL for downloading the attachment
16
+ expires_in (int): Seconds until the URL expires
17
+ """
18
+
19
+ url: str
20
+ expires_in: int
21
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
22
+
23
+ def to_dict(self) -> dict[str, Any]:
24
+ url = self.url
25
+
26
+ expires_in = self.expires_in
27
+
28
+ field_dict: dict[str, Any] = {}
29
+ field_dict.update(self.additional_properties)
30
+ field_dict.update(
31
+ {
32
+ "url": url,
33
+ "expires_in": expires_in,
34
+ }
35
+ )
36
+
37
+ return field_dict
38
+
39
+ @classmethod
40
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
41
+ d = dict(src_dict)
42
+ url = d.pop("url")
43
+
44
+ expires_in = d.pop("expires_in")
45
+
46
+ run_attachment_download_url_response = cls(
47
+ url=url,
48
+ expires_in=expires_in,
49
+ )
50
+
51
+ run_attachment_download_url_response.additional_properties = d
52
+ return run_attachment_download_url_response
53
+
54
+ @property
55
+ def additional_keys(self) -> list[str]:
56
+ return list(self.additional_properties.keys())
57
+
58
+ def __getitem__(self, key: str) -> Any:
59
+ return self.additional_properties[key]
60
+
61
+ def __setitem__(self, key: str, value: Any) -> None:
62
+ self.additional_properties[key] = value
63
+
64
+ def __delitem__(self, key: str) -> None:
65
+ del self.additional_properties[key]
66
+
67
+ def __contains__(self, key: str) -> bool:
68
+ return key in self.additional_properties