cyberdesk 1.8.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.

Files changed (41) hide show
  1. cyberdesk/__init__.py +13 -1
  2. cyberdesk/client.py +357 -0
  3. {cyberdesk-1.8.0.dist-info → cyberdesk-1.10.0.dist-info}/METADATA +39 -17
  4. {cyberdesk-1.8.0.dist-info → cyberdesk-1.10.0.dist-info}/RECORD +41 -13
  5. openapi_client/cyberdesk_cloud_client/api/computer/fs_list_v1_computer_machine_id_fs_list_get.py +188 -0
  6. openapi_client/cyberdesk_cloud_client/api/computer/fs_read_v1_computer_machine_id_fs_read_get.py +188 -0
  7. openapi_client/cyberdesk_cloud_client/api/computer/fs_write_v1_computer_machine_id_fs_write_post.py +201 -0
  8. openapi_client/cyberdesk_cloud_client/api/computer/powershell_exec_v1_computer_machine_id_shell_powershell_exec_post.py +219 -0
  9. openapi_client/cyberdesk_cloud_client/api/computer/powershell_session_v1_computer_machine_id_shell_powershell_session_post.py +219 -0
  10. openapi_client/cyberdesk_cloud_client/api/run_attachments/__init__.py +1 -0
  11. openapi_client/cyberdesk_cloud_client/api/run_attachments/create_run_attachment_v1_run_attachments_post.py +184 -0
  12. openapi_client/cyberdesk_cloud_client/api/run_attachments/delete_run_attachment_v1_run_attachments_attachment_id_delete.py +170 -0
  13. openapi_client/cyberdesk_cloud_client/api/run_attachments/download_run_attachment_v1_run_attachments_attachment_id_download_get.py +170 -0
  14. openapi_client/cyberdesk_cloud_client/api/run_attachments/get_run_attachment_download_url_v1_run_attachments_attachment_id_download_url_get.py +209 -0
  15. openapi_client/cyberdesk_cloud_client/api/run_attachments/get_run_attachment_v1_run_attachments_attachment_id_get.py +172 -0
  16. openapi_client/cyberdesk_cloud_client/api/run_attachments/list_run_attachments_v1_run_attachments_get.py +240 -0
  17. openapi_client/cyberdesk_cloud_client/api/run_attachments/update_run_attachment_v1_run_attachments_attachment_id_put.py +194 -0
  18. openapi_client/cyberdesk_cloud_client/models/__init__.py +40 -0
  19. openapi_client/cyberdesk_cloud_client/models/attachment_type.py +9 -0
  20. openapi_client/cyberdesk_cloud_client/models/file_input.py +99 -0
  21. openapi_client/cyberdesk_cloud_client/models/file_write_request.py +78 -0
  22. openapi_client/cyberdesk_cloud_client/models/fs_list_v1_computer_machine_id_fs_list_get_response_fs_list_v1_computer_machine_id_fs_list_get.py +44 -0
  23. openapi_client/cyberdesk_cloud_client/models/fs_read_v1_computer_machine_id_fs_read_get_response_fs_read_v1_computer_machine_id_fs_read_get.py +44 -0
  24. openapi_client/cyberdesk_cloud_client/models/fs_write_v1_computer_machine_id_fs_write_post_response_fs_write_v1_computer_machine_id_fs_write_post.py +44 -0
  25. openapi_client/cyberdesk_cloud_client/models/paginated_response_run_attachment_response.py +97 -0
  26. openapi_client/cyberdesk_cloud_client/models/power_shell_exec_request.py +110 -0
  27. openapi_client/cyberdesk_cloud_client/models/power_shell_session_request.py +81 -0
  28. openapi_client/cyberdesk_cloud_client/models/powershell_exec_v1_computer_machine_id_shell_powershell_exec_post_response_powershell_exec_v1_computer_machine_id_shell_powershell_exec_post.py +47 -0
  29. openapi_client/cyberdesk_cloud_client/models/powershell_session_v1_computer_machine_id_shell_powershell_session_post_response_powershell_session_v1_computer_machine_id_shell_powershell_session_post.py +47 -0
  30. openapi_client/cyberdesk_cloud_client/models/run_attachment_create.py +157 -0
  31. openapi_client/cyberdesk_cloud_client/models/run_attachment_download_url_response.py +68 -0
  32. openapi_client/cyberdesk_cloud_client/models/run_attachment_response.py +189 -0
  33. openapi_client/cyberdesk_cloud_client/models/run_attachment_update.py +84 -0
  34. openapi_client/cyberdesk_cloud_client/models/run_create.py +41 -0
  35. openapi_client/cyberdesk_cloud_client/models/run_response.py +26 -0
  36. openapi_client/cyberdesk_cloud_client/models/workflow_create.py +9 -0
  37. openapi_client/cyberdesk_cloud_client/models/workflow_response.py +9 -0
  38. openapi_client/cyberdesk_cloud_client/models/workflow_update.py +20 -0
  39. {cyberdesk-1.8.0.dist-info → cyberdesk-1.10.0.dist-info}/WHEEL +0 -0
  40. {cyberdesk-1.8.0.dist-info → cyberdesk-1.10.0.dist-info}/licenses/LICENSE +0 -0
  41. {cyberdesk-1.8.0.dist-info → cyberdesk-1.10.0.dist-info}/top_level.txt +0 -0
cyberdesk/__init__.py CHANGED
@@ -13,15 +13,21 @@ from .client import (
13
13
  RunUpdate,
14
14
  RunResponse,
15
15
  RunStatus,
16
+ FileInput,
16
17
  ConnectionCreate,
17
18
  ConnectionResponse,
18
19
  ConnectionStatus,
19
20
  TrajectoryCreate,
20
21
  TrajectoryUpdate,
21
22
  TrajectoryResponse,
23
+ RunAttachmentCreate,
24
+ RunAttachmentUpdate,
25
+ RunAttachmentResponse,
26
+ RunAttachmentDownloadUrlResponse,
27
+ AttachmentType,
22
28
  )
23
29
 
24
- __version__ = "1.8.0"
30
+ __version__ = "1.10.0"
25
31
 
26
32
  __all__ = [
27
33
  "CyberdeskClient",
@@ -36,10 +42,16 @@ __all__ = [
36
42
  "RunUpdate",
37
43
  "RunResponse",
38
44
  "RunStatus",
45
+ "FileInput",
39
46
  "ConnectionCreate",
40
47
  "ConnectionResponse",
41
48
  "ConnectionStatus",
42
49
  "TrajectoryCreate",
43
50
  "TrajectoryUpdate",
44
51
  "TrajectoryResponse",
52
+ "RunAttachmentCreate",
53
+ "RunAttachmentUpdate",
54
+ "RunAttachmentResponse",
55
+ "RunAttachmentDownloadUrlResponse",
56
+ "AttachmentType",
45
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
 
@@ -40,6 +41,15 @@ from openapi_client.cyberdesk_cloud_client.api.trajectories import (
40
41
  delete_trajectory_v1_trajectories_trajectory_id_delete,
41
42
  get_latest_trajectory_for_workflow_v1_workflows_workflow_id_latest_trajectory_get,
42
43
  )
44
+ from openapi_client.cyberdesk_cloud_client.api.run_attachments import (
45
+ list_run_attachments_v1_run_attachments_get,
46
+ create_run_attachment_v1_run_attachments_post,
47
+ get_run_attachment_v1_run_attachments_attachment_id_get,
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,
50
+ update_run_attachment_v1_run_attachments_attachment_id_put,
51
+ delete_run_attachment_v1_run_attachments_attachment_id_delete,
52
+ )
43
53
 
44
54
  # Import models
45
55
  from openapi_client.cyberdesk_cloud_client.models import (
@@ -54,17 +64,24 @@ from openapi_client.cyberdesk_cloud_client.models import (
54
64
  RunUpdate,
55
65
  RunResponse,
56
66
  RunStatus,
67
+ FileInput,
57
68
  ConnectionCreate,
58
69
  ConnectionResponse,
59
70
  ConnectionStatus,
60
71
  TrajectoryCreate,
61
72
  TrajectoryUpdate,
62
73
  TrajectoryResponse,
74
+ RunAttachmentCreate,
75
+ RunAttachmentUpdate,
76
+ RunAttachmentResponse,
77
+ RunAttachmentDownloadUrlResponse,
78
+ AttachmentType,
63
79
  PaginatedResponseMachineResponse,
64
80
  PaginatedResponseWorkflowResponse,
65
81
  PaginatedResponseRunResponse,
66
82
  PaginatedResponseConnectionResponse,
67
83
  PaginatedResponseTrajectoryResponse,
84
+ PaginatedResponseRunAttachmentResponse,
68
85
  )
69
86
 
70
87
  # Re-export common types
@@ -81,12 +98,18 @@ __all__ = [
81
98
  "RunUpdate",
82
99
  "RunResponse",
83
100
  "RunStatus",
101
+ "FileInput",
84
102
  "ConnectionCreate",
85
103
  "ConnectionResponse",
86
104
  "ConnectionStatus",
87
105
  "TrajectoryCreate",
88
106
  "TrajectoryUpdate",
89
107
  "TrajectoryResponse",
108
+ "RunAttachmentCreate",
109
+ "RunAttachmentUpdate",
110
+ "RunAttachmentResponse",
111
+ "RunAttachmentDownloadUrlResponse",
112
+ "AttachmentType",
90
113
  ]
91
114
 
92
115
  DEFAULT_API_BASE_URL = "https://api.cyberdesk.io"
@@ -738,6 +761,339 @@ class TrajectoriesAPI:
738
761
  return ApiResponse(error=e)
739
762
 
740
763
 
764
+ class RunAttachmentsAPI:
765
+ """Run Attachments API endpoints."""
766
+
767
+ def __init__(self, client: AuthenticatedClient):
768
+ self.client = client
769
+
770
+ async def list(
771
+ self,
772
+ skip: Optional[int] = None,
773
+ limit: Optional[int] = None,
774
+ run_id: Optional[str] = None,
775
+ attachment_type: Optional[AttachmentType] = None
776
+ ) -> ApiResponse:
777
+ """List run attachments with optional filtering."""
778
+ try:
779
+ response = await list_run_attachments_v1_run_attachments_get.asyncio(
780
+ client=self.client,
781
+ skip=_to_unset_or_value(skip),
782
+ limit=_to_unset_or_value(limit),
783
+ run_id=_to_uuid(run_id) if run_id else UNSET,
784
+ attachment_type=attachment_type
785
+ )
786
+ return ApiResponse(data=response)
787
+ except Exception as e:
788
+ return ApiResponse(error=e)
789
+
790
+ def list_sync(
791
+ self,
792
+ skip: Optional[int] = None,
793
+ limit: Optional[int] = None,
794
+ run_id: Optional[str] = None,
795
+ attachment_type: Optional[AttachmentType] = None
796
+ ) -> ApiResponse:
797
+ """List run attachments with optional filtering (synchronous)."""
798
+ try:
799
+ response = list_run_attachments_v1_run_attachments_get.sync(
800
+ client=self.client,
801
+ skip=_to_unset_or_value(skip),
802
+ limit=_to_unset_or_value(limit),
803
+ run_id=_to_uuid(run_id) if run_id else UNSET,
804
+ attachment_type=attachment_type
805
+ )
806
+ return ApiResponse(data=response)
807
+ except Exception as e:
808
+ return ApiResponse(error=e)
809
+
810
+ async def create(self, data: RunAttachmentCreate) -> ApiResponse:
811
+ """Create a new run attachment."""
812
+ try:
813
+ response = await create_run_attachment_v1_run_attachments_post.asyncio(
814
+ client=self.client,
815
+ body=data
816
+ )
817
+ return ApiResponse(data=response)
818
+ except Exception as e:
819
+ return ApiResponse(error=e)
820
+
821
+ def create_sync(self, data: RunAttachmentCreate) -> ApiResponse:
822
+ """Create a new run attachment (synchronous)."""
823
+ try:
824
+ response = create_run_attachment_v1_run_attachments_post.sync(
825
+ client=self.client,
826
+ body=data
827
+ )
828
+ return ApiResponse(data=response)
829
+ except Exception as e:
830
+ return ApiResponse(error=e)
831
+
832
+ async def get(self, attachment_id: str) -> ApiResponse:
833
+ """Get a specific run attachment by ID."""
834
+ try:
835
+ response = await get_run_attachment_v1_run_attachments_attachment_id_get.asyncio(
836
+ client=self.client,
837
+ attachment_id=_to_uuid(attachment_id)
838
+ )
839
+ return ApiResponse(data=response)
840
+ except Exception as e:
841
+ return ApiResponse(error=e)
842
+
843
+ def get_sync(self, attachment_id: str) -> ApiResponse:
844
+ """Get a specific run attachment by ID (synchronous)."""
845
+ try:
846
+ response = get_run_attachment_v1_run_attachments_attachment_id_get.sync(
847
+ client=self.client,
848
+ attachment_id=_to_uuid(attachment_id)
849
+ )
850
+ return ApiResponse(data=response)
851
+ except Exception as e:
852
+ return ApiResponse(error=e)
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
+
910
+ async def download(self, attachment_id: str) -> ApiResponse:
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
918
+
919
+ Returns:
920
+ ApiResponse with data containing the raw file bytes
921
+ """
922
+ try:
923
+ response = await download_run_attachment_v1_run_attachments_attachment_id_download_get.asyncio(
924
+ client=self.client,
925
+ attachment_id=_to_uuid(attachment_id)
926
+ )
927
+ return ApiResponse(data=response)
928
+ except Exception as e:
929
+ return ApiResponse(error=e)
930
+
931
+ def download_sync(self, attachment_id: str) -> ApiResponse:
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
939
+
940
+ Returns:
941
+ ApiResponse with data containing the raw file bytes
942
+ """
943
+ try:
944
+ response = download_run_attachment_v1_run_attachments_attachment_id_download_get.sync(
945
+ client=self.client,
946
+ attachment_id=_to_uuid(attachment_id)
947
+ )
948
+ return ApiResponse(data=response)
949
+ except Exception as e:
950
+ return ApiResponse(error=e)
951
+
952
+ async def update(self, attachment_id: str, data: RunAttachmentUpdate) -> ApiResponse:
953
+ """Update a run attachment (e.g., set expiration)."""
954
+ try:
955
+ response = await update_run_attachment_v1_run_attachments_attachment_id_put.asyncio(
956
+ client=self.client,
957
+ attachment_id=_to_uuid(attachment_id),
958
+ body=data
959
+ )
960
+ return ApiResponse(data=response)
961
+ except Exception as e:
962
+ return ApiResponse(error=e)
963
+
964
+ def update_sync(self, attachment_id: str, data: RunAttachmentUpdate) -> ApiResponse:
965
+ """Update a run attachment (e.g., set expiration) (synchronous)."""
966
+ try:
967
+ response = update_run_attachment_v1_run_attachments_attachment_id_put.sync(
968
+ client=self.client,
969
+ attachment_id=_to_uuid(attachment_id),
970
+ body=data
971
+ )
972
+ return ApiResponse(data=response)
973
+ except Exception as e:
974
+ return ApiResponse(error=e)
975
+
976
+ async def delete(self, attachment_id: str) -> ApiResponse:
977
+ """Delete a run attachment."""
978
+ try:
979
+ await delete_run_attachment_v1_run_attachments_attachment_id_delete.asyncio(
980
+ client=self.client,
981
+ attachment_id=_to_uuid(attachment_id)
982
+ )
983
+ return ApiResponse(data={"success": True})
984
+ except Exception as e:
985
+ return ApiResponse(error=e)
986
+
987
+ def delete_sync(self, attachment_id: str) -> ApiResponse:
988
+ """Delete a run attachment (synchronous)."""
989
+ try:
990
+ delete_run_attachment_v1_run_attachments_attachment_id_delete.sync(
991
+ client=self.client,
992
+ attachment_id=_to_uuid(attachment_id)
993
+ )
994
+ return ApiResponse(data={"success": True})
995
+ except Exception as e:
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)
1095
+
1096
+
741
1097
  class CyberdeskClient:
742
1098
  """Main Cyberdesk SDK client."""
743
1099
 
@@ -762,6 +1118,7 @@ class CyberdeskClient:
762
1118
  self.runs = RunsAPI(self._client)
763
1119
  self.connections = ConnectionsAPI(self._client)
764
1120
  self.trajectories = TrajectoriesAPI(self._client)
1121
+ self.run_attachments = RunAttachmentsAPI(self._client)
765
1122
 
766
1123
  # TODO: Add computer API for screenshot functionality
767
1124
  # The openapi-python-client doesn't generate code for binary responses like PNG images
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cyberdesk
3
- Version: 1.8.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
@@ -26,30 +26,52 @@ pip install cyberdesk
26
26
 
27
27
  ## Quick Start
28
28
 
29
+ The most common use case is to execute workflows that you've created in the [Cyberdesk Dashboard](https://cyberdesk.io/dashboard).
30
+
29
31
  ```python
30
- from cyberdesk import CyberdeskClient
32
+ from cyberdesk import CyberdeskClient, RunCreate
33
+ import time
31
34
 
32
35
  # Initialize the client
33
36
  client = CyberdeskClient(api_key="your-api-key")
34
37
 
35
- # List machines
36
- response = client.machines.list_sync()
37
- if response.data:
38
- for machine in response.data.items:
39
- print(f"Machine: {machine.name} - Status: {machine.status}")
40
-
41
- # Create a workflow
42
- from cyberdesk import WorkflowCreate
43
-
44
- workflow_data = WorkflowCreate(
45
- name="My Workflow",
46
- description="Automated task workflow"
38
+ # Create a run for your workflow
39
+ run_data = RunCreate(
40
+ workflow_id="your-workflow-id",
41
+ machine_id="your-machine-id",
42
+ input_values={
43
+ # Your workflow-specific input data
44
+ "patient_id": "12345",
45
+ "patient_first_name": "John",
46
+ "patient_last_name": "Doe"
47
+ }
47
48
  )
48
- response = client.workflows.create_sync(workflow_data)
49
- if response.data:
50
- print(f"Created workflow: {response.data.id}")
49
+
50
+ response = client.runs.create_sync(run_data)
51
+ if response.error:
52
+ print(f"Error creating run: {response.error}")
53
+ else:
54
+ run = response.data
55
+
56
+ # Wait for the run to complete
57
+ while run.status in ["scheduling", "running"]:
58
+ time.sleep(5) # Wait 5 seconds
59
+ response = client.runs.get_sync(run.id)
60
+ run = response.data
61
+
62
+ # Get the output data
63
+ if run.status == "success":
64
+ print("Result:", run.output_data)
65
+ else:
66
+ print("Run failed:", ", ".join(run.error or []))
51
67
  ```
52
68
 
69
+ ## Full Documentation
70
+
71
+ For complete documentation including async/sync usage, error handling, and all available methods, visit:
72
+
73
+ **[https://docs.cyberdesk.io/sdk-guides/python](https://docs.cyberdesk.io/sdk-guides/python)**
74
+
53
75
  ## Async Support
54
76
 
55
77
  The SDK provides both synchronous and asynchronous methods for all operations:
@@ -1,6 +1,6 @@
1
- cyberdesk/__init__.py,sha256=YVzunEmic2iYsva79cKMkFGrrg5T_AmtBsRIWJsIs04,845
2
- cyberdesk/client.py,sha256=f3kT8v_ip5b49IYVoxNRgILd0SVLs_8MH5OiAkGF_IU,27713
3
- cyberdesk-1.8.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
@@ -8,6 +8,9 @@ openapi_client/cyberdesk_cloud_client/py.typed,sha256=8ZJUsxZiuOy1oJeVhsTWQhTG_6
8
8
  openapi_client/cyberdesk_cloud_client/types.py,sha256=AX4orxQZQJat3vZrgjJ-TYb2sNBL8kNo9yqYDT-n8y8,1391
9
9
  openapi_client/cyberdesk_cloud_client/api/__init__.py,sha256=zTSiG_ujSjAqWPyc435YXaX9XTlpMjiJWBbV-f-YtdA,45
10
10
  openapi_client/cyberdesk_cloud_client/api/computer/__init__.py,sha256=5vd9uJWAjRqa9xzxzYkLD1yoZ12Ld_bAaNB5WX4fbE8,56
11
+ openapi_client/cyberdesk_cloud_client/api/computer/fs_list_v1_computer_machine_id_fs_list_get.py,sha256=gI3DVyJZMiLoeer0YiUNyhjIIBIUq2BeNoRPFSr58rY,5794
12
+ openapi_client/cyberdesk_cloud_client/api/computer/fs_read_v1_computer_machine_id_fs_read_get.py,sha256=QstHlkfxARLnNt6WKjfwgER8wq-JfK1JOvU39veSlLI,5607
13
+ openapi_client/cyberdesk_cloud_client/api/computer/fs_write_v1_computer_machine_id_fs_write_post.py,sha256=4Un-26ll3YEKVMQve1MN_JdGEkOVj65FgNKvH1HWLrg,5808
11
14
  openapi_client/cyberdesk_cloud_client/api/computer/get_display_dimensions_v1_computer_machine_id_display_dimensions_get.py,sha256=aHCgck_f0IvtoNtmIF91mFrmNW4jSfh-lQkUFbgZbrY,4356
12
15
  openapi_client/cyberdesk_cloud_client/api/computer/get_mouse_position_v1_computer_machine_id_input_mouse_position_get.py,sha256=6vl34SKSBiRqeuHJrzQIS1hVSrIcQn4UaRejfDq4HvM,4274
13
16
  openapi_client/cyberdesk_cloud_client/api/computer/get_screenshot_v1_computer_machine_id_display_screenshot_get.py,sha256=aXmTIvBfyMR279Qjot6zvyFQovUJs3bI1oFNR8Zcq4Q,3888
@@ -15,6 +18,8 @@ openapi_client/cyberdesk_cloud_client/api/computer/keyboard_key_v1_computer_mach
15
18
  openapi_client/cyberdesk_cloud_client/api/computer/keyboard_type_v1_computer_machine_id_input_keyboard_type_post.py,sha256=tVBv4T6cg5UscdZtFuZpV4WJFF1Lqg7jDP97dbpoPnk,4664
16
19
  openapi_client/cyberdesk_cloud_client/api/computer/mouse_click_v1_computer_machine_id_input_mouse_click_post.py,sha256=_b8dCyAI0W3Fr0Ra5vo35yJuMb36cS0o41SSlLT1xf8,4984
17
20
  openapi_client/cyberdesk_cloud_client/api/computer/mouse_move_v1_computer_machine_id_input_mouse_move_post.py,sha256=CNfIj6oTs8QSRo4674pmHw9kJQIBw7D-u7mKT62tMDg,4704
21
+ openapi_client/cyberdesk_cloud_client/api/computer/powershell_exec_v1_computer_machine_id_shell_powershell_exec_post.py,sha256=iZCvu92FFTVAZfIkw-PIWPllUe4NRuAdjB63IasSxKw,6567
22
+ openapi_client/cyberdesk_cloud_client/api/computer/powershell_session_v1_computer_machine_id_shell_powershell_session_post.py,sha256=Bw-zP9ekElWvHbfts1bGfZX6mkEfrNwZ-A9rajAuzYM,6799
18
23
  openapi_client/cyberdesk_cloud_client/api/connections/__init__.py,sha256=5vd9uJWAjRqa9xzxzYkLD1yoZ12Ld_bAaNB5WX4fbE8,56
19
24
  openapi_client/cyberdesk_cloud_client/api/connections/create_connection_v1_connections_post.py,sha256=063OBpx_Hgn5A9kKINc9kD4emMDLPR23acamQ8sBGBY,5046
20
25
  openapi_client/cyberdesk_cloud_client/api/connections/delete_connection_v1_connections_connection_id_delete.py,sha256=-eiGKQa9Y2RW3zKsdygsAt636YyCVoy30DUdu6ce6yE,4653
@@ -38,6 +43,14 @@ openapi_client/cyberdesk_cloud_client/api/request_logs/delete_request_log_v1_req
38
43
  openapi_client/cyberdesk_cloud_client/api/request_logs/get_request_log_v1_request_logs_log_id_get.py,sha256=ooWgn9o_AGVP2EEPQjCAkOmcy4-jF42s2ocTKPU4O2o,4534
39
44
  openapi_client/cyberdesk_cloud_client/api/request_logs/list_request_logs_v1_request_logs_get.py,sha256=_CpUhLbesyefEaC5X_NeKWe3DTjILMDmn28eWrUYvVE,8076
40
45
  openapi_client/cyberdesk_cloud_client/api/request_logs/update_request_log_v1_request_logs_log_id_patch.py,sha256=7PGcu1GnN3EEkPo6cAZO45qRqd5cxK2Ge_rBp0__nfQ,5880
46
+ openapi_client/cyberdesk_cloud_client/api/run_attachments/__init__.py,sha256=5vd9uJWAjRqa9xzxzYkLD1yoZ12Ld_bAaNB5WX4fbE8,56
47
+ openapi_client/cyberdesk_cloud_client/api/run_attachments/create_run_attachment_v1_run_attachments_post.py,sha256=DTcoKhj8uflj1FUJAIKrVhbCXaQIjjWH3ZpijDJZdJI,5216
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=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
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
52
+ openapi_client/cyberdesk_cloud_client/api/run_attachments/list_run_attachments_v1_run_attachments_get.py,sha256=LGcoHCLkujfTHgwzapuYV8Ve8y4yw_VZ3jkSK5Rt91o,7783
53
+ openapi_client/cyberdesk_cloud_client/api/run_attachments/update_run_attachment_v1_run_attachments_attachment_id_put.py,sha256=4jsIek-Z4U5hbKHRMBsnJr0DgfOoY5B2sC22d5Af-UU,5395
41
54
  openapi_client/cyberdesk_cloud_client/api/runs/__init__.py,sha256=5vd9uJWAjRqa9xzxzYkLD1yoZ12Ld_bAaNB5WX4fbE8,56
42
55
  openapi_client/cyberdesk_cloud_client/api/runs/create_run_v1_runs_post.py,sha256=WarcoB_UIzZsTcvFGWAYZhjA0LsIY4wcP89wILtsTZs,5343
43
56
  openapi_client/cyberdesk_cloud_client/api/runs/delete_run_v1_runs_run_id_delete.py,sha256=ux5K74BTi5jarECVfTc5AxgAhDPfuFkt1XmaWWmRdLE,4116
@@ -60,13 +73,19 @@ openapi_client/cyberdesk_cloud_client/api/workflows/get_workflow_v1_workflows_wo
60
73
  openapi_client/cyberdesk_cloud_client/api/workflows/get_workflow_versions_v1_workflows_workflow_id_versions_get.py,sha256=jBJJwJQfKBBYTX1FhSe7qWFxK0ZvYD_QKcrxTgo361U,5857
61
74
  openapi_client/cyberdesk_cloud_client/api/workflows/list_workflows_v1_workflows_get.py,sha256=xM1Ex78PdeJK2IrQ10ghKqk93FwNGOnVOPt666hUhwE,5626
62
75
  openapi_client/cyberdesk_cloud_client/api/workflows/update_workflow_v1_workflows_workflow_id_patch.py,sha256=G6l9aClbapqjCmDsjK01447iqRKhRFp9CnJDLHV8OBc,5705
63
- openapi_client/cyberdesk_cloud_client/models/__init__.py,sha256=RluO9EWqHyLOQm-UGyLx3yDUN1cR0byhdfI-ejljubc,5499
76
+ openapi_client/cyberdesk_cloud_client/models/__init__.py,sha256=SRvxZix5iwyWa-eVhB0FcjhWgkRexP_YMP1KGH2vQDc,8104
77
+ openapi_client/cyberdesk_cloud_client/models/attachment_type.py,sha256=zqPOsSd2AmxGNqb5HQ6ZYBAYL8k-0UbWHhfAJYNHoro,161
64
78
  openapi_client/cyberdesk_cloud_client/models/connection_create.py,sha256=gCI36DmjJDZxzGFPbykyYw9k4QEf_4dVNz9b-xZfLo4,3288
65
79
  openapi_client/cyberdesk_cloud_client/models/connection_response.py,sha256=aFxqJX75wSEw5dZ-kvh3Wgv_haJ6xYJ7o72vSAbEtHY,5247
66
80
  openapi_client/cyberdesk_cloud_client/models/connection_status.py,sha256=XTpa-W0TinYhypU7P-LaJEI3I2JsEaT3voUZQ3zoJO0,203
67
81
  openapi_client/cyberdesk_cloud_client/models/database_health_check_v1_health_db_get_response_database_health_check_v1_health_db_get.py,sha256=ubG8Qi6xR4BBxLB9fZYfWZ0AqZr3_ywj9-MkWJcOZSM,1544
68
82
  openapi_client/cyberdesk_cloud_client/models/display_dimensions.py,sha256=_YjSuYuJIzETS5QzOUxsUJvgrOuvScDlUSUp36sr5Dk,1640
69
83
  openapi_client/cyberdesk_cloud_client/models/dummy_test_endpoint_v1_test_post_response_dummy_test_endpoint_v1_test_post.py,sha256=9z2ys68FDs76-xnXgUTB76gFEIss6qOKwTekFbBiGA4,1488
84
+ openapi_client/cyberdesk_cloud_client/models/file_input.py,sha256=7RpWoLxoVkGJsqntD2jh6PJZ-SJGWIM1XQziVEGHu5I,3046
85
+ openapi_client/cyberdesk_cloud_client/models/file_write_request.py,sha256=B4NRx8b3D1DcJCJvKezkpVmEehhBkmyEIinZXlrcsvg,2001
86
+ openapi_client/cyberdesk_cloud_client/models/fs_list_v1_computer_machine_id_fs_list_get_response_fs_list_v1_computer_machine_id_fs_list_get.py,sha256=vMvNvXLqVbXPU24_2zq5GsOg6sfmv59Z54qB5szYWyM,1576
87
+ openapi_client/cyberdesk_cloud_client/models/fs_read_v1_computer_machine_id_fs_read_get_response_fs_read_v1_computer_machine_id_fs_read_get.py,sha256=xIH_ifsONpWUEgHO2IjPjrVtWp3VEaU6dVXDJ3T9aP8,1576
88
+ openapi_client/cyberdesk_cloud_client/models/fs_write_v1_computer_machine_id_fs_write_post_response_fs_write_v1_computer_machine_id_fs_write_post.py,sha256=RLeOMxpL9PFC66efgfdvMJmLi9JwzVPPPwPbp080NKU,1606
70
89
  openapi_client/cyberdesk_cloud_client/models/get_workflow_versions_v1_workflows_workflow_id_versions_get_response_200_item.py,sha256=awMbgNS26JsLsyyRMKYHP_BGi9g5VKSVK65z-v4p35g,1505
71
90
  openapi_client/cyberdesk_cloud_client/models/health_check_v1_health_get_response_health_check_v1_health_get.py,sha256=xiy1oRClleq7BPHm8Ud_qd03gVkN9uI23PCm0PkLRNY,1432
72
91
  openapi_client/cyberdesk_cloud_client/models/http_validation_error.py,sha256=OvQ-alRPbtXXwrQunI1Cp1-BWf7ZkVHkigk-YVMFXN0,2213
@@ -82,15 +101,24 @@ openapi_client/cyberdesk_cloud_client/models/mouse_position.py,sha256=t8PW-7xKfy
82
101
  openapi_client/cyberdesk_cloud_client/models/paginated_response.py,sha256=P9bt0Koea8rODsULodX8dDAwm-uP2KRE1mRi8AK-VBY,1988
83
102
  openapi_client/cyberdesk_cloud_client/models/paginated_response_connection_response.py,sha256=2WxYXSS1RoBeh2ealxdQeEBSv0pBpllar1m98toeYHs,2527
84
103
  openapi_client/cyberdesk_cloud_client/models/paginated_response_machine_response.py,sha256=m_bJGQwSQkqPeJwcQ2UnXglhdmPqsj_tjjx_3S-YZyE,2491
104
+ openapi_client/cyberdesk_cloud_client/models/paginated_response_run_attachment_response.py,sha256=OHsnkYeV1_35TYMrYRaG0XxdjaBXp5Qcq64hbHxzjV4,2568
85
105
  openapi_client/cyberdesk_cloud_client/models/paginated_response_run_response.py,sha256=UFk93224AiT0TkMlxxy5UiTUP94JeCxy1EYx55wECWk,2443
86
106
  openapi_client/cyberdesk_cloud_client/models/paginated_response_trajectory_response.py,sha256=gOdLxB8NSEualTnfJ8ww7M7evX8HpPlRgtUS8cgJHy8,2527
87
107
  openapi_client/cyberdesk_cloud_client/models/paginated_response_workflow_response.py,sha256=vjx7RtvrVv9hiE1CPNMdReyc4kKbbTdSEMfU0Z-jhK0,2503
108
+ openapi_client/cyberdesk_cloud_client/models/power_shell_exec_request.py,sha256=LoFKZ1fUeW3NM-fxrAMhbplyEDC_wOWpOjEb2vOQbuQ,3543
109
+ openapi_client/cyberdesk_cloud_client/models/power_shell_session_request.py,sha256=2Ix3dnjljWXO6KuOTPCykkYJim1at0_vAu1dh4Dahcw,2361
110
+ openapi_client/cyberdesk_cloud_client/models/powershell_exec_v1_computer_machine_id_shell_powershell_exec_post_response_powershell_exec_v1_computer_machine_id_shell_powershell_exec_post.py,sha256=N496N5sS2XP1dqAvoB3EplU3Dxwtf867Vr8hhh315V8,1813
111
+ openapi_client/cyberdesk_cloud_client/models/powershell_session_v1_computer_machine_id_shell_powershell_session_post_response_powershell_session_v1_computer_machine_id_shell_powershell_session_post.py,sha256=pmt2dgp_0v1YoLJqDXTXdpJ29TBenyCC4C_xmUCFGgA,1873
88
112
  openapi_client/cyberdesk_cloud_client/models/request_log_create.py,sha256=6CNnBvl9oyGs0J0R994eFn-TIdl6ohsofvCc2SXVfWc,6072
89
113
  openapi_client/cyberdesk_cloud_client/models/request_log_response.py,sha256=mU3lUdbLRFg9XppHnO-GjKcvt4M_BCG5CynWwU7ivZE,7445
90
114
  openapi_client/cyberdesk_cloud_client/models/request_log_update.py,sha256=VcXBNffDOoEYYBjwvdkuSWPz04BW3c8YTcqzlZRb0ns,5677
91
- openapi_client/cyberdesk_cloud_client/models/run_create.py,sha256=MtO_9PWVPgeimH-zqtxD6GDEHyGnnneobVOtWIQGoYc,4343
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
117
+ openapi_client/cyberdesk_cloud_client/models/run_attachment_response.py,sha256=LZEFltiyC_bBVNlz3LM1H5MXFoBkVzk-CzNuvlTumJ4,5769
118
+ openapi_client/cyberdesk_cloud_client/models/run_attachment_update.py,sha256=rGXcB21waSTXG0-mt0XhNcwoJI1PhBpBDUkLfp8mM-0,2573
119
+ openapi_client/cyberdesk_cloud_client/models/run_create.py,sha256=hUMuozdNHMQwndTl-mCfQ8hGwPeJ_EkPeZEmAUQWMHc,6083
92
120
  openapi_client/cyberdesk_cloud_client/models/run_create_input_values_type_0.py,sha256=APV4O0GduU3fhHoJHMMOBk-h92Hf21c1ZU-pIsJoZpg,1282
93
- openapi_client/cyberdesk_cloud_client/models/run_response.py,sha256=JtUerG8he5GjGqwrU914kKvBsxO9HKPzD7LSvWf67nA,9660
121
+ openapi_client/cyberdesk_cloud_client/models/run_response.py,sha256=zZUNgMVc8-Lmm_X3t_XzWdY1x_B7f3JixPWebfwl_40,10689
94
122
  openapi_client/cyberdesk_cloud_client/models/run_response_input_values_type_0.py,sha256=NpMqT3qaMrLGA7mHBjvtS1fnMGc5zxwWLoFWunjjupA,1292
95
123
  openapi_client/cyberdesk_cloud_client/models/run_response_output_data_type_0.py,sha256=rO4YJAa26G_83CFtBTQ_ZKCURAxNS7PcvdKbfuvDcrA,1287
96
124
  openapi_client/cyberdesk_cloud_client/models/run_response_run_message_history_type_0_item.py,sha256=3x1N3yi3kyc1que3bizmHEuGBn5s7pEirEg4TgBV9FU,1348
@@ -110,11 +138,11 @@ openapi_client/cyberdesk_cloud_client/models/trajectory_response_trajectory_data
110
138
  openapi_client/cyberdesk_cloud_client/models/trajectory_update.py,sha256=dzqD6zAT-jySWaASRi833gpHmahpkXd_r3LMD3-M8Lw,3568
111
139
  openapi_client/cyberdesk_cloud_client/models/trajectory_update_trajectory_data_type_0_item.py,sha256=3Zt8-nV3ZHjXzL1y5xKQdrHb-7ILG4EjHvtA4xabde4,1355
112
140
  openapi_client/cyberdesk_cloud_client/models/validation_error.py,sha256=ZlK9hbhWr4zSC-dxZh9giERvMiYf9s2k8e1O9Rch_NI,2181
113
- openapi_client/cyberdesk_cloud_client/models/workflow_create.py,sha256=0W5E5fIw3P0c7hR2XKBsGsa7jvUS2dQXWfWxPfjAGXE,3023
114
- openapi_client/cyberdesk_cloud_client/models/workflow_response.py,sha256=LS3QfsYFaBLwo5OyiOsDNJFn31B8L9mQTphdNwVybVw,6470
141
+ openapi_client/cyberdesk_cloud_client/models/workflow_create.py,sha256=Z7XG8k1js_cXclCJKEBV_xk25mgr3BDuYgPLuQcXWEk,3490
142
+ openapi_client/cyberdesk_cloud_client/models/workflow_response.py,sha256=kC_ZGUweaiogKqyRS1yjByHuYqZW0jzxuEyM9CIfFsc,6937
115
143
  openapi_client/cyberdesk_cloud_client/models/workflow_response_old_versions_type_0_item.py,sha256=W9AxxlBlN3rUwLDcoUx5H7MUiYA9UztfX9iEpNGlgAs,1340
116
- openapi_client/cyberdesk_cloud_client/models/workflow_update.py,sha256=JF82Mw0QkYsfita6nWPBtfDHLduoz8Bf7pJw8VmDXbA,3506
117
- cyberdesk-1.8.0.dist-info/METADATA,sha256=zoiYGTrQQ-ySZo5l1w093qcnZJBP5re-DyLuQKfnh88,6051
118
- cyberdesk-1.8.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
119
- cyberdesk-1.8.0.dist-info/top_level.txt,sha256=qTYHZHVHh3VClNPQsiFFA8p8tmJgFGhq9G1COd-pX_A,25
120
- cyberdesk-1.8.0.dist-info/RECORD,,
144
+ openapi_client/cyberdesk_cloud_client/models/workflow_update.py,sha256=_zMo2mJbYdKILygBXwebAD37SJJCUZOTkJkMOCzeNTA,4439
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,,